Class AggregateReduceFunctionsRule

All Implemented Interfaces:
TransformationRule

@Enclosing public class AggregateReduceFunctionsRule extends RelRule<AggregateReduceFunctionsRule.Config> implements TransformationRule
Planner rule that reduces aggregate functions in Aggregates to simpler forms.

Rewrites:

  • AVG(x) → SUM(x) / COUNT(x)
  • STDDEV_POP(x) → SQRT( (SUM(x * x) - SUM(x) * SUM(x) / COUNT(x)) / COUNT(x))
  • STDDEV_SAMP(x) → SQRT( (SUM(x * x) - SUM(x) * SUM(x) / COUNT(x)) / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END)
  • VAR_POP(x) → (SUM(x * x) - SUM(x) * SUM(x) / COUNT(x)) / COUNT(x)
  • VAR_SAMP(x) → (SUM(x * x) - SUM(x) * SUM(x) / COUNT(x)) / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END
  • COVAR_POP(x, y) → (SUM(x * y) - SUM(x, y) * SUM(y, x) / REGR_COUNT(x, y)) / REGR_COUNT(x, y)
  • COVAR_SAMP(x, y) → (SUM(x * y) - SUM(x, y) * SUM(y, x) / REGR_COUNT(x, y)) / CASE REGR_COUNT(x, y) WHEN 1 THEN NULL ELSE REGR_COUNT(x, y) - 1 END
  • REGR_SXX(x, y) → REGR_COUNT(x, y) * VAR_POP(y)
  • REGR_SYY(x, y) → REGR_COUNT(x, y) * VAR_POP(x)

Since many of these rewrites introduce multiple occurrences of simpler forms like COUNT(x), the rule gathers common sub-expressions as it goes.

See Also:
  • Constructor Details

  • Method Details

    • matches

      public boolean matches(RelOptRuleCall call)
      Description copied from class: RelOptRule
      Returns whether this rule could possibly match the given operands.

      This method is an opportunity to apply side-conditions to a rule. The RelOptPlanner calls this method after matching all operands of the rule, and before calling RelOptRule.onMatch(RelOptRuleCall).

      In implementations of RelOptPlanner which may queue up a matched RelOptRuleCall for a long time before calling RelOptRule.onMatch(RelOptRuleCall), this method is beneficial because it allows the planner to discard rules earlier in the process.

      The default implementation of this method returns true. It is acceptable for any implementation of this method to give a false positives, that is, to say that the rule matches the operands but have RelOptRule.onMatch(RelOptRuleCall) subsequently not generate any successors.

      The following script is useful to identify rules which commonly produce no successors. You should override this method for these rules:

      awk '
       /Apply rule/ {rule=$4; ruleCount[rule]++;}
       /generated 0 successors/ {ruleMiss[rule]++;}
       END {
         printf "%-30s %s %s\n", "Rule", "Fire", "Miss";
         for (i in ruleCount) {
           printf "%-30s %5d %5d\n", i, ruleCount[i], ruleMiss[i];
         }
       } ' FarragoTrace.log
      Overrides:
      matches in class RelOptRule
      Parameters:
      call - Rule call which has been determined to match all operands of this rule
      Returns:
      whether this RelOptRule matches a given RelOptRuleCall
    • onMatch

      public void onMatch(RelOptRuleCall ruleCall)
      Description copied from class: RelOptRule
      Receives notification about a rule match. At the time that this method is called, call.rels holds the set of relational expressions which match the operands to the rule; call.rels[0] is the root expression.

      Typically a rule would check that the nodes are valid matches, creates a new expression, then calls back RelOptRuleCall.transformTo(org.apache.calcite.rel.RelNode, java.util.Map<org.apache.calcite.rel.RelNode, org.apache.calcite.rel.RelNode>, org.apache.calcite.plan.RelHintsPropagator) to register the expression.

      Specified by:
      onMatch in class RelOptRule
      Parameters:
      ruleCall - Rule call
      See Also:
    • canReduce

      public boolean canReduce(AggregateCall call)
      Returns whether this rule can reduce a given aggregate function call.
    • canReduceAggCallByGrouping

      public boolean canReduceAggCallByGrouping(Aggregate oldAggRel, AggregateCall call)
      Returns whether this rule can reduce some agg-call, which its arg exists in the aggregate's group.
    • newAggregateRel

      protected void newAggregateRel(RelBuilder relBuilder, Aggregate oldAggregate, List<AggregateCall> newCalls)
      Does a shallow clone of oldAggRel and updates aggCalls. Could be refactored into Aggregate and subclasses - but it's only needed for some subclasses.
      Parameters:
      relBuilder - Builder of relational expressions; at the top of its stack is its input
      oldAggregate - LogicalAggregate to clone.
      newCalls - New list of AggregateCalls
    • newCalcRel

      protected void newCalcRel(RelBuilder relBuilder, RelDataType rowType, List<RexNode> exprs)
      Adds a calculation with the expressions to compute the original aggregate calls from the decomposed ones.
      Parameters:
      relBuilder - Builder of relational expressions; at the top of its stack is its input
      rowType - The output row type of the original aggregate.
      exprs - The expressions to compute the original aggregate calls