Program: 67335
Project: 67335
Buggy source:
/** 
 * ADVANCED: If a platform is Informix, then the outer join must be in the FROM clause. This is used internally by EclipseLink for building Informix outer join syntax which differs from other platforms(Oracle,Sybase) that print the outer join in the WHERE clause and from DB2 which prints the. OuterJoinedAliases passed in to keep track of tables used for outer join so no normal join is given
 */
public void appendFromClauseForInformixOuterJoin(ExpressionSQLPrinter printer,Vector outerJoinedAliases) throws IOException {
  Writer writer=printer.getWriter();
  AbstractSession session=printer.getSession();
  boolean firstTable=true;
  for (int index=0; index < getOuterJoinExpressions().size(); index++) {
    QueryKeyExpression outerExpression=(QueryKeyExpression)getOuterJoinExpressions().elementAt(index);
    CompoundExpression relationExpression=(CompoundExpression)getOuterJoinedMappingCriteria().elementAt(index);
    DatabaseTable targetTable=null;
    if (outerExpression.getMapping().isDirectCollectionMapping()) {
      targetTable=((DirectCollectionMapping)outerExpression.getMapping()).getReferenceTable();
    }
 else {
      targetTable=outerExpression.getMapping().getReferenceDescriptor().getTables().firstElement();
    }
    DatabaseTable sourceTable;
    if (outerExpression.getMapping().isObjectReferenceMapping() && ((ObjectReferenceMapping)outerExpression.getMapping()).isForeignKeyRelationship()) {
      sourceTable=(outerExpression.getMapping().getFields().firstElement()).getTable();
    }
 else {
      sourceTable=((ObjectExpression)outerExpression.getBaseExpression()).getDescriptor().getTables().firstElement();
    }
    DatabaseTable sourceAlias=outerExpression.getBaseExpression().aliasForTable(sourceTable);
    DatabaseTable targetAlias=outerExpression.aliasForTable(targetTable);
    if (!(outerJoinedAliases.contains(sourceAlias) || outerJoinedAliases.contains(targetAlias))) {
      if (!firstTable) {
        writer.write("String_Node_Str");
      }
      firstTable=false;
      writer.write(sourceTable.getQualifiedName());
      outerJoinedAliases.addElement(sourceAlias);
      writer.write("String_Node_Str");
      writer.write(sourceAlias.getQualifiedName());
      if (outerExpression.getMapping().isManyToManyMapping()) {
        DatabaseTable newTarget=((ManyToManyMapping)outerExpression.getMapping()).getRelationTable();
        DatabaseTable newAlias=relationExpression.aliasForTable(newTarget);
        writer.write("String_Node_Str");
        writer.write(newTarget.getQualifiedName());
        writer.write("String_Node_Str");
        outerJoinedAliases.addElement(newAlias);
        writer.write(newAlias.getQualifiedName());
      }
 else       if (outerExpression.getMapping().isDirectCollectionMapping()) {
        DatabaseTable newTarget=((DirectCollectionMapping)outerExpression.getMapping()).getReferenceTable();
        DatabaseTable newAlias=relationExpression.aliasForTable(newTarget);
        writer.write("String_Node_Str");
        writer.write(newTarget.getQualifiedName());
        writer.write("String_Node_Str");
        outerJoinedAliases.addElement(newAlias);
        writer.write(newAlias.getQualifiedName());
      }
 else {
        for (Enumeration target=outerExpression.getMapping().getReferenceDescriptor().getTables().elements(); target.hasMoreElements(); ) {
          DatabaseTable newTarget=(DatabaseTable)target.nextElement();
          Expression onExpression=outerExpression;
          DatabaseTable newAlias=outerExpression.aliasForTable(newTarget);
          writer.write("String_Node_Str");
          writer.write(newTarget.getQualifiedName());
          writer.write("String_Node_Str");
          outerJoinedAliases.addElement(newAlias);
          writer.write(newAlias.getQualifiedName());
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * ADVANCED: If a platform is Informix, then the outer join must be in the FROM clause. This is used internally by EclipseLink for building Informix outer join syntax which differs from other platforms (Oracle,Sybase) that print the outer join in the WHERE clause and from DB2 which prints the OuterJoinedAliases passed in to keep track of tables used for outer join so no normal join is given. This syntax is old for Informix, so should probably be removed.
 */
public void appendFromClauseForInformixOuterJoin(ExpressionSQLPrinter printer,Vector outerJoinedAliases) throws IOException {
  Writer writer=printer.getWriter();
  boolean firstTable=true;
  for (int index=0; index < getOuterJoinExpressions().size(); index++) {
    QueryKeyExpression outerExpression=(QueryKeyExpression)getOuterJoinExpressions().elementAt(index);
    CompoundExpression relationExpression=(CompoundExpression)getOuterJoinedMappingCriteria().elementAt(index);
    DatabaseTable targetTable=null;
    if (outerExpression.getMapping().isDirectCollectionMapping()) {
      targetTable=((DirectCollectionMapping)outerExpression.getMapping()).getReferenceTable();
    }
 else {
      targetTable=outerExpression.getMapping().getReferenceDescriptor().getTables().firstElement();
    }
    DatabaseTable sourceTable;
    if (outerExpression.getMapping().isObjectReferenceMapping() && ((ObjectReferenceMapping)outerExpression.getMapping()).isForeignKeyRelationship()) {
      sourceTable=(outerExpression.getMapping().getFields().firstElement()).getTable();
    }
 else {
      sourceTable=((ObjectExpression)outerExpression.getBaseExpression()).getDescriptor().getTables().firstElement();
    }
    DatabaseTable sourceAlias=outerExpression.getBaseExpression().aliasForTable(sourceTable);
    DatabaseTable targetAlias=outerExpression.aliasForTable(targetTable);
    if (!(outerJoinedAliases.contains(sourceAlias) || outerJoinedAliases.contains(targetAlias))) {
      if (!firstTable) {
        writer.write("String_Node_Str");
      }
      firstTable=false;
      writer.write(sourceTable.getQualifiedName());
      outerJoinedAliases.addElement(sourceAlias);
      writer.write("String_Node_Str");
      writer.write(sourceAlias.getQualifiedName());
      if (outerExpression.getMapping().isManyToManyMapping()) {
        DatabaseTable newTarget=((ManyToManyMapping)outerExpression.getMapping()).getRelationTable();
        DatabaseTable newAlias=relationExpression.aliasForTable(newTarget);
        writer.write("String_Node_Str");
        writer.write(newTarget.getQualifiedName());
        writer.write("String_Node_Str");
        outerJoinedAliases.addElement(newAlias);
        writer.write(newAlias.getQualifiedName());
      }
 else       if (outerExpression.getMapping().isDirectCollectionMapping()) {
        DatabaseTable newTarget=((DirectCollectionMapping)outerExpression.getMapping()).getReferenceTable();
        DatabaseTable newAlias=relationExpression.aliasForTable(newTarget);
        writer.write("String_Node_Str");
        writer.write(newTarget.getQualifiedName());
        writer.write("String_Node_Str");
        outerJoinedAliases.addElement(newAlias);
        writer.write(newAlias.getQualifiedName());
      }
 else {
        for (Enumeration target=outerExpression.getMapping().getReferenceDescriptor().getTables().elements(); target.hasMoreElements(); ) {
          DatabaseTable newTarget=(DatabaseTable)target.nextElement();
          DatabaseTable newAlias=outerExpression.aliasForTable(newTarget);
          writer.write("String_Node_Str");
          writer.write(newTarget.getQualifiedName());
          writer.write("String_Node_Str");
          outerJoinedAliases.addElement(newAlias);
          writer.write(newAlias.getQualifiedName());
        }
      }
    }
  }
}