use of org.datanucleus.store.rdbms.sql.SQLTable in project datanucleus-rdbms by datanucleus.
the class MapKeyMethod method getAsJoin.
/**
* Implementation of KEY(mapExpr) using a join to the table representing the map, and returning an expression for the key.
* @param mapExpr The map expression
* @return The value expression
*/
protected SQLExpression getAsJoin(SQLStatement stmt, MapExpression mapExpr) {
JavaTypeMapping m = mapExpr.getJavaTypeMapping();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
AbstractMemberMetaData mmd = m.getMemberMetaData();
// Use the statement of the table for this Map expression, since it could be in an outer query
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 key expression
if (mapmd.getKeyClassMetaData(clr) != null && !mapmd.isEmbeddedKey()) {
// Persistable key so join to its table (default to "{mapJoinAlias}_KEY")
DatastoreClass keyTable = storeMgr.getDatastoreClass(mapmd.getKeyType(), clr);
SQLTable keySqlTbl = stmt.getTable(mapJoinAlias + "_KEY");
if (keySqlTbl == null) {
keySqlTbl = stmt.join(JoinType.INNER_JOIN, joinSqlTbl, joinTbl.getKeyMapping(), keyTable, mapJoinAlias + "_KEY", keyTable.getIdMapping(), null, null);
}
return exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
}
return exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getKeyMapping());
} 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 key expression
AbstractMemberMetaData valKeyMmd = mapmd.getValueClassMetaData(clr).getMetaDataForMember(mmd.getKeyMetaData().getMappedBy());
JavaTypeMapping keyMapping = valTable.getMemberMapping(valKeyMmd);
return exprFactory.newExpression(stmt, valSqlTbl, keyMapping);
} 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 key expression
return exprFactory.newExpression(stmt, keySqlTbl, keyTable.getIdMapping());
}
}
throw new NucleusException("KEY(map) for the filter is not supported for " + mapExpr + ". Why not contribute support for it?");
}
use of org.datanucleus.store.rdbms.sql.SQLTable in project datanucleus-rdbms by datanucleus.
the class CollectionContainsMethod method containsAsJoin.
/**
* Method to return an expression for Collection.contains using INNER JOIN to the element.
* This is only for use when there are no "!contains" and no "OR" operations.
* Creates SQL by adding INNER JOIN to the join table (where it exists), and also to the element table
* adding an AND condition on the element (with value of the elemExpr).
* Returns a BooleanExpression "TRUE" (since the INNER JOIN will guarantee if the element is
* contained of not).
* @param stmt SQLStatement
* @param collExpr Collection expression
* @param elemExpr Expression for the element
* @param joinType Join type
* @return Contains expression
*/
protected SQLExpression containsAsJoin(SQLStatement stmt, CollectionExpression collExpr, SQLExpression elemExpr, SQLJoin.JoinType joinType) {
boolean elemIsUnbound = (elemExpr instanceof UnboundExpression);
String varName = null;
String elemAlias = null;
String elemType = null;
if (elemIsUnbound) {
varName = ((UnboundExpression) elemExpr).getVariableName();
NucleusLogger.QUERY.debug("collection.contains(" + elemExpr + ") binding unbound variable " + varName + " using INNER JOIN");
} else if (!stmt.getQueryGenerator().hasExplicitJoins()) {
if (stmt.getJoinTypeForTable(elemExpr.getSQLTable()) == JoinType.CROSS_JOIN) {
elemAlias = stmt.removeCrossJoin(elemExpr.getSQLTable());
elemIsUnbound = true;
elemType = elemExpr.getJavaTypeMapping().getType();
NucleusLogger.QUERY.debug("collection.contains(" + elemExpr + ") was previously bound as CROSS JOIN but changing to INNER JOIN");
}
}
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
AbstractMemberMetaData mmd = collExpr.getJavaTypeMapping().getMemberMetaData();
AbstractClassMetaData elemCmd = mmd.getCollection().getElementClassMetaData(clr);
CollectionTable joinTbl = (CollectionTable) storeMgr.getTable(mmd);
if (elemIsUnbound) {
Class varType = stmt.getQueryGenerator().getTypeOfVariable(varName);
if (varType != null) {
elemType = varType.getName();
elemCmd = storeMgr.getMetaDataManager().getMetaDataForClass(elemType, clr);
}
}
if (elemType == null) {
elemType = mmd.getCollection().getElementType();
}
if (joinTbl != null) {
// JoinTable Collection - join from owner to join, then from join to element
if (elemCmd == null) {
// Collection<Non-PC>
SQLTable joinSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), joinTbl, elemAlias, joinTbl.getOwnerMapping(), null, null);
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, null, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
} else {
// Collection<PC>
SQLTable joinSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
if (!mmd.getCollection().isEmbeddedElement()) {
DatastoreClass elemTbl = storeMgr.getDatastoreClass(elemType, clr);
SQLTable elemSqlTbl = null;
if (joinTbl.getElementMapping() instanceof ReferenceMapping && ((ReferenceMapping) joinTbl.getElementMapping()).getMappingStrategy() == ReferenceMapping.PER_IMPLEMENTATION_MAPPING) {
JavaTypeMapping elemMapping = null;
JavaTypeMapping[] elemImplMappings = ((ReferenceMapping) joinTbl.getElementMapping()).getJavaTypeMapping();
for (int i = 0; i < elemImplMappings.length; i++) {
if (elemImplMappings[i].getType().equals(elemCmd.getFullClassName())) {
elemMapping = elemImplMappings[i];
break;
}
}
elemSqlTbl = stmt.join(joinType, joinSqlTbl, elemMapping, joinTbl.getElementMapping(), elemTbl, elemAlias, elemTbl.getIdMapping(), null, null, null, true, null);
} else {
elemSqlTbl = stmt.join(joinType, joinSqlTbl, joinTbl.getElementMapping(), elemTbl, elemAlias, elemTbl.getIdMapping(), null, null);
}
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
} else {
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
if (elemIsUnbound) {
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
}
}
} else {
// FK Collection - join from owner to element
DatastoreClass elemTbl = storeMgr.getDatastoreClass(mmd.getCollection().getElementType(), clr);
JavaTypeMapping ownerMapping = null;
if (mmd.getMappedBy() != null) {
ownerMapping = elemTbl.getMemberMapping(mmd.getRelatedMemberMetaData(clr)[0]);
} else {
ownerMapping = elemTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
}
SQLTable elemSqlTbl = stmt.join(joinType, collExpr.getSQLTable(), collExpr.getSQLTable().getTable().getIdMapping(), elemTbl, elemAlias, ownerMapping, null, null);
if (elemIsUnbound) {
SQLExpression elemIdExpr = null;
if (!elemType.equals(mmd.getCollection().getElementType())) {
// Variable is defined as a subclass of the declared type so add extra join to variable type
DatastoreClass varTbl = storeMgr.getDatastoreClass(elemType, clr);
SQLTable varSqlTbl = stmt.join(joinType, elemSqlTbl, elemTbl.getIdMapping(), varTbl, null, varTbl.getIdMapping(), null, null);
elemIdExpr = exprFactory.newExpression(stmt, varSqlTbl, varTbl.getIdMapping());
} else {
elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
}
// Bind the variable in the QueryGenerator
stmt.getQueryGenerator().bindVariable(varName, elemCmd, elemIdExpr.getSQLTable(), elemIdExpr.getJavaTypeMapping());
} else {
// Add restrict to element
SQLExpression elemIdExpr = exprFactory.newExpression(stmt, elemSqlTbl, elemTbl.getIdMapping());
addRestrictionOnElement(stmt, elemIdExpr, elemExpr);
}
}
JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, true));
}
use of org.datanucleus.store.rdbms.sql.SQLTable in project datanucleus-rdbms by datanucleus.
the class ListGetMethod method getAsInnerJoin.
/**
* Implementation of List.get() using an inner join to the table representing the list, adding a condition on the index and returning the element.
* @param stmt SQLStatement
* @param listExpr The list expression
* @param idxExpr The index expression
* @return The element expression
*/
protected SQLExpression getAsInnerJoin(SQLStatement stmt, CollectionExpression listExpr, SQLExpression idxExpr) {
JavaTypeMapping m = listExpr.getJavaTypeMapping();
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
AbstractMemberMetaData mmd = m.getMemberMetaData();
AbstractMemberMetaData[] relatedMmds = mmd.getRelatedMemberMetaData(clr);
if (mmd.getJoinMetaData() != null || relatedMmds != null && relatedMmds[0].getJoinMetaData() != null) {
// Join table List
CollectionTable joinTbl = (CollectionTable) storeMgr.getTable(mmd);
// Add join to join table
SQLTable joinSqlTbl = stmt.join(JoinType.INNER_JOIN, listExpr.getSQLTable(), listExpr.getSQLTable().getTable().getIdMapping(), joinTbl, null, joinTbl.getOwnerMapping(), null, null);
// Add condition on index
SQLExpression idxSqlExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getOrderMapping());
stmt.whereAnd(idxSqlExpr.eq(idxExpr), true);
// Return element expression
SQLExpression valueExpr = exprFactory.newExpression(stmt, joinSqlTbl, joinTbl.getElementMapping());
return valueExpr;
}
// FK List
DatastoreClass elementTbl = storeMgr.getDatastoreClass(mmd.getCollection().getElementType(), clr);
// Add join to element table
JavaTypeMapping targetMapping = null;
JavaTypeMapping orderMapping = null;
if (relatedMmds != null) {
targetMapping = elementTbl.getMemberMapping(relatedMmds[0]);
orderMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
} else {
targetMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_FK);
orderMapping = elementTbl.getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
}
SQLTable elemSqlTbl = stmt.join(JoinType.INNER_JOIN, listExpr.getSQLTable(), listExpr.getSQLTable().getTable().getIdMapping(), elementTbl, null, targetMapping, null, null);
// Add condition on index
SQLExpression idxSqlExpr = exprFactory.newExpression(stmt, elemSqlTbl, orderMapping);
stmt.whereAnd(idxSqlExpr.eq(idxExpr), true);
// Return element expression
return exprFactory.newExpression(stmt, elemSqlTbl, elementTbl.getIdMapping());
}
use of org.datanucleus.store.rdbms.sql.SQLTable in project datanucleus-rdbms by datanucleus.
the class SQLExpressionFactory method newExpression.
/**
* Factory for an expression representing a mapping on a table.
* @param stmt The statement
* @param sqlTbl The table
* @param mapping The mapping
* @param parentMapping Optional parent mapping of this mapping (e.g when handling an implementation of an interface)
* @return The expression
*/
public SQLExpression newExpression(SQLStatement stmt, SQLTable sqlTbl, JavaTypeMapping mapping, JavaTypeMapping parentMapping) {
// Use "new SQLExpression(SQLStatement, SQLTable, JavaTypeMapping)"
SQLTable exprSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(stmt, sqlTbl, parentMapping == null ? mapping : parentMapping);
Object[] args = new Object[] { stmt, exprSqlTbl, mapping };
Class expressionClass = expressionClassByMappingName.get(mapping.getClass().getName());
if (expressionClass != null) {
// Use built-in expression class
return (SQLExpression) ClassUtils.newInstance(expressionClass, EXPR_CREATION_ARG_TYPES, new Object[] { stmt, exprSqlTbl, mapping });
}
try {
// Fallback to the plugin mechanism
SQLExpression sqlExpr = (SQLExpression) storeMgr.getNucleusContext().getPluginManager().createExecutableExtension("org.datanucleus.store.rdbms.sql_expression", "mapping-class", mapping.getClass().getName(), "expression-class", EXPR_CREATION_ARG_TYPES, args);
if (sqlExpr == null) {
throw new NucleusException(Localiser.msg("060004", mapping.getClass().getName()));
}
expressionClassByMappingName.put(mapping.getClass().getName(), sqlExpr.getClass());
return sqlExpr;
} catch (Exception e) {
String msg = Localiser.msg("060005", mapping.getClass().getName());
NucleusLogger.QUERY.error(msg, e);
throw new NucleusException(msg, e);
}
}
Aggregations