Program: 96051
Project: 96051
Buggy source:
/** 
 * Converts the root node and its descendants into the configuration that enables progressive aggregation. Basically aggregate subqueries are blocking operations while others operations are divided into smaller- scale operations (which involve different portions of data).
 * @param nodeBlock
 * @return Returns the root of the multiple aggregation nodes (each of which involves different combinationsof partitions)
 * @throws VerdictDBValueException 
 */
public QueryExecutionNode convertToProgressiveAgg() throws VerdictDBValueException {
  List<QueryExecutionNode> individualAggNodes=new ArrayList<>();
  List<QueryExecutionNode> combiners=new ArrayList<>();
  ScrambleMeta scrambleMeta=plan.getScrambleMeta();
  List<Pair<QueryExecutionNode,Triple<String,String,String>>> scrambledNodes=identifyScrambledNodes(scrambleMeta,blockNodes);
  List<Pair<String,String>> scrambles=new ArrayList<>();
  for (  Pair<QueryExecutionNode,Triple<String,String,String>> a : scrambledNodes) {
    String schemaName=a.getRight().getLeft();
    String tableName=a.getRight().getMiddle();
    scrambles.add(Pair.of(schemaName,tableName));
  }
  AggBlockMeta aggMeta=new AggBlockMeta(scrambleMeta,scrambles);
  for (int i=0; i < aggMeta.totalBlockAggCount(); i++) {
    AggExecutionNodeBlock copy=deepcopyExcludingDependentAggregates();
    List<Pair<QueryExecutionNode,Triple<String,String,String>>> scrambledNodeAndTableName=identifyScrambledNodes(scrambleMeta,copy.getNodesInBlock());
    for (    Pair<QueryExecutionNode,Triple<String,String,String>> a : scrambledNodeAndTableName) {
      QueryExecutionNode scrambledNode=a.getLeft();
      String schemaName=a.getRight().getLeft();
      String tableName=a.getRight().getMiddle();
      String aliasName=a.getRight().getRight();
      Pair<Integer,Integer> span=aggMeta.getAggBlockSpanForTable(schemaName,tableName,i);
      String aggblockColumn=scrambleMeta.getAggregationBlockColumn(schemaName,tableName);
      SelectQuery q=(SelectQuery)scrambledNode.getSelectQuery();
      if (aliasName == null) {
        throw new VerdictDBValueException(String.format("String_Node_Str",schemaName,tableName));
      }
      int left=span.getLeft();
      int right=span.getRight();
      if (left == right) {
        q.addFilterByAnd(ColumnOp.equal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(left)));
      }
 else {
        q.addFilterByAnd(ColumnOp.greaterequal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(left)));
        q.addFilterByAnd(ColumnOp.lessequal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(right)));
      }
    }
    individualAggNodes.add(copy.getBlockRootNode());
  }
  for (  QueryExecutionNode n : individualAggNodes) {
    n.clearBroadcastingQueues();
  }
  for (int i=1; i < aggMeta.totalBlockAggCount(); i++) {
    AggCombinerExecutionNode combiner;
    if (i == 1) {
      combiner=AggCombinerExecutionNode.create(plan,individualAggNodes.get(0),individualAggNodes.get(1));
    }
 else {
      combiner=AggCombinerExecutionNode.create(plan,combiners.get(i - 2),individualAggNodes.get(i));
    }
    combiners.add(combiner);
  }
  QueryExecutionNode newRoot=AsyncAggExecutionNode.create(plan,individualAggNodes,combiners);
  List<ExecutionTokenQueue> broadcastingQueue=blockRoot.getBroadcastingQueues();
  for (  ExecutionTokenQueue queue : broadcastingQueue) {
    newRoot.addBroadcastingQueue(queue);
  }
  return newRoot;
}

