Program: 66497
Project: 66497
Buggy source:
/** 
 * 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).
 */
public void appendFromClauseForOuterJoin(ExpressionSQLPrinter printer,Vector outerJoinedAliases,Collection aliasesOfTablesToBeLocked,boolean shouldPrintUpdateClauseForAllTables) throws IOException {
  Writer writer=printer.getWriter();
  AbstractSession session=printer.getSession();
  DatabasePlatform platform=session.getPlatform();
  boolean firstTable=true;
  boolean requiresEscape=false;
  boolean usesHistory=(getBuilder() != null) && getBuilder().hasAsOfClause();
  OuterJoinExpressionHolders outerJoinExpressionHolders=new OuterJoinExpressionHolders();
  for (int index=0; index < getOuterJoinExpressions().size(); index++) {
    QueryKeyExpression outerExpression=(QueryKeyExpression)getOuterJoinExpressions().elementAt(index);
    DatabaseTable targetTable=null;
    DatabaseTable sourceTable=null;
    DatabaseTable sourceAlias=null;
    DatabaseTable targetAlias=null;
    if (outerExpression != null) {
      targetTable=outerExpression.getReferenceTable();
      sourceTable=outerExpression.getSourceTable();
      sourceAlias=outerExpression.getBaseExpression().aliasForTable(sourceTable);
      targetAlias=outerExpression.aliasForTable(targetTable);
      if (usesHistory) {
        sourceTable=(DatabaseTable)getTableAliases().get(sourceAlias);
        targetTable=(DatabaseTable)getTableAliases().get(targetAlias);
      }
    }
 else {
      sourceTable=((ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index)).getTables().firstElement();
      targetTable=((ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index)).getInheritancePolicy().getChildrenTables().get(0);
      Expression exp=(Expression)((Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index)).get(targetTable);
      sourceAlias=exp.aliasForTable(sourceTable);
      targetAlias=exp.aliasForTable(targetTable);
    }
    outerJoinExpressionHolders.add(new OuterJoinExpressionHolder(outerExpression,index,targetTable,sourceTable,targetAlias,sourceAlias));
  }
  for (Iterator i=outerJoinExpressionHolders.linearize(this).iterator(); i.hasNext(); ) {
    OuterJoinExpressionHolder holder=(OuterJoinExpressionHolder)i.next();
    QueryKeyExpression outerExpression=holder.joinExpression;
    int index=holder.index;
    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("String_Node_Str");
        }
        if (!firstTable) {
          writer.write("String_Node_Str");
        }
        if (platform.shouldUseJDBCOuterJoinSyntax()) {
          writer.write(platform.getJDBCOuterJoinString());
        }
        requiresEscape=true;
        firstTable=false;
        writer.write(sourceTable.getQualifiedNameDelimited(printer.getPlatform()));
        outerJoinedAliases.addElement(sourceAlias);
        writer.write("String_Node_Str");
        if (sourceAlias.isDecorated()) {
          ((DecoratedDatabaseTable)sourceAlias).getAsOfClause().printSQL(printer);
          writer.write("String_Node_Str");
        }
        writer.write(sourceAlias.getQualifiedNameDelimited(printer.getPlatform()));
        printForUpdateClauseOnJoin(sourceAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
      }
      if (outerExpression == null) {
        printAdditionalJoins(printer,outerJoinedAliases,(ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index),(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index),aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
      }
 else {
        DatabaseTable relationTable=outerExpression.getRelationTable();
        if (relationTable == null) {
          if (outerExpression.isDirectCollection()) {
            Expression onExpression=(Expression)getOuterJoinedMappingCriteria().elementAt(index);
            DatabaseTable newAlias=onExpression.aliasForTable(targetTable);
            writer.write("String_Node_Str");
            writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
            writer.write("String_Node_Str");
            if (newAlias.isDecorated()) {
              ((DecoratedDatabaseTable)newAlias).getAsOfClause().printSQL(printer);
              writer.write("String_Node_Str");
            }
            outerJoinedAliases.addElement(newAlias);
            writer.write(newAlias.getQualifiedNameDelimited(printer.getPlatform()));
            printForUpdateClauseOnJoin(newAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
            printOnClause(onExpression,printer,platform);
          }
 else {
            writer.write("String_Node_Str");
            Map tablesJoinExpression=(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index);
            boolean hasAdditionalJoinExpressions=tablesJoinExpression != null && !tablesJoinExpression.isEmpty();
            if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
              writer.write("String_Node_Str");
            }
            writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
            writer.write("String_Node_Str");
            if (targetAlias.isDecorated()) {
              ((DecoratedDatabaseTable)targetAlias).getAsOfClause().printSQL(printer);
              writer.write("String_Node_Str");
            }
            outerJoinedAliases.addElement(targetAlias);
            writer.write(targetAlias.getQualifiedNameDelimited(printer.getPlatform()));
            printForUpdateClauseOnJoin(targetAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
            if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
              printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
              writer.write("String_Node_Str");
            }
            Expression sourceToTargetJoin=(Expression)getOuterJoinedMappingCriteria().elementAt(index);
            printOnClause(sourceToTargetJoin,printer,platform);
            if (hasAdditionalJoinExpressions && !platform.supportsNestingOuterJoins()) {
              printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
            }
          }
        }
 else {
          DatabaseTable relationAlias=((Expression)getOuterJoinedMappingCriteria().elementAt(index)).aliasForTable(relationTable);
          Vector tablesInOrder=NonSynchronizedVector.newInstance(3);
          tablesInOrder.add(sourceAlias);
          tablesInOrder.add(relationAlias);
          tablesInOrder.add(targetAlias);
          TreeMap indexToExpressionMap=new TreeMap();
          mapTableIndexToExpression((Expression)getOuterJoinedMappingCriteria().elementAt(index),indexToExpressionMap,tablesInOrder);
          Expression sourceToRelationJoin=(Expression)indexToExpressionMap.get(Integer.valueOf(1));
          Expression relationToTargetJoin=(Expression)indexToExpressionMap.get(Integer.valueOf(2));
          writer.write("String_Node_Str");
          if (platform.supportsNestingOuterJoins()) {
            writer.write("String_Node_Str");
          }
          writer.write(relationTable.getQualifiedNameDelimited(printer.getPlatform()));
          writer.write("String_Node_Str");
          if (relationAlias.isDecorated()) {
            ((DecoratedDatabaseTable)relationAlias).getAsOfClause().printSQL(printer);
            writer.write("String_Node_Str");
          }
          outerJoinedAliases.add(relationAlias);
          printForUpdateClauseOnJoin(relationAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
          writer.write(relationAlias.getQualifiedNameDelimited(printer.getPlatform()));
          if (!platform.supportsNestingOuterJoins()) {
            printOnClause(sourceToRelationJoin,printer,platform);
          }
          if (!session.getPlatform().supportsANSIInnerJoinSyntax()) {
            writer.write("String_Node_Str");
          }
          writer.write("String_Node_Str");
          writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
          writer.write("String_Node_Str");
          if (targetAlias.isDecorated()) {
            ((DecoratedDatabaseTable)targetAlias).getAsOfClause().printSQL(printer);
            writer.write("String_Node_Str");
          }
          outerJoinedAliases.add(targetAlias);
          writer.write(targetAlias.getQualifiedNameDelimited(printer.getPlatform()));
          printForUpdateClauseOnJoin(targetAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
          printOnClause(relationToTargetJoin,printer,platform);
          Map tablesJoinExpression=(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index);
          if (tablesJoinExpression != null && !tablesJoinExpression.isEmpty()) {
            printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
          }
          if (platform.supportsNestingOuterJoins()) {
            writer.write("String_Node_Str");
            printOnClause(sourceToRelationJoin,printer,platform);
          }
        }
      }
    }
  }
  if (requiresEscape && session.getPlatform().shouldUseJDBCOuterJoinSyntax()) {
    writer.write("String_Node_Str");
  }
}

Fixed version (ground truth):
/** 
 * 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).
 */
public void appendFromClauseForOuterJoin(ExpressionSQLPrinter printer,Vector outerJoinedAliases,Collection aliasesOfTablesToBeLocked,boolean shouldPrintUpdateClauseForAllTables) throws IOException {
  Writer writer=printer.getWriter();
  AbstractSession session=printer.getSession();
  DatabasePlatform platform=session.getPlatform();
  boolean firstTable=true;
  boolean requiresEscape=false;
  boolean usesHistory=(getBuilder() != null) && getBuilder().hasAsOfClause();
  int nSize=getOuterJoinExpressions().size();
  List<OuterJoinExpressionHolder> outerJoinExpressionHolders=new ArrayList(nSize);
  for (int index=0; index < nSize; index++) {
    QueryKeyExpression outerExpression=(QueryKeyExpression)getOuterJoinExpressions().elementAt(index);
    DatabaseTable targetTable=null;
    DatabaseTable sourceTable=null;
    DatabaseTable sourceAlias=null;
    DatabaseTable targetAlias=null;
    if (outerExpression != null) {
      targetTable=outerExpression.getReferenceTable();
      sourceTable=outerExpression.getSourceTable();
      sourceAlias=outerExpression.getBaseExpression().aliasForTable(sourceTable);
      targetAlias=outerExpression.aliasForTable(targetTable);
      if (usesHistory) {
        sourceTable=(DatabaseTable)getTableAliases().get(sourceAlias);
        targetTable=(DatabaseTable)getTableAliases().get(targetAlias);
      }
    }
 else {
      sourceTable=((ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index)).getTables().firstElement();
      targetTable=((ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index)).getInheritancePolicy().getChildrenTables().get(0);
      Expression exp=(Expression)((Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index)).get(targetTable);
      sourceAlias=exp.aliasForTable(sourceTable);
      targetAlias=exp.aliasForTable(targetTable);
    }
    outerJoinExpressionHolders.add(new OuterJoinExpressionHolder(outerExpression,index,targetTable,sourceTable,targetAlias,sourceAlias));
  }
  if (nSize > 1) {
    sortOuterJoinExpressionHolders(outerJoinExpressionHolders);
  }
  for (  OuterJoinExpressionHolder holder : outerJoinExpressionHolders) {
    QueryKeyExpression outerExpression=holder.joinExpression;
    int index=holder.index;
    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("String_Node_Str");
        }
        if (!firstTable) {
          writer.write("String_Node_Str");
        }
        if (platform.shouldUseJDBCOuterJoinSyntax()) {
          writer.write(platform.getJDBCOuterJoinString());
        }
        requiresEscape=true;
        firstTable=false;
        writer.write(sourceTable.getQualifiedNameDelimited(printer.getPlatform()));
        outerJoinedAliases.addElement(sourceAlias);
        writer.write("String_Node_Str");
        if (sourceAlias.isDecorated()) {
          ((DecoratedDatabaseTable)sourceAlias).getAsOfClause().printSQL(printer);
          writer.write("String_Node_Str");
        }
        writer.write(sourceAlias.getQualifiedNameDelimited(printer.getPlatform()));
        printForUpdateClauseOnJoin(sourceAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
      }
      if (outerExpression == null) {
        printAdditionalJoins(printer,outerJoinedAliases,(ClassDescriptor)getDescriptorsForMultitableInheritanceOnly().get(index),(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index),aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
      }
 else {
        DatabaseTable relationTable=outerExpression.getRelationTable();
        if (relationTable == null) {
          if (outerExpression.isDirectCollection()) {
            Expression onExpression=(Expression)getOuterJoinedMappingCriteria().elementAt(index);
            DatabaseTable newAlias=onExpression.aliasForTable(targetTable);
            writer.write("String_Node_Str");
            writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
            writer.write("String_Node_Str");
            if (newAlias.isDecorated()) {
              ((DecoratedDatabaseTable)newAlias).getAsOfClause().printSQL(printer);
              writer.write("String_Node_Str");
            }
            outerJoinedAliases.addElement(newAlias);
            writer.write(newAlias.getQualifiedNameDelimited(printer.getPlatform()));
            printForUpdateClauseOnJoin(newAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
            printOnClause(onExpression,printer,platform);
          }
 else {
            writer.write("String_Node_Str");
            Map tablesJoinExpression=(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index);
            boolean hasAdditionalJoinExpressions=tablesJoinExpression != null && !tablesJoinExpression.isEmpty();
            if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
              writer.write("String_Node_Str");
            }
            writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
            writer.write("String_Node_Str");
            if (targetAlias.isDecorated()) {
              ((DecoratedDatabaseTable)targetAlias).getAsOfClause().printSQL(printer);
              writer.write("String_Node_Str");
            }
            outerJoinedAliases.addElement(targetAlias);
            writer.write(targetAlias.getQualifiedNameDelimited(printer.getPlatform()));
            printForUpdateClauseOnJoin(targetAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
            if (hasAdditionalJoinExpressions && platform.supportsNestingOuterJoins()) {
              printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
              writer.write("String_Node_Str");
            }
            Expression sourceToTargetJoin=(Expression)getOuterJoinedMappingCriteria().elementAt(index);
            printOnClause(sourceToTargetJoin,printer,platform);
            if (hasAdditionalJoinExpressions && !platform.supportsNestingOuterJoins()) {
              printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
            }
          }
        }
 else {
          DatabaseTable relationAlias=((Expression)getOuterJoinedMappingCriteria().elementAt(index)).aliasForTable(relationTable);
          Vector tablesInOrder=NonSynchronizedVector.newInstance(3);
          tablesInOrder.add(sourceAlias);
          tablesInOrder.add(relationAlias);
          tablesInOrder.add(targetAlias);
          TreeMap indexToExpressionMap=new TreeMap();
          mapTableIndexToExpression((Expression)getOuterJoinedMappingCriteria().elementAt(index),indexToExpressionMap,tablesInOrder);
          Expression sourceToRelationJoin=(Expression)indexToExpressionMap.get(Integer.valueOf(1));
          Expression relationToTargetJoin=(Expression)indexToExpressionMap.get(Integer.valueOf(2));
          writer.write("String_Node_Str");
          if (platform.supportsNestingOuterJoins()) {
            writer.write("String_Node_Str");
          }
          writer.write(relationTable.getQualifiedNameDelimited(printer.getPlatform()));
          writer.write("String_Node_Str");
          if (relationAlias.isDecorated()) {
            ((DecoratedDatabaseTable)relationAlias).getAsOfClause().printSQL(printer);
            writer.write("String_Node_Str");
          }
          outerJoinedAliases.add(relationAlias);
          printForUpdateClauseOnJoin(relationAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
          writer.write(relationAlias.getQualifiedNameDelimited(printer.getPlatform()));
          if (!platform.supportsNestingOuterJoins()) {
            printOnClause(sourceToRelationJoin,printer,platform);
          }
          if (!session.getPlatform().supportsANSIInnerJoinSyntax()) {
            writer.write("String_Node_Str");
          }
          writer.write("String_Node_Str");
          writer.write(targetTable.getQualifiedNameDelimited(printer.getPlatform()));
          writer.write("String_Node_Str");
          if (targetAlias.isDecorated()) {
            ((DecoratedDatabaseTable)targetAlias).getAsOfClause().printSQL(printer);
            writer.write("String_Node_Str");
          }
          outerJoinedAliases.add(targetAlias);
          writer.write(targetAlias.getQualifiedNameDelimited(printer.getPlatform()));
          printForUpdateClauseOnJoin(targetAlias,printer,shouldPrintUpdateClauseForAllTables,aliasesOfTablesToBeLocked,platform);
          printOnClause(relationToTargetJoin,printer,platform);
          Map tablesJoinExpression=(Map)getOuterJoinedAdditionalJoinCriteria().elementAt(index);
          if (tablesJoinExpression != null && !tablesJoinExpression.isEmpty()) {
            printAdditionalJoins(printer,outerJoinedAliases,outerExpression.getDescriptor(),tablesJoinExpression,aliasesOfTablesToBeLocked,shouldPrintUpdateClauseForAllTables,usesHistory);
          }
          if (platform.supportsNestingOuterJoins()) {
            writer.write("String_Node_Str");
            printOnClause(sourceToRelationJoin,printer,platform);
          }
        }
      }
    }
  }
  if (requiresEscape && session.getPlatform().shouldUseJDBCOuterJoinSyntax()) {
    writer.write("String_Node_Str");
  }
}