@Override
public void transform(List<LogicalOperator> nodes)
throws OptimizerException {
try {
LOForEach foreach = (LOForEach) getOperator(nodes);
LogicalOperator successor = mPlan.getSuccessors(foreach).get(0);
if (mSwap) {
mPlan.swap(successor, foreach);
} else if (mInsertBetween) {
// mark the flattened columns as not flattened in the foreach
// create a new foreach operator that projects each column of the
// successor. Mark the remapped flattened columns as flattened
// in the new foreach operator
if(mFlattenedColumnReMap == null) {
int errCode = 2153;
String msg = "Internal error. The mapping for the flattened columns is empty";
throw new OptimizerException(msg, errCode, PigException.BUG);
}
// set flatten to false for all columns in the mapping
ArrayList<Boolean> flattenList = (ArrayList<Boolean>)foreach.getFlatten();
for(Integer key: mFlattenedColumnReMap.keySet()) {
flattenList.set(key, false);
}
// rebuild schemas of the foreach and the successor after the foreach modification
foreach.regenerateSchema();
successor.regenerateSchema();
Schema successorSchema = successor.getSchema();
if(successorSchema == null) {
int errCode = 2154;
String msg = "Internal error. Schema of successor cannot be null for pushing down foreach with flatten.";
throw new OptimizerException(msg, errCode, PigException.BUG);
}
flattenList = new ArrayList<Boolean>();
ArrayList<LogicalPlan> foreachInnerPlans = new ArrayList<LogicalPlan>();
for(int i = 0; i < successorSchema.size(); ++i) {
LogicalPlan innerPlan = new LogicalPlan();
LOProject project = new LOProject(innerPlan, OperatorKey
.genOpKey(foreach.getOperatorKey().scope),
successor, i);
innerPlan.add(project);
foreachInnerPlans.add(innerPlan);
flattenList.add(false);
}
// set the flattened remapped column to true
for(Integer key: mFlattenedColumnReMap.keySet()) {
Integer value = mFlattenedColumnReMap.get(key);
flattenList.set(value, true);
}
LOForEach newForeach = new LOForEach(mPlan, OperatorKey
.genOpKey(foreach.getOperatorKey().scope), foreachInnerPlans,
flattenList);
// add the new foreach to the plan
mPlan.add(newForeach);