/**
* The Node Processor for Column Pruning on Reduce Sink Operators.
*/
public static class ColumnPrunerReduceSinkProc implements NodeProcessor {
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx ctx, Object... nodeOutputs) throws SemanticException {
ReduceSinkOperator op = (ReduceSinkOperator)nd;
ColumnPrunerProcCtx cppCtx = (ColumnPrunerProcCtx)ctx;
HashMap<Operator<? extends Serializable>, OpParseContext> opToParseCtxMap =
cppCtx.getOpToParseCtxMap();
RowResolver redSinkRR = opToParseCtxMap.get(op).getRR();
reduceSinkDesc conf = op.getConf();
List<Operator<? extends Serializable>> childOperators = op.getChildOperators();
List<Operator<? extends Serializable>> parentOperators = op.getParentOperators();
List<String> colLists = new ArrayList<String>();
ArrayList<exprNodeDesc> keys = conf.getKeyCols();
for (exprNodeDesc key : keys)
colLists = Utilities.mergeUniqElems(colLists, key.getCols());
if ((childOperators.size() == 1) && (childOperators.get(0) instanceof JoinOperator)) {
assert parentOperators.size() == 1;
Operator<? extends Serializable> par = parentOperators.get(0);
JoinOperator childJoin = (JoinOperator)childOperators.get(0);
RowResolver parRR = opToParseCtxMap.get(par).getRR();
List<String> childJoinCols = cppCtx.getJoinPrunedColLists().get(childJoin).get((byte)conf.getTag());
boolean[] flags = new boolean[conf.getValueCols().size()];
for (int i = 0; i < flags.length; i++)
flags[i] = false;
if (childJoinCols != null && childJoinCols.size() > 0) {
Map<String,exprNodeDesc> exprMap = op.getColumnExprMap();
for (String childCol : childJoinCols) {
exprNodeDesc desc = exprMap.get(childCol);
int index = conf.getValueCols().indexOf(desc);
flags[index] = true;
String[] nm = redSinkRR.reverseLookup(childCol);