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 b632152f5c159334c76245b8816c721edca84fd5 Author: Julian Hyde <jh...@apache.org> AuthorDate: Mon Mar 2 16:29:48 2020 -0800 [CALCITE-3839] After calling RelBuilder.aggregate, cannot lookup field by name --- .../java/org/apache/calcite/tools/RelBuilder.java | 12 +++++++++--- .../org/apache/calcite/test/RelBuilderTest.java | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) 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 2f4e3a5..b4283d4 100644 --- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java +++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java @@ -1715,6 +1715,7 @@ public class RelBuilder { assert groupSet.contains(set); } + List<Field> inFields = frame.fields; if (config.pruneInputOfAggregate() && r instanceof Project) { final Set<Integer> fieldsUsed = @@ -1744,6 +1745,7 @@ public class RelBuilder { for (AggregateCall aggregateCall : oldAggregateCalls) { aggregateCalls.add(aggregateCall.transform(targetMapping)); } + inFields = Mappings.permute(inFields, targetMapping.inverse()); final Project project = (Project) r; final List<RexNode> newProjects = new ArrayList<>(); @@ -1760,7 +1762,7 @@ public class RelBuilder { if (!config.dedupAggregateCalls() || Util.isDistinct(aggregateCalls)) { return aggregate_(groupSet, groupSets, r, aggregateCalls, - registrar.extraNodes, frame.fields); + registrar.extraNodes, inFields); } // There are duplicate aggregate calls. Rebuild the list to eliminate @@ -1782,7 +1784,7 @@ public class RelBuilder { projects.add(Pair.of(groupSet.cardinality() + i, aggregateCall.name)); } aggregate_(groupSet, groupSets, r, distinctAggregateCalls, - registrar.extraNodes, frame.fields); + registrar.extraNodes, inFields); final List<RexNode> fields = projects.stream() .map(p -> p.right == null ? field(p.left) : alias(field(p.left), p.right)) @@ -1795,7 +1797,7 @@ public class RelBuilder { private RelBuilder aggregate_(ImmutableBitSet groupSet, ImmutableList<ImmutableBitSet> groupSets, RelNode input, List<AggregateCall> aggregateCalls, List<RexNode> extraNodes, - ImmutableList<Field> inFields) { + List<Field> inFields) { final RelNode aggregate = struct.aggregateFactory.createAggregate(input, ImmutableList.of(), groupSet, groupSets, aggregateCalls); @@ -3004,6 +3006,10 @@ public class RelBuilder { this.fields = builder.build(); } + @Override public String toString() { + return rel + ": " + fields; + } + private static String deriveAlias(RelNode rel) { if (rel instanceof TableScan) { final List<String> names = rel.getTable().getQualifiedName(); 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 a6038f1..09d8aba 100644 --- a/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelBuilderTest.java @@ -1081,6 +1081,28 @@ public class RelBuilderTest { assertThat(root, hasTree(expected)); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-3839">[CALCITE-3839] + * After calling RelBuilder.aggregate, cannot lookup field by name</a>. */ + @Test public void testAggregateAndThenProjectNamedField() { + final Function<RelBuilder, RelNode> f = builder -> + builder.scan("EMP") + .project(builder.field("EMPNO"), builder.field("ENAME"), + builder.field("SAL")) + .aggregate(builder.groupKey(builder.field("ENAME")), + builder.sum(builder.field("SAL"))) + // Before [CALCITE-3839] was fixed, the following line gave + // 'field [ENAME] not found' + .project(builder.field("ENAME")) + .build(); + final String expected = "" + + "LogicalProject(ENAME=[$0])\n" + + " LogicalAggregate(group=[{0}], agg#0=[SUM($1)])\n" + + " LogicalProject(ENAME=[$1], SAL=[$5])\n" + + " LogicalTableScan(table=[[scott, EMP]])\n"; + assertThat(f.apply(createBuilder(c -> c)), hasTree(expected)); + } + /** Tests that {@link RelBuilder#aggregate} eliminates duplicate aggregate * calls and creates a {@code Project} to compensate. */ @Test public void testAggregateEliminatesDuplicateCalls() {