/** INTERNAL: Find the alias for a given table */ public DatabaseTable aliasForTable(DatabaseTable table) { DatabaseMapping mapping = getMapping(); if (isAttribute() || ((mapping != null) && (mapping.isAggregateObjectMapping() || mapping.isTransformationMapping()))) { return ((DataExpression) getBaseExpression()).aliasForTable(table); } // "ref" and "structure" mappings, no table printed in the FROM clause, need to get the table // alias form the parent table if ((mapping != null) && (mapping.isReferenceMapping() || mapping.isStructureMapping())) { DatabaseTable alias = getBaseExpression().aliasForTable(mapping.getDescriptor().getTables().firstElement()); alias.setName(alias.getName() + "." + mapping.getField().getName()); return alias; } // For direct-collection mappings the alias is store on the table expression. if ((mapping != null) && (mapping.isDirectCollectionMapping())) { if (tableAliases != null) { DatabaseTable aliasedTable = tableAliases.keyAtValue(table); if (aliasedTable != null) { return aliasedTable; } } return getTable(table).aliasForTable(table); } return super.aliasForTable(table); }
/** INTERNAL: Print SQL onto the stream, using the ExpressionPrinter for context */ public void printSQL(ExpressionSQLPrinter printer) { if (isAttribute()) { printer.printField(getAliasedField()); } // If the mapping is a direct collection then this falls into a gray area. // It must be treated as an attribute at this moment for it has a direct field. // However it is not an attribute in the sense that it also represents a foreign // reference and a mapping criteria has been added. // For bug 2900974 these are now handled as non-attributes during normalize but // as attributes when printing SQL. // if ((!isAttribute()) && (getMapping() != null) && getMapping().isDirectCollectionMapping()) { DirectCollectionMapping directCollectionMapping = (DirectCollectionMapping) getMapping(); // The aliased table comes for free as it was a required part of the join criteria. TableExpression table = (TableExpression) getTable(directCollectionMapping.getReferenceTable()); DatabaseTable aliasedTable = table.aliasForTable(table.getTable()); DatabaseField aliasedField = (DatabaseField) directCollectionMapping.getDirectField().clone(); aliasedField.setTable(aliasedTable); printer.printField(aliasedField); } if ((getMapping() != null) && getMapping().isNestedTableMapping()) { DatabaseTable tableAlias = aliasForTable(new NestedTable(this)); printer.printString(tableAlias.getName()); } }
/** * INTERNAL: Returns the first field from each of the owned tables, used for fine-grained * pessimistic locking. */ protected Vector getForUpdateOfFields() { Vector allFields = getFields(); int expected = getTableAliases().size(); Vector firstFields = new Vector(expected); DatabaseTable lastTable = null; DatabaseField field = null; int i = 0; // The following loop takes O(n*m) time. n=# of fields. m=#tables. // However, in the m=1 case this will take one pass only. // Also assuming that fields are generally sorted by table, this will // take O(n) time. // An even faster way may be to go getDescriptor().getAdditionalPrimaryKeyFields. while ((i < allFields.size()) && (firstFields.size() < expected)) { field = (DatabaseField) allFields.elementAt(i++); if ((lastTable == null) || !field.getTable().equals(lastTable)) { lastTable = field.getTable(); int j = 0; while (j < firstFields.size()) { if (lastTable.equals(((DatabaseField) firstFields.elementAt(j)).getTable())) { break; } j++; } if (j == firstFields.size()) { firstFields.addElement(field); } } } return firstFields; }