@SuppressWarnings("incomplete-switch")
  private static List<RexNode> rewriteProjects(List<RexNode> projects,
          RexNode newPushedCondition, RelBuilder relBuilder) {
    final List<RexNode> conjunctions = RelOptUtil.conjunctions(newPushedCondition);
    final Map<String, RexNode> conditions = new HashMap<String, RexNode>();
    for (RexNode conjunction: conjunctions) {
      // 1.1. If it is not a RexCall, we continue
      if (!(conjunction instanceof RexCall)) {
        continue;
      }
      // 1.2. We extract the information that we need
      RexCall conjCall = (RexCall) conjunction;
      switch (conjCall.getOperator().getKind()) {
        case EQUALS:
          if (!(RexUtil.isConstant(conjCall.operands.get(0))) &&
                  RexUtil.isConstant(conjCall.operands.get(1))) {
            conditions.put(conjCall.operands.get(0).toString(), conjCall.operands.get(1));
          } else if (!(RexUtil.isConstant(conjCall.operands.get(1))) &&
                  RexUtil.isConstant(conjCall.operands.get(0))) {
            conditions.put(conjCall.operands.get(1).toString(), conjCall.operands.get(0));
          }
          break;
        case IS_NULL:
          conditions.put(conjCall.operands.get(0).toString(),
                  relBuilder.getRexBuilder().makeNullLiteral(
                          conjCall.operands.get(0).getType()));
      }
    }

    RexReplacer replacer = new RexReplacer(relBuilder.getRexBuilder(), conditions);
    List<RexNode> newProjects = Lists.newArrayList(projects);
    replacer.mutate(newProjects);
    if (replacer.replaced) {
      return newProjects;
    }
    return null;
  }
Planner rule that infers constant expressions from Filter into
a Project operator.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveProjectFilterPullUpConstantsRule.java