@Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      FilterOperator filterOp = (FilterOperator) nd;
      // We try to push the full Filter predicate iff:
      // - the Filter is on top of a TableScan, or
      // - the Filter is on top of a PTF (between PTF and Filter, there might be Select operators)
      // - the Filter is on top of a LateralViewJoinOperator (the filter can be pushed through one
      //   side of the join with the base table predicate, but not the UDTF side.)
      // Otherwise, we push only the synthetic join predicates
      // Note : pushing Filter on top of PTF is necessary so the LimitPushdownOptimizer for Rank
      // functions gets enabled.
      boolean onlySyntheticJoinPredicate = false;
      if (!(filterOp.getParentOperators().get(0) instanceof TableScanOperator)) {
        onlySyntheticJoinPredicate = true;
        Operator<?> parent = filterOp;
        while (true) {
          assert parent.getParentOperators().size() == 1;
          parent = parent.getParentOperators().get(0);
          if (parent instanceof SelectOperator) {
            continue;
          } else if (parent instanceof PTFOperator) {
            onlySyntheticJoinPredicate = false;
            break;
          } else if (parent instanceof LateralViewJoinOperator) {
            onlySyntheticJoinPredicate = false;
            break;
          } else {
            break;
          }
        }
      }
      return process(nd, stack, procCtx, onlySyntheticJoinPredicate, nodeOutputs);
    }
Determines the push down predicates in its where expression and then
combines it with the push down predicates that are passed from its children.
ql/src/java/org/apache/hadoop/hive/ql/ppd/OpProcFactory.java