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;
ReduceSinkDesc conf = op.getConf();
List<String> colLists = new ArrayList<String>();
ArrayList<ExprNodeDesc> keys = conf.getKeyCols();
for (ExprNodeDesc key : keys) {
colLists = Utilities.mergeUniqElems(colLists, key.getCols());
}
assert op.getNumChild() == 1;
Operator<? extends OperatorDesc> child = op.getChildOperators().get(0);
List<String> childCols;
if (child instanceof CommonJoinOperator) {
childCols = cppCtx.getJoinPrunedColLists().get(child)
.get((byte) conf.getTag());
} else {
childCols = cppCtx.getPrunedColList(child);
}
if (childCols != null) {
/*
* in the case of count(or sum) distinct if we are not able to map
* a parameter column references back to the ReduceSink value columns
* we give up and assume all columns are needed.
*/
boolean hasUnresolvedReference = false;
boolean[] flags = new boolean[conf.getValueCols().size()];
Map<String, ExprNodeDesc> exprMap = op.getColumnExprMap();
for (String childCol : childCols) {
ExprNodeDesc desc = exprMap.get(childCol);
int index = conf.getValueCols().indexOf(desc);
if (index < 0) {
hasUnresolvedReference = desc == null || ExprNodeDescUtils.indexOf(desc, conf.getKeyCols()) < 0;
if ( hasUnresolvedReference ) {
break;
}
continue;
}
flags[index] = true;
colLists = Utilities.mergeUniqElems(colLists, desc.getCols());
}
if ( hasUnresolvedReference ) {
for (ExprNodeDesc val : conf.getValueCols()) {
colLists = Utilities.mergeUniqElems(colLists, val.getCols());
}
cppCtx.getPrunedColLists().put(op, colLists);
return null;
}
Collections.sort(colLists);
pruneReduceSinkOperator(flags, op, cppCtx);
cppCtx.getPrunedColLists().put(op, colLists);
return null;
}
// Reduce Sink contains the columns needed - no need to aggregate from
// children
ArrayList<ExprNodeDesc> vals = conf.getValueCols();
for (ExprNodeDesc val : vals) {
colLists = Utilities.mergeUniqElems(colLists, val.getCols());
}
cppCtx.getPrunedColLists().put(op, colLists);