join.isInner = true;
join.isEnabled = true;
for (int i = 0; i < nDKColumnCount; ++i)
{
Column column = destinationKey.getIndexColumn(i).getColumn();
addOutputField(dkFieldArray[i] = new Field(query, join, column,
column.getValueType(), m_adapter.getConverter(column.getValueType(), column),
m_adapter.getBind(column), true));
}
query.setChildItem(dkFieldArray);
}
}
else
{
Index sourceKey = (Index)query.getKey(false);
SQLJoin parent;
if (sourceKey.isObjectKey())
{
parent = (SQLJoin)query.getParent().getMapping();
sourceKey = parent.table.getPrimaryKey();
}
else
{
parent = addTable(query.getParent(), sourceKey.getTable());
}
parent.isEnabled = true;
if (bHomogeneous)
{
Index destinationKey = (Index)query.getKey(true);
SQLJoin join = addTable(query, destinationKey.getTable());
join.parent = parent;
join.sourceKey = sourceKey;
join.destinationKey = destinationKey;
// Decide whether we can use the left joined table
// source key instead of the right joined table primary key
// to reduce the number of indirections in the SQL query
// TODO: Traverse the parent list up for more potential savings
if (query.getWhere() == null &&
(destinationKey.isObjectKey() &&
(!query.isOutput() ||
(!sourceKey.isObjectKey() || query.isRequired()) &&
query.getFieldCount() == 0 &&
query.getAssocCount(Query.ASSOC_QUERY) == 0) ||
destinationKey.isObjectKeyPart() &&
!query.isOutput() &&
query.getFieldCount() == 0 &&
query.getAssocCount(Query.ASSOC_QUERY) == 0))
{
primarySource = query.getParent();
primaryJoin = parent;
primaryKey = sourceKey;
}
else
{
primaryJoin = join;
primaryKey = join.table.getPrimaryKey();
if (destinationKey.isObjectKeyPart() &&
(!sourceKey.isObjectKey() || query.isRequired()))
{
fieldSource = query.getParent();
fieldJoin = parent;
fieldKey = sourceKey;
}
}
if (join.parent.isInner && query.isRequired())
{
join.isInner = true;
}
}
else
{
primarySource = query.getParent();
primaryJoin = parent;
primaryKey = sourceKey;
}
}
primaryJoin.isEnabled = true;
int nPKColumnCount = primaryKey.getIndexColumnCount();
Field[] pkFieldArray = new Field[nPKColumnCount];
for (int i = 0; i < nPKColumnCount; ++i)
{
Column column = primaryKey.getIndexColumn(i).getColumn();
pkFieldArray[i] = new Field(primarySource, primaryJoin, column,
column.getValueType(), m_adapter.getConverter(column.getValueType(), column),
m_adapter.getBind(column), true);
}
if (query.getParent() != null && query.getParentItem() == null)
{
query.setParentItem(pkFieldArray);
}
if (bHomogeneous || (query.getRestriction() & Query.RESTRICTION_WHERE) != 0)
{
// The following conditional relies on the visit order
// to avoid overwriting the PK in a hetero query
if (query.getItem() == null)
{
query.setItem(pkFieldArray);
if (fieldSource != null)
{
int nColumnCount = fieldKey.getIndexColumnCount();
Field[] fieldArray = new Field[nColumnCount];
for (int i = 0; i < nColumnCount; ++i)
{
Column column = fieldKey.getIndexColumn(i).getColumn();
fieldArray[i] = new Field(primarySource, fieldJoin, column,
column.getValueType(), m_adapter.getConverter(column.getValueType(), column),
m_adapter.getBind(column), true);
}
query.setFieldItem(fieldArray);
}
else
{
query.setFieldItem(pkFieldArray);
}
}
}
if (query.isOutput() ||
!bHomogeneous && (query.getRestriction() & Query.RESTRICTION_WHERE) == 0)
{
if (query.isIdentity() || !query.isOutput())
{
// Output the primary key columns
for (int i = 0; i < nPKColumnCount; ++i)
{
addOutputField(pkFieldArray[i]);
}
}
m_query.addOutputQuery(query);
}
if (bHomogeneous)
{
// Bind the columns to the attributes
for (Iterator itr = query.getFieldIterator(); itr.hasNext();)
{
Field field = (Field)itr.next();
if (!field.isPersistent())
{
continue;
}
Operator op = field.getOperator();
if (op != null)
{
if (op.getType() instanceof Primitive)
{
field.setBind(m_adapter.getBind((Primitive)op.getType()));
}
}
else
{
Column column = ((RelationalPrimitiveMapping)field.getAttributeMapping()).getColumn();
SQLJoin join = addTable(query, column.getTable());
join.isEnabled = true;
field.setMapping(join);
field.setItem(column);
field.setConverter(m_adapter.getConverter((Primitive)field.getAttribute().getType(), column));