private static void replaceSemijoinExpressions(TableScanOperator tsOp, List<ExprNodeDesc> semijoinExprNodes) {
    ExprNodeDesc constNode = new ExprNodeConstantDesc(
        TypeInfoFactory.booleanTypeInfo, Boolean.TRUE);
    // TS operator
    if (tsOp.getConf().getFilterExpr() != null) {
      ExprNodeDesc tsFilterExpr = tsOp.getConf().getFilterExpr();
      if (FunctionRegistry.isOpAnd(tsFilterExpr)) {
        tsFilterExpr.getChildren().removeIf(SharedWorkOptimizer::isSemijoinExpr);
        tsFilterExpr.getChildren().addAll(semijoinExprNodes);
        if (tsFilterExpr.getChildren().isEmpty() ||
            (tsFilterExpr.getChildren().size() == 1 && !(tsFilterExpr.getChildren().get(0) instanceof ExprNodeGenericFuncDesc))) {
          tsOp.getConf().setFilterExpr(null);
        }
      }
    }
    // Filter operators on top
    if (tsOp.getChildOperators() != null) {
      for (Operator op : tsOp.getChildOperators()) {
        if (op instanceof FilterOperator) {
          FilterOperator filterOp = (FilterOperator) op;
          ExprNodeDesc filterExpr = filterOp.getConf().getPredicate();
          if (FunctionRegistry.isOpAnd(filterExpr)) {
            filterExpr.getChildren().removeIf(SharedWorkOptimizer::isSemijoinExpr);
            if (filterExpr.getChildren().isEmpty()) {
              filterOp.getConf().setPredicate(constNode);
            } else if (filterExpr.getChildren().size() == 1) {
              filterOp.getConf().setPredicate(filterExpr.getChildren().get(0));
            }
          }
        }
      }
    }
  }
When we call this method, we have already verified that the SJ expressions targeting
two TS operators are the same.
Since we already had a method to push the filter expressions on top of the discardable
TS (pushFilterToTopOfTableScan), here we remove the old SJ expressions from the
discardable TS (and follow-up Filters if present) and we add the SJ expressions
from the retainable TS. That way the SJ expressions will be pushed on top of the
discardable TS by pushFilterToTopOfTableScan.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/SharedWorkOptimizer.java