{
// 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 = ((ClassTable)candidateTable).getManagedClasses();
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
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();
addConditionForCandidateClass(stmt, candidateName, dismd, discriminatorMapping, discrimTableExpr, storeMgr);
if (includeSubclasses)
{
Iterator iterator = storeMgr.getSubClassesForClass(candidateName, true, clr).iterator();
while (iterator.hasNext())
{
String subCandidateType = (String)iterator.next();
addConditionForCandidateClass(stmt, subCandidateType, dismd, discriminatorMapping, discrimTableExpr, storeMgr);
}
}
}
if (allowNulls)
{
// Allow for null value of discriminator
ScalarExpression discrExpr = discriminatorMapping.newScalarExpression(stmt, discrimTableExpr);
ScalarExpression discrVal = new NullLiteral(stmt);
stmt.iorCondition(discrExpr.eq(discrVal));
}
}
return stmt;