Program: 9873
Project: 9873
Buggy source:
/** 
 * [    null,  h: int, i: string,   null ] [ a: int      null,      null, x: geo ] ?s = uri(concat("http://...", ?c1, ?c2)); ?s -> [c1: string, c2: int] with expr foo and restriction bar.
 */
public Mapping union(List<Mapping> members){
  if (members.size() == 1) {
    logger.warn("String_Node_Str");
    Mapping result=members.get(0);
  }
  Multimap<Var,RestrictedExpr> unionVarDefs=HashMultimap.create();
  List<Map<String,SqlExpr>> unionMemberProjections=new ArrayList<Map<String,SqlExpr>>();
  for (int i=0; i < members.size(); ++i) {
    Map<String,SqlExpr> tmp=new HashMap<String,SqlExpr>();
    unionMemberProjections.add(tmp);
  }
  Multimap<Var,Integer> varToMembers=HashMultimap.create();
  for (int i=0; i < members.size(); ++i) {
    Mapping mapping=members.get(i);
    for (    Var var : mapping.getVarDefinition().getMap().keySet()) {
      varToMembers.put(var,i);
    }
  }
  Generator aliasGen=Gensym.create("String_Node_Str");
  ExprCommonFactor factorizer=new ExprCommonFactor(aliasGen);
  Map<String,TypeToken> unionTypeMap=new HashMap<String,TypeToken>();
  for (  Entry<Var,Collection<Integer>> entry : varToMembers.asMap().entrySet()) {
    Var var=entry.getKey();
    Collection<Integer> memberIndexes=entry.getValue();
    Multimap<Expr,ArgExpr> cluster=HashMultimap.create();
    for (    int index : memberIndexes) {
      Mapping member=members.get(index);
      Collection<RestrictedExpr> exprsForVar=member.getVarDefinition().getDefinitions(var);
      for (      RestrictedExpr def : exprsForVar) {
        Map<String,TypeToken> columnToDatatype=member.getSqlOp().getSchema().getTypeMap();
        Expr datatypeNorm=exprNormalizer.normalize(def.getExpr(),columnToDatatype);
        cluster.put(datatypeNorm,new ArgExpr(def.getExpr(),index));
      }
    }
    for (    Entry<Expr,Collection<ArgExpr>> clusterEntry : cluster.asMap().entrySet()) {
      Collection<ArgExpr> argExprs=clusterEntry.getValue();
      List<Expr> exprs=new ArrayList<Expr>();
      Map<Integer,Integer> exprToOp=new HashMap<Integer,Integer>();
      int i=0;
      for (      ArgExpr argExpr : argExprs) {
        Expr expr=argExpr.getExpr();
        exprs.add(expr);
        exprToOp.put(i,argExpr.getIndex());
        ++i;
      }
      List<Map<Var,Expr>> tmpPartialProjections=new ArrayList<Map<Var,Expr>>();
      Expr common=factorizer.transform(exprs,tmpPartialProjections);
      List<Map<String,SqlExpr>> partialProjections=new ArrayList<Map<String,SqlExpr>>();
      for (int j=0; j < tmpPartialProjections.size(); ++j) {
        int memberIndex=exprToOp.get(j);
        Mapping member=members.get(memberIndex);
        Map<Var,Expr> tmpMap=tmpPartialProjections.get(j);
        Map<String,SqlExpr> map=new HashMap<String,SqlExpr>();
        for (        Entry<Var,Expr> e : tmpMap.entrySet()) {
          Expr expr=e.getValue();
          Map<String,TypeToken> typeMap=member.getSqlOp().getSchema().getTypeMap();
          SqlExpr sqlExpr=sqlTranslator.translate(expr,null,typeMap);
          map.put(e.getKey().getVarName(),sqlExpr);
        }
        partialProjections.add(map);
      }
      unionVarDefs.put(var,new RestrictedExpr(common));
      for (int j=0; j < partialProjections.size(); ++j) {
        int originalIndex=exprToOp.get(j);
        Map<String,SqlExpr> projection=unionMemberProjections.get(originalIndex);
        Map<String,SqlExpr> partialProjection=partialProjections.get(j);
        for (        Entry<String,SqlExpr> ppEntry : partialProjection.entrySet()) {
          projection.put(ppEntry.getKey(),ppEntry.getValue());
        }
      }
    }
  }
  for (int i=0; i < unionMemberProjections.size(); ++i) {
    Mapping member=members.get(i);
    Map<String,TypeToken> typeMap=member.getSqlOp().getSchema().getTypeMap();
    Map<String,SqlExpr> projection=unionMemberProjections.get(i);
    for (    Entry<String,SqlExpr> entry : projection.entrySet()) {
      SqlExpr expr=entry.getValue();
      unionTypeMap.put(entry.getKey(),expr.getDatatype());
    }
  }
  List<String> unionColumnOrder=new ArrayList<String>(unionTypeMap.keySet());
  List<SqlOp> extended=new ArrayList<SqlOp>();
  for (int i=0; i < members.size(); ++i) {
    Mapping member=members.get(i);
    Map<String,SqlExpr> unionMemberProjection=unionMemberProjections.get(i);
    Set<String> names=new HashSet<String>(unionMemberProjection.keySet());
    Set<String> unboundColumns=Sets.difference(unionTypeMap.keySet(),names);
    for (    String columnName : unboundColumns) {
      TypeToken datatype=unionTypeMap.get(columnName);
      S_Constant nullValue=new S_Constant(datatype,null);
      unionMemberProjection.put(columnName,nullValue);
    }
    Projection finalMemberProjection=new Projection(unionColumnOrder,unionMemberProjection);
    SqlOpExtend extend=SqlOpExtend.create(member.getSqlOp(),finalMemberProjection);
    SqlOpProject opProject=SqlOpProject.create(extend,unionColumnOrder);
    extended.add(opProject);
  }
  SqlOpUnionN newUnion=SqlOpUnionN.create(extended);
  VarDefinition varDefinition=new VarDefinition(unionVarDefs);
  Mapping result=new Mapping(varDefinition,newUnion);
  return result;
}

