Program: 56118
Project: 56118
Buggy source:
/** 
 * Private utility method that generates the alternative Match nodes, given fixed shipping strategies for the inputs.
 * @param target The list to put the alternatives in.
 * @param pred1 The predecessor node for the first input.
 * @param pred2 The predecessor node for the second input.
 * @param ss1 The shipping strategy for the first input.
 * @param ss2 The shipping strategy for the second input.
 * @param estimator The cost estimator.
 */
private void createLocalAlternatives(List<MatchNode> target,OptimizerNode pred1,OptimizerNode pred2,ShipStrategy ss1,ShipStrategy ss2,CostEstimator estimator){
  GlobalProperties gp1=PactConnection.getGlobalPropertiesAfterConnection(pred1,ss1);
  GlobalProperties gp2=PactConnection.getGlobalPropertiesAfterConnection(pred2,ss2);
  LocalProperties lp1=PactConnection.getLocalPropertiesAfterConnection(pred1,ss1);
  LocalProperties lp2=PactConnection.getLocalPropertiesAfterConnection(pred2,ss2);
  GlobalProperties outGp=new GlobalProperties();
  outGp.setPartitioning(gp1.getPartitioning().isPartitioned() ? gp1.getPartitioning() : gp2.getPartitioning());
  outGp.setKeyOrder(gp1.getKeyOrder().isOrdered() ? gp1.getKeyOrder() : gp2.getKeyOrder());
  LocalProperties outLp=new LocalProperties();
  outLp.setKeyOrder(lp1.getKeyOrder().isOrdered() && lp1.getKeyOrder() == lp2.getKeyOrder() ? lp1.getKeyOrder() : Order.NONE);
  outLp.setKeysGrouped(outLp.getKeyOrder().isOrdered());
  LocalStrategy ls=getLocalStrategy();
  if (ls != LocalStrategy.NONE) {
    if (ls == LocalStrategy.SORTMERGE) {
      outLp.setKeyOrder(Order.ASCENDING);
      outLp.setKeysGrouped(true);
    }
 else     if (ls == LocalStrategy.HYBRIDHASH_FIRST || ls == LocalStrategy.HYBRIDHASH_SECOND || ls == LocalStrategy.MMHASH_FIRST || ls == LocalStrategy.MMHASH_SECOND) {
      outLp.setKeyOrder(Order.NONE);
      outLp.setKeysGrouped(false);
    }
    createMatchAlternative(target,pred1,pred2,ss1,ss2,ls,outGp,outLp,estimator);
  }
 else   if (outLp.getKeyOrder().isOrdered()) {
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.NONE,outGp,outLp,estimator);
  }
 else   if (lp1.getKeyOrder().isOrdered() || lp2.getKeyOrder().isOrdered()) {
    outLp.setKeyOrder(lp1.getKeyOrder().isOrdered() ? lp1.getKeyOrder() : lp2.getKeyOrder());
    outLp.setKeysGrouped(true);
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.SORTMERGE,outGp,outLp,estimator);
  }
 else {
    if (pred1.estimatedOutputSize > 0 && pred2.estimatedOutputSize > 0) {
      createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.HYBRIDHASH_FIRST,outGp.createCopy(),outLp.createCopy(),estimator);
      createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.HYBRIDHASH_SECOND,outGp.createCopy(),outLp.createCopy(),estimator);
    }
    outLp.setKeyOrder(Order.ASCENDING);
    outLp.setKeysGrouped(true);
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.SORTMERGE,outGp,outLp,estimator);
  }
}

Fixed version (ground truth):
/** 
 * Private utility method that generates the alternative Match nodes, given fixed shipping strategies for the inputs.
 * @param target The list to put the alternatives in.
 * @param pred1 The predecessor node for the first input.
 * @param pred2 The predecessor node for the second input.
 * @param ss1 The shipping strategy for the first input.
 * @param ss2 The shipping strategy for the second input.
 * @param estimator The cost estimator.
 */
private void createLocalAlternatives(List<MatchNode> target,OptimizerNode pred1,OptimizerNode pred2,ShipStrategy ss1,ShipStrategy ss2,CostEstimator estimator){
  GlobalProperties gp1=PactConnection.getGlobalPropertiesAfterConnection(pred1,this,ss1);
  GlobalProperties gp2=PactConnection.getGlobalPropertiesAfterConnection(pred2,this,ss2);
  LocalProperties lp1=PactConnection.getLocalPropertiesAfterConnection(pred1,this,ss1);
  LocalProperties lp2=PactConnection.getLocalPropertiesAfterConnection(pred2,this,ss2);
  GlobalProperties outGp=new GlobalProperties();
  outGp.setPartitioning(gp1.getPartitioning().isComputablyPartitioned() ? gp1.getPartitioning() : gp2.getPartitioning());
  outGp.setKeyOrder(gp1.getKeyOrder().isOrdered() ? gp1.getKeyOrder() : gp2.getKeyOrder());
  LocalProperties outLp=new LocalProperties();
  outLp.setKeyOrder(lp1.getKeyOrder().isOrdered() && lp1.getKeyOrder() == lp2.getKeyOrder() ? lp1.getKeyOrder() : Order.NONE);
  outLp.setKeysGrouped(outLp.getKeyOrder().isOrdered());
  LocalStrategy ls=getLocalStrategy();
  if (ls != LocalStrategy.NONE) {
    if (ls == LocalStrategy.SORTMERGE) {
      outLp.setKeyOrder(Order.ASCENDING);
      outLp.setKeysGrouped(true);
    }
 else     if (ls == LocalStrategy.HYBRIDHASH_FIRST || ls == LocalStrategy.HYBRIDHASH_SECOND || ls == LocalStrategy.MMHASH_FIRST || ls == LocalStrategy.MMHASH_SECOND) {
      outLp.setKeyOrder(Order.NONE);
      outLp.setKeysGrouped(false);
    }
    createMatchAlternative(target,pred1,pred2,ss1,ss2,ls,outGp,outLp,estimator);
  }
 else   if (outLp.getKeyOrder().isOrdered()) {
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.NONE,outGp,outLp,estimator);
  }
 else   if (lp1.getKeyOrder().isOrdered() || lp2.getKeyOrder().isOrdered()) {
    outLp.setKeyOrder(lp1.getKeyOrder().isOrdered() ? lp1.getKeyOrder() : lp2.getKeyOrder());
    outLp.setKeysGrouped(true);
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.SORTMERGE,outGp,outLp,estimator);
  }
 else {
    if (pred1.estimatedOutputSize > 0 && pred2.estimatedOutputSize > 0) {
      createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.HYBRIDHASH_FIRST,outGp.createCopy(),outLp.createCopy(),estimator);
      createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.HYBRIDHASH_SECOND,outGp.createCopy(),outLp.createCopy(),estimator);
    }
    outLp.setKeyOrder(Order.ASCENDING);
    outLp.setKeysGrouped(true);
    createMatchAlternative(target,pred1,pred2,ss1,ss2,LocalStrategy.SORTMERGE,outGp,outLp,estimator);
  }
}