use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MapGetMethod method getAsSubquery.
/**
* Implementation of Map.get() using a subquery on the table representing the map,
* adding a condition on the key and returning the value.
* @param stmt SQLStatement
* @param mapExpr The map expression
* @param keyValExpr The key value expression
* @return The value expression
*/
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr, SQLExpression keyValExpr) {
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
MapMetaData mapmd = mmd.getMap();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
JavaTypeMapping ownerMapping = null;
JavaTypeMapping keyMapping = null;
JavaTypeMapping valMapping = null;
Table mapTbl = null;
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
// JoinTable
mapTbl = storeMgr.getTable(mmd);
ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
keyMapping = ((MapTable) mapTbl).getKeyMapping();
valMapping = ((MapTable) mapTbl).getValueMapping();
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// ForeignKey from value table to key
AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
String keyFieldName = mmd.getKeyMetaData().getMappedBy();
AbstractMemberMetaData valKeyMmd = valCmd.getMetaDataForMember(keyFieldName);
keyMapping = mapTbl.getMemberMapping(valKeyMmd);
valMapping = mapTbl.getIdMapping();
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// ForeignKey from key table to value
AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
keyMapping = mapTbl.getIdMapping();
String valFieldName = mmd.getValueMetaData().getMappedBy();
AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(valFieldName);
valMapping = mapTbl.getMemberMapping(keyValMmd);
} else {
throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
}
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
subStmt.setClassLoaderResolver(clr);
SQLExpression valExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
subStmt.select(valExpr, null);
// Link to primary statement
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
// Condition on key
SQLExpression keyExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), keyMapping);
subStmt.whereAnd(keyExpr.eq(keyValExpr), true);
SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
subExpr.setJavaTypeMapping(valMapping);
return subExpr;
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MapValueMethod method getAsSubquery.
/**
* Implementation of VALUE(map) using a subquery on the table representing the map, returning the value.
* @param stmt SQLStatement
* @param mapExpr The map expression
* @return The value expression
*/
protected SQLExpression getAsSubquery(SQLStatement stmt, MapExpression mapExpr) {
AbstractMemberMetaData mmd = mapExpr.getJavaTypeMapping().getMemberMetaData();
MapMetaData mapmd = mmd.getMap();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
JavaTypeMapping ownerMapping = null;
JavaTypeMapping valMapping = null;
Table mapTbl = null;
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
// JoinTable
mapTbl = storeMgr.getTable(mmd);
ownerMapping = ((MapTable) mapTbl).getOwnerMapping();
valMapping = ((MapTable) mapTbl).getValueMapping();
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// ForeignKey from value table to key
AbstractClassMetaData valCmd = mapmd.getValueClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getValueType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
valMapping = mapTbl.getIdMapping();
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// ForeignKey from key table to value
AbstractClassMetaData keyCmd = mapmd.getKeyClassMetaData(clr);
mapTbl = storeMgr.getDatastoreClass(mmd.getMap().getKeyType(), clr);
if (mmd.getMappedBy() != null) {
ownerMapping = mapTbl.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
ownerMapping = ((DatastoreClass) mapTbl).getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
String valFieldName = mmd.getValueMetaData().getMappedBy();
AbstractMemberMetaData keyValMmd = keyCmd.getMetaDataForMember(valFieldName);
valMapping = mapTbl.getMemberMapping(keyValMmd);
} else {
throw new NucleusException("Invalid map for " + mapExpr + " in get() call");
}
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
SelectStatement subStmt = new SelectStatement(stmt, storeMgr, mapTbl, null, null);
subStmt.setClassLoaderResolver(clr);
SQLExpression valExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), valMapping);
subStmt.select(valExpr, null);
// Link to primary statement
SQLExpression elementOwnerExpr = exprFactory.newExpression(subStmt, subStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerIdExpr = exprFactory.newExpression(stmt, mapExpr.getSQLTable(), mapExpr.getSQLTable().getTable().getIdMapping());
subStmt.whereAnd(elementOwnerExpr.eq(ownerIdExpr), true);
SubqueryExpression subExpr = new SubqueryExpression(stmt, subStmt);
subExpr.setJavaTypeMapping(valMapping);
return subExpr;
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class MapValueMethod method getAsJoin.
/**
* Implementation of VALUE(map) using a join to the table representing the map, and returning the value.
* @param parentStmt The parent SQL statement
* @param mapExpr The map expression
* @return The value expression
*/
protected SQLExpression getAsJoin(SQLStatement parentStmt, MapExpression mapExpr) {
JavaTypeMapping m = mapExpr.getJavaTypeMapping();
RDBMSStoreManager storeMgr = parentStmt.getRDBMSManager();
ClassLoaderResolver clr = parentStmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = parentStmt.getSQLExpressionFactory();
AbstractMemberMetaData mmd = m.getMemberMetaData();
// Use the statement of the table for this Map expression, since it could be in an outer query
SQLStatement stmt = mapExpr.getSQLTable().getSQLStatement();
if (mmd != null) {
MapMetaData mapmd = mmd.getMap();
SQLTable mapSqlTbl = mapExpr.getSQLTable();
// Set alias of "map" table from MapExpression in case it was defined in FROM clause
String mapJoinAlias = mapExpr.getAliasForMapTable();
if (mapJoinAlias == null) {
mapJoinAlias = (mapExpr.getSQLTable().getAlias().toString() + "_" + mmd.getName()).toUpperCase();
}
if (mapmd.getMapType() == MapType.MAP_TYPE_JOIN) {
// Add join to join table
MapTable joinTbl = (MapTable) storeMgr.getTable(mmd);
SQLTable joinSqlTbl = stmt.getTable(mapJoinAlias);
if (joinSqlTbl == null) {
joinSqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), joinTbl, mapJoinAlias, joinTbl.getOwnerMapping(), null, null);
}
// Return value expression
if (mapmd.getValueClassMetaData(clr) != null && !mapmd.isEmbeddedValue()) {
// Persistable value so join to its table (default to "{mapJoinAlias}_VALUE")
DatastoreClass valTable = storeMgr.getDatastoreClass(mapmd.getValueType(), clr);
SQLTable valueSqlTbl = stmt.getTable(mapJoinAlias + "_VALUE");
if (valueSqlTbl == null) {
valueSqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getValueMapping(), valTable, mapJoinAlias + "_VALUE", valTable.getIdMapping(), null, null);
}
return exprFactory.newExpression(stmt, valueSqlTbl, valTable.getIdMapping());
}
return exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getValueMapping());
} else if (mapmd.getMapType() == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Key stored in value table, so join to value table
DatastoreClass valTable = storeMgr.getDatastoreClass(mapmd.getValueType(), clr);
AbstractClassMetaData valCmd = mmd.getMap().getValueClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = valTable.getMemberMapping(valCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = valTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable valSqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), valTable, mapJoinAlias, mapTblOwnerMapping, null, null);
// Return value expression
return exprFactory.newExpression(stmt, valSqlTbl, valTable.getIdMapping());
} else if (mapmd.getMapType() == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Value stored in key table, so join to key table
DatastoreClass keyTable = storeMgr.getDatastoreClass(mapmd.getKeyType(), clr);
AbstractClassMetaData keyCmd = mmd.getMap().getKeyClassMetaData(clr);
JavaTypeMapping mapTblOwnerMapping;
if (mmd.getMappedBy() != null) {
mapTblOwnerMapping = keyTable.getMemberMapping(keyCmd.getMetaDataForMember(mmd.getMappedBy()));
} else {
mapTblOwnerMapping = keyTable.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable keySqlTbl = stmt.join(JoinType.INNER_JOIN, mapSqlTbl, mapSqlTbl.getTable().getIdMapping(), keyTable, mapJoinAlias, mapTblOwnerMapping, null, null);
// Return value expression
AbstractMemberMetaData valKeyMmd = mapmd.getKeyClassMetaData(clr).getMetaDataForMember(mmd.getValueMetaData().getMappedBy());
JavaTypeMapping valueMapping = keyTable.getMemberMapping(valKeyMmd);
return exprFactory.newExpression(stmt, keySqlTbl, valueMapping);
}
}
throw new NucleusException("KEY(map) for the filter is not supported for " + mapExpr + ". Why not contribute support for it?");
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class ListIndexOfMethod method getExpression.
/* (non-Javadoc)
* @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
*/
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
SQLExpression collSqlExpr = null;
SQLExpression elemSqlExpr = null;
if (expr != null) {
if (args == null || args.size() == 0 || args.size() > 1) {
throw new NucleusException(Localiser.msg("060016", "indexOf", "CollectionExpression", 1));
}
elemSqlExpr = args.get(0);
collSqlExpr = expr;
} else {
if (args == null || args.size() != 2) {
throw new NucleusException(Localiser.msg("060016", "indexOf", "CollectionExpression", 2));
}
elemSqlExpr = args.get(0);
collSqlExpr = args.get(1);
}
AbstractMemberMetaData mmd = collSqlExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd == null) {
// TODO Cater for the List being an input parameter
throw new NucleusException(Localiser.msg("060020", "indexOf", collSqlExpr.getClass().getName()));
}
if (!mmd.hasCollection()) {
throw new NucleusException("List.indexOf expression for field " + mmd.getFullFieldName() + " does not represent a collection!");
} else if (!mmd.getOrderMetaData().isIndexedList()) {
throw new NucleusException("List.indexOf expression for field " + mmd.getFullFieldName() + " does not represent an indexed list!");
}
JavaTypeMapping orderMapping = null;
SQLTable orderTable = null;
Table joinTbl = stmt.getRDBMSManager().getTable(mmd);
if (joinTbl != null) {
// 1-N via join table
CollectionTable collTable = (CollectionTable) joinTbl;
orderTable = stmt.getTableForDatastoreContainer(collTable);
if (orderTable == null) {
// TODO Allow control over the join type? the alias?
orderTable = stmt.join(JoinType.LEFT_OUTER_JOIN, collSqlExpr.getSQLTable(), collSqlExpr.getSQLTable().getTable().getIdMapping(), collTable, null, collTable.getOwnerMapping(), null, null);
}
orderMapping = collTable.getOrderMapping();
} else {
// 1-N via FK
orderTable = elemSqlExpr.getSQLTable();
orderMapping = ((ClassTable) elemSqlExpr.getSQLTable().getTable()).getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
}
return new NumericExpression(stmt, orderTable, orderMapping);
}
use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.
the class ArrayContainsMethod method getExpression.
/* (non-Javadoc)
* @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
*/
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
if (args == null || args.size() != 1) {
throw new NucleusException("Incorrect arguments for Array.contains(SQLExpression)");
}
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ArrayExpression arrExpr = (ArrayExpression) expr;
SQLExpression elemExpr = args.get(0);
if (elemExpr.isParameter()) {
// Element is a parameter so make sure its type is set
AbstractMemberMetaData mmd = arrExpr.getJavaTypeMapping().getMemberMetaData();
if (mmd != null) {
stmt.getQueryGenerator().bindParameter(elemExpr.getParameterName(), mmd.getType().getComponentType());
}
}
if (expr instanceof ArrayLiteral) {
if (elemExpr instanceof UnboundExpression) {
Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
}
ArrayLiteral lit = (ArrayLiteral) expr;
Object array = lit.getValue();
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
if (array == null || Array.getLength(array) == 0) {
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
if (arrExpr.isParameter()) {
stmt.getQueryGenerator().useParameterExpressionAsLiteral((ArrayLiteral) arrExpr);
}
boolean useInExpression = false;
List<SQLExpression> collElementExprs = lit.getElementExpressions();
if (collElementExprs != null && !collElementExprs.isEmpty()) {
// Make sure the the collection element(s) are compatible with the elemExpr
boolean incompatible = true;
Class elemtype = clr.classForName(elemExpr.getJavaTypeMapping().getType());
Iterator<SQLExpression> collElementExprIter = collElementExprs.iterator();
while (collElementExprIter.hasNext()) {
SQLExpression collElementExpr = collElementExprIter.next();
Class collElemType = clr.classForName(collElementExpr.getJavaTypeMapping().getType());
if (elementTypeCompatible(elemtype, collElemType)) {
incompatible = false;
break;
}
}
if (incompatible) {
// The provided element type isn't assignable to any of the input collection elements!
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
}
// Check if we should compare using an "IN (...)" expression
SQLExpression collElementExpr = collElementExprs.get(0);
if (collElementExpr instanceof StringExpression || collElementExpr instanceof NumericExpression || collElementExpr instanceof TemporalExpression || collElementExpr instanceof CharacterExpression || collElementExpr instanceof EnumExpression) {
useInExpression = true;
}
}
if (useInExpression) {
// Return "elem IN (val1, val2, ...)"
SQLExpression[] exprs = (collElementExprs != null ? collElementExprs.toArray(new SQLExpression[collElementExprs.size()]) : null);
return new InExpression(elemExpr, exprs);
}
// TODO If elemExpr is a parameter and collExpr is derived from a parameter ?
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = lit.getElementExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
SQLExpression arrElemExpr = elementExprs.get(i);
if (bExpr == null) {
bExpr = arrElemExpr.eq(elemExpr);
} else {
bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
} else if (arrExpr.getElementExpressions() != null) {
if (elemExpr instanceof UnboundExpression) {
Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
}
// Array defined in query that has some expressions for elements, so just do OR chain
BooleanExpression bExpr = null;
List<SQLExpression> elementExprs = arrExpr.getElementExpressions();
for (int i = 0; i < elementExprs.size(); i++) {
SQLExpression arrElemExpr = elementExprs.get(i);
if (bExpr == null) {
bExpr = arrElemExpr.eq(elemExpr);
} else {
bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
}
}
if (bExpr != null) {
bExpr.encloseInParentheses();
}
return bExpr;
} else {
// TODO Support inner join variant
return containsAsSubquery(stmt, arrExpr, elemExpr);
}
}
Aggregations