if (null == qualifier || null == expression) {
return null;
}
ERXExistsQualifier existsQualifier = (ERXExistsQualifier)qualifier;
EOQualifier subqualifier = existsQualifier.subqualifier();
String baseKeyPath = existsQualifier.baseKeyPath();
EOEntity baseEntity = expression.entity();
EORelationship relationship = null;
// Walk the key path to the last entity.
if (baseKeyPath != null) {
for (String path : NSArray.componentsSeparatedByString(baseKeyPath, ".")) {
if (null == relationship) {
relationship = baseEntity.anyRelationshipNamed(path);
} else {
relationship = relationship.destinationEntity().anyRelationshipNamed(path);
}
}
}
EOEntity srcEntity = relationship != null ? relationship.entity() : baseEntity;
EOEntity destEntity = relationship != null ? relationship.destinationEntity() : baseEntity;
// We need to do a bunch of hand-waiving to get the right table aliases for the table used in the exists
// subquery and for the join clause back to the source table.
String sourceTableAlias = "t0"; // The alias for the the source table of the baseKeyPath from the main query.
String destTableAlias; // The alias for the table used in the subquery.
if (!srcEntity.equals(baseEntity)) { // The exists clause is applied to the different table.
sqlStringForAttributeNamedInExpression(baseKeyPath, expression);
destTableAlias = (String)expression.aliasesByRelationshipPath().valueForKey(baseKeyPath);
if (null == destTableAlias) {
destTableAlias = EXISTS_ALIAS + (expression.aliasesByRelationshipPath().count()); // The first entry = "t0".
expression.aliasesByRelationshipPath().takeValueForKey(destTableAlias, baseKeyPath);
}
} else { // The exists clause is applied to the base table.
destTableAlias = EXISTS_ALIAS + expression.aliasesByRelationshipPath().count(); // Probably "t1"
}
String srcEntityForeignKey = null;
NSArray<EOAttribute> sourceAttributes = relationship.sourceAttributes();
if (sourceAttributes != null && sourceAttributes.count() > 0) {
EOAttribute fk = sourceAttributes.lastObject();
srcEntityForeignKey = expression.sqlStringForAttribute(fk);
} else {
// (AR) could not find relationship from source object into "exists" clause, use primary key then instead
EOAttribute pk = srcEntity.primaryKeyAttributes().lastObject();
srcEntityForeignKey = expression.sqlStringForAttribute(pk);
}
EOJoin parentChildJoin = ERXArrayUtilities.firstObject(relationship.joins());
String destEntityForeignKey = "." + expression.sqlStringForSchemaObjectName(parentChildJoin.destinationAttribute().columnName());
EOQualifier qual = EOQualifierSQLGeneration.Support._schemaBasedQualifierWithRootEntity(subqualifier, destEntity);
EOFetchSpecification fetchSpecification = new EOFetchSpecification(destEntity.name(), qual, null, false, true, null);
EODatabaseContext context = EODatabaseContext.registeredDatabaseContextForModel(destEntity.model(), EOObjectStoreCoordinator.defaultCoordinator());
EOSQLExpressionFactory factory = context.database().adaptor().expressionFactory();