ReduceSinkOperator op = (ReduceSinkOperator) nd;
ColumnPrunerProcCtx cppCtx = (ColumnPrunerProcCtx) ctx;
HashMap<Operator<? extends OperatorDesc>, OpParseContext> opToParseCtxMap = cppCtx
.getOpToParseCtxMap();
RowResolver redSinkRR = opToParseCtxMap.get(op).getRowResolver();
ReduceSinkDesc conf = op.getConf();
List<Operator<? extends OperatorDesc>> childOperators = op
.getChildOperators();
List<Operator<? extends OperatorDesc>> 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 OperatorDesc> par = parentOperators.get(0);
JoinOperator childJoin = (JoinOperator) childOperators.get(0);
RowResolver parRR = opToParseCtxMap.get(par).getRowResolver();
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);
if (nm != null) {
ColumnInfo cInfo = parRR.get(nm[0], nm[1]);
if (!colLists.contains(cInfo.getInternalName())) {
colLists.add(cInfo.getInternalName());
}
}
}
}
Collections.sort(colLists);
pruneReduceSinkOperator(flags, op, cppCtx);
} else if ((childOperators.size() == 1)
&& (childOperators.get(0) instanceof ExtractOperator )
&& (childOperators.get(0).getChildOperators().size() == 1)
&& (childOperators.get(0).getChildOperators().get(0) instanceof PTFOperator )
&& ((PTFOperator)childOperators.get(0).
getChildOperators().get(0)).getConf().forWindowing() ) {
/*
* For RS that are followed by Extract & PTFOp for windowing
* - do the same thing as above. Reconstruct ValueColumn list based on what is required
* by the PTFOp.
*/
assert parentOperators.size() == 1;
PTFOperator ptfOp = (PTFOperator) childOperators.get(0).getChildOperators().get(0);
List<String> childCols = cppCtx.getPrunedColList(ptfOp);
boolean[] flags = new boolean[conf.getValueCols().size()];
for (int i = 0; i < flags.length; i++) {
flags[i] = false;
}
if (childCols != null && childCols.size() > 0) {
ArrayList<String> outColNames = op.getConf().getOutputValueColumnNames();
for(int i=0; i < outColNames.size(); i++ ) {
if ( childCols.contains(outColNames.get(i))) {
ExprNodeDesc exprNode = op.getConf().getValueCols().get(i);
flags[i] = true;
Utilities.mergeUniqElems(colLists, exprNode.getCols());
}
}
}
Collections.sort(colLists);
pruneReduceSinkOperator(flags, op, cppCtx);
} else {
// 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());
}
}