use of org.eclipse.persistence.internal.history.DecoratedDatabaseTable in project eclipselink by eclipse-ee4j.
the class SQLSelectStatement method computeTablesFromTables.
/**
* If there is no where clause, alias the tables from the tables list directly. Assume there's
* no ambiguity
*/
public void computeTablesFromTables() {
Map<DatabaseTable, DatabaseTable> allTables = new Hashtable<>();
AsOfClause asOfClause = null;
if (getBuilder().hasAsOfClause() && !getBuilder().getSession().getProject().hasGenericHistorySupport()) {
asOfClause = getBuilder().getAsOfClause();
}
for (int index = 0; index < getTables().size(); index++) {
DatabaseTable next = getTables().get(index);
// Aliases in allTables must now be decorated database tables.
DatabaseTable alias = new DecoratedDatabaseTable("t" + (index), asOfClause);
allTables.put(alias, next);
}
setTableAliases(allTables);
}
use of org.eclipse.persistence.internal.history.DecoratedDatabaseTable in project eclipselink by eclipse-ee4j.
the class SQLSelectStatement method appendFromClauseToWriter.
/**
* Print the from clause.
* This includes outer joins, these must be printed before the normal join to ensure that the source tables are not joined again.
* Outer joins are not printed in the FROM clause on Oracle or Sybase.
*/
public void appendFromClauseToWriter(ExpressionSQLPrinter printer) throws IOException {
Writer writer = printer.getWriter();
AbstractSession session = printer.getSession();
writer.write(" FROM ");
// Print outer joins
boolean firstTable = true;
// Must keep track of tables used for outer join so no normal join is given
List<DatabaseTable> outerJoinedAliases = new ArrayList<>(4);
// prepare to lock tables if required
boolean shouldPrintUpdateClause = printer.getPlatform().shouldPrintForUpdateClause() && !printer.getPlatform().shouldPrintLockingClauseAfterWhereClause() && (getForUpdateClause() != null);
Collection aliasesOfTablesToBeLocked = null;
boolean shouldPrintUpdateClauseForAllTables = false;
if (shouldPrintUpdateClause) {
aliasesOfTablesToBeLocked = getForUpdateClause().getAliasesOfTablesToBeLocked(this);
shouldPrintUpdateClauseForAllTables = aliasesOfTablesToBeLocked.size() == getTableAliases().size();
}
if (hasOuterJoinExpressions()) {
if (session.getPlatform().isInformixOuterJoin()) {
appendFromClauseForInformixOuterJoin(printer, outerJoinedAliases);
} else if (!session.getPlatform().shouldPrintOuterJoinInWhereClause() || !session.getPlatform().shouldPrintInnerJoinInWhereClause()) {
appendFromClauseForOuterJoin(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
}
firstTable = false;
}
// most likely the wrong builder was used, or wrong builder on the left in a sub-query.
if (getTableAliases().isEmpty()) {
// Query is set in execute.
throw QueryException.invalidBuilderInQuery(null);
}
// Print tables for normal join
for (DatabaseTable alias : getTableAliases().keySet()) {
if (!outerJoinedAliases.contains(alias)) {
DatabaseTable table = getTableAliases().get(alias);
if (requiresAliases()) {
if (!firstTable) {
writer.write(", ");
}
firstTable = false;
table.printSQL(printer);
writer.write(" ");
if (alias.isDecorated()) {
((DecoratedDatabaseTable) alias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
alias.printSQL(printer);
} else {
table.printSQL(printer);
if (alias.isDecorated()) {
writer.write(" ");
((DecoratedDatabaseTable) alias).getAsOfClause().printSQL(printer);
}
}
if (shouldPrintUpdateClause) {
if (shouldPrintUpdateClauseForAllTables || aliasesOfTablesToBeLocked.remove(alias)) {
getForUpdateClause().printSQL(printer, this);
}
}
}
}
}
use of org.eclipse.persistence.internal.history.DecoratedDatabaseTable in project eclipselink by eclipse-ee4j.
the class SQLSelectStatement method appendFromClauseForOuterJoin.
/**
* ADVANCED:
* Appends the SQL standard outer join clause, and some variation per platform.
* Most platforms use this syntax, support is also offered for Oracle to join in the where clause (although it should use the FROM clause as the WHERE clause is obsolete).
* This is also used for inner joins when configured in the platform.
*/
public void appendFromClauseForOuterJoin(ExpressionSQLPrinter printer, List<DatabaseTable> outerJoinedAliases, Collection aliasesOfTablesToBeLocked, boolean shouldPrintUpdateClauseForAllTables) throws IOException {
Writer writer = printer.getWriter();
AbstractSession session = printer.getSession();
DatabasePlatform platform = session.getPlatform();
// Print outer joins
boolean firstTable = true;
// Checks if the JDBC closing escape syntax is needed.
boolean requiresEscape = false;
boolean usesHistory = (getBuilder() != null) && getBuilder().hasAsOfClause();
int nSize = getOuterJoinExpressionsHolders().size();
for (OuterJoinExpressionHolder holder : getOuterJoinExpressionsHolders()) {
holder.process(usesHistory);
}
if (nSize > 1) {
sortOuterJoinExpressionHolders(getOuterJoinExpressionsHolders());
}
for (OuterJoinExpressionHolder holder : outerJoinExpressionHolders) {
ObjectExpression outerExpression = holder.joinExpression;
boolean isOuterJoin = (outerExpression == null) || outerExpression.shouldUseOuterJoin();
DatabaseTable targetTable = holder.targetTable;
DatabaseTable sourceTable = holder.sourceTable;
DatabaseTable sourceAlias = holder.sourceAlias;
DatabaseTable targetAlias = holder.targetAlias;
if (!outerJoinedAliases.contains(targetAlias)) {
if (!outerJoinedAliases.contains(sourceAlias)) {
if (requiresEscape && session.getPlatform().shouldUseJDBCOuterJoinSyntax()) {
writer.write("}");
}
if (!firstTable) {
writer.write(",");
}
if (platform.shouldUseJDBCOuterJoinSyntax()) {
writer.write(platform.getJDBCOuterJoinString());
}
requiresEscape = true;
firstTable = false;
sourceTable.printSQL(printer);
outerJoinedAliases.add(sourceAlias);
writer.write(" ");
if (sourceAlias.isDecorated()) {
((DecoratedDatabaseTable) sourceAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
sourceAlias.printSQL(printer);
printForUpdateClauseOnJoin(sourceAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
}
if (outerExpression == null) {
holder.printAdditionalJoins(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
} else {
DatabaseTable relationTable = outerExpression.getRelationTable();
boolean hasAdditionalJoinExpressions = holder.hasAdditionalJoinExpressions();
boolean isMapKeyObject = holder.hasMapKeyHolder();
Expression additionalOnExpression = outerExpression.getOnClause();
if (relationTable == null) {
if (outerExpression.isDirectCollection()) {
// Append the join clause,
// If this is a direct collection, join to direct table.
Expression onExpression = holder.outerJoinedMappingCriteria;
DatabaseTable newAlias = onExpression.aliasForTable(targetTable);
if (isOuterJoin) {
writer.write(" LEFT OUTER JOIN ");
} else {
writer.write(" JOIN ");
}
targetTable.printSQL(printer);
writer.write(" ");
if (newAlias.isDecorated()) {
((DecoratedDatabaseTable) newAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(newAlias);
newAlias.printSQL(printer);
printForUpdateClauseOnJoin(newAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
printOnClause(onExpression.and(additionalOnExpression), printer, platform);
} else {
// the rest of the tables are joined with the additional join criteria.
if (isOuterJoin) {
writer.write(" LEFT OUTER JOIN ");
} else {
writer.write(" JOIN ");
}
if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
writer.write("(");
}
targetTable.printSQL(printer);
writer.write(" ");
if (targetAlias.isDecorated()) {
((DecoratedDatabaseTable) targetAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(targetAlias);
targetAlias.printSQL(printer);
printForUpdateClauseOnJoin(targetAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
holder.printAdditionalJoins(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
writer.write(")");
}
Expression sourceToTargetJoin = holder.outerJoinedMappingCriteria;
if (additionalOnExpression != null) {
if (sourceToTargetJoin == null) {
sourceToTargetJoin = additionalOnExpression;
} else {
sourceToTargetJoin = sourceToTargetJoin.and(additionalOnExpression);
}
}
printOnClause(sourceToTargetJoin, printer, platform);
if (hasAdditionalJoinExpressions && !platform.supportsNestingOuterJoins()) {
holder.printAdditionalJoins(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
}
}
} else {
// Bug#4240751 Treat ManyToManyMapping separately for out join
// Must outer join each of the targets tables.
// The first table is joined with the mapping join criteria,
// the rest of the tables are joined with the additional join criteria.
// For example: EMPLOYEE t1 LEFT OUTER JOIN (PROJ_EMP t3 LEFT OUTER JOIN PROJECT t0 ON (t0.PROJ_ID = t3.PROJ_ID)) ON (t3.EMP_ID = t1.EMP_ID)
// Now OneToOneMapping also may have relation table.
DatabaseTable relationAlias = holder.outerJoinedMappingCriteria.aliasForTable(relationTable);
DatabaseTable mapKeyAlias = null;
DatabaseTable mapKeyTable = null;
List<DatabaseTable> tablesInOrder = new ArrayList<>();
// glassfish issue 2440: store aliases instead of tables
// in the tablesInOrder. This allows to distinguish source
// and target table in case of an self referencing relationship.
tablesInOrder.add(sourceAlias);
tablesInOrder.add(relationAlias);
tablesInOrder.add(targetAlias);
if (isMapKeyObject) {
// Need to also join the map key key.
mapKeyAlias = holder.mapKeyHolder.targetAlias;
mapKeyTable = holder.mapKeyHolder.targetTable;
tablesInOrder.add(mapKeyAlias);
}
TreeMap indexToExpressionMap = new TreeMap();
mapTableIndexToExpression(holder.outerJoinedMappingCriteria, indexToExpressionMap, tablesInOrder);
Expression sourceToRelationJoin = (Expression) indexToExpressionMap.get(1);
Expression relationToTargetJoin = (Expression) indexToExpressionMap.get(2);
Expression relationToKeyJoin = null;
if (isMapKeyObject) {
relationToKeyJoin = (Expression) indexToExpressionMap.get(3);
}
if (outerExpression.shouldUseOuterJoin()) {
writer.write(" LEFT OUTER JOIN ");
} else {
writer.write(" JOIN ");
}
if (platform.supportsNestingOuterJoins()) {
writer.write("(");
}
relationTable.printSQL(printer);
writer.write(" ");
if (relationAlias.isDecorated()) {
((DecoratedDatabaseTable) relationAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(relationAlias);
relationAlias.printSQL(printer);
printForUpdateClauseOnJoin(relationAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
if (!platform.supportsNestingOuterJoins()) {
printOnClause(sourceToRelationJoin.and(additionalOnExpression), printer, platform);
}
if (isMapKeyObject) {
// Append join to map key.
if (isOuterJoin && !session.getPlatform().supportsANSIInnerJoinSyntax()) {
writer.write(" LEFT OUTER");
}
writer.write(" JOIN ");
mapKeyTable.printSQL(printer);
writer.write(" ");
if (mapKeyAlias.isDecorated()) {
((DecoratedDatabaseTable) mapKeyAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(mapKeyAlias);
mapKeyAlias.printSQL(printer);
printForUpdateClauseOnJoin(mapKeyAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
printOnClause(relationToKeyJoin.and(additionalOnExpression), printer, platform);
if (holder.mapKeyHolder.hasAdditionalJoinExpressions()) {
holder.mapKeyHolder.printAdditionalJoins(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
}
}
if (isOuterJoin && !session.getPlatform().supportsANSIInnerJoinSyntax()) {
// if the DB does not support 'JOIN', do a left outer
// join instead. This will give the same result because
// the left table is a join table and has therefore
// no rows that are not in the right table.
writer.write(" LEFT OUTER");
}
writer.write(" JOIN ");
targetTable.printSQL(printer);
writer.write(" ");
if (targetAlias.isDecorated()) {
((DecoratedDatabaseTable) targetAlias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(targetAlias);
targetAlias.printSQL(printer);
printForUpdateClauseOnJoin(targetAlias, printer, shouldPrintUpdateClauseForAllTables, aliasesOfTablesToBeLocked, platform);
printOnClause(relationToTargetJoin, printer, platform);
if (hasAdditionalJoinExpressions) {
holder.printAdditionalJoins(printer, outerJoinedAliases, aliasesOfTablesToBeLocked, shouldPrintUpdateClauseForAllTables);
}
if (platform.supportsNestingOuterJoins()) {
writer.write(")");
printOnClause(sourceToRelationJoin, printer, platform);
}
}
}
}
}
if (requiresEscape && session.getPlatform().shouldUseJDBCOuterJoinSyntax()) {
writer.write("}");
}
}
use of org.eclipse.persistence.internal.history.DecoratedDatabaseTable in project eclipselink by eclipse-ee4j.
the class OuterJoinExpressionHolder method printAdditionalJoins.
void printAdditionalJoins(ExpressionSQLPrinter printer, List<DatabaseTable> outerJoinedAliases, Collection aliasesOfTablesToBeLocked, boolean shouldPrintUpdateClauseForAllTables) throws IOException {
Writer writer = printer.getWriter();
AbstractSession session = printer.getSession();
int size = this.additionalTargetAliases.size();
for (int i = 0; i < size; i++) {
DatabaseTable table = this.additionalTargetTables.get(i);
if (this.additionalTargetIsDescriptorTable.get(i)) {
// it's descriptor's own table
if (!session.getPlatform().supportsANSIInnerJoinSyntax()) {
// if the DB does not support 'JOIN', do a:
if (this.hasInheritance) {
// right outer join instead. This will give the same
// result because the right table has no rows that
// are not in the left table (left table maps to the
// main class, right table to a subclass in an
// inheritance mapping with a joined subclass
// strategy).
writer.write(" RIGHT OUTER");
} else {
// left outer join instead. This will give the same
// result because the left table has no rows that
// are not in the right table (left table is either
// a join table or it is joining secondary tables to
// a primary table).
writer.write(" LEFT OUTER");
}
}
writer.write(" JOIN ");
} else {
// it's child's table
writer.write(" LEFT OUTER JOIN ");
}
DatabaseTable alias = this.additionalTargetAliases.get(i);
table.printSQL(printer);
writer.write(" ");
if (alias.isDecorated()) {
((DecoratedDatabaseTable) alias).getAsOfClause().printSQL(printer);
writer.write(" ");
}
outerJoinedAliases.add(alias);
alias.printSQL(printer);
if (shouldPrintUpdateClauseForAllTables || (aliasesOfTablesToBeLocked != null && aliasesOfTablesToBeLocked.remove(alias))) {
getForUpdateClause().printSQL(printer, statement);
}
writer.write(" ON ");
if (session.getPlatform() instanceof DB2MainframePlatform) {
((RelationExpression) this.additionalJoinOnExpression.get(i)).printSQLNoParens(printer);
} else {
this.additionalJoinOnExpression.get(i).printSQL(printer);
}
}
}
Aggregations