Class AggregateReduceFunctionsRule
- java.lang.Object
-
- org.apache.calcite.plan.RelOptRule
-
- org.apache.calcite.rel.rules.AggregateReduceFunctionsRule
-
public class AggregateReduceFunctionsRule extends RelOptRule
Planner rule that reduces aggregate functions inAggregate
s 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.
-
-
Field Summary
Fields Modifier and Type Field Description static AggregateReduceFunctionsRule
INSTANCE
The singleton.-
Fields inherited from class org.apache.calcite.plan.RelOptRule
description, operands, relBuilderFactory
-
-
Constructor Summary
Constructors Constructor Description AggregateReduceFunctionsRule(RelOptRuleOperand operand, RelBuilderFactory relBuilderFactory)
Creates an AggregateReduceFunctionsRule.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private boolean
containsAvgStddevVarCall(java.util.List<AggregateCall> aggCallList)
Returns whether any of the aggregates are calls to AVG, STDDEV_*, VAR_*.private AggregateCall
createAggregateCallWithBinding(RelDataTypeFactory typeFactory, SqlAggFunction aggFunction, RelDataType operandType, Aggregate oldAggRel, AggregateCall oldCall, int argOrdinal, int filter)
private RelDataType
getFieldType(RelNode relNode, int i)
private RexNode
getRegrCountRexNode(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, ImmutableIntList argOrdinals, com.google.common.collect.ImmutableList<RelDataType> operandTypes, int filterArg)
private RexNode
getSumAggregatedRexNode(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, RexBuilder rexBuilder, int argOrdinal, int filterArg)
private RexNode
getSumAggregatedRexNodeWithBinding(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, RelDataType operandType, int argOrdinal, int filter)
private boolean
isReducible(SqlKind kind)
Returns whether the aggregate call is a reducible functionprivate static <T> int
lookupOrAdd(java.util.List<T> list, T element)
Finds the ordinal of an element in a list, or adds it.boolean
matches(RelOptRuleCall call)
Returns whether this rule could possibly match the given operands.protected void
newAggregateRel(RelBuilder relBuilder, Aggregate oldAggregate, java.util.List<AggregateCall> newCalls)
Do a shallow clone of oldAggRel and update aggCalls.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.void
onMatch(RelOptRuleCall ruleCall)
Receives notification about a rule match.private RexNode
reduceAgg(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
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.private RexNode
reduceAvg(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
private RexNode
reduceCovariance(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
private RexNode
reduceRegrSzz(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs, int xIndex, int yIndex, int nullFilterIndex)
private RexNode
reduceStddev(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, boolean sqrt, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
private RexNode
reduceSum(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping)
-
Methods inherited from class org.apache.calcite.plan.RelOptRule
any, convert, convert, convertList, convertOperand, convertOperand, equals, equals, getOperand, getOperands, getOutConvention, getOutTrait, hashCode, none, operand, operand, operand, operand, operand, operandJ, operandJ, some, toString, unordered
-
-
-
-
Field Detail
-
INSTANCE
public static final AggregateReduceFunctionsRule INSTANCE
The singleton.
-
-
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 callingRelOptRule.onMatch(RelOptRuleCall)
.In implementations of
RelOptPlanner
which may queue up a matchedRelOptRuleCall
for a long time before callingRelOptRule.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 haveRelOptRule.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 classRelOptRule
- 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>)
to register the expression.- Specified by:
onMatch
in classRelOptRule
- Parameters:
ruleCall
- Rule call- See Also:
RelOptRule.matches(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.
-
reduceAgg
private RexNode reduceAgg(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
-
createAggregateCallWithBinding
private AggregateCall createAggregateCallWithBinding(RelDataTypeFactory typeFactory, SqlAggFunction aggFunction, RelDataType operandType, Aggregate oldAggRel, AggregateCall oldCall, int argOrdinal, int filter)
-
reduceAvg
private RexNode reduceAvg(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
-
reduceSum
private RexNode reduceSum(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping)
-
reduceStddev
private RexNode reduceStddev(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, boolean sqrt, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
-
getSumAggregatedRexNode
private RexNode getSumAggregatedRexNode(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, RexBuilder rexBuilder, int argOrdinal, int filterArg)
-
getSumAggregatedRexNodeWithBinding
private RexNode getSumAggregatedRexNodeWithBinding(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, RelDataType operandType, int argOrdinal, int filter)
-
getRegrCountRexNode
private RexNode getRegrCountRexNode(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, ImmutableIntList argOrdinals, com.google.common.collect.ImmutableList<RelDataType> operandTypes, int filterArg)
-
reduceRegrSzz
private RexNode reduceRegrSzz(Aggregate oldAggRel, AggregateCall oldCall, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs, int xIndex, int yIndex, int nullFilterIndex)
-
reduceCovariance
private RexNode reduceCovariance(Aggregate oldAggRel, AggregateCall oldCall, boolean biased, java.util.List<AggregateCall> newCalls, java.util.Map<AggregateCall,RexNode> aggCallMapping, java.util.List<RexNode> inputExprs)
-
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
- Listelement
- 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 inputoldAggregate
- 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 inputrowType
- The output row type of the original aggregate.exprs
- The expressions to compute the original agg calls.
-
getFieldType
private RelDataType getFieldType(RelNode relNode, int i)
-
-