This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/calcite.git
commit ceb972952739929c175dfd0895407e8e17e0b502 Author: Julian Hyde <[email protected]> AuthorDate: Fri Jan 31 16:57:31 2020 -0800 [CALCITE-3763] RelBuilder.aggregate should prune unused fields from the input, if the input is a Project --- .../java/org/apache/calcite/plan/RelOptUtil.java | 13 +- .../rel/rules/AbstractMaterializedViewRule.java | 2 +- .../java/org/apache/calcite/tools/RelBuilder.java | 72 +++++++++- .../java/org/apache/calcite/test/JdbcTest.java | 11 +- .../org/apache/calcite/test/PigRelBuilderTest.java | 34 +++-- .../org/apache/calcite/test/RelBuilderTest.java | 160 ++++++++++++++++++--- .../org/apache/calcite/test/RelOptRulesTest.xml | 116 ++++++++------- .../java/org/apache/calcite/test/PigRelOpTest.java | 4 +- .../java/org/apache/calcite/test/PigletTest.java | 4 +- 9 files changed, 309 insertions(+), 107 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java index 0183486..99469d6 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java @@ -627,7 +627,8 @@ public abstract class RelOptUtil { * Creates a plan suitable for use in <code>EXISTS</code> or <code>IN</code> * statements. * - * @see org.apache.calcite.sql2rel.SqlToRelConverter#convertExists + * @see org.apache.calcite.sql2rel.SqlToRelConverter + * SqlToRelConverter#convertExists * * @param seekRel A query rel, for example the resulting rel from 'select * * from emp' or 'values (1,2,3)' or '('Foo', 34)'. @@ -898,9 +899,15 @@ public abstract class RelOptUtil { /** Gets all fields in an aggregate. */ public static Set<Integer> getAllFields(Aggregate aggregate) { + return getAllFields2(aggregate.getGroupSet(), aggregate.getAggCallList()); + } + + /** Gets all fields in an aggregate. */ + public static Set<Integer> getAllFields2(ImmutableBitSet groupSet, + List<AggregateCall> aggCallList) { final Set<Integer> allFields = new TreeSet<>(); - allFields.addAll(aggregate.getGroupSet().asList()); - for (AggregateCall aggregateCall : aggregate.getAggCallList()) { + allFields.addAll(groupSet.asList()); + for (AggregateCall aggregateCall : aggCallList) { allFields.addAll(aggregateCall.getArgList()); if (aggregateCall.filterArg >= 0) { allFields.add(aggregateCall.filterArg); diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java index cd24090..80eb1ff 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AbstractMaterializedViewRule.java @@ -506,7 +506,7 @@ public abstract class AbstractMaterializedViewRule extends RelOptRule { // Then, we trigger the unifying method. This method will either create a // Project or an Aggregate operator on top of the view. It will also compute // the output expressions for the query. - RelBuilder builder = call.builder(); + RelBuilder builder = call.builder().transform(c -> c.withPruneInputOfAggregate(false)); RelNode viewWithFilter; if (!viewCompensationPred.isAlwaysTrue()) { RexNode newPred = diff --git a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java index e4ef056..800f6d9 100644 --- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java +++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java @@ -110,6 +110,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.Deque; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -1584,7 +1585,7 @@ public class RelBuilder { final Registrar registrar = new Registrar(fields(), peek().getRowType().getFieldNames()); final GroupKeyImpl groupKey_ = (GroupKeyImpl) groupKey; - final ImmutableBitSet groupSet = + ImmutableBitSet groupSet = ImmutableBitSet.of(registrar.registerExpressions(groupKey_.nodes)); label: if (Iterables.isEmpty(aggCalls)) { @@ -1610,7 +1611,7 @@ public class RelBuilder { return project(fields(groupSet)); } } - final ImmutableList<ImmutableBitSet> groupSets; + ImmutableList<ImmutableBitSet> groupSets; if (groupKey_.nodeLists != null) { final int sizeBefore = registrar.extraNodes.size(); final SortedSet<ImmutableBitSet> groupSetSet = @@ -1646,7 +1647,7 @@ public class RelBuilder { project(registrar.extraNodes); rename(registrar.names); final Frame frame = stack.pop(); - final RelNode r = frame.rel; + RelNode r = frame.rel; final List<AggregateCall> aggregateCalls = new ArrayList<>(); for (AggCall aggCall : aggCalls) { final AggregateCall aggregateCall; @@ -1685,6 +1686,49 @@ public class RelBuilder { assert groupSet.contains(set); } + if (config.pruneInputOfAggregate() + && r instanceof Project) { + final Set<Integer> fieldsUsed = + RelOptUtil.getAllFields2(groupSet, aggregateCalls); + // Some parts of the system can't handle rows with zero fields, so + // pretend that one field is used. + if (fieldsUsed.isEmpty()) { + r = ((Project) r).getInput(); + } else if (fieldsUsed.size() < r.getRowType().getFieldCount()) { + // Some fields are computed but not used. Prune them. + final Map<Integer, Integer> map = new HashMap<>(); + for (int source : fieldsUsed) { + map.put(source, map.size()); + } + + groupSet = groupSet.permute(map); + groupSets = + ImmutableBitSet.ORDERING.immutableSortedCopy( + ImmutableBitSet.permute(groupSets, map)); + + final Mappings.TargetMapping targetMapping = + Mappings.target(map, r.getRowType().getFieldCount(), + fieldsUsed.size()); + final List<AggregateCall> oldAggregateCalls = + new ArrayList<>(aggregateCalls); + aggregateCalls.clear(); + for (AggregateCall aggregateCall : oldAggregateCalls) { + aggregateCalls.add(aggregateCall.transform(targetMapping)); + } + + final Project project = (Project) r; + final List<RexNode> newProjects = new ArrayList<>(); + final RelDataTypeFactory.Builder builder = + cluster.getTypeFactory().builder(); + for (int i : fieldsUsed) { + newProjects.add(project.getProjects().get(i)); + builder.add(project.getRowType().getFieldList().get(i)); + } + r = project.copy(r.getTraitSet(), project.getInput(), newProjects, + builder.build()); + } + } + if (!config.dedupAggregateCalls() || Util.isDistinct(aggregateCalls)) { return aggregate_(groupSet, groupSets, r, aggregateCalls, registrar.extraNodes, frame.fields); @@ -2724,10 +2768,17 @@ public class RelBuilder { if (distinct) { b.append("DISTINCT "); } - b.append(operands) - .append(')'); + final int iMax = operands.size() - 1; + for (int i = 0; ; i++) { + b.append(operands.get(i)); + if (i == iMax) { + break; + } + b.append(", "); + } + b.append(')'); if (filter != null) { - b.append(" FILTER (WHERE" + filter + ")"); + b.append(" FILTER (WHERE ").append(filter).append(')'); } return b.toString(); } @@ -3011,6 +3062,15 @@ public class RelBuilder { /** Sets {@link #dedupAggregateCalls}. */ Config withDedupAggregateCalls(boolean dedupAggregateCalls); + /** Whether {@link RelBuilder#aggregate} should prune unused + * input columns; default true. */ + @ImmutableBeans.Property + @ImmutableBeans.BooleanDefault(true) + boolean pruneInputOfAggregate(); + + /** Sets {@link #pruneInputOfAggregate}. */ + Config withPruneInputOfAggregate(boolean pruneInputOfAggregate); + /** Whether to simplify expressions; default true. */ @ImmutableBeans.Property @ImmutableBeans.BooleanDefault(true) diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java index c00fe13..7605703 100644 --- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java +++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java @@ -3428,12 +3428,11 @@ public class JdbcTest { CalciteAssert.hr() .query("select count(*) c from \"hr\".\"emps\", \"hr\".\"depts\"") .convertContains("LogicalAggregate(group=[{}], C=[COUNT()])\n" - + " LogicalProject(DUMMY=[0])\n" - + " LogicalJoin(condition=[true], joinType=[inner])\n" - + " LogicalProject(DUMMY=[0])\n" - + " EnumerableTableScan(table=[[hr, emps]])\n" - + " LogicalProject(DUMMY=[0])\n" - + " EnumerableTableScan(table=[[hr, depts]])"); + + " LogicalJoin(condition=[true], joinType=[inner])\n" + + " LogicalProject(DUMMY=[0])\n" + + " EnumerableTableScan(table=[[hr, emps]])\n" + + " LogicalProject(DUMMY=[0])\n" + + " EnumerableTableScan(table=[[hr, depts]])"); } } diff --git a/core/src/test/java/org/apache/calcite/test/PigRelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/PigRelBuilderTest.java index 43b6bbe..784c45c 100644 --- a/core/src/test/java/org/apache/calcite/test/PigRelBuilderTest.java +++ b/core/src/test/java/org/apache/calcite/test/PigRelBuilderTest.java @@ -26,6 +26,7 @@ import org.apache.calcite.util.Util; import org.junit.jupiter.api.Test; +import java.util.function.Function; import java.util.function.UnaryOperator; import static org.hamcrest.CoreMatchers.is; @@ -108,16 +109,26 @@ public class PigRelBuilderTest { // [PARTITION BY partitioner] [PARALLEL n]; // Equivalent to Pig Latin: // r = GROUP e BY (deptno, job); - final PigRelBuilder builder = PigRelBuilder.create(config().build()); - final RelNode root = builder - .scan("EMP") - .group(null, null, -1, builder.groupKey("DEPTNO", "JOB").alias("e")) - .build(); + final Function<PigRelBuilder, RelNode> f = builder -> + builder.scan("EMP") + .group(null, null, -1, builder.groupKey("DEPTNO", "JOB").alias("e")) + .build(); final String plan = "" + + "LogicalAggregate(group=[{0, 1}], EMP=[COLLECT($2)])\n" + + " LogicalProject(JOB=[$2], DEPTNO=[$7], " + + "$f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(str(f.apply(createBuilder(b -> b))), is(plan)); + + // now without pruning + final String plan2 = "" + "LogicalAggregate(group=[{2, 7}], EMP=[COLLECT($8)])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], " + + "HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(str(root), is(plan)); + assertThat( + str(f.apply(createBuilder(b -> b.withPruneInputOfAggregate(false)))), + is(plan2)); } @Test public void testGroup2() { @@ -132,10 +143,11 @@ public class PigRelBuilderTest { builder.groupKey("DEPTNO").alias("d")) .build(); final String plan = "LogicalJoin(condition=[=($0, $2)], joinType=[inner])\n" - + " LogicalAggregate(group=[{0}], EMP=[COLLECT($8)])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" - + " LogicalTableScan(table=[[scott, EMP]])\n LogicalAggregate(group=[{0}], DEPT=[COLLECT($3)])\n" - + " LogicalProject(DEPTNO=[$0], DNAME=[$1], LOC=[$2], $f3=[ROW($0, $1, $2)])\n" + + " LogicalAggregate(group=[{0}], EMP=[COLLECT($1)])\n" + + " LogicalProject(EMPNO=[$0], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n" + + " LogicalAggregate(group=[{0}], DEPT=[COLLECT($1)])\n" + + " LogicalProject(DEPTNO=[$0], $f3=[ROW($0, $1, $2)])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; assertThat(str(root), is(plan)); } diff --git a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java index 4e546d3..75cde59 100644 --- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java @@ -81,6 +81,7 @@ import java.util.List; import java.util.Locale; import java.util.NoSuchElementException; import java.util.TreeSet; +import java.util.function.Function; import java.util.function.UnaryOperator; import static org.apache.calcite.test.Matchers.hasHints; @@ -901,8 +902,7 @@ public class RelBuilderTest { // SELECT COUNT(*) AS c, SUM(mgr + 1) AS s // FROM emp // GROUP BY ename, hiredate + mgr - final RelBuilder builder = RelBuilder.create(config().build()); - RelNode root = + final Function<RelBuilder, RelNode> f = builder -> builder.scan("EMP") .aggregate( builder.groupKey(builder.field(1), @@ -916,10 +916,20 @@ public class RelBuilderTest { builder.literal(1))).as("S")) .build(); final String expected = "" + + "LogicalAggregate(group=[{0, 1}], C=[COUNT()], S=[SUM($2)])\n" + + " LogicalProject(ENAME=[$1], $f8=[+($4, $3)], $f9=[+($3, 1)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now without pruning + final String expected2 = "" + "LogicalAggregate(group=[{1, 8}], C=[COUNT()], S=[SUM($9)])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[+($4, $3)], $f9=[+($3, 1)])\n" + + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], " + + "HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[+($4, $3)], " + + "$f9=[+($3, 1)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(root, hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); } /** Test case for @@ -1080,8 +1090,7 @@ public class RelBuilderTest { // SELECT deptno, COUNT(*) FILTER (WHERE empno > 100) AS c // FROM emp // GROUP BY ROLLUP(deptno) - final RelBuilder builder = RelBuilder.create(config().build()); - RelNode root = + final Function<RelBuilder, RelNode> f = builder -> builder.scan("EMP") .aggregate( builder.groupKey(ImmutableBitSet.of(7), @@ -1095,10 +1104,19 @@ public class RelBuilderTest { .as("C")) .build(); final String expected = "" + + "LogicalAggregate(group=[{0}], groups=[[{0}, {}]], C=[COUNT() FILTER $1])\n" + + " LogicalProject(DEPTNO=[$7], $f8=[>($0, 100)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now without pruning + final String expected2 = "" + "LogicalAggregate(group=[{7}], groups=[[{7}, {}]], C=[COUNT() FILTER $8])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[>($0, 100)])\n" + + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], " + + "HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[>($0, 100)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(root, hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); } @Test public void testAggregateFilterFails() { @@ -1128,8 +1146,7 @@ public class RelBuilderTest { // SELECT deptno, SUM(sal) FILTER (WHERE comm < 100) AS c // FROM emp // GROUP BY deptno - final RelBuilder builder = RelBuilder.create(config().build()); - RelNode root = + final Function<RelBuilder, RelNode> f = builder -> builder.scan("EMP") .aggregate( builder.groupKey(builder.field("DEPTNO")), @@ -1140,10 +1157,18 @@ public class RelBuilderTest { .as("C")) .build(); final String expected = "" + + "LogicalAggregate(group=[{1}], C=[SUM($0) FILTER $2])\n" + + " LogicalProject(SAL=[$5], DEPTNO=[$7], $f8=[IS TRUE(<($6, 100))])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now without pruning + final String expected2 = "" + "LogicalAggregate(group=[{7}], C=[SUM($5) FILTER $8])\n" + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[IS TRUE(<($6, 100))])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(root, hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); } /** Test case for @@ -1169,8 +1194,7 @@ public class RelBuilderTest { } @Test public void testAggregateProjectWithExpression() { - final RelBuilder builder = RelBuilder.create(config().build()); - RelNode root = + final Function<RelBuilder, RelNode> f = builder -> builder.scan("EMP") .project(builder.field("DEPTNO")) .aggregate( @@ -1181,10 +1205,105 @@ public class RelBuilderTest { "d3"))) .build(); final String expected = "" + + "LogicalAggregate(group=[{0}])\n" + + " LogicalProject(d3=[+($7, 3)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now without pruning + final String expected2 = "" + "LogicalAggregate(group=[{1}])\n" + " LogicalProject(DEPTNO=[$7], d3=[+($7, 3)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(root, hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); + } + + /** Tests that {@link RelBuilder#aggregate} on top of a {@link Project} prunes + * away expressions that are not used. + * + * @see RelBuilder.Config#pruneInputOfAggregate */ + @Test public void testAggregateProjectPrune() { + // SELECT deptno, SUM(sal) FILTER (WHERE b) + // FROM ( + // SELECT deptno, empno + 10, sal, job = 'CLERK' AS b + // FROM emp) + // GROUP BY deptno + // --> + // SELECT deptno, SUM(sal) FILTER (WHERE b) + // FROM ( + // SELECT deptno, sal, job = 'CLERK' AS b + // FROM emp) + // GROUP BY deptno + final Function<RelBuilder, RelNode> f = builder -> + builder.scan("EMP") + .project(builder.field("DEPTNO"), + builder.call(SqlStdOperatorTable.PLUS, + builder.field("EMPNO"), builder.literal(10)), + builder.field("SAL"), + builder.field("JOB")) + .aggregate( + builder.groupKey(builder.field("DEPTNO")), + builder.sum(builder.field("SAL")) + .filter( + builder.call(SqlStdOperatorTable.EQUALS, + builder.field("JOB"), builder.literal("CLERK")))) + .build(); + final String expected = "" + + "LogicalAggregate(group=[{0}], agg#0=[SUM($1) FILTER $2])\n" + + " LogicalProject(DEPTNO=[$7], SAL=[$5], $f4=[IS TRUE(=($2, 'CLERK'))])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), + hasTree(expected)); + + // now with pruning disabled + final String expected2 = "" + + "LogicalAggregate(group=[{0}], agg#0=[SUM($2) FILTER $4])\n" + + " LogicalProject(DEPTNO=[$7], $f1=[+($0, 10)], SAL=[$5], JOB=[$2], " + + "$f4=[IS TRUE(=($2, 'CLERK'))])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); + } + + /** Tests that (a) if the input is a project and no fields are used + * we remove the project (rather than projecting zero fields, which + * would be wrong), and (b) if the same aggregate function is used + * twice, we add a project on top. */ + @Test public void testAggregateProjectPruneEmpty() { + // SELECT COUNT(*) AS C, COUNT(*) AS C2 FROM ( + // SELECT deptno, empno + 10, sal, job = 'CLERK' AS b + // FROM emp) + // --> + // SELECT C, C AS C2 FROM ( + // SELECT COUNT(*) AS c + // FROM emp) + final Function<RelBuilder, RelNode> f = builder -> + builder.scan("EMP") + .project(builder.field("DEPTNO"), + builder.call(SqlStdOperatorTable.PLUS, + builder.field("EMPNO"), builder.literal(10)), + builder.field("SAL"), + builder.field("JOB")) + .aggregate( + builder.groupKey(), + builder.countStar("C"), + builder.countStar("C2")) + .build(); + final String expected = "" + + "LogicalProject(C=[$0], C2=[$0])\n" + + " LogicalAggregate(group=[{}], C=[COUNT()])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now with pruning disabled + final String expected2 = "" + + "LogicalProject(C=[$0], C2=[$0])\n" + + " LogicalAggregate(group=[{}], C=[COUNT()])\n" + + " LogicalProject(DEPTNO=[$7], $f1=[+($0, 10)], SAL=[$5], JOB=[$2])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); } @Test public void testAggregateGroupingKeyOutOfRangeFails() { @@ -1317,8 +1436,7 @@ public class RelBuilderTest { // but applying "select ... group by ()" to it would change the result. // In theory, we could omit the distinct if we know there is precisely one // row, but we don't currently. - final RelBuilder builder = RelBuilder.create(config().build()); - RelNode root = + final Function<RelBuilder, RelNode> f = builder -> builder.scan("EMP") .filter( builder.call(SqlStdOperatorTable.IS_NULL, @@ -1327,10 +1445,18 @@ public class RelBuilderTest { .distinct() .build(); final String expected = "LogicalAggregate(group=[{}])\n" + + " LogicalFilter(condition=[IS NULL($6)])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + + // now without pruning + // (The empty LogicalProject is dubious, but it's what we've always done) + final String expected2 = "LogicalAggregate(group=[{}])\n" + " LogicalProject\n" + " LogicalFilter(condition=[IS NULL($6)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; - assertThat(root, hasTree(expected)); + assertThat(f.apply(createBuilder(c -> c.withPruneInputOfAggregate(false))), + hasTree(expected2)); } @Test public void testUnion() { diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml index d1cefda..1661066 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -40,8 +40,8 @@ LogicalAggregate(group=[{}], SUM_SAL=[SUM($0)], COUNT_DISTINCT_CLERK=[COUNT(DIST <Resource name="planAfter"> <![CDATA[ LogicalProject(SUM_SAL=[$0], COUNT_DISTINCT_CLERK=[$1], SUM_SAL_D10=[$2], SUM_SAL_D20=[$3], COUNT_D30=[CAST($4):INTEGER], COUNT_D40=[$5], COUNT_D20=[$6]) - LogicalAggregate(group=[{}], SUM_SAL=[SUM($0)], COUNT_DISTINCT_CLERK=[COUNT(DISTINCT $7) FILTER $8], SUM_SAL_D10=[SUM($9) FILTER $10], SUM_SAL_D20=[SUM($11) FILTER $12], COUNT_D30=[COUNT() FILTER $13], COUNT_D40=[COUNT() FILTER $14], COUNT_D20=[COUNT() FILTER $15]) - LogicalProject(SAL=[$5], $f1=[CASE(=($2, 'CLERK'), $7, null:INTEGER)], $f2=[CASE(=($7, 10), $5, null:INTEGER)], $f3=[CASE(=($7, 20), $5, 0)], $f4=[CASE(=($7, 30), 1, 0)], $f5=[CASE(=($7, 40), 'x', null:CHAR(1))], $f6=[CASE(=($7, 20), 1, null:INTEGER)], DEPTNO=[$7], $f8=[=($2, 'CLERK')], SAL0=[$5], $f10=[=($7, 10)], SAL1=[$5], $f12=[=($7, 20)], $f13=[=($7, 30)], $f14=[=($7, 40)], $f15=[=($7, 20)]) + LogicalAggregate(group=[{}], SUM_SAL=[SUM($0)], COUNT_DISTINCT_CLERK=[COUNT(DISTINCT $1) FILTER $2], SUM_SAL_D10=[SUM($3) FILTER $4], SUM_SAL_D20=[SUM($5) FILTER $6], COUNT_D30=[COUNT() FILTER $7], COUNT_D40=[COUNT() FILTER $8], COUNT_D20=[COUNT() FILTER $9]) + LogicalProject(SAL=[$5], DEPTNO=[$7], $f8=[=($2, 'CLERK')], SAL0=[$5], $f10=[=($7, 10)], SAL1=[$5], $f12=[=($7, 20)], $f13=[=($7, 30)], $f14=[=($7, 40)], $f15=[=($7, 20)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -717,7 +717,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$ LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalProject(DEPTNO=[$0], $f1=[true]) LogicalAggregate(group=[{0}]) - LogicalProject(DEPTNO=[$7], i=[true]) + LogicalProject(DEPTNO=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -782,11 +782,11 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$ LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalProject(DEPTNO=[$0], $f1=[true]) LogicalAggregate(group=[{0}]) - LogicalProject(DEPTNO=[$7], i=[true]) + LogicalProject(DEPTNO=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalProject(JOB=[$0], $f1=[true]) LogicalAggregate(group=[{0}]) - LogicalProject(JOB=[$2], i=[true]) + LogicalProject(JOB=[$2]) LogicalFilter(condition=[=($5, 34)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -843,7 +843,7 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$ LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalProject(DEPTNO=[$0], $f1=[true]) LogicalAggregate(group=[{0}]) - LogicalProject(DEPTNO=[$7], i=[true]) + LogicalProject(DEPTNO=[$7]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -1167,8 +1167,8 @@ LogicalAggregate(group=[{}], EXPR$0=[SUM($0)], EXPR$1=[COUNT(DISTINCT $1) FILTER </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{}], EXPR$0=[MIN($2) FILTER $4], EXPR$1=[COUNT($0) FILTER $3]) - LogicalProject(SAL=[$0], $f2=[$1], EXPR$0=[$2], $g_0_f_1=[AND(=($3, 0), IS TRUE($1))], $g_3=[=($3, 3)]) +LogicalAggregate(group=[{}], EXPR$0=[MIN($1) FILTER $3], EXPR$1=[COUNT($0) FILTER $2]) + LogicalProject(SAL=[$0], EXPR$0=[$2], $g_0_f_1=[AND(=($3, 0), IS TRUE($1))], $g_3=[=($3, 3)]) LogicalAggregate(group=[{1, 2}], groups=[[{1, 2}, {}]], EXPR$0=[SUM($0)], $g=[GROUPING($1, $2)]) LogicalProject(COMM=[$6], SAL=[$5], $f2=[>($5, 1000)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -1179,7 +1179,7 @@ LogicalAggregate(group=[{}], EXPR$0=[MIN($2) FILTER $4], EXPR$1=[COUNT($0) FILTE <Resource name="sql"> <![CDATA[SELECT COUNT(DISTINCT c) FILTER (WHERE d), COUNT(DISTINCT d) FILTER (WHERE c) -FROM (select sal > 1000 is true as c, sal < 500 is true as d from emp)]]> +FROM (select sal > 1000 is true as c, sal < 500 is true as d, comm from emp)]]> </Resource> <Resource name="planBefore"> <![CDATA[ @@ -1214,8 +1214,8 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($1)], EXPR$2=[COUNT(DISTINCT $2) FILTE <Resource name="planAfter"> <![CDATA[ LogicalProject(DEPTNO=[$0], EXPR$1=[CAST($1):INTEGER NOT NULL], EXPR$2=[$2]) - LogicalAggregate(group=[{0}], EXPR$1=[MIN($3) FILTER $5], EXPR$2=[COUNT($1) FILTER $4]) - LogicalProject(DEPTNO=[$0], SAL=[$1], $f3=[$2], EXPR$1=[$3], $g_0_f_2=[AND(=($4, 0), IS TRUE($2))], $g_3=[=($4, 3)]) + LogicalAggregate(group=[{0}], EXPR$1=[MIN($2) FILTER $4], EXPR$2=[COUNT($1) FILTER $3]) + LogicalProject(DEPTNO=[$0], SAL=[$1], EXPR$1=[$3], $g_0_f_2=[AND(=($4, 0), IS TRUE($2))], $g_3=[=($4, 3)]) LogicalAggregate(group=[{0, 2, 3}], groups=[[{0, 2, 3}, {0}]], EXPR$1=[SUM($1)], $g=[GROUPING($0, $2, $3)]) LogicalProject(DEPTNO=[$7], COMM=[$6], SAL=[$5], $f3=[>($5, 1000)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -1489,29 +1489,27 @@ LogicalProject(EXPR$0=[1]) </TestCase> <TestCase name="testPushAboveFiltersIntoInnerJoinCondition"> <Resource name="sql"> - <![CDATA[ -select * from sales.dept d inner join sales.emp e + <![CDATA[select * from sales.dept d inner join sales.emp e on d.deptno = e.deptno and d.deptno > e.mgr -where d.deptno > e.mgr -]]> +where d.deptno > e.mgr]]> </Resource> - <Resource name="planBefore"> - <![CDATA[ + <Resource name="planBefore"> + <![CDATA[ LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10]) LogicalFilter(condition=[>($0, $5)]) LogicalJoin(condition=[AND(=($0, $9), >($0, $5))], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> - </Resource> - <Resource name="planAfter"> - <![CDATA[ + </Resource> + <Resource name="planAfter"> + <![CDATA[ LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10]) LogicalJoin(condition=[AND(=($0, $9), >($0, $5))], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> - </Resource> + </Resource> </TestCase> <TestCase name="testPushFilterThroughSemiJoin"> <Resource name="sql"> @@ -3331,8 +3329,8 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$ LogicalTableScan(table=[[CATALOG, SALES, EMP]]) LogicalAggregate(group=[{0, 1}]) LogicalProject(EXPR$0=[$2], EMPNO=[$1]) - LogicalAggregate(group=[{0, 1}], EXPR$0=[MAX($3)]) - LogicalProject(DEPTNO=[$7], EMPNO=[$0], $f1=['abc'], SAL=[$5]) + LogicalAggregate(group=[{0, 1}], EXPR$0=[MAX($2)]) + LogicalProject(DEPTNO=[$7], EMPNO=[$0], SAL=[$5]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4805,8 +4803,8 @@ LogicalProject(DEPTNO=[$0], EXPR$1=[$2]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{0}], EXPR$1=[MAX($2)]) - LogicalProject(DEPTNO=[$7], FOUR=[4], MGR=[$3]) +LogicalAggregate(group=[{0}], EXPR$1=[MAX($1)]) + LogicalProject(DEPTNO=[$7], MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4827,8 +4825,8 @@ LogicalProject(DEPTNO=[$0], EXPR$1=[$2]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{0}], EXPR$1=[MAX($2)]) - LogicalProject(DEPTNO=[$7], FOUR=[4], ENAME=[$1]) +LogicalAggregate(group=[{0}], EXPR$1=[MAX($1)]) + LogicalProject(DEPTNO=[$7], ENAME=[$1]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4850,8 +4848,8 @@ LogicalProject(DEPTNO=[$0], EXPR$1=[$4]) <Resource name="planAfter"> <![CDATA[ LogicalProject(DEPTNO=[$0], EXPR$1=[$2]) - LogicalAggregate(group=[{0, 3}], EXPR$1=[MAX($4)]) - LogicalProject(DEPTNO=[$7], FOUR=[4], TWO_PLUS_THREE=[+(2, 3)], DEPTNO42=[+($7, 42)], MGR=[$3]) + LogicalAggregate(group=[{0, 1}], EXPR$1=[MAX($2)]) + LogicalProject(DEPTNO=[$7], DEPTNO42=[+($7, 42)], MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4872,8 +4870,8 @@ LogicalProject(DEPTNO=[$1], EXPR$1=[$2]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{1}], EXPR$1=[MAX($2)]) - LogicalProject(FOUR=[4], DEPTNO=[$7], MGR=[$3]) +LogicalAggregate(group=[{0}], EXPR$1=[MAX($1)]) + LogicalProject(DEPTNO=[$7], MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4894,8 +4892,8 @@ LogicalProject(DEPTNO=[$1], EXPR$1=[$2]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{1}], EXPR$1=[MAX($2)]) - LogicalProject($f0=[+(42, 24)], DEPTNO=[$7], MGR=[$3]) +LogicalAggregate(group=[{0}], EXPR$1=[MAX($1)]) + LogicalProject(DEPTNO=[$7], MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4916,8 +4914,8 @@ LogicalAggregate(group=[{0, 1}], EXPR$2=[MAX($2)]) <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[$0], EXPR$1=[+(2, 3)], EXPR$2=[$1]) - LogicalAggregate(group=[{0}], EXPR$2=[MAX($2)]) - LogicalProject(EXPR$0=[4], EXPR$1=[+(2, 3)], MGR=[$3]) + LogicalAggregate(group=[{0}], EXPR$2=[MAX($1)]) + LogicalProject(EXPR$0=[4], MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4938,8 +4936,8 @@ LogicalAggregate(group=[{0, 1}], EXPR$2=[MAX($2)]) <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[$0], EXPR$1=[+(2, 3)], EXPR$2=[$1]) - LogicalAggregate(group=[{0}], EXPR$2=[MAX($2)]) - LogicalProject(EXPR$0=[4], EXPR$1=[+(2, 3)], FIVE=[5]) + LogicalAggregate(group=[{0}], EXPR$2=[MAX($1)]) + LogicalProject(EXPR$0=[4], FIVE=[5]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -4960,8 +4958,8 @@ LogicalAggregate(group=[{0, 1}], EXPR$2=[MAX($2)]) <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[$0], EXPR$1=[+(2, 3)], EXPR$2=[$1]) - LogicalAggregate(group=[{0}], EXPR$2=[MAX($2)]) - LogicalProject(EXPR$0=[4], EXPR$1=[+(2, 3)], $f2=[5]) + LogicalAggregate(group=[{0}], EXPR$2=[MAX($1)]) + LogicalProject(EXPR$0=[4], $f2=[5]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> </Resource> @@ -6715,7 +6713,7 @@ LogicalProject(DEPTNO=[$0], NAME=[$1]) LogicalJoin(condition=[=($0, $2)], joinType=[inner]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) LogicalAggregate(group=[{0}]) - LogicalProject(DEPTNO=[$7], $f0=[true]) + LogicalProject(DEPTNO=[$7]) LogicalFilter(condition=[>($5, 100)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -6724,7 +6722,7 @@ LogicalProject(DEPTNO=[$0], NAME=[$1]) <![CDATA[ LogicalJoin(condition=[=($0, $2)], joinType=[semi]) LogicalTableScan(table=[[CATALOG, SALES, DEPT]]) - LogicalProject(DEPTNO=[$7], $f0=[true]) + LogicalProject(DEPTNO=[$7]) LogicalFilter(condition=[>($5, 100)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -7837,8 +7835,8 @@ LogicalAggregate(group=[{}], EXPR$0=[SUM($9)]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{}], EXPR$0=[SUM($3)]) - LogicalProject(SAL=[$0], $f1=[$1], SAL0=[$2], $f3=[CAST(*($1, $2)):INTEGER]) +LogicalAggregate(group=[{}], EXPR$0=[SUM($0)]) + LogicalProject($f3=[CAST(*($1, $2)):INTEGER]) LogicalJoin(condition=[=($0, $2)], joinType=[inner]) LogicalAggregate(group=[{5}], agg#0=[COUNT()]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -7870,8 +7868,8 @@ LogicalProject(JOB=[$0], MGR0=[$2], DEPTNO=[$1], HIREDATE1=[$3], COMM1=[$4]) <Resource name="planAfter"> <![CDATA[ LogicalProject(JOB=[$0], MGR0=[$2], DEPTNO=[$1], HIREDATE1=[$3], COMM1=[$4]) - LogicalAggregate(group=[{0, 2, 4}], HIREDATE1=[MAX($6)], COMM1=[SUM($8)]) - LogicalProject(JOB=[$0], SAL=[$1], DEPTNO=[$2], $f3=[$3], MGR=[$4], SAL0=[$5], HIREDATE1=[$6], COMM1=[$7], $f8=[CAST(*($3, $7)):INTEGER NOT NULL]) + LogicalAggregate(group=[{0, 1, 2}], HIREDATE1=[MAX($3)], COMM1=[SUM($4)]) + LogicalProject(JOB=[$0], DEPTNO=[$2], MGR=[$4], HIREDATE1=[$6], $f8=[CAST(*($3, $7)):INTEGER NOT NULL]) LogicalJoin(condition=[=($1, $5)], joinType=[inner]) LogicalAggregate(group=[{2, 5, 7}], agg#0=[COUNT()]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -7930,8 +7928,8 @@ LogicalAggregate(group=[{}], EXPR$0=[SUM($5)]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{}], EXPR$0=[SUM($4)]) - LogicalProject(JOB=[$0], EXPR$0=[$1], NAME=[$2], $f1=[$3], $f4=[CAST(*($1, $3)):INTEGER]) +LogicalAggregate(group=[{}], EXPR$0=[SUM($0)]) + LogicalProject($f4=[CAST(*($1, $3)):INTEGER]) LogicalJoin(condition=[=($0, $2)], joinType=[inner]) LogicalAggregate(group=[{2}], EXPR$0=[SUM($5)]) LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8]) @@ -7961,8 +7959,8 @@ LogicalAggregate(group=[{}], EXPR$0=[SUM($5)]) <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[CASE(=($1, 0), null:INTEGER, $0)]) - LogicalAggregate(group=[{}], EXPR$0=[$SUM0($5)], agg#1=[$SUM0($6)]) - LogicalProject(JOB=[$0], EXPR$0=[$1], $f2=[$2], NAME=[$3], $f1=[$4], $f5=[CAST(*($1, $4)):INTEGER NOT NULL], $f6=[*($2, $4)]) + LogicalAggregate(group=[{}], EXPR$0=[$SUM0($0)], agg#1=[$SUM0($1)]) + LogicalProject($f5=[CAST(*($1, $4)):INTEGER NOT NULL], $f6=[*($2, $4)]) LogicalJoin(condition=[=($0, $3)], joinType=[inner]) LogicalAggregate(group=[{2}], EXPR$0=[$SUM0($5)], agg#1=[COUNT()]) LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8]) @@ -8579,8 +8577,8 @@ LogicalAggregate(group=[{}], EXPR$0=[COUNT()]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{}], EXPR$0=[$SUM0($4)]) - LogicalProject(JOB=[$0], EXPR$0=[$1], NAME=[$2], EXPR$00=[$3], $f4=[*($1, $3)]) +LogicalAggregate(group=[{}], EXPR$0=[$SUM0($0)]) + LogicalProject($f4=[*($1, $3)]) LogicalJoin(condition=[=($0, $2)], joinType=[inner]) LogicalAggregate(group=[{2}], EXPR$0=[COUNT()]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) @@ -8605,8 +8603,8 @@ LogicalAggregate(group=[{}], VOLUME=[COUNT()], C1_SUM_SAL=[SUM($0)]) </Resource> <Resource name="planAfter"> <![CDATA[ -LogicalAggregate(group=[{}], VOLUME=[$SUM0($3)], C1_SUM_SAL=[SUM($4)]) - LogicalProject(ENAME=[$0], SAL=[$1], ENAME0=[$2], VOLUME=[$3], $f4=[CAST(*($1, $3)):INTEGER]) +LogicalAggregate(group=[{}], VOLUME=[$SUM0($0)], C1_SUM_SAL=[SUM($1)]) + LogicalProject(VOLUME=[$3], $f4=[CAST(*($1, $3)):INTEGER]) LogicalJoin(condition=[=($0, $2)], joinType=[inner]) LogicalProject(ENAME=[$1], SAL=[$0]) LogicalProject(SAL=[$5], ENAME=[$1]) @@ -10887,8 +10885,8 @@ LogicalProject(C=[$2]) <![CDATA[ LogicalProject(C=[$2]) LogicalProject(DEPTNO=[10], SAL=[$0], C=[$1]) - LogicalAggregate(group=[{1}], C=[COUNT()]) - LogicalProject(DEPTNO=[$7], SAL=[$5]) + LogicalAggregate(group=[{0}], C=[COUNT()]) + LogicalProject(SAL=[$5]) LogicalFilter(condition=[=($7, 10)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -10944,7 +10942,7 @@ LogicalProject(JOB=[$1]) LogicalFilter(condition=[>($2, 3)]) LogicalProject(SAL=[$0], JOB=['Clerk':VARCHAR(10)], $f2=[$1]) LogicalAggregate(group=[{0}], agg#0=[COUNT()]) - LogicalProject(SAL=[$5], JOB=[$2]) + LogicalProject(SAL=[$5]) LogicalFilter(condition=[AND(IS NULL($5), =($2, 'Clerk'))]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -10974,7 +10972,7 @@ LogicalProject(HIREDATE=[$1]) LogicalFilter(condition=[>($2, 3)]) LogicalProject(SAL=[$0], HIREDATE=[CURRENT_TIMESTAMP], $f2=[$1]) LogicalAggregate(group=[{0}], agg#0=[COUNT()]) - LogicalProject(SAL=[$5], HIREDATE=[$4]) + LogicalProject(SAL=[$5]) LogicalFilter(condition=[AND(IS NULL($5), =($4, CURRENT_TIMESTAMP))]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> @@ -11333,8 +11331,8 @@ LogicalAggregate(group=[{0, 1, 2}], S=[SUM($2)]) <Resource name="planAfter"> <![CDATA[ LogicalProject(JOB=[$0], EMPNO=[10], SAL=[$1], S=[$2]) - LogicalAggregate(group=[{0, 2}], S=[SUM($2)]) - LogicalProject(JOB=[$2], EMPNO=[$0], SAL=[$5]) + LogicalAggregate(group=[{0, 1}], S=[SUM($1)]) + LogicalProject(JOB=[$2], SAL=[$5]) LogicalFilter(condition=[=($0, 10)]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) ]]> diff --git a/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java b/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java index c29ff62..25ea76d 100644 --- a/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java +++ b/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java @@ -1050,8 +1050,8 @@ public class PigRelOpTest extends PigRelTestBase { + " LogicalTableScan(table=[[scott, DEPT]])\n"; final String optimizedPlan = "" + "LogicalProject($f0=[$1])\n" - + " LogicalAggregate(group=[{0}], agg#0=[COLLECT($2)])\n" - + " LogicalProject(DEPTNO=[$0], DNAME=[$1], $f2=[ROW($0, $1)])\n" + + " LogicalAggregate(group=[{0}], agg#0=[COLLECT($1)])\n" + + " LogicalProject(DEPTNO=[$0], $f2=[ROW($0, $1)])\n" + " LogicalTableScan(table=[[scott, DEPT]])\n"; final String result = "" + "({(20,RESEARCH)})\n" diff --git a/piglet/src/test/java/org/apache/calcite/test/PigletTest.java b/piglet/src/test/java/org/apache/calcite/test/PigletTest.java index 19f53fb..83efe3b 100644 --- a/piglet/src/test/java/org/apache/calcite/test/PigletTest.java +++ b/piglet/src/test/java/org/apache/calcite/test/PigletTest.java @@ -135,8 +135,8 @@ public class PigletTest { final String s = "A = LOAD 'EMP';\n" + "B = GROUP A BY DEPTNO;"; final String expected = "" - + "LogicalAggregate(group=[{7}], A=[COLLECT($8)])\n" - + " LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + + "LogicalAggregate(group=[{0}], A=[COLLECT($1)])\n" + + " LogicalProject(DEPTNO=[$7], $f8=[ROW($0, $1, $2, $3, $4, $5, $6, $7)])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; pig(s).explainContains(expected); }
