private static void pushFilterToTopOfTableScan(
      SharedWorkOptimizerCache optimizerCache, DecomposedTs tsModel)
                  throws UDFArgumentException {
    TableScanOperator tsOp = tsModel.ts;
    ExprNodeGenericFuncDesc tableScanExprNode = (ExprNodeGenericFuncDesc) tsModel.getFullFilterExpr();
    if (tableScanExprNode == null) {
      return;
    }
    List<Operator<? extends OperatorDesc>> allChildren =
        Lists.newArrayList(tsOp.getChildOperators());
    childOperators:
    for (Operator<? extends OperatorDesc> op : allChildren) {
      if (optimizerCache.isKnownFilteringOperator(op)) {
        continue;
      }
      if (op instanceof FilterOperator) {
        FilterOperator filterOp = (FilterOperator) op;
        ExprNodeDesc filterExprNode  = filterOp.getConf().getPredicate();
        if (tableScanExprNode.isSame(filterExprNode)) {
          // We do not need to do anything
          optimizerCache.setKnownFilteringOperator(filterOp);
          continue;
        }
        if (tableScanExprNode.getGenericUDF() instanceof GenericUDFOPOr) {
          for (ExprNodeDesc childExprNode : tableScanExprNode.getChildren()) {
            if (childExprNode.isSame(filterExprNode)) {
              // We do not need to do anything, it is in the OR expression
              // so probably we pushed previously
              optimizerCache.setKnownFilteringOperator(filterOp);
              continue childOperators;
            }
          }
        }
        ExprNodeDesc newFilterExpr = conjunction(filterExprNode, tableScanExprNode);
        if (!isSame(filterOp.getConf().getPredicate(), newFilterExpr)) {
          filterOp.getConf().setPredicate(newFilterExpr);
        }
        optimizerCache.setKnownFilteringOperator(filterOp);
      } else {
        Operator<FilterDesc> newOp = OperatorFactory.get(tsOp.getCompilationOpContext(),
                new FilterDesc(tableScanExprNode.clone(), false),
            new RowSchema(tsOp.getSchema().getSignature()));
        tsOp.replaceChild(op, newOp);
        newOp.getParentOperators().add(tsOp);
        op.replaceParent(tsOp, newOp);
        newOp.getChildOperators().add(op);
        // Add to cache (same group as tsOp)
        optimizerCache.putIfWorkExists(newOp, tsOp);
        optimizerCache.setKnownFilteringOperator(newOp);
      }
    }

  }
Orders TS operators in decreasing order by "weight".
ql/src/java/org/apache/hadoop/hive/ql/optimizer/SharedWorkOptimizer.java