{
SQLStatement stmt = expr1.stmt;
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getClassLoaderResolver();
ApiAdapter api = storeMgr.getApiAdapter();
if (expr1 instanceof ObjectLiteral && expr2 instanceof ObjectLiteral)
{
// ObjectLiterall == ObjectLiteral
ObjectLiteral lit1 = (ObjectLiteral)expr1;
ObjectLiteral lit2 = (ObjectLiteral)expr2;
return new BooleanLiteral(stmt, expr1.mapping,
equals ? lit1.getValue().equals(lit2.getValue()) : !lit1.getValue().equals(lit2.getValue()));
}
else if (expr1 instanceof ObjectLiteral || expr2 instanceof ObjectLiteral)
{
// ObjectExpression == ObjectLiteral, ObjectLiteral == ObjectExpression
BooleanExpression bExpr = null;
boolean secondIsLiteral = (expr2 instanceof ObjectLiteral);
Object value = (!secondIsLiteral ? ((ObjectLiteral)expr1).getValue() : ((ObjectLiteral)expr2).getValue());
if (value instanceof OID)
{
// Object is an OID
JavaTypeMapping m = storeMgr.getSQLExpressionFactory().getMappingForType(
((OID)value).getKeyValue().getClass(), false);
SQLExpression oidLit = exprFactory.newLiteral(stmt, m, ((OID)value).getKeyValue());
if (equals)
{
return (secondIsLiteral ? expr1.subExprs.getExpression(0).eq(oidLit) : expr2.subExprs.getExpression(0).eq(oidLit));
}
else
{
return (secondIsLiteral ? expr1.subExprs.getExpression(0).ne(oidLit) : expr2.subExprs.getExpression(0).ne(oidLit));
}
}
else if (api.isSingleFieldIdentity(value))
{
// Object is SingleFieldIdentity
JavaTypeMapping m = storeMgr.getSQLExpressionFactory().getMappingForType(
api.getTargetClassForSingleFieldIdentity(value), false);
SQLExpression oidLit = exprFactory.newLiteral(stmt, m,
api.getTargetKeyForSingleFieldIdentity(value));
if (equals)
{
return (secondIsLiteral ? expr1.subExprs.getExpression(0).eq(oidLit) : expr2.subExprs.getExpression(0).eq(oidLit));
}
else
{
return (secondIsLiteral ? expr1.subExprs.getExpression(0).ne(oidLit) : expr2.subExprs.getExpression(0).ne(oidLit));
}
}
else
{
AbstractClassMetaData cmd =
storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(value.getClass(), clr);
if (cmd != null)
{
// Value is a persistable object
if (cmd.getIdentityType() == IdentityType.APPLICATION)
{
// Application identity
if (api.getIdForObject(value) != null)
{
// Persistent PC object (FCO)
// Cater for composite PKs and parts of PK being PC mappings, and recursion
ObjectExpression expr = (secondIsLiteral ? expr1 : expr2);
JavaTypeMapping[] pkMappingsApp = new JavaTypeMapping[expr.subExprs.size()];
Object[] pkFieldValues = new Object[expr.subExprs.size()];
int position = 0;
ExecutionContext ec = api.getExecutionContext(value);
JavaTypeMapping thisMapping = expr.mapping;
if (expr.mapping instanceof ReferenceMapping)
{
// "InterfaceField == value", so pick an implementation mapping that is castable
thisMapping = null;
ReferenceMapping refMapping = (ReferenceMapping)expr.mapping;
JavaTypeMapping[] implMappings = refMapping.getJavaTypeMapping();
for (int i=0;i<implMappings.length;i++)
{
Class implType = clr.classForName(implMappings[i].getType());
if (implType.isAssignableFrom(value.getClass()))
{
thisMapping = implMappings[i];
break;
}
}
}
if (thisMapping == null)
{
// Just return a (1=0) since no implementation castable
return exprFactory.newLiteral(stmt, expr1.mapping, false).eq(exprFactory.newLiteral(stmt, expr1.mapping, true));
}
for (int i=0;i<cmd.getNoOfPrimaryKeyMembers();i++)
{
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(cmd.getPKMemberPositions()[i]);
Object fieldValue = ExpressionUtils.getValueForMemberOfObject(ec, mmd, value);
JavaTypeMapping mapping = ((PersistableMapping)thisMapping).getJavaTypeMapping()[i];
if (mapping instanceof PersistableMapping)
{
position = ExpressionUtils.populatePrimaryKeyMappingsValuesForPCMapping(pkMappingsApp,
pkFieldValues, position, (PersistableMapping)mapping,
cmd, mmd, fieldValue, storeMgr, clr);
}
else
{
pkMappingsApp[position] = mapping;
pkFieldValues[position] = fieldValue;
position++;
}
}
for (int i=0; i<expr.subExprs.size(); i++)
{
SQLExpression source = expr.subExprs.getExpression(i);
SQLExpression target =
exprFactory.newLiteral(stmt, pkMappingsApp[i], pkFieldValues[i]);
BooleanExpression subExpr = (secondIsLiteral ? source.eq(target) : target.eq(source));
if (bExpr == null)
{
bExpr = subExpr;
}
else
{
bExpr = bExpr.and(subExpr);
}
}
}
else
{
// PC object with no id (embedded, or transient maybe)
if (secondIsLiteral)
{
for (int i=0; i<expr1.subExprs.size(); i++)
{
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(LOCALISER.msg("037003", value));
bExpr = exprFactory.newLiteral(stmt, expr1.mapping, false).eq(exprFactory.newLiteral(stmt, expr1.mapping, true));
// It is arguable that we should compare the id with null (as below)
/*bExpr = expr.eq(new NullLiteral(qs));*/
}
}
else
{
for (int i=0; i<expr2.subExprs.size(); i++)
{
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(LOCALISER.msg("037003", value));
bExpr = exprFactory.newLiteral(stmt, expr2.mapping, false).eq(exprFactory.newLiteral(stmt, expr2.mapping, true));
// It is arguable that we should compare the id with null (as below)
/*bExpr = expr.eq(new NullLiteral(qs));*/
}
}
}
// TODO Allow for !equals
return bExpr;
}
else if (cmd.getIdentityType() == IdentityType.DATASTORE)
{
// Datastore identity
SQLExpression source = (secondIsLiteral ? expr1.subExprs.getExpression(0) : expr2.subExprs.getExpression(0));
JavaTypeMapping mapping = (secondIsLiteral ? expr1.mapping : expr2.mapping);
OID objectId = (OID)api.getIdForObject(value);
if (objectId == null)
{
// PC object with no id (embedded, or transient maybe)
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(LOCALISER.msg("037003", value));