Java源码示例:org.apache.calcite.rel.core.Aggregate
示例1
private static boolean isAggregateSupported(Aggregate aggregate, boolean allowFunctions) {
if (!allowFunctions && !aggregate.getAggCallList().isEmpty()) {
return false;
}
if (aggregate.getGroupType() != Aggregate.Group.SIMPLE) {
return false;
}
// If any aggregate functions do not support splitting, bail out
// If any aggregate call has a filter or is distinct, bail out
for (AggregateCall aggregateCall : aggregate.getAggCallList()) {
if (aggregateCall.getAggregation().unwrap(SqlSplittableAggFunction.class)
== null) {
return false;
}
if (aggregateCall.filterArg >= 0 || aggregateCall.isDistinct()) {
return false;
}
}
return true;
}
示例2
public MaterializedViewOnlyAggregateRule(RelOptRuleOperand operand,
RelBuilderFactory relBuilderFactory, String description,
boolean generateUnionRewriting, HepProgram unionRewritingPullProgram,
RelOptRule filterProjectTransposeRule,
RelOptRule filterAggregateTransposeRule,
RelOptRule aggregateProjectPullUpConstantsRule,
RelOptRule projectMergeRule) {
super(
operand(Aggregate.class, any()),
relBuilderFactory,
"MaterializedViewAggregateRule(Aggregate)",
generateUnionRewriting, unionRewritingPullProgram,
filterProjectTransposeRule,
filterAggregateTransposeRule,
aggregateProjectPullUpConstantsRule,
projectMergeRule);
}
示例3
private List<RelBuilder.AggCall> getNewAggCallList(
Aggregate oldAggregate,
RelBuilder relBuilder,
Mapping mapping) {
final List<RelBuilder.AggCall> newAggCallList = new ArrayList<>();
for (AggregateCall aggCall : oldAggregate.getAggCallList()) {
final RexNode filterArg = aggCall.filterArg < 0 ? null
: relBuilder.field(Mappings.apply(mapping, aggCall.filterArg));
newAggCallList.add(
relBuilder
.aggregateCall(
aggCall.getAggregation(),
relBuilder.fields(Mappings.apply2(mapping, aggCall.getArgList())))
.distinct(aggCall.isDistinct())
.filter(filterArg)
.approximate(aggCall.isApproximate())
.sort(relBuilder.fields(aggCall.collation))
.as(aggCall.name));
}
return newAggCallList;
}
示例4
public void onMatch(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
final RelNode input = call.rel(1);
// Distinct is "GROUP BY c1, c2" (where c1, c2 are a set of columns on
// which the input is unique, i.e. contain a key) and has no aggregate
// functions or the functions we enumerated. It can be removed.
final RelNode newInput = convert(input, aggregate.getTraitSet().simplify());
// If aggregate was projecting a subset of columns, add a project for the
// same effect.
final RelBuilder relBuilder = call.builder();
relBuilder.push(newInput);
List<Integer> projectIndices = new ArrayList<>(aggregate.getGroupSet().asList());
for (AggregateCall aggCall : aggregate.getAggCallList()) {
projectIndices.addAll(aggCall.getArgList());
}
relBuilder.project(relBuilder.fields(projectIndices));
// Create a project if some of the columns have become
// NOT NULL due to aggregate functions are removed
relBuilder.convert(aggregate.getRowType(), true);
call.transformTo(relBuilder.build());
}
示例5
private RexNode getSumAggregatedRexNodeWithBinding(Aggregate oldAggRel,
AggregateCall oldCall,
List<AggregateCall> newCalls,
Map<AggregateCall, RexNode> aggCallMapping,
RelDataType operandType,
int argOrdinal,
int filter) {
RelOptCluster cluster = oldAggRel.getCluster();
final AggregateCall sumArgSquaredAggCall =
createAggregateCallWithBinding(cluster.getTypeFactory(),
SqlStdOperatorTable.SUM, operandType, oldAggRel, oldCall, argOrdinal, filter);
return cluster.getRexBuilder().addAggCall(sumArgSquaredAggCall,
oldAggRel.getGroupCount(),
newCalls,
aggCallMapping,
ImmutableList.of(sumArgSquaredAggCall.getType()));
}
示例6
private AggregateCall createAggregateCallWithBinding(
RelDataTypeFactory typeFactory,
SqlAggFunction aggFunction,
RelDataType operandType,
Aggregate oldAggRel,
AggregateCall oldCall,
int argOrdinal,
int filter) {
final Aggregate.AggCallBinding binding =
new Aggregate.AggCallBinding(typeFactory, aggFunction,
ImmutableList.of(operandType), oldAggRel.getGroupCount(),
filter >= 0);
return AggregateCall.create(aggFunction,
oldCall.isDistinct(),
oldCall.isApproximate(),
ImmutableIntList.of(argOrdinal),
filter,
oldCall.collation,
aggFunction.inferReturnType(binding),
null);
}
示例7
public Double getSelectivity(Aggregate rel, RelMetadataQuery mq,
RexNode predicate) {
final List<RexNode> notPushable = new ArrayList<>();
final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
rel.getGroupSet(),
predicate,
pushable,
notPushable);
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
RexNode childPred =
RexUtil.composeConjunction(rexBuilder, pushable, true);
Double selectivity = mq.getSelectivity(rel.getInput(), childPred);
if (selectivity == null) {
return null;
} else {
RexNode pred =
RexUtil.composeConjunction(rexBuilder, notPushable, true);
return selectivity * RelMdUtil.guessSelectivity(pred);
}
}
示例8
/**
* Creates a AggregateUnionAggregateRule.
*/
public AggregateUnionAggregateRule(Class<? extends Aggregate> aggregateClass,
Class<? extends Union> unionClass,
Class<? extends RelNode> firstUnionInputClass,
Class<? extends RelNode> secondUnionInputClass,
RelBuilderFactory relBuilderFactory,
String desc) {
super(
operandJ(aggregateClass, null, Aggregate::isSimple,
operand(unionClass,
operand(firstUnionInputClass, any()),
operand(secondUnionInputClass, any()))),
relBuilderFactory, desc);
}
示例9
@Override public void onMatch(RelOptRuleCall call) {
final Delta delta = call.rel(0);
Util.discard(delta);
final Aggregate aggregate = call.rel(1);
final LogicalDelta newDelta =
LogicalDelta.create(aggregate.getInput());
final LogicalAggregate newAggregate =
LogicalAggregate.create(newDelta, aggregate.getGroupSet(),
aggregate.groupSets, aggregate.getAggCallList());
call.transformTo(newAggregate);
}
示例10
private String getGroupByIndices(Aggregate n) {
StringBuilder res = new StringBuilder();
int count = 0;
for (int i : n.getGroupSet()) {
if (++count > 1) {
res.append(", ");
}
res.append(i);
}
return res.toString();
}
示例11
@Override
public Aggregate copy(RelTraitSet traitSet, RelNode input, boolean indicator, ImmutableBitSet groupSet,
List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) {
try {
return new OLAPAggregateRel(getCluster(), traitSet, input, indicator, groupSet, groupSets, aggCalls);
} catch (InvalidRelException e) {
throw new IllegalStateException("Can't create OLAPAggregateRel!", e);
}
}
示例12
public Double getDistinctRowCount(Aggregate rel, RelMetadataQuery mq,
ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
}
}
// determine which predicates can be applied on the child of the
// aggregate
final List<RexNode> notPushable = new ArrayList<>();
final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(
rel.getGroupSet(),
predicate,
pushable,
notPushable);
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
RexNode childPreds =
RexUtil.composeConjunction(rexBuilder, pushable, true);
// set the bits as they correspond to the child input
ImmutableBitSet.Builder childKey = ImmutableBitSet.builder();
RelMdUtil.setAggChildKeys(groupKey, rel, childKey);
Double distinctRowCount =
mq.getDistinctRowCount(rel.getInput(), childKey.build(), childPreds);
if (distinctRowCount == null) {
return null;
} else if (notPushable.isEmpty()) {
return distinctRowCount;
} else {
RexNode preds =
RexUtil.composeConjunction(rexBuilder, notPushable, true);
return distinctRowCount * RelMdUtil.guessSelectivity(preds);
}
}
示例13
/**
* Creates an AggregateRemoveRule.
*/
public AggregateRemoveRule(Class<? extends Aggregate> aggregateClass,
RelBuilderFactory relBuilderFactory) {
super(
operandJ(aggregateClass, null, agg -> isAggregateSupported(agg),
any()), relBuilderFactory, null);
}
示例14
@Deprecated // to be removed before 2.0
public AggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
RelFactories.AggregateFactory aggregateFactory,
Class<? extends Join> joinClass,
RelFactories.JoinFactory joinFactory,
RelFactories.ProjectFactory projectFactory) {
this(aggregateClass, joinClass,
RelBuilder.proto(aggregateFactory, joinFactory, projectFactory), false);
}
示例15
public Double getMinRowCount(Aggregate rel, RelMetadataQuery mq) {
if (rel.getGroupSet().isEmpty()) {
// Aggregate with no GROUP BY always returns 1 row (even on empty table).
return 1D;
}
final Double rowCount = mq.getMinRowCount(rel.getInput());
if (rowCount != null && rowCount >= 1D) {
return (double) rel.getGroupSets().size();
}
return 0D;
}
示例16
public boolean hasTrickyRollup(Sort e, Aggregate aggregate) {
return !dialect.supportsAggregateFunction(SqlKind.ROLLUP)
&& dialect.supportsGroupByWithRollup()
&& (aggregate.getGroupType() == Aggregate.Group.ROLLUP
|| aggregate.getGroupType() == Aggregate.Group.CUBE
&& aggregate.getGroupSet().cardinality() == 1)
&& e.collation.getFieldCollations().stream().allMatch(fc ->
fc.getFieldIndex() < aggregate.getGroupSet().cardinality());
}
示例17
@Override public void onMatch(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
final Values values = call.rel(1);
Util.discard(values);
final RelBuilder relBuilder = call.builder();
final RexBuilder rexBuilder = relBuilder.getRexBuilder();
final List<RexLiteral> literals = new ArrayList<>();
for (final AggregateCall aggregateCall : aggregate.getAggCallList()) {
switch (aggregateCall.getAggregation().getKind()) {
case COUNT:
case SUM0:
literals.add(
(RexLiteral) rexBuilder.makeLiteral(
BigDecimal.ZERO, aggregateCall.getType(), false));
break;
case MIN:
case MAX:
case SUM:
literals.add(rexBuilder.makeNullLiteral(aggregateCall.getType()));
break;
default:
// Unknown what this aggregate call should do on empty Values. Bail out to be safe.
return;
}
}
call.transformTo(
relBuilder.values(ImmutableList.of(literals), aggregate.getRowType())
.build());
// New plan is absolutely better than old plan.
call.getPlanner().prune(aggregate);
}
示例18
@Deprecated // to be removed before 2.0
public FlinkAggregateJoinTransposeRule(Class<? extends Aggregate> aggregateClass,
RelFactories.AggregateFactory aggregateFactory,
Class<? extends Join> joinClass,
RelFactories.JoinFactory joinFactory) {
this(aggregateClass, joinClass,
RelBuilder.proto(aggregateFactory, joinFactory), false);
}
示例19
/**
* Converts an aggregate relational expression that contains just one
* distinct aggregate function (or perhaps several over the same arguments)
* and no non-distinct aggregate functions.
*/
private RelBuilder convertMonopole(RelBuilder relBuilder, Aggregate aggregate,
List<Integer> argList, int filterArg) {
// For example,
// SELECT deptno, COUNT(DISTINCT sal), SUM(DISTINCT sal)
// FROM emp
// GROUP BY deptno
//
// becomes
//
// SELECT deptno, COUNT(distinct_sal), SUM(distinct_sal)
// FROM (
// SELECT DISTINCT deptno, sal AS distinct_sal
// FROM EMP GROUP BY deptno)
// GROUP BY deptno
// Project the columns of the GROUP BY plus the arguments
// to the agg function.
final Map<Integer, Integer> sourceOf = new HashMap<>();
createSelectDistinct(relBuilder, aggregate, argList, filterArg, sourceOf);
// Create an aggregate on top, with the new aggregate list.
final List<AggregateCall> newAggCalls =
com.google.common.collect.Lists.newArrayList(aggregate.getAggCallList());
rewriteAggCalls(newAggCalls, argList, sourceOf);
final int cardinality = aggregate.getGroupSet().cardinality();
relBuilder.push(
aggregate.copy(aggregate.getTraitSet(), relBuilder.build(),
aggregate.indicator, ImmutableBitSet.range(cardinality), null,
newAggCalls));
return relBuilder;
}
示例20
public Result visitChild(int i, RelNode e) {
if (e instanceof Union) {
return visitUnion((Union) e);
} else if (e instanceof Join) {
return visitJoin((Join) e);
} else if (e instanceof Filter) {
return visitFilter((Filter) e);
} else if (e instanceof Project) {
return visitProject((Project) e);
} else if (e instanceof Aggregate) {
return visitAggregate((Aggregate) e);
} else if (e instanceof TableScan) {
return visitTableScan((TableScan) e);
} else if (e instanceof Intersect) {
return visitIntersect((Intersect) e);
} else if (e instanceof Minus) {
return visitMinus((Minus) e);
} else if (e instanceof Calc) {
return visitCalc((Calc) e);
} else if (e instanceof Sort) {
return visitSort((Sort) e);
} else if (e instanceof TableModify) {
return visitTableModify((TableModify) e);
} else if (e instanceof Limit) {
return visitLimit((Limit) e);
} else {
throw new AssertionError("Need to Implement for " + e.getClass().getName()); // TODO:
}
}
示例21
/** Creates a MaterializedViewAggregateRule. */
protected MaterializedViewAggregateRule(RelOptRuleOperand operand, RelBuilderFactory relBuilderFactory,
String description, boolean generateUnionRewriting, HepProgram unionRewritingPullProgram) {
super(operand, relBuilderFactory, description, generateUnionRewriting, unionRewritingPullProgram, false);
this.filterProjectTransposeRule = new FilterProjectTransposeRule(Filter.class, Project.class, true, true,
relBuilderFactory);
this.filterAggregateTransposeRule = new FilterAggregateTransposeRule(Filter.class, relBuilderFactory,
Aggregate.class);
this.aggregateProjectPullUpConstantsRule = new AggregateProjectPullUpConstantsRule(Aggregate.class,
Filter.class, relBuilderFactory, "AggFilterPullUpConstants");
this.projectMergeRule = new ProjectMergeRule(true, relBuilderFactory);
}
示例22
@Override public void onMatch(RelOptRuleCall call) {
final Project project = call.rel(0);
final Join join = call.rel(1);
final RelNode left = call.rel(2);
final Aggregate aggregate = call.rel(3);
perform(call, project, join, left, aggregate);
}
示例23
protected SemiJoinRule(Class<Join> joinClass, Class<Aggregate> aggregateClass,
RelBuilderFactory relBuilderFactory, String description) {
super(
operandJ(joinClass, null, NOT_GENERATE_NULLS_ON_LEFT,
some(operand(RelNode.class, any()),
operand(aggregateClass, any()))),
relBuilderFactory, description);
}
示例24
@Override public Aggregate copy(RelTraitSet traitSet, RelNode input,
ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets,
List<AggregateCall> aggCalls) {
try {
return new MongoAggregate(getCluster(), traitSet, input,
groupSet, groupSets, aggCalls);
} catch (InvalidRelException e) {
// Semantic error not possible. Must be a bug. Convert to
// internal error.
throw new AssertionError(e);
}
}
示例25
RemoveCorrelationForScalarAggregateRule(RelBuilderFactory relBuilderFactory) {
super(
operand(LogicalCorrelate.class,
operand(RelNode.class, any()),
operand(LogicalProject.class,
operandJ(LogicalAggregate.class, null, Aggregate::isSimple,
operand(LogicalProject.class,
operand(RelNode.class, any()))))),
relBuilderFactory, null);
}
示例26
/**
* If the node is an Aggregate, it returns a list of references to the grouping columns.
* Otherwise, it returns a list of references to all columns in the node.
* The returned list is immutable.
*/
private static List<RexNode> extractReferences(RexBuilder rexBuilder, RelNode node) {
ImmutableList.Builder<RexNode> exprs = ImmutableList.builder();
if (node instanceof Aggregate) {
Aggregate aggregate = (Aggregate) node;
for (int i = 0; i < aggregate.getGroupCount(); i++) {
exprs.add(rexBuilder.makeInputRef(aggregate, i));
}
} else {
for (int i = 0; i < node.getRowType().getFieldCount(); i++) {
exprs.add(rexBuilder.makeInputRef(node, i));
}
}
return exprs.build();
}
示例27
/**
* Creates a FilterAggregateTransposeRule.
*
* <p>If {@code filterFactory} is null, creates the same kind of filter as
* matched in the rule. Similarly {@code aggregateFactory}.</p>
*/
public FilterAggregateTransposeRule(
Class<? extends Filter> filterClass,
RelBuilderFactory builderFactory,
Class<? extends Aggregate> aggregateClass) {
this(
operand(filterClass,
operand(aggregateClass, any())),
builderFactory);
}
示例28
/** Creates an AggregateUnionTransposeRule. */
public AggregateUnionTransposeRule(Class<? extends Aggregate> aggregateClass,
Class<? extends Union> unionClass, RelBuilderFactory relBuilderFactory) {
super(
operand(aggregateClass,
operand(unionClass, any())),
relBuilderFactory, null);
}
示例29
public Double getRowCount(Aggregate rel, RelMetadataQuery mq) {
if (ProjectableSqlAggFunctions.isProjectableAggregate(rel)) {
return mq.getRowCount(rel.getInput());
}
// try the next handler
return null;
}
示例30
private RelNode getNewAggregate(Aggregate oldAggregate, RelBuilder relBuilder, Mapping mapping) {
final ImmutableBitSet newGroupSet =
Mappings.apply(mapping, oldAggregate.getGroupSet());
final Iterable<ImmutableBitSet> newGroupSets =
oldAggregate.getGroupSets().stream()
.map(bitSet -> Mappings.apply(mapping, bitSet))
.collect(Collectors.toList());
final List<RelBuilder.AggCall> newAggCallList =
getNewAggCallList(oldAggregate, relBuilder, mapping);
final RelBuilder.GroupKey groupKey =
relBuilder.groupKey(newGroupSet, newGroupSets);
if (oldAggregate instanceof LogicalWindowAggregate) {
if (newGroupSet.size() == 0 && newAggCallList.size() == 0) {
// Return the old LogicalWindowAggregate directly, as we can't get an empty Aggregate
// from the relBuilder.
return oldAggregate;
} else {
relBuilder.aggregate(groupKey, newAggCallList);
Aggregate newAggregate = (Aggregate) relBuilder.build();
LogicalWindowAggregate oldLogicalWindowAggregate = (LogicalWindowAggregate) oldAggregate;
return LogicalWindowAggregate.create(
oldLogicalWindowAggregate.getWindow(),
oldLogicalWindowAggregate.getNamedProperties(),
newAggregate);
}
} else {
relBuilder.aggregate(groupKey, newAggCallList);
return relBuilder.build();
}
}