* @param candidateAlias Alias for the candidate
* @return The Query Statement for iterating through objects with a discriminator column
*/
public QueryExpression getQueryStatement(DatastoreIdentifier candidateAlias)
{
QueryExpression stmt = null;
DiscriminatorMetaData dismd = candidateTable.getDiscriminatorMetaData();
JavaTypeMapping discriminatorMapping = candidateTable.getDiscriminatorMapping(true);
if (discriminatorMapping != null)
{
// Use discriminator metadata from the place where the discriminator mapping is defined
dismd = discriminatorMapping.getDatastoreContainer().getDiscriminatorMetaData();
}
boolean hasDiscriminator = (discriminatorMapping != null && dismd.getStrategy() != DiscriminatorStrategy.NONE);
LogicSetExpression discrimTableExpr = null;
if (selectTable != null)
{
// Select the required "selectTable"
stmt = dba.newQueryStatement(selectTable, candidateAlias, clr);
// Join from the "selectTable" to the table of our candidate
ScalarExpression selectExpression = selectCandidateMapping.newScalarExpression(stmt, stmt.getMainTableExpression());
LogicSetExpression candidateTableExpression = stmt.newTableExpression(candidateTable, candidateTableIdentifier);
ScalarExpression candidateExpression = candidateTable.getIDMapping().newScalarExpression(stmt, candidateTableExpression);
if (allowNulls)
{
// Do LEFT OUTER JOIN since we need to allow nulls in the results
stmt.leftOuterJoin(selectExpression, candidateExpression, candidateTableExpression, true);
}
else
{
// Do INNER JOIN since we don't allow nulls in the results
stmt.innerJoin(selectExpression, candidateExpression, candidateTableExpression, true);
}
discrimTableExpr = stmt.getTableExpression(candidateTableIdentifier);
if (hasDiscriminator && selectDiscriminator)
{
// Select the discriminator column so we can process the ResultSet
stmt.selectScalarExpression(candidateTable.getDiscriminatorMapping(true).newScalarExpression(stmt, candidateTableExpression));
}
}
else
{
// Select the candidate table
stmt = dba.newQueryStatement(candidateTable, candidateAlias, clr);
discrimTableExpr = stmt.getMainTableExpression();
if (hasDiscriminator && selectDiscriminator)
{
// Select the discriminator column so we can process the ResultSet
stmt.select(discriminatorMapping);
}
}
// Check if we can omit the discriminator restriction
if (includeSubclasses && hasDiscriminator && candidateTable.getDiscriminatorMapping(false) != null &&
!storeMgr.getOMFContext().getMetaDataManager().isPersistentDefinitionImplementation(candidateFullClassName))
{
String[] managedClasses = getCandidateTableManagedClasses();
if (managedClasses.length == 1)
{
// Only the candidate managed by this table and the discrim is here and we're including subclasses
// in the SELECT so don't apply any restriction on the discriminator value
// Note : we omit the persistent interface impl case from here for now
restrictDiscriminator = false;
}
}
if (hasDiscriminator && restrictDiscriminator)
{
// Add the discriminator required values to the WHERE clause
// Loop through each possible candidate type and add the discrim values for each branch
boolean multipleDiscriminatorValues = candidateTypes.length > 1 ? true: false;
BooleanExpression discExpr = null;
for (int i=0; i<candidateTypes.length; i++)
{
// For this candidate type, go through the possible classes persistable in this table and add an OR to the WHERE clause
String candidateName = candidateTypes[i].getName();
BooleanExpression discExprCand = getExpressionForDiscriminatorForClass(stmt, candidateName,
dismd, discriminatorMapping, discrimTableExpr, storeMgr);
if (discExpr != null)
{
discExpr = discExpr.ior(discExprCand);
}
else
{
discExpr = discExprCand;
}
if (includeSubclasses)
{
Iterator iterator = storeMgr.getSubClassesForClass(candidateName, true, clr).iterator();
while (iterator.hasNext())
{
String subCandidateType = (String)iterator.next();
BooleanExpression discExprSub = getExpressionForDiscriminatorForClass(stmt,
subCandidateType, dismd, discriminatorMapping, discrimTableExpr, storeMgr);
discExpr = discExpr.ior(discExprSub);
if (!multipleDiscriminatorValues)
{
multipleDiscriminatorValues = true;
}
}
}
}
if (allowNulls)
{
// Allow for null value of discriminator
ScalarExpression expr = discriminatorMapping.newScalarExpression(stmt, discrimTableExpr);
ScalarExpression val = new NullLiteral(stmt);
BooleanExpression nullDiscExpr = expr.eq(val);
discExpr = discExpr.ior(nullDiscExpr);
if (!multipleDiscriminatorValues)
{
multipleDiscriminatorValues = true;
}
}
// Apply the discriminator to the query statement
if (multipleDiscriminatorValues)
{
discExpr.encloseWithInParentheses();
}
stmt.andCondition(discExpr);
}
return stmt;
}