core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
/**
   * Reduces a list of expressions.
   *
   * @param rel     Relational expression
   * @param expList List of expressions, modified in place
   * @param predicates Constraints known to hold on input expressions
   * @return whether reduction found something to change, and succeeded
   */
Reduces a list of expressions.
@param rel     Relational expression
@param expList List of expressions, modified in place
@param predicates Constraints known to hold on input expressions
@return whether reduction found something to change, and succeeded
Reduces a list of expressions . @param rel Relational expression @param expList List of expressions modified in place @param predicates Constraints known to hold on input expressions @return whether reduction found something to change and succeeded
static boolean reduceExpressions(RelNode rel, List<RexNode> expList,
      RelOptPredicateList predicates) {
    RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    final List<RexNode> constExps = Lists.newArrayList();
    List<Boolean> addCasts = Lists.newArrayList();
    final List<RexNode> removableCasts = Lists.newArrayList();
    final ImmutableMap<RexNode, RexLiteral> constants =
        predicateConstants(predicates);
    findReducibleExps(rel.getCluster().getTypeFactory(), expList, constants,
        constExps, addCasts, removableCasts);
    if (constExps.isEmpty() && removableCasts.isEmpty()) {
      return false;
    }
    if (!removableCasts.isEmpty()) {
      final List<RexNode> reducedExprs = Lists.newArrayList();
      for (RexNode exp : removableCasts) {
        RexCall call = (RexCall) exp;
        reducedExprs.add(call.getOperands().get(0));
      }
      RexReplacer replacer =
          new RexReplacer(
              rexBuilder,
              removableCasts,
              reducedExprs,
              Collections.nCopies(removableCasts.size(), false));
      replacer.mutate(expList);
    }
    if (constExps.isEmpty()) {
      return true;
    }
    final List<RexNode> constExps2 = Lists.newArrayList(constExps);
    if (!constants.isEmpty()) {
      final List<Map.Entry<RexNode, RexNode>> pairs =
          (List<Map.Entry<RexNode, RexNode>>) (List)
              Lists.newArrayList(constants.entrySet());
      RexReplacer replacer =
          new RexReplacer(
              rexBuilder,
              Pair.left(pairs),
              Pair.right(pairs),
              Collections.nCopies(pairs.size(), false));
      replacer.mutate(constExps2);
    }
    RelOptPlanner.Executor executor =
        rel.getCluster().getPlanner().getExecutor();
    final List<RexNode> reducedValues = Lists.newArrayList();
    executor.reduce(rexBuilder, constExps2, reducedValues);
    if (rel instanceof LogicalProject) {
      addCasts = Collections.nCopies(reducedValues.size(), true);
    }
    RexReplacer replacer =
        new RexReplacer(
            rexBuilder,
            constExps,
            reducedValues,
            addCasts);
    replacer.mutate(expList);
    return true;
  }
static boolean reduceExpressions ( RelNode rel , List < RexNode > expList , RelOptPredicateList predicates ) { RexBuilder rexBuilder = rel . getCluster ( ) . getRexBuilder ( ) ; final List < RexNode > constExps = Lists . newArrayList ( ) ; List < Boolean > addCasts = Lists . newArrayList ( ) ; final List < RexNode > removableCasts = Lists . newArrayList ( ) ; final ImmutableMap < RexNode , RexLiteral > constants = predicateConstants ( predicates ) ; findReducibleExps ( rel . getCluster ( ) . getTypeFactory ( ) , expList , constants , constExps , addCasts , removableCasts ) ; if ( constExps . isEmpty ( ) && removableCasts . isEmpty ( ) ) { return false ; } if ( ! removableCasts . isEmpty ( ) ) { final List < RexNode > reducedExprs = Lists . newArrayList ( ) ; for ( RexNode exp : removableCasts ) { RexCall call = ( RexCall ) exp ; reducedExprs . add ( call . getOperands ( ) . get ( 0 ) ) ; } RexReplacer replacer = new RexReplacer ( rexBuilder , removableCasts , reducedExprs , Collections . nCopies ( removableCasts . size ( ) , false ) ) ; replacer . mutate ( expList ) ; } if ( constExps . isEmpty ( ) ) { return true ; } final List < RexNode > constExps2 = Lists . newArrayList ( constExps ) ; if ( ! constants . isEmpty ( ) ) { final List < Map . Entry < RexNode , RexNode > > pairs = ( List < Map . Entry < RexNode , RexNode > > ) ( List ) Lists . newArrayList ( constants . entrySet ( ) ) ; RexReplacer replacer = new RexReplacer ( rexBuilder , Pair . left ( pairs ) , Pair . right ( pairs ) , Collections . nCopies ( pairs . size ( ) , false ) ) ; replacer . mutate ( constExps2 ) ; } RelOptPlanner . Executor executor = rel . getCluster ( ) . getPlanner ( ) . getExecutor ( ) ; final List < RexNode > reducedValues = Lists . newArrayList ( ) ; executor . reduce ( rexBuilder , constExps2 , reducedValues ) ; if ( rel instanceof LogicalProject ) { addCasts = Collections . nCopies ( reducedValues . size ( ) , true ) ; } RexReplacer replacer = new RexReplacer ( rexBuilder , constExps , reducedValues , addCasts ) ; replacer . mutate ( expList ) ; return true ; }
Reduces a list of expressions.
Reduces a list of expressions .
// Find reducible expressions. // Remove redundant casts before reducing constant expressions. // If the argument to the redundant cast is a reducible constant, // reducing that argument to a constant first will result in not being // able to locate the original cast expression. //noinspection unchecked // Compute the values they reduce to. // For Project, we have to be sure to preserve the result // types, so always cast regardless of the expression type. // For other RelNodes like Filter, in general, this isn't necessary, // and the presence of casts could hinder other rules such as sarg // analysis, which require bare literals.  But there are special cases, // like when the expression is a UDR argument, that need to be // handled as special cases.