Fixed version (ground truth):
/** 
 * [    null,  h: int, i: string,   null ] [ a: int      null,      null, x: geo ] ?s = uri(concat("http://...", ?c1, ?c2)); ?s -> [c1: string, c2: int] with expr foo and restriction bar.
 */
public Mapping union(List<Mapping> members){
  if (members.size() == 1) {
    logger.warn("String_Node_Str");
    Mapping result=members.get(0);
    return result;
  }
  Multimap<Var,RestrictedExpr> unionVarDefs=HashMultimap.create();
  List<Map<String,SqlExpr>> unionMemberProjections=new ArrayList<Map<String,SqlExpr>>();
  for (int i=0; i < members.size(); ++i) {
    Map<String,SqlExpr> tmp=new HashMap<String,SqlExpr>();
    unionMemberProjections.add(tmp);
  }
  Multimap<Var,Integer> varToMembers=HashMultimap.create();
  for (int i=0; i < members.size(); ++i) {
    Mapping mapping=members.get(i);
    for (    Var var : mapping.getVarDefinition().getMap().keySet()) {
      varToMembers.put(var,i);
    }
  }
  Generator aliasGen=Gensym.create("String_Node_Str");
  ExprCommonFactor factorizer=new ExprCommonFactor(aliasGen);
  Map<String,TypeToken> unionTypeMap=new HashMap<String,TypeToken>();
  for (  Entry<Var,Collection<Integer>> entry : varToMembers.asMap().entrySet()) {
    Var var=entry.getKey();
    Collection<Integer> memberIndexes=entry.getValue();
    Multimap<String,ArgExpr> cluster=HashMultimap.create();
    for (    int index : memberIndexes) {
      Mapping member=members.get(index);
      Collection<RestrictedExpr> exprsForVar=member.getVarDefinition().getDefinitions(var);
      for (      RestrictedExpr def : exprsForVar) {
        Map<String,TypeToken> columnToDatatype=member.getSqlOp().getSchema().getTypeMap();
        Expr datatypeNorm=exprNormalizer.normalize(def.getExpr(),columnToDatatype);
        String hash=datatypeNorm.toString();
        cluster.put(hash,new ArgExpr(def.getExpr(),index));
      }
    }
    for (    Entry<String,Collection<ArgExpr>> clusterEntry : cluster.asMap().entrySet()) {
      Collection<ArgExpr> argExprs=clusterEntry.getValue();
      List<Expr> exprs=new ArrayList<Expr>();
      Map<Integer,Integer> exprToOp=new HashMap<Integer,Integer>();
      int i=0;
      for (      ArgExpr argExpr : argExprs) {
        Expr expr=argExpr.getExpr();
        exprs.add(expr);
        exprToOp.put(i,argExpr.getIndex());
        ++i;
      }
      List<Map<Var,Expr>> tmpPartialProjections=new ArrayList<Map<Var,Expr>>();
      Expr common=factorizer.transform(exprs,tmpPartialProjections);
      List<Map<String,SqlExpr>> partialProjections=new ArrayList<Map<String,SqlExpr>>();
      for (int j=0; j < tmpPartialProjections.size(); ++j) {
        int memberIndex=exprToOp.get(j);
        Mapping member=members.get(memberIndex);
        Map<String,TypeToken> typeMap=member.getSqlOp().getSchema().getTypeMap();
        Map<Var,Expr> tmpMap=tmpPartialProjections.get(j);
        Map<String,SqlExpr> map=new HashMap<String,SqlExpr>();
        for (        Entry<Var,Expr> e : tmpMap.entrySet()) {
          String columnName=e.getKey().getVarName();
          Expr expr=e.getValue();
          SqlExpr sqlExpr=sqlTranslator.translate(expr,null,typeMap);
          map.put(columnName,sqlExpr);
          if (columnName.equals("String_Node_Str")) {
            System.out.println("String_Node_Str");
          }
          unionTypeMap.put(columnName,sqlExpr.getDatatype());
          System.out.println("String_Node_Str" + unionTypeMap);
        }
        partialProjections.add(map);
      }
      unionVarDefs.put(var,new RestrictedExpr(common));
      for (int j=0; j < partialProjections.size(); ++j) {
        int originalIndex=exprToOp.get(j);
        Map<String,SqlExpr> projection=unionMemberProjections.get(originalIndex);
        Map<String,SqlExpr> partialProjection=partialProjections.get(j);
        for (        Entry<String,SqlExpr> ppEntry : partialProjection.entrySet()) {
          projection.put(ppEntry.getKey(),ppEntry.getValue());
        }
      }
    }
  }
  List<String> unionColumnOrder=new ArrayList<String>(unionTypeMap.keySet());
  System.out.println("String_Node_Str" + unionTypeMap);
  List<SqlOp> extended=new ArrayList<SqlOp>();
  for (int i=0; i < members.size(); ++i) {
    Mapping member=members.get(i);
    Map<String,SqlExpr> unionMemberProjection=unionMemberProjections.get(i);
    Set<String> names=new HashSet<String>(unionMemberProjection.keySet());
    Set<String> unboundColumns=Sets.difference(unionTypeMap.keySet(),names);
    for (    String columnName : unboundColumns) {
      TypeToken datatype=unionTypeMap.get(columnName);
      S_Constant nullValue=new S_Constant(datatype,null);
      unionMemberProjection.put(columnName,nullValue);
    }
    Projection finalMemberProjection=new Projection(unionColumnOrder,unionMemberProjection);
    SqlOpExtend extend=SqlOpExtend.create(member.getSqlOp(),finalMemberProjection);
    SqlOpProject opProject=SqlOpProject.create(extend,unionColumnOrder);
    extended.add(opProject);
  }
  SqlOpUnionN newUnion=SqlOpUnionN.create(extended);
  for (  SqlOp m : newUnion.getSubOps()) {
    System.out.println(m.getSchema().getColumnNames());
  }
  VarDefinition varDefinition=new VarDefinition(unionVarDefs);
  Mapping result=new Mapping(varDefinition,newUnion);
  return result;
}