use of org.datanucleus.store.rdbms.sql.UnionStatementGenerator in project datanucleus-rdbms by datanucleus.
the class MapValueCollectionStore method getSQLStatementForIterator.
/**
* Method to generate an SQLStatement for iterating through values of the map.
* Populates the iteratorMappingDef and iteratorMappingParams.
* Creates a statement that selects the value table(s), and adds any necessary join to the containerTable
* if that is not the value table. If the value is embedded then selects the table it is embedded in.
* Adds a restriction on the ownerMapping of the containerTable so we can restrict to the owner object.
* @param ownerOP ObjectProvider for the owner object
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForIterator(ObjectProvider ownerOP) {
SelectStatement sqlStmt = null;
ExecutionContext ec = ownerOP.getExecutionContext();
final ClassLoaderResolver clr = ec.getClassLoaderResolver();
final Class valueCls = clr.classForName(elementType);
SQLTable containerSqlTbl = null;
MapType mapType = getOwnerMemberMetaData().getMap().getMapType();
FetchPlan fp = ec.getFetchPlan();
if (elementCmd != null && elementCmd.getDiscriminatorStrategyForTable() != null && elementCmd.getDiscriminatorStrategyForTable() != DiscriminatorStrategy.NONE) {
// Map<?, PC> where value has discriminator
if (ClassUtils.isReferenceType(valueCls)) {
// Take the metadata for the first implementation of the reference type
String[] clsNames = storeMgr.getNucleusContext().getMetaDataManager().getClassesImplementingInterface(elementType, clr);
Class[] cls = new Class[clsNames.length];
for (int j = 0; j < clsNames.length; j++) {
cls[j] = clr.classForName(clsNames[j]);
}
SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, cls, true, null, null);
sqlStmt = stmtGen.getStatement(ec);
} else {
SelectStatementGenerator stmtGen = new DiscriminatorStatementGenerator(storeMgr, clr, valueCls, true, null, null);
sqlStmt = stmtGen.getStatement(ec);
}
iterateUsingDiscriminator = true;
if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
// Join to key table and select value fields
JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
iteratorMappingDef = new StatementClassMapping();
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Select value fields
containerSqlTbl = sqlStmt.getPrimaryTable();
iteratorMappingDef = new StatementClassMapping();
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
// Join to join table and select value fields
JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
iteratorMappingDef = new StatementClassMapping();
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
}
} else {
if (mapType == MapType.MAP_TYPE_VALUE_IN_KEY) {
if (elementCmd != null) {
// TODO Allow for null value [change to select the key table and left outer join to the key]
// Select of value table, joining to key table
iteratorMappingDef = new StatementClassMapping();
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
// Select of value in key table
sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
containerSqlTbl = sqlStmt.getPrimaryTable();
SQLTable elemSqlTblForValue = containerSqlTbl;
if (elementMapping.getTable() != containerSqlTbl.getTable()) {
elemSqlTblForValue = sqlStmt.getTableForDatastoreContainer(elementMapping.getTable());
if (elemSqlTblForValue == null) {
// Add join to key table holding value
elemSqlTblForValue = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), sqlStmt.getPrimaryTable().getTable().getIdMapping(), elementMapping.getTable(), null, elementMapping.getTable().getIdMapping(), null, null, true);
}
}
sqlStmt.select(elemSqlTblForValue, elementMapping, null);
}
} else if (mapType == MapType.MAP_TYPE_KEY_IN_VALUE) {
// Select of value in value table (allow union of possible value types)
iteratorMappingDef = new StatementClassMapping();
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
containerSqlTbl = sqlStmt.getPrimaryTable();
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
if (elementCmd != null) {
// TODO Allow for null value [change to select the join table and left outer join to the key]
// Select of value table, joining to key table
iteratorMappingDef = new StatementClassMapping();
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
iteratorMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
JavaTypeMapping valueIdMapping = sqlStmt.getPrimaryTable().getTable().getIdMapping();
containerSqlTbl = sqlStmt.join(JoinType.INNER_JOIN, sqlStmt.getPrimaryTable(), valueIdMapping, containerTable, null, elementMapping, null, null, true);
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, iteratorMappingDef, fp, sqlStmt.getPrimaryTable(), elementCmd, fp.getMaxFetchDepth());
} else {
// Select of value in join table
sqlStmt = new SelectStatement(storeMgr, containerTable, null, null);
containerSqlTbl = sqlStmt.getPrimaryTable();
sqlStmt.select(sqlStmt.getPrimaryTable(), elementMapping, null);
}
}
}
// Apply condition on owner field to filter by owner
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, containerSqlTbl, ownerMapping);
SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
// Input parameter(s) - the owner
int inputParamNum = 1;
StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
if (sqlStmt.getNumberOfUnions() > 0) {
// Add parameter occurrence for each union of statement
for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
} else {
int[] paramPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerMapping.getNumberOfDatastoreMappings(); k++) {
paramPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(paramPositions);
}
iteratorMappingParams = new StatementParameterMapping();
iteratorMappingParams.addMappingForParameter("owner", ownerIdx);
return sqlStmt;
}
use of org.datanucleus.store.rdbms.sql.UnionStatementGenerator in project datanucleus-rdbms by datanucleus.
the class JoinMapStore method getSQLStatementForGet.
/**
* Method to return an SQLStatement for retrieving the value for a key.
* Selects the join table and optionally joins to the value table if it has its own table.
* @param ownerOP ObjectProvider for the owning object
* @return The SQLStatement
*/
protected SelectStatement getSQLStatementForGet(ObjectProvider ownerOP) {
SelectStatement sqlStmt = null;
ExecutionContext ec = ownerOP.getExecutionContext();
final ClassLoaderResolver clr = ownerOP.getExecutionContext().getClassLoaderResolver();
Class valueCls = clr.classForName(this.valueType);
if (valuesAreEmbedded || valuesAreSerialised) {
// Value is stored in join table
sqlStmt = new SelectStatement(storeMgr, mapTable, null, null);
sqlStmt.setClassLoaderResolver(clr);
sqlStmt.select(sqlStmt.getPrimaryTable(), valueMapping, null);
} else {
// Value is stored in own table
getMappingDef = new StatementClassMapping();
if (!valueCmd.getFullClassName().equals(valueCls.getName())) {
valueCls = clr.classForName(valueCmd.getFullClassName());
}
UnionStatementGenerator stmtGen = new UnionStatementGenerator(storeMgr, clr, valueCls, true, null, null, mapTable, null, valueMapping);
stmtGen.setOption(SelectStatementGenerator.OPTION_SELECT_DN_TYPE);
getMappingDef.setNucleusTypeColumnName(UnionStatementGenerator.DN_TYPE_COLUMN);
sqlStmt = stmtGen.getStatement(ec);
// Select the value field(s)
SQLTable valueSqlTbl = sqlStmt.getTable(valueTable, sqlStmt.getPrimaryTable().getGroupName());
if (valueSqlTbl == null) {
// Root value candidate has no table, so try to find a value candidate with a table that exists in this statement
Collection<String> valueSubclassNames = storeMgr.getSubClassesForClass(valueType, true, clr);
if (valueSubclassNames != null && !valueSubclassNames.isEmpty()) {
for (String valueSubclassName : valueSubclassNames) {
DatastoreClass valueTbl = storeMgr.getDatastoreClass(valueSubclassName, clr);
if (valueTbl != null) {
valueSqlTbl = sqlStmt.getTable(valueTbl, sqlStmt.getPrimaryTable().getGroupName());
if (valueSqlTbl != null) {
break;
}
}
}
}
}
SQLStatementHelper.selectFetchPlanOfSourceClassInStatement(sqlStmt, getMappingDef, ec.getFetchPlan(), valueSqlTbl, valueCmd, ec.getFetchPlan().getMaxFetchDepth());
}
// Apply condition on owner field to filter by owner
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
SQLTable ownerSqlTbl = SQLStatementHelper.getSQLTableForMappingOfTable(sqlStmt, sqlStmt.getPrimaryTable(), ownerMapping);
SQLExpression ownerExpr = exprFactory.newExpression(sqlStmt, ownerSqlTbl, ownerMapping);
SQLExpression ownerVal = exprFactory.newLiteralParameter(sqlStmt, ownerMapping, null, "OWNER");
sqlStmt.whereAnd(ownerExpr.eq(ownerVal), true);
// Apply condition on key
if (keyMapping instanceof SerialisedMapping) {
// if the keyMapping contains a BLOB column (or any other column not supported by the database
// as primary key), uses like instead of the operator OP_EQ (=)
// in future do not check if the keyMapping is of ObjectMapping, but use the database
// adapter to check the data types not supported as primary key
// if object mapping (BLOB) use like
SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
sqlStmt.whereAnd(new org.datanucleus.store.rdbms.sql.expression.BooleanExpression(keyExpr, Expression.OP_LIKE, keyVal), true);
} else {
SQLExpression keyExpr = exprFactory.newExpression(sqlStmt, sqlStmt.getPrimaryTable(), keyMapping);
SQLExpression keyVal = exprFactory.newLiteralParameter(sqlStmt, keyMapping, null, "KEY");
sqlStmt.whereAnd(keyExpr.eq(keyVal), true);
}
// Input parameter(s) - owner, key
int inputParamNum = 1;
StatementMappingIndex ownerIdx = new StatementMappingIndex(ownerMapping);
StatementMappingIndex keyIdx = new StatementMappingIndex(keyMapping);
if (sqlStmt.getNumberOfUnions() > 0) {
// Add parameter occurrence for each union of statement
for (int j = 0; j < sqlStmt.getNumberOfUnions() + 1; j++) {
int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerPositions.length; k++) {
ownerPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(ownerPositions);
int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < keyPositions.length; k++) {
keyPositions[k] = inputParamNum++;
}
keyIdx.addParameterOccurrence(keyPositions);
}
} else {
int[] ownerPositions = new int[ownerMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < ownerPositions.length; k++) {
ownerPositions[k] = inputParamNum++;
}
ownerIdx.addParameterOccurrence(ownerPositions);
int[] keyPositions = new int[keyMapping.getNumberOfDatastoreMappings()];
for (int k = 0; k < keyPositions.length; k++) {
keyPositions[k] = inputParamNum++;
}
keyIdx.addParameterOccurrence(keyPositions);
}
getMappingParams = new StatementParameterMapping();
getMappingParams.addMappingForParameter("owner", ownerIdx);
getMappingParams.addMappingForParameter("key", keyIdx);
return sqlStmt;
}
Aggregations