@Override
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
Object... nodeOutputs) throws SemanticException {
AnnotateStatsProcCtx aspCtx = (AnnotateStatsProcCtx) procCtx;
FilterOperator fop = (FilterOperator) nd;
Operator<? extends OperatorDesc> parent = fop.getParentOperators().get(0);
Statistics parentStats = parent.getStatistics();
List<String> neededCols = null;
if (parent instanceof TableScanOperator) {
TableScanOperator tsop = (TableScanOperator) parent;
neededCols = tsop.getNeededColumns();
}
try {
if (parentStats != null) {
ExprNodeDesc pred = fop.getConf().getPredicate();
// evaluate filter expression and update statistics
long newNumRows = evaluateExpression(parentStats, pred, aspCtx, neededCols);
Statistics st = parentStats.clone();
if (satisfyPrecondition(parentStats)) {
// update statistics based on column statistics.
// OR conditions keeps adding the stats independently, this may
// result in number of rows getting more than the input rows in
// which case stats need not be updated
if (newNumRows <= parentStats.getNumRows()) {
updateStats(st, newNumRows, true);
}
if (LOG.isDebugEnabled()) {
LOG.debug("[0] STATS-" + fop.toString() + ": " + st.extendedToString());
}
} else {
// update only the basic statistics in the absence of column statistics
if (newNumRows <= parentStats.getNumRows()) {
updateStats(st, newNumRows, false);
}
if (LOG.isDebugEnabled()) {
LOG.debug("[1] STATS-" + fop.toString() + ": " + st.extendedToString());
}
}
fop.setStatistics(st);
aspCtx.setAndExprStats(null);
}
} catch (CloneNotSupportedException e) {
throw new SemanticException(ErrorMsg.STATISTICS_CLONING_FAILED.getMsg());
}