Class AggregateReduceFunctionsRule


  • public class AggregateReduceFunctionsRule
    extends RelOptRule
    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.

    • Constructor Detail

      • AggregateReduceFunctionsRule

        public AggregateReduceFunctionsRule​(RelOptRuleOperand operand,
                                            RelBuilderFactory relBuilderFactory)
        Creates an AggregateReduceFunctionsRule.
    • Method Detail

      • 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
      • containsAvgStddevVarCall

        private boolean containsAvgStddevVarCall​(java.util.List<AggregateCall> aggCallList)
        Returns whether any of the aggregates are calls to AVG, STDDEV_*, VAR_*.
        Parameters:
        aggCallList - List of aggregate calls
      • isReducible

        private boolean isReducible​(SqlKind kind)
        Returns whether the aggregate call is a reducible function
      • reduceAggs

        private void reduceAggs​(RelOptRuleCall ruleCall,
                                Aggregate oldAggRel)
        Reduces all calls to AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP in the aggregates list to.

        It handles newly generated common subexpressions since this was done at the sql2rel stage.

      • lookupOrAdd

        private static <T> int lookupOrAdd​(java.util.List<T> list,
                                           T element)
        Finds the ordinal of an element in a list, or adds it.
        Type Parameters:
        T - Element type
        Parameters:
        list - List
        element - Element to lookup or add
        Returns:
        Ordinal of element in list
      • newAggregateRel

        protected void newAggregateRel​(RelBuilder relBuilder,
                                       Aggregate oldAggregate,
                                       java.util.List<AggregateCall> newCalls)
        Do a shallow clone of oldAggRel and update 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,
                                  java.util.List<RexNode> exprs)
        Add a calc with the expressions to compute the original agg 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 agg calls.