[GitHub] julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable
julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable URL: https://github.com/apache/calcite/pull/1078#discussion_r261428663 ## File path: core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java ## @@ -58,37 +68,63 @@ public AggregateRemoveRule(Class aggregateClass, // distinct to make it correct up-front, we can get rid of the reference // to the child here. super( -operand(aggregateClass, +operandJ(aggregateClass, null, agg -> isAggregateSupported(agg), operand(RelNode.class, any())), relBuilderFactory, null); } + private static boolean isAggregateSupported(Aggregate aggregate) { +if (aggregate.indicator || +aggregate.getGroupType() != Aggregate.Group.SIMPLE) { + return false; +} +// If any aggregate functions do not support splitting, bail out +for (AggregateCall aggregateCall : aggregate.getAggCallList()) { + if (aggregateCall.filterArg >= 0 || + aggregateCall.getAggregation() + .unwrap(SqlSplittableAggFunction.class) == null) { +return false; + } +} +return true; + } + //~ Methods public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelNode input = call.rel(1); -if (!aggregate.getAggCallList().isEmpty() || aggregate.indicator) { - return; -} final RelMetadataQuery mq = call.getMetadataQuery(); if (!SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet( { return; } -// 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. 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 RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder(); +final List projects = new LinkedList<>(); +for (AggregateCall aggCall : aggregate.getAggCallList()) { + final SqlAggFunction aggregation = aggCall.getAggregation(); + final SqlSplittableAggFunction splitter = + Objects.requireNonNull( + aggregation.unwrap(SqlSplittableAggFunction.class)); + final RexNode singleton = splitter.singleton( + rexBuilder, input.getRowType(), aggCall); + projects.add(singleton); +} + +final RelNode newInput = convert(input, aggregate.getTraitSet().simplify()); final RelBuilder relBuilder = call.builder(); relBuilder.push(newInput); -if (newInput.getRowType().getFieldCount() +if (!projects.isEmpty()) { + projects.addAll(0, relBuilder.fields(aggregate.getGroupSet().asList())); + relBuilder.project(projects); +} else if (newInput.getRowType().getFieldCount() > aggregate.getRowType().getFieldCount()) { + // If aggregate was projecting a subset of columns, and there were no + // aggregate functions, add a project for the same effect. relBuilder.project(relBuilder.fields(aggregate.getGroupSet().asList())); } -call.transformTo(relBuilder.build()); +final RelNode newRel = relBuilder.build(); +call.transformTo(newRel); Review comment: the variable doesn't seem necessary This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services
[GitHub] julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable
julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable URL: https://github.com/apache/calcite/pull/1078#discussion_r261429146 ## File path: core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java ## @@ -58,37 +68,63 @@ public AggregateRemoveRule(Class aggregateClass, // distinct to make it correct up-front, we can get rid of the reference // to the child here. super( -operand(aggregateClass, +operandJ(aggregateClass, null, agg -> isAggregateSupported(agg), operand(RelNode.class, any())), relBuilderFactory, null); } + private static boolean isAggregateSupported(Aggregate aggregate) { +if (aggregate.indicator +|| aggregate.getGroupType() != Aggregate.Group.SIMPLE) { + return false; +} +// If any aggregate functions do not support splitting, bail out +for (AggregateCall aggregateCall : aggregate.getAggCallList()) { + if (aggregateCall.filterArg >= 0 + || aggregateCall.getAggregation() + .unwrap(SqlSplittableAggFunction.class) == null) { +return false; + } +} +return true; + } + //~ Methods public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelNode input = call.rel(1); -if (!aggregate.getAggCallList().isEmpty() || aggregate.indicator) { - return; -} final RelMetadataQuery mq = call.getMetadataQuery(); if (!SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet( { return; } -// 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. 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 RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder(); Review comment: an easier way to get rexBuilder is from relBuilder; just initialize relBuilder a few lines earlier This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services
[GitHub] julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable
julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable URL: https://github.com/apache/calcite/pull/1078#discussion_r261430620 ## File path: core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java ## @@ -3619,6 +3620,69 @@ private void transitiveInference(RelOptRule... extraRules) throws Exception { checkPlanUnchanged(new HepPlanner(program), sql); } + @Test public void testAggregateRemove1() { Review comment: Describe what the test is trying to achieve, and why. This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services
[GitHub] julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable
julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable URL: https://github.com/apache/calcite/pull/1078#discussion_r261429313 ## File path: core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java ## @@ -58,37 +68,63 @@ public AggregateRemoveRule(Class aggregateClass, // distinct to make it correct up-front, we can get rid of the reference // to the child here. super( -operand(aggregateClass, +operandJ(aggregateClass, null, agg -> isAggregateSupported(agg), operand(RelNode.class, any())), relBuilderFactory, null); } + private static boolean isAggregateSupported(Aggregate aggregate) { +if (aggregate.indicator +|| aggregate.getGroupType() != Aggregate.Group.SIMPLE) { + return false; +} +// If any aggregate functions do not support splitting, bail out +for (AggregateCall aggregateCall : aggregate.getAggCallList()) { + if (aggregateCall.filterArg >= 0 + || aggregateCall.getAggregation() + .unwrap(SqlSplittableAggFunction.class) == null) { +return false; + } +} +return true; + } + //~ Methods public void onMatch(RelOptRuleCall call) { final Aggregate aggregate = call.rel(0); final RelNode input = call.rel(1); -if (!aggregate.getAggCallList().isEmpty() || aggregate.indicator) { - return; -} final RelMetadataQuery mq = call.getMetadataQuery(); if (!SqlFunctions.isTrue(mq.areColumnsUnique(input, aggregate.getGroupSet( { return; } -// 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. 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 RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder(); +final List projects = new LinkedList<>(); +for (AggregateCall aggCall : aggregate.getAggCallList()) { Review comment: it's unusual to use LinkedList; since you're only appending, ArrayList would be the least surprising choice This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services
[GitHub] julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable
julianhyde commented on a change in pull request #1078: [CALCITE-896] Remove Aggregate if grouping columns are unique and all functions are splittable URL: https://github.com/apache/calcite/pull/1078#discussion_r261430446 ## File path: core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java ## @@ -173,11 +173,11 @@ public RexNode singleton(RexBuilder rexBuilder, RelDataType inputRowType, final RexNode predicate = RexUtil.composeConjunction(rexBuilder, predicates, true); if (predicate == null) { -return rexBuilder.makeExactLiteral(BigDecimal.ONE); +return rexBuilder.makeBigintLiteral(BigDecimal.ONE); Review comment: Let's not assume that COUNT is BIGINT. (In some type systems it might be INT.) Use AggregateCall.type? This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services