// TODO Enable instanceof on non-PC fields (currently just return "true")
return new BooleanLiteral(qs, mapping, true).eq(new BooleanLiteral(qs, mapping, true));
}
// Check if the table of the field has a discriminator
IdentifierFactory idFactory = qs.getStoreManager().getIdentifierFactory();
DiscriminatorMetaData dismd = table.getDiscriminatorMetaData();
DiscriminatorMapping discriminatorMapping = (DiscriminatorMapping)table.getDiscriminatorMapping(false);
if (discriminatorMapping != null)
{
// Has a discriminator so do a join to the table of the field and apply a constraint on its discriminator
LogicSetExpression fieldTblExpr = null;
if (fieldName == null)
{
// Using THIS so use default table expression
fieldTblExpr = qs.getMainTableExpression();
}
else
{
// Using field, so our real table will have an identifier of "THIS_{fieldName}" via INNER JOIN
String fieldIdentifier = te.getAlias().getIdentifier();
fieldIdentifier += '.' + fieldName;
DatastoreIdentifier fieldRangeVar = idFactory.newIdentifier(IdentifierFactory.TABLE, fieldIdentifier);
fieldTblExpr = qs.getTableExpression(fieldRangeVar);
if (fieldTblExpr == null)
{
fieldTblExpr = qs.newTableExpression(table, fieldRangeVar);
}
ScalarExpression fieldExpr = table.getIDMapping().newScalarExpression(qs, fieldTblExpr);
expr = mapping.newScalarExpression(qs, te);
qs.innerJoin(fieldExpr, expr, fieldTblExpr, true, true);
}
// Return a constraint on the discriminator for this table to get the right instances
// This allows all discriminator values for the instanceof class and all of its subclasses
// DISCRIM = 'baseVal' OR DISCRIM = 'sub1Val' OR DISCRIM = 'sub2Val' ... etc
BooleanExpression discrExpr =
booleanConditionForClassInDiscriminator(qs, instanceofClass.getName(), dismd,
discriminatorMapping, fieldTblExpr);
Iterator subclassIter = qs.getStoreManager().getSubClassesForClass(instanceofClass.getName(),
true, clr).iterator();
while (subclassIter.hasNext())
{
String subCandidateType = (String)subclassIter.next();
discrExpr.ior(booleanConditionForClassInDiscriminator(qs, subCandidateType, dismd,
discriminatorMapping, fieldTblExpr));
}
discrExpr.encloseWithInParentheses();
return discrExpr;
}
else
{
// No discriminator so maybe union, or just a SELECT
// Need to join to the instanceof class (where appropriate)
// TODO RDBMS-71 Only join on the UNION select that it is applicable to
if (table instanceof DatastoreClass)
{
DatastoreClass ct = (DatastoreClass)table;
if (ct.managesClass(instanceofClass.getName()))
{
// This type is managed in this table so must be an instance
return new BooleanLiteral(qs, mapping, true).eq(new BooleanLiteral(qs, mapping, true));
}
else
{
// The instanceof type is not managed here
DatastoreClass instanceofTable = qs.getStoreManager().getDatastoreClass(
instanceofClass.getName(), clr);
String fieldIdentifier = te.getAlias().getIdentifier();
if (fieldName == null)
{
// Using THIS, so our real table will have an identifier of "THIS_INST"
fieldIdentifier += ".INST";
}
else
{
// Using field, so our real table will have an identifier of "THIS_{fieldName}"
fieldIdentifier += '.' + fieldName;
}
DatastoreIdentifier fieldRangeVar = idFactory.newIdentifier(IdentifierFactory.TABLE, fieldIdentifier);
LogicSetExpression fieldTblExpr = qs.newTableExpression(instanceofTable, fieldRangeVar);
ScalarExpression fieldExpr = table.getIDMapping().newScalarExpression(qs, te);
if (fieldName == null)
{
expr = instanceofTable.getIDMapping().newScalarExpression(qs, fieldTblExpr);