You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2020/02/13 02:12:11 UTC
[calcite] 02/03: [CALCITE-3763] RelBuilder.aggregate should prune
unused fields from the input, if the input is a Project
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 <jh...@apache.org>
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);
}