private void mergeOneCombinePlanWithIndex(PhysicalPlan from,
PhysicalPlan to, int initial, int current, byte mapKeyType) throws VisitorException {
POPackage cpk = (POPackage)from.getRoots().get(0);
from.remove(cpk);
PODemux demux = (PODemux)to.getLeaves().get(0);
boolean isSameKeyType = demux.isSameMapKeyType();
POMultiQueryPackage pkg = (POMultiQueryPackage)to.getRoots().get(0);
// if current > initial + 1, it means we had
// a split in the map of the MROper we are trying to
// merge. In that case we would have changed the indices
// of the POLocalRearranges in the split to be in the
// range initial to current. To handle key, value pairs
// coming out of those POLocalRearranges, we add
// the Packages in the 'from' POMultiQueryPackage (in this case,
// it has to be a POMultiQueryPackage since we had
// a POSplit in the map) to the 'to' POMultiQueryPackage.
// These Packages would have correct positions in the package
// list and would be able to handle the outputs from the different
// POLocalRearranges.
int total = current - initial;
int pkCount = 0;
if (cpk instanceof POMultiQueryPackage) {
List<POPackage> pkgs = ((POMultiQueryPackage)cpk).getPackages();
for (POPackage p : pkgs) {
pkg.addPackage(p);
if (!isSameKeyType) {
p.setKeyType(DataType.TUPLE);
}
pkCount++;
}
} else {
pkg.addPackage(cpk);
pkCount = 1;
}
if (pkCount != total) {
int errCode = 2146;
String msg = "Internal Error. Inconsistency in key index found during optimization.";
throw new OptimizerException(msg, errCode, PigException.BUG);
}
// all packages should have the same key type
if (!isSameKeyType) {
cpk.setKeyType(DataType.TUPLE);
}
pkg.setKeyType(cpk.getKeyType());
boolean[] keyPos = cpk.getKeyPositionsInTuple();
// See comment above for why we flatten the Packages
// in the from plan - for the same reason, we flatten
// the inner plans of Demux operator now.
int plCount = 0;
PhysicalOperator leaf = from.getLeaves().get(0);
if (leaf instanceof PODemux) {
List<PhysicalPlan> pls = ((PODemux)leaf).getPlans();
for (PhysicalPlan pl : pls) {
demux.addPlan(pl, mapKeyType, keyPos);
POLocalRearrange lr = (POLocalRearrange)pl.getLeaves().get(0);
try {
lr.setMultiQueryIndex(initial + plCount++);
} catch (ExecException e) {
int errCode = 2136;
String msg = "Internal Error. Unable to set multi-query index for optimization.";
throw new OptimizerException(msg, errCode, PigException.BUG, e);
}
// change the map key type to tuple when
// multiple splittees have different map key types
if (!isSameKeyType) {
lr.setKeyType(DataType.TUPLE);
}
}
} else {
demux.addPlan(from, mapKeyType, keyPos);
POLocalRearrange lr = (POLocalRearrange)from.getLeaves().get(0);
try {
lr.setMultiQueryIndex(initial + plCount++);
} catch (ExecException e) {
int errCode = 2136;