Fixed version (ground truth):
/** 
 * Converts the root node and its descendants into the configuration that enables progressive aggregation. Basically aggregate subqueries are blocking operations while others operations are divided into smaller- scale operations (which involve different portions of data).
 * @param nodeBlock
 * @return Returns the root of the multiple aggregation nodes (each of which involves different combinationsof partitions)
 * @throws VerdictDBValueException 
 */
public QueryExecutionNode convertToProgressiveAgg() throws VerdictDBValueException {
  List<QueryExecutionNode> individualAggNodes=new ArrayList<>();
  List<QueryExecutionNode> combiners=new ArrayList<>();
  ScrambleMeta scrambleMeta=plan.getScrambleMeta();
  List<Pair<QueryExecutionNode,Triple<String,String,String>>> scrambledNodes=identifyScrambledNodes(scrambleMeta,blockNodes);
  List<Pair<String,String>> scrambles=new ArrayList<>();
  for (  Pair<QueryExecutionNode,Triple<String,String,String>> a : scrambledNodes) {
    String schemaName=a.getRight().getLeft();
    String tableName=a.getRight().getMiddle();
    scrambles.add(Pair.of(schemaName,tableName));
  }
  AggBlockMeta aggMeta=new AggBlockMeta(scrambleMeta,scrambles);
  for (int i=0; i < aggMeta.totalBlockAggCount(); i++) {
    AggExecutionNodeBlock copy=deepcopyExcludingDependentAggregates();
    QueryExecutionNode aggroot=copy.getBlockRootNode();
    for (    QueryExecutionNode parent : aggroot.getParents()) {
      parent.getDependents().remove(aggroot);
    }
    aggroot.getParents().clear();
    List<Pair<QueryExecutionNode,Triple<String,String,String>>> scrambledNodeAndTableName=identifyScrambledNodes(scrambleMeta,copy.getNodesInBlock());
    for (    Pair<QueryExecutionNode,Triple<String,String,String>> a : scrambledNodeAndTableName) {
      QueryExecutionNode scrambledNode=a.getLeft();
      String schemaName=a.getRight().getLeft();
      String tableName=a.getRight().getMiddle();
      String aliasName=a.getRight().getRight();
      Pair<Integer,Integer> span=aggMeta.getAggBlockSpanForTable(schemaName,tableName,i);
      String aggblockColumn=scrambleMeta.getAggregationBlockColumn(schemaName,tableName);
      SelectQuery q=(SelectQuery)scrambledNode.getSelectQuery();
      if (aliasName == null) {
        throw new VerdictDBValueException(String.format("String_Node_Str",schemaName,tableName));
      }
      int left=span.getLeft();
      int right=span.getRight();
      if (left == right) {
        q.addFilterByAnd(ColumnOp.equal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(left)));
      }
 else {
        q.addFilterByAnd(ColumnOp.greaterequal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(left)));
        q.addFilterByAnd(ColumnOp.lessequal(new BaseColumn(aliasName,aggblockColumn),ConstantColumn.valueOf(right)));
      }
    }
    individualAggNodes.add(aggroot);
  }
  for (  QueryExecutionNode n : individualAggNodes) {
    n.clearBroadcastingQueues();
  }
  for (int i=1; i < aggMeta.totalBlockAggCount(); i++) {
    AggCombinerExecutionNode combiner;
    if (i == 1) {
      combiner=AggCombinerExecutionNode.create(plan,individualAggNodes.get(0),individualAggNodes.get(1));
    }
 else {
      combiner=AggCombinerExecutionNode.create(plan,combiners.get(i - 2),individualAggNodes.get(i));
    }
    combiners.add(combiner);
  }
  QueryExecutionNode newRoot=AsyncAggExecutionNode.create(plan,individualAggNodes,combiners);
  List<ExecutionTokenQueue> broadcastingQueue=blockRoot.getBroadcastingQueues();
  for (  ExecutionTokenQueue queue : broadcastingQueue) {
    newRoot.addBroadcastingQueue(queue);
  }
  return newRoot;
}