This is an automated email from the ASF dual-hosted git repository. jhyde pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/calcite.git
commit ddb4200f8f52b02afb1b866abb0785218e2c5994 Author: Julian Hyde <[email protected]> AuthorDate: Fri Apr 7 12:11:02 2023 -0400 Refactor: Add fields AggregateCall.rexList and RelBuilder.AggCall.preOperands These changes are in preparation for [CALCITE-4334] LITERAL_AGG. Also improve the fix for [CALCITE-5506]. --- .../java/org/apache/calcite/plan/RelOptUtil.java | 4 +- .../apache/calcite/plan/SubstitutionVisitor.java | 3 +- .../org/apache/calcite/rel/core/Aggregate.java | 48 +++++--- .../org/apache/calcite/rel/core/AggregateCall.java | 136 +++++++++++++-------- .../java/org/apache/calcite/rel/core/Window.java | 3 +- .../calcite/rel/externalize/RelJsonReader.java | 3 +- .../apache/calcite/rel/rel2sql/SqlImplementor.java | 30 +++-- .../rel/rules/AggregateCaseToFilterRule.java | 34 +++--- .../AggregateExpandDistinctAggregatesRule.java | 24 ++-- .../rel/rules/AggregateFilterTransposeRule.java | 2 +- .../rel/rules/AggregateReduceFunctionsRule.java | 14 ++- .../calcite/rel/rules/AggregateStarTableRule.java | 26 ++-- .../rel/rules/AggregateUnionTransposeRule.java | 2 +- .../rel/rules/ProjectAggregateMergeRule.java | 4 +- .../org/apache/calcite/sql/SqlOperatorBinding.java | 9 +- .../calcite/sql/SqlSplittableAggFunction.java | 23 ++-- .../calcite/sql/fun/SqlBasicAggFunction.java | 11 +- .../apache/calcite/sql2rel/SqlToRelConverter.java | 9 +- .../java/org/apache/calcite/tools/RelBuilder.java | 123 ++++++++++++++----- .../materialize/NormalizationTrimFieldTest.java | 2 +- .../org/apache/calcite/plan/RelWriterTest.java | 6 +- .../calcite/plan/volcano/TraitPropagationTest.java | 3 +- .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 3 +- .../org/apache/calcite/test/RelMetadataTest.java | 4 +- 24 files changed, 345 insertions(+), 181 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 b3e9552dac..1e1df16a29 100644 --- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java +++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java @@ -959,8 +959,8 @@ public abstract class RelOptUtil { for (int i = 0; i < aggCallCnt; i++) { aggCalls.add( AggregateCall.create(SqlStdOperatorTable.SINGLE_VALUE, false, false, - false, ImmutableList.of(i), -1, null, RelCollations.EMPTY, 0, rel, - null, null)); + false, ImmutableList.of(), ImmutableList.of(i), -1, + null, RelCollations.EMPTY, 0, rel, null, null)); } return LogicalAggregate.create(rel, ImmutableList.of(), ImmutableBitSet.of(), diff --git a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java index 2315c5d672..f631cce3f1 100644 --- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java +++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java @@ -1979,6 +1979,7 @@ public class SubstitutionVisitor { newAggCall = AggregateCall.create(aggFunction, aggregateCall.isDistinct(), aggregateCall.isApproximate(), aggregateCall.ignoreNulls(), + aggregateCall.rexList, ImmutableList.of(target.groupSet.cardinality() + i), -1, aggregateCall.distinctKeys, aggregateCall.collation, aggregateCall.type, aggregateCall.name); @@ -2048,7 +2049,7 @@ public class SubstitutionVisitor { } return AggregateCall.create(aggregation, queryAggCall.isDistinct(), queryAggCall.isApproximate(), - queryAggCall.ignoreNulls(), + queryAggCall.ignoreNulls(), queryAggCall.rexList, newArgList, -1, queryAggCall.distinctKeys, queryAggCall.collation, queryAggCall.type, queryAggCall.name); diff --git a/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java b/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java index 568a1b45d4..0736bfa054 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Aggregate.java @@ -46,7 +46,6 @@ import org.apache.calcite.util.Litmus; import org.apache.calcite.util.Pair; import org.apache.calcite.util.Util; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.math.IntMath; @@ -56,9 +55,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; +import static com.google.common.base.Preconditions.checkArgument; + +import static java.util.Objects.requireNonNull; + /** * Relational operator that eliminates * duplicates and computes totals. @@ -102,7 +104,7 @@ public abstract class Aggregate extends SingleRel implements Hintable { * before 2.0. */ @Experimental public static void checkIndicator(boolean indicator) { - Preconditions.checkArgument(!indicator, + checkArgument(!indicator, "indicator is no longer supported; use GROUPING function instead"); } @@ -160,7 +162,7 @@ public abstract class Aggregate extends SingleRel implements Hintable { super(cluster, traitSet, input); this.hints = ImmutableList.copyOf(hints); this.aggCalls = ImmutableList.copyOf(aggCalls); - this.groupSet = Objects.requireNonNull(groupSet, "groupSet"); + this.groupSet = requireNonNull(groupSet, "groupSet"); if (groupSets == null) { this.groupSets = ImmutableList.of(groupSet); } else { @@ -173,7 +175,7 @@ public abstract class Aggregate extends SingleRel implements Hintable { assert groupSet.length() <= input.getRowType().getFieldCount(); for (AggregateCall aggCall : aggCalls) { assert typeMatchesInferred(aggCall, Litmus.THROW); - Preconditions.checkArgument(aggCall.filterArg < 0 + checkArgument(aggCall.filterArg < 0 || isPredicate(input, aggCall.filterArg), "filter must be BOOLEAN NOT NULL"); } @@ -574,6 +576,7 @@ public abstract class Aggregate extends SingleRel implements Hintable { * context of a {@link org.apache.calcite.rel.logical.LogicalAggregate}. */ public static class AggCallBinding extends SqlOperatorBinding { + private final List<RelDataType> preOperands; private final List<RelDataType> operands; private final int groupCount; private final boolean filter; @@ -583,22 +586,33 @@ public abstract class Aggregate extends SingleRel implements Hintable { * * @param typeFactory Type factory * @param aggFunction Aggregate function + * @param preOperands Data types of pre-operands * @param operands Data types of operands * @param groupCount Number of columns in the GROUP BY clause * @param filter Whether the aggregate function has a FILTER clause */ public AggCallBinding(RelDataTypeFactory typeFactory, - SqlAggFunction aggFunction, List<RelDataType> operands, int groupCount, + SqlAggFunction aggFunction, List<RelDataType> preOperands, + List<RelDataType> operands, int groupCount, boolean filter) { super(typeFactory, aggFunction); - this.operands = operands; + this.preOperands = requireNonNull(preOperands, "preOperands"); + this.operands = + requireNonNull(operands, + "operands of aggregate call should not be null"); this.groupCount = groupCount; this.filter = filter; - assert operands != null - : "operands of aggregate call should not be null"; - assert groupCount >= 0 - : "number of group by columns should be greater than zero in " - + "aggregate call. Got " + groupCount; + checkArgument(groupCount >= 0, + "number of group by columns should be greater than zero in " + + "aggregate call. Got %s", groupCount); + } + + @Deprecated // to be removed before 2.0 + public AggCallBinding(RelDataTypeFactory typeFactory, + SqlAggFunction aggFunction, List<RelDataType> operands, int groupCount, + boolean filter) { + this(typeFactory, aggFunction, ImmutableList.of(), operands, groupCount, + filter); } @Override public int getGroupCount() { @@ -609,12 +623,18 @@ public abstract class Aggregate extends SingleRel implements Hintable { return filter; } + @Override public int getPreOperandCount() { + return preOperands.size(); + } + @Override public int getOperandCount() { - return operands.size(); + return preOperands.size() + operands.size(); } @Override public RelDataType getOperandType(int ordinal) { - return operands.get(ordinal); + return ordinal < preOperands.size() + ? preOperands.get(ordinal) + : operands.get(ordinal - preOperands.size()); } @Override public CalciteException newError( diff --git a/core/src/main/java/org/apache/calcite/rel/core/AggregateCall.java b/core/src/main/java/org/apache/calcite/rel/core/AggregateCall.java index b1cdcbc57f..fa0d978962 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/AggregateCall.java +++ b/core/src/main/java/org/apache/calcite/rel/core/AggregateCall.java @@ -22,6 +22,8 @@ import org.apache.calcite.rel.RelCollations; import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; +import org.apache.calcite.rex.RexNode; +import org.apache.calcite.rex.RexUtil; import org.apache.calcite.sql.SqlAggFunction; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.type.SqlTypeUtil; @@ -38,6 +40,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; import java.util.Objects; +import static java.util.Objects.requireNonNull; + /** * Call to an aggregate function within an * {@link org.apache.calcite.rel.core.Aggregate}. @@ -52,6 +56,7 @@ public class AggregateCall { private final boolean ignoreNulls; public final RelDataType type; public final @Nullable String name; + public final List<RexNode> rexList; // We considered using ImmutableIntList but we would not save much memory: // since all values are small, ImmutableList uses cached Integer values. @@ -79,7 +84,8 @@ public class AggregateCall { RelDataType type, String name) { this(aggFunction, distinct, false, false, - argList, -1, null, RelCollations.EMPTY, type, name); + ImmutableList.of(), argList, -1, null, + RelCollations.EMPTY, type, name); } /** @@ -88,6 +94,7 @@ public class AggregateCall { * @param aggFunction Aggregate function * @param distinct Whether distinct * @param approximate Whether approximate + * @param rexList List of pre-arguments * @param argList List of ordinals of arguments * @param filterArg Ordinal of filter argument (the * {@code FILTER (WHERE ...)} clause in SQL), or -1 @@ -99,16 +106,18 @@ public class AggregateCall { * @param name Name (may be null) */ private AggregateCall(SqlAggFunction aggFunction, boolean distinct, - boolean approximate, boolean ignoreNulls, List<Integer> argList, + boolean approximate, boolean ignoreNulls, + List<RexNode> rexList, List<Integer> argList, int filterArg, @Nullable ImmutableBitSet distinctKeys, RelCollation collation, RelDataType type, @Nullable String name) { - this.type = Objects.requireNonNull(type, "type"); + this.type = requireNonNull(type, "type"); this.name = name; - this.aggFunction = Objects.requireNonNull(aggFunction, "aggFunction"); + this.aggFunction = requireNonNull(aggFunction, "aggFunction"); this.argList = ImmutableList.copyOf(argList); + this.rexList = ImmutableList.copyOf(rexList); this.distinctKeys = distinctKeys; this.filterArg = filterArg; - this.collation = Objects.requireNonNull(collation, "collation"); + this.collation = requireNonNull(collation, "collation"); this.distinct = distinct; this.approximate = approximate; this.ignoreNulls = ignoreNulls; @@ -124,7 +133,8 @@ public class AggregateCall { public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, List<Integer> argList, int groupCount, RelNode input, @Nullable RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, false, false, argList, -1, + return create(aggFunction, distinct, false, false, + ImmutableList.of(), argList, -1, null, RelCollations.EMPTY, groupCount, input, type, name); } @@ -132,7 +142,8 @@ public class AggregateCall { public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, List<Integer> argList, int filterArg, int groupCount, RelNode input, @Nullable RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, false, false, argList, filterArg, + return create(aggFunction, distinct, false, false, + ImmutableList.of(), argList, filterArg, null, RelCollations.EMPTY, groupCount, input, type, name); } @@ -141,7 +152,8 @@ public class AggregateCall { boolean distinct, boolean approximate, List<Integer> argList, int filterArg, int groupCount, RelNode input, @Nullable RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, approximate, false, argList, + return create(aggFunction, distinct, approximate, false, + ImmutableList.of(), argList, filterArg, null, RelCollations.EMPTY, groupCount, input, type, name); } @@ -150,36 +162,51 @@ public class AggregateCall { boolean distinct, boolean approximate, List<Integer> argList, int filterArg, RelCollation collation, int groupCount, RelNode input, @Nullable RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, approximate, false, argList, filterArg, + return create(aggFunction, distinct, approximate, false, + ImmutableList.of(), argList, filterArg, null, collation, groupCount, input, type, name); } - /** Creates an AggregateCall, inferring its type if {@code type} is null. */ + @Deprecated // to be removed before 2.0 public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, boolean approximate, boolean ignoreNulls, List<Integer> argList, int filterArg, @Nullable ImmutableBitSet distinctKeys, RelCollation collation, int groupCount, RelNode input, @Nullable RelDataType type, @Nullable String name) { + return create(aggFunction, distinct, approximate, ignoreNulls, + ImmutableList.of(), argList, filterArg, + distinctKeys, collation, groupCount, input, type, name); + } + + /** Creates an AggregateCall, inferring its type if {@code type} is null. */ + public static AggregateCall create(SqlAggFunction aggFunction, + boolean distinct, boolean approximate, boolean ignoreNulls, + List<RexNode> rexList, List<Integer> argList, int filterArg, + @Nullable ImmutableBitSet distinctKeys, RelCollation collation, + int groupCount, + RelNode input, @Nullable RelDataType type, @Nullable String name) { if (type == null) { final RelDataTypeFactory typeFactory = input.getCluster().getTypeFactory(); + final List<RelDataType> preTypes = RexUtil.types(rexList); final List<RelDataType> types = SqlTypeUtil.projectTypes(input.getRowType(), argList); final Aggregate.AggCallBinding callBinding = - new Aggregate.AggCallBinding(typeFactory, aggFunction, types, - groupCount, filterArg >= 0); + new Aggregate.AggCallBinding(typeFactory, aggFunction, preTypes, + types, groupCount, filterArg >= 0); type = aggFunction.inferReturnType(callBinding); } - return create(aggFunction, distinct, approximate, ignoreNulls, argList, - filterArg, distinctKeys, collation, type, name); + return create(aggFunction, distinct, approximate, ignoreNulls, + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Deprecated // to be removed before 2.0 public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, List<Integer> argList, int filterArg, RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, false, false, argList, filterArg, null, + return create(aggFunction, distinct, false, false, + ImmutableList.of(), argList, filterArg, null, RelCollations.EMPTY, type, name); } @@ -187,7 +214,8 @@ public class AggregateCall { public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, boolean approximate, List<Integer> argList, int filterArg, RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, approximate, false, argList, filterArg, + return create(aggFunction, distinct, approximate, false, + ImmutableList.of(), argList, filterArg, null, RelCollations.EMPTY, type, name); } @@ -195,7 +223,8 @@ public class AggregateCall { public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, boolean approximate, List<Integer> argList, int filterArg, RelCollation collation, RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, approximate, false, argList, filterArg, + return create(aggFunction, distinct, approximate, false, + ImmutableList.of(), argList, filterArg, null, collation, type, name); } @@ -204,20 +233,21 @@ public class AggregateCall { boolean distinct, boolean approximate, boolean ignoreNulls, List<Integer> argList, int filterArg, RelCollation collation, RelDataType type, @Nullable String name) { - return create(aggFunction, distinct, approximate, ignoreNulls, argList, + return create(aggFunction, distinct, approximate, ignoreNulls, + ImmutableList.of(), argList, filterArg, null, collation, type, name); } /** Creates an AggregateCall. */ public static AggregateCall create(SqlAggFunction aggFunction, boolean distinct, boolean approximate, boolean ignoreNulls, - List<Integer> argList, int filterArg, + List<RexNode> rexList, List<Integer> argList, int filterArg, @Nullable ImmutableBitSet distinctKeys, RelCollation collation, RelDataType type, @Nullable String name) { final boolean distinct2 = distinct && (aggFunction.getDistinctOptionality() != Optionality.IGNORED); return new AggregateCall(aggFunction, distinct2, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -234,7 +264,7 @@ public class AggregateCall { public AggregateCall withDistinct(boolean distinct) { return distinct == this.distinct ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -251,7 +281,7 @@ public class AggregateCall { public AggregateCall withApproximate(boolean approximate) { return approximate == this.approximate ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -267,7 +297,7 @@ public class AggregateCall { public AggregateCall withIgnoreNulls(boolean ignoreNulls) { return ignoreNulls == this.ignoreNulls ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -293,7 +323,7 @@ public class AggregateCall { public AggregateCall withCollation(RelCollation collation) { return collation.equals(this.collation) ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -311,7 +341,7 @@ public class AggregateCall { public AggregateCall withArgList(List<Integer> argList) { return argList.equals(this.argList) ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** Withs {@link #distinctKeys}. */ @@ -319,7 +349,7 @@ public class AggregateCall { @Nullable ImmutableBitSet distinctKeys) { return Objects.equals(distinctKeys, this.distinctKeys) ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -344,7 +374,7 @@ public class AggregateCall { public AggregateCall withName(@Nullable String name) { return Objects.equals(name, this.name) ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Deprecated // to be removed before 2.0 @@ -362,6 +392,12 @@ public class AggregateCall { buf.append((argList.size() == 0) ? "DISTINCT" : "DISTINCT "); } int i = -1; + for (RexNode rexNode : rexList) { + if (++i > 0) { + buf.append(", "); + } + buf.append(rexNode); + } for (Integer arg : argList) { if (++i > 0) { buf.append(", "); @@ -399,7 +435,7 @@ public class AggregateCall { public AggregateCall withFilter(int filterArg) { return filterArg == this.filterArg ? this : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Override public boolean equals(@Nullable Object o) { @@ -417,7 +453,7 @@ public class AggregateCall { @Override public int hashCode() { return Objects.hash(aggFunction, distinct, approximate, ignoreNulls, - argList, filterArg, distinctKeys, collation); + rexList, argList, filterArg, distinctKeys, collation); } /** @@ -428,19 +464,19 @@ public class AggregateCall { public Aggregate.AggCallBinding createBinding( Aggregate aggregateRelBase) { final RelDataType rowType = aggregateRelBase.getInput().getRowType(); + final RelDataTypeFactory typeFactory = + aggregateRelBase.getCluster().getTypeFactory(); if (aggFunction.getKind() == SqlKind.PERCENTILE_DISC || aggFunction.getKind() == SqlKind.PERCENTILE_CONT) { assert collation.getKeys().size() == 1; - return new Aggregate.PercentileDiscAggCallBinding( - aggregateRelBase.getCluster().getTypeFactory(), aggFunction, - SqlTypeUtil.projectTypes(rowType, argList), + return new Aggregate.PercentileDiscAggCallBinding(typeFactory, + aggFunction, SqlTypeUtil.projectTypes(rowType, argList), SqlTypeUtil.projectTypes(rowType, collation.getKeys()).get(0), aggregateRelBase.getGroupCount(), hasFilter()); } - return new Aggregate.AggCallBinding( - aggregateRelBase.getCluster().getTypeFactory(), aggFunction, - SqlTypeUtil.projectTypes(rowType, argList), + return new Aggregate.AggCallBinding(typeFactory, aggFunction, + RexUtil.types(rexList), SqlTypeUtil.projectTypes(rowType, argList), aggregateRelBase.getGroupCount(), hasFilter()); } @@ -449,33 +485,36 @@ public class AggregateCall { * * @see #transform(Mappings.TargetMapping) * - * @param args Arguments + * @param argList Arguments * @return AggregateCall that suits new inputs and GROUP BY columns */ @Deprecated // to be removed before 2.0 - public AggregateCall copy(List<Integer> args, int filterArg, + public AggregateCall copy(List<Integer> argList, int filterArg, @Nullable ImmutableBitSet distinctKeys, RelCollation collation) { return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, - args, filterArg, distinctKeys, collation, type, name); + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Deprecated // to be removed before 2.0 - public AggregateCall copy(List<Integer> args, int filterArg, + public AggregateCall copy(List<Integer> argList, int filterArg, RelCollation collation) { // ignoring distinctKeys is error-prone - return copy(args, filterArg, distinctKeys, collation); + return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Deprecated // to be removed before 2.0 - public AggregateCall copy(List<Integer> args, int filterArg) { + public AggregateCall copy(List<Integer> argList, int filterArg) { // ignoring distinctKeys, collation is error-prone - return copy(args, filterArg, distinctKeys, collation); + return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, + rexList, argList, filterArg, distinctKeys, collation, type, name); } @Deprecated // to be removed before 2.0 - public AggregateCall copy(List<Integer> args) { + public AggregateCall copy(List<Integer> argList) { // ignoring filterArg, distinctKeys, collation is error-prone - return copy(args, filterArg, distinctKeys, collation); + return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, + rexList, argList, filterArg, distinctKeys, collation, type, name); } /** @@ -499,17 +538,18 @@ public class AggregateCall { && filterArg == this.filterArg ? type : null; - return create(aggFunction, distinct, approximate, ignoreNulls, argList, - filterArg, distinctKeys, collation, + return create(aggFunction, distinct, approximate, ignoreNulls, + rexList, argList, filterArg, distinctKeys, collation, newGroupKeyCount, input, newType, getName()); } /** Creates a copy of this aggregate call, applying a mapping to its * arguments. */ public AggregateCall transform(Mappings.TargetMapping mapping) { - return copy(Mappings.apply2((Mapping) mapping, argList), + return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls, + rexList, Mappings.apply2((Mapping) mapping, argList), hasFilter() ? Mappings.apply(mapping, filterArg) : -1, distinctKeys == null ? null : distinctKeys.permute(mapping), - RelCollations.permute(collation, mapping)); + RelCollations.permute(collation, mapping), type, name); } } diff --git a/core/src/main/java/org/apache/calcite/rel/core/Window.java b/core/src/main/java/org/apache/calcite/rel/core/Window.java index 8b52f999e8..437944f0c5 100644 --- a/core/src/main/java/org/apache/calcite/rel/core/Window.java +++ b/core/src/main/java/org/apache/calcite/rel/core/Window.java @@ -368,7 +368,8 @@ public abstract class Window extends SingleRel implements Hintable { final RexWinAggCall aggCall = aggCalls.get(index); final SqlAggFunction op = (SqlAggFunction) aggCall.getOperator(); return AggregateCall.create(op, aggCall.distinct, false, - aggCall.ignoreNulls, getProjectOrdinals(aggCall.getOperands()), + aggCall.ignoreNulls, ImmutableList.of(), + getProjectOrdinals(aggCall.getOperands()), -1, null, RelCollations.EMPTY, aggCall.getType(), fieldNames.get(aggCall.ordinal)); } diff --git a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java index 8b6d1e0f03..80624bb122 100644 --- a/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java +++ b/core/src/main/java/org/apache/calcite/rel/externalize/RelJsonReader.java @@ -338,7 +338,8 @@ public class RelJsonReader { final RelDataType type = relJson.toType(cluster.getTypeFactory(), jsonAggType); final String name = (String) jsonAggCall.get("name"); - return AggregateCall.create(aggregation, distinct, false, false, operands, + return AggregateCall.create(aggregation, distinct, false, false, + ImmutableList.of(), operands, filterOperand == null ? -1 : filterOperand, null, RelCollations.EMPTY, type, name); } diff --git a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java index 6b77384110..1b2151b44b 100644 --- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java +++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java @@ -88,6 +88,7 @@ import org.apache.calcite.sql.type.SqlTypeFamily; import org.apache.calcite.sql.type.SqlTypeName; import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.util.DateString; +import org.apache.calcite.util.ImmutableBitSet; import org.apache.calcite.util.Pair; import org.apache.calcite.util.RangeSets; import org.apache.calcite.util.Sarg; @@ -1834,15 +1835,26 @@ public abstract class SqlImplementor { if (rel instanceof Project) { Project project = (Project) rel; RelNode input = project.getInput(); - // Cannot merge because "select 1 from t" - // is different from "select 1 from (select count(1) from t)" - final boolean hasInputRef = project.getProjects() - .stream() - .anyMatch(rex -> RexUtil.containsInputRef(rex)); - final boolean hasAggregate = - input instanceof Aggregate && input.getRowType().getFieldCount() > 0; - if (!hasInputRef && hasAggregate) { - return true; + if (input instanceof Aggregate) { + // Cannot merge because "select 1 from t" + // is different from "select 1 from (select count(1) from t)" + // + // Some databases don't allow "GROUP BY ()". On those databases, + // SELECT MIN(1) FROM t + // is valid and + // SELECT 1 FROM t GROUP BY () + // is not. So, if an aggregate has no group keys we can only remove + // the subquery if there is at least one aggregate function. + // See RelToSqlConverter.buildAggregate. + final Aggregate aggregate = (Aggregate) input; + final ImmutableBitSet fieldsUsed = + RelOptUtil.InputFinder.bits(project.getProjects(), null); + final boolean hasAggregate = + !aggregate.getGroupSet().isEmpty() + || !aggregate.getAggCallList().isEmpty(); + if (hasAggregate && fieldsUsed.isEmpty()) { + return true; + } } } diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateCaseToFilterRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateCaseToFilterRule.java index 1ebe303a5c..f4642855ac 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateCaseToFilterRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateCaseToFilterRule.java @@ -134,9 +134,9 @@ public class AggregateCaseToFilterRule call.getPlanner().prune(aggregate); } - private static @Nullable AggregateCall transform(AggregateCall aggregateCall, + private static @Nullable AggregateCall transform(AggregateCall call, Project project, List<RexNode> newProjects) { - final int singleArg = soleArgument(aggregateCall); + final int singleArg = soleArgument(call); if (singleArg < 0) { return null; } @@ -166,17 +166,17 @@ public class AggregateCaseToFilterRule // Combine the CASE filter with an honest-to-goodness SQL FILTER, if the // latter is present. final RexNode filter; - if (aggregateCall.filterArg >= 0) { + if (call.filterArg >= 0) { filter = rexBuilder.makeCall(SqlStdOperatorTable.AND, - project.getProjects().get(aggregateCall.filterArg), + project.getProjects().get(call.filterArg), filterFromCase); } else { filter = filterFromCase; } - final SqlKind kind = aggregateCall.getAggregation().getKind(); - if (aggregateCall.isDistinct()) { + final SqlKind kind = call.getAggregation().getKind(); + if (call.isDistinct()) { // Just one style supported: // COUNT(DISTINCT CASE WHEN x = 'foo' THEN y END) // => @@ -187,9 +187,9 @@ public class AggregateCaseToFilterRule newProjects.add(arg1); newProjects.add(filter); return AggregateCall.create(SqlStdOperatorTable.COUNT, true, false, - false, ImmutableList.of(newProjects.size() - 2), + false, call.rexList, ImmutableList.of(newProjects.size() - 2), newProjects.size() - 1, null, RelCollations.EMPTY, - aggregateCall.getType(), aggregateCall.getName()); + call.getType(), call.getName()); } return null; } @@ -211,9 +211,9 @@ public class AggregateCaseToFilterRule && RexLiteral.isNullLiteral(arg2)) { newProjects.add(filter); return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false, - false, ImmutableList.of(), newProjects.size() - 1, null, - RelCollations.EMPTY, aggregateCall.getType(), - aggregateCall.getName()); + false, call.rexList, ImmutableList.of(), newProjects.size() - 1, null, + RelCollations.EMPTY, call.getType(), + call.getName()); } else if (kind == SqlKind.SUM // Case B && isIntLiteral(arg1, BigDecimal.ONE) && isIntLiteral(arg2, BigDecimal.ZERO)) { @@ -224,18 +224,18 @@ public class AggregateCaseToFilterRule typeFactory.createTypeWithNullability( typeFactory.createSqlType(SqlTypeName.BIGINT), false); return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false, - false, ImmutableList.of(), newProjects.size() - 1, null, - RelCollations.EMPTY, dataType, aggregateCall.getName()); + false, call.rexList, ImmutableList.of(), newProjects.size() - 1, null, + RelCollations.EMPTY, dataType, call.getName()); } else if ((RexLiteral.isNullLiteral(arg2) // Case A1 - && aggregateCall.getAggregation().allowsFilter()) + && call.getAggregation().allowsFilter()) || (kind == SqlKind.SUM // Case A2 && isIntLiteral(arg2, BigDecimal.ZERO))) { newProjects.add(arg1); newProjects.add(filter); - return AggregateCall.create(aggregateCall.getAggregation(), false, - false, false, ImmutableList.of(newProjects.size() - 2), + return AggregateCall.create(call.getAggregation(), false, + false, false, call.rexList, ImmutableList.of(newProjects.size() - 2), newProjects.size() - 1, null, RelCollations.EMPTY, - aggregateCall.getType(), aggregateCall.getName()); + call.getType(), call.getName()); } else { return null; } diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java index 51e1132ba6..41d8313e59 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandDistinctAggregatesRule.java @@ -323,7 +323,7 @@ public final class AggregateExpandDistinctAggregatesRule if (!aggCall.isDistinct()) { final AggregateCall newCall = AggregateCall.create(aggCall.getAggregation(), false, - aggCall.isApproximate(), aggCall.ignoreNulls(), + aggCall.isApproximate(), aggCall.ignoreNulls(), aggCall.rexList, aggCall.getArgList(), -1, aggCall.distinctKeys, aggCall.collation, bottomGroupSet.cardinality(), relBuilder.peek(), null, aggCall.name); @@ -352,6 +352,7 @@ public final class AggregateExpandDistinctAggregatesRule false, aggCall.isApproximate(), aggCall.ignoreNulls(), + aggCall.rexList, newArgList, -1, aggCall.distinctKeys, @@ -369,16 +370,15 @@ public final class AggregateExpandDistinctAggregatesRule newCall = AggregateCall.create(new SqlSumEmptyIsZeroAggFunction(), false, aggCall.isApproximate(), aggCall.ignoreNulls(), - newArgs, -1, aggCall.distinctKeys, aggCall.collation, - originalGroupSet.cardinality(), relBuilder.peek(), - null, - aggCall.getName()); + aggCall.rexList, newArgs, -1, aggCall.distinctKeys, + aggCall.collation, originalGroupSet.cardinality(), + relBuilder.peek(), null, aggCall.getName()); } else { newCall = AggregateCall.create(aggCall.getAggregation(), false, aggCall.isApproximate(), aggCall.ignoreNulls(), - newArgs, -1, aggCall.distinctKeys, aggCall.collation, - originalGroupSet.cardinality(), + aggCall.rexList, newArgs, -1, aggCall.distinctKeys, + aggCall.collation, originalGroupSet.cardinality(), relBuilder.peek(), null, aggCall.name); } nonDistinctAggCallProcessedSoFar++; @@ -472,7 +472,7 @@ public final class AggregateExpandDistinctAggregatesRule distinctAggCalls.add( AggregateCall.create(SqlStdOperatorTable.GROUPING, false, false, false, - ImmutableIntList.copyOf(fullGroupSet), -1, + ImmutableList.of(), ImmutableIntList.copyOf(fullGroupSet), -1, null, RelCollations.EMPTY, groupSets.size(), relBuilder.peek(), null, "$g")); @@ -530,7 +530,8 @@ public final class AggregateExpandDistinctAggregatesRule final AggregateCall newCall = AggregateCall.create(aggregation, false, aggCall.isApproximate(), aggCall.ignoreNulls(), - newArgList, newFilterArg, aggCall.distinctKeys, aggCall.collation, + aggCall.rexList, newArgList, newFilterArg, + aggCall.distinctKeys, aggCall.collation, aggregate.getGroupCount(), relBuilder.peek(), null, aggCall.name); newCalls.add(newCall); } @@ -744,7 +745,7 @@ public final class AggregateExpandDistinctAggregatesRule () -> "sourceOf.get(" + aggCall.filterArg + ")"); final AggregateCall newAggCall = AggregateCall.create(aggCall.getAggregation(), false, - aggCall.isApproximate(), aggCall.ignoreNulls(), + aggCall.isApproximate(), aggCall.ignoreNulls(), aggCall.rexList, newArgs, newFilterArg, aggCall.distinctKeys, aggCall.collation, aggCall.getType(), aggCall.getName()); assert refs.get(i) == null; @@ -832,7 +833,8 @@ public final class AggregateExpandDistinctAggregatesRule } final AggregateCall newAggCall = AggregateCall.create(aggCall.getAggregation(), false, - aggCall.isApproximate(), aggCall.ignoreNulls(), newArgs, -1, + aggCall.isApproximate(), aggCall.ignoreNulls(), + aggCall.rexList, newArgs, -1, aggCall.distinctKeys, aggCall.collation, aggCall.getType(), aggCall.getName()); newAggCalls.set(i, newAggCall); diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateFilterTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateFilterTransposeRule.java index 9fe4bcc194..43524a2900 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateFilterTransposeRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateFilterTransposeRule.java @@ -147,7 +147,7 @@ public class AggregateFilterTransposeRule topAggCallList.add( AggregateCall.create(rollup, aggregateCall.isDistinct(), aggregateCall.isApproximate(), aggregateCall.ignoreNulls(), - ImmutableList.of(i++), -1, + aggregateCall.rexList, ImmutableList.of(i++), -1, aggregateCall.distinctKeys, aggregateCall.collation, aggregateCall.type, aggregateCall.name)); } diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java index f92b2a74de..ec09c77c47 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateReduceFunctionsRule.java @@ -371,12 +371,13 @@ public class AggregateReduceFunctionsRule int filter) { final Aggregate.AggCallBinding binding = new Aggregate.AggCallBinding(typeFactory, aggFunction, - ImmutableList.of(operandType), oldAggRel.getGroupCount(), - filter >= 0); + ImmutableList.of(), ImmutableList.of(operandType), + oldAggRel.getGroupCount(), filter >= 0); return AggregateCall.create(aggFunction, oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, ImmutableIntList.of(argOrdinal), filter, oldCall.distinctKeys, @@ -398,6 +399,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys, @@ -411,6 +413,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys, @@ -455,7 +458,7 @@ public class AggregateReduceFunctionsRule final AggregateCall sumZeroCall = AggregateCall.create(SqlStdOperatorTable.SUM0, oldCall.isDistinct(), - oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.isApproximate(), oldCall.ignoreNulls(), oldCall.rexList, oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys, oldCall.collation, oldAggRel.getGroupCount(), oldAggRel.getInput(), null, oldCall.name); @@ -464,6 +467,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys, @@ -554,6 +558,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, ImmutableIntList.of(argOrdinal), oldCall.filterArg, oldCall.distinctKeys, @@ -579,6 +584,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys, @@ -643,6 +649,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, ImmutableIntList.of(argOrdinal), filterArg, oldCall.distinctKeys, @@ -688,6 +695,7 @@ public class AggregateReduceFunctionsRule oldCall.isDistinct(), oldCall.isApproximate(), oldCall.ignoreNulls(), + oldCall.rexList, argOrdinals, filterArg, oldCall.distinctKeys, diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateStarTableRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateStarTableRule.java index 3b432da412..7b2e9a1696 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateStarTableRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateStarTableRule.java @@ -194,14 +194,14 @@ public class AggregateStarTableRule call.transformTo(relBuilder.build()); } - private static @Nullable AggregateCall rollUp(int groupCount, RelBuilder relBuilder, - AggregateCall aggregateCall, TileKey tileKey) { - if (aggregateCall.isDistinct()) { + private static @Nullable AggregateCall rollUp(int groupCount, + RelBuilder relBuilder, AggregateCall call, TileKey tileKey) { + if (call.isDistinct()) { return null; } - final SqlAggFunction aggregation = aggregateCall.getAggregation(); + final SqlAggFunction aggregation = call.getAggregation(); final Pair<SqlAggFunction, List<Integer>> seek = - Pair.of(aggregation, aggregateCall.getArgList()); + Pair.of(aggregation, call.getArgList()); final int offset = tileKey.dimensions.cardinality(); final ImmutableList<Lattice.Measure> measures = tileKey.measures; @@ -214,17 +214,17 @@ public class AggregateStarTableRule if (roll == null) { break tryRoll; } - return AggregateCall.create(roll, false, aggregateCall.isApproximate(), - aggregateCall.ignoreNulls(), ImmutableList.of(offset + i), -1, - aggregateCall.distinctKeys, aggregateCall.collation, - groupCount, relBuilder.peek(), null, aggregateCall.name); + return AggregateCall.create(roll, false, call.isApproximate(), + call.ignoreNulls(), call.rexList, ImmutableList.of(offset + i), -1, + call.distinctKeys, call.collation, + groupCount, relBuilder.peek(), null, call.name); } // Second, try to satisfy the aggregation based on group set columns. tryGroup: { List<Integer> newArgs = new ArrayList<>(); - for (Integer arg : aggregateCall.getArgList()) { + for (Integer arg : call.getArgList()) { int z = tileKey.dimensions.indexOf(arg); if (z < 0) { break tryGroup; @@ -232,9 +232,9 @@ public class AggregateStarTableRule newArgs.add(z); } return AggregateCall.create(aggregation, false, - aggregateCall.isApproximate(), aggregateCall.ignoreNulls(), - newArgs, -1, aggregateCall.distinctKeys, aggregateCall.collation, - groupCount, relBuilder.peek(), null, aggregateCall.name); + call.isApproximate(), call.ignoreNulls(), call.rexList, + newArgs, -1, call.distinctKeys, call.collation, + groupCount, relBuilder.peek(), null, call.name); } // No roll up possible. diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java index fda5254c20..32df27a641 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateUnionTransposeRule.java @@ -215,7 +215,7 @@ public class AggregateUnionTransposeRule AggregateCall newCall = AggregateCall.create(aggFun, origCall.isDistinct(), origCall.isApproximate(), origCall.ignoreNulls(), - ImmutableList.of(groupCount + ord.i), -1, + origCall.rexList, ImmutableList.of(groupCount + ord.i), -1, origCall.distinctKeys, origCall.collation, groupCount, input, aggType, origCall.getName()); newCalls.add(newCall); diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectAggregateMergeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectAggregateMergeRule.java index 11af131f4c..3c2f5e404c 100644 --- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectAggregateMergeRule.java +++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectAggregateMergeRule.java @@ -165,8 +165,8 @@ public class ProjectAggregateMergeRule List<AggregateCall> aggCallList) { final AggregateCall sum0 = AggregateCall.create(SqlStdOperatorTable.SUM0, sum.isDistinct(), - sum.isApproximate(), sum.ignoreNulls(), sum.getArgList(), - sum.filterArg, sum.distinctKeys, sum.collation, + sum.isApproximate(), sum.ignoreNulls(), sum.rexList, + sum.getArgList(), sum.filterArg, sum.distinctKeys, sum.collation, typeFactory.createTypeWithNullability(sum.type, false), null); final int i = aggCallList.indexOf(sum0); if (i >= 0) { diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java index 04e64cfeca..578c1ee505 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java @@ -208,9 +208,16 @@ public abstract class SqlOperatorBinding { getOperandType(ordinal).getSqlTypeName()); } - /** Returns the number of bound operands. */ + /** Returns the number of bound operands. + * Includes pre-operands and regular operands. */ public abstract int getOperandCount(); + /** Returns the number of pre-operands. + * Zero except for a few aggregate functions. */ + public int getPreOperandCount() { + return 0; + } + /** * Gets the type of a bound operand. * diff --git a/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java b/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java index 7bd55d7b22..452ff6ef9a 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java @@ -135,9 +135,10 @@ public interface SqlSplittableAggFunction { @Override public @Nullable AggregateCall other(RelDataTypeFactory typeFactory, AggregateCall e) { + final RelDataType type = typeFactory.createSqlType(SqlTypeName.BIGINT); return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false, - false, ImmutableIntList.of(), -1, null, RelCollations.EMPTY, - typeFactory.createSqlType(SqlTypeName.BIGINT), null); + false, ImmutableList.of(), ImmutableIntList.of(), -1, null, + RelCollations.EMPTY, type, null); } @Override public AggregateCall topSplit(RexBuilder rexBuilder, @@ -165,8 +166,9 @@ public interface SqlSplittableAggFunction { } int ordinal = extra.register(node); return AggregateCall.create(SqlStdOperatorTable.SUM0, false, false, - false, ImmutableList.of(ordinal), -1, aggregateCall.distinctKeys, - aggregateCall.collation, aggregateCall.type, aggregateCall.name); + false, aggregateCall.rexList, ImmutableList.of(ordinal), -1, + aggregateCall.distinctKeys, aggregateCall.collation, + aggregateCall.type, aggregateCall.name); } /** @@ -205,7 +207,7 @@ public interface SqlSplittableAggFunction { || top.getAggregation().getKind() == SqlKind.SUM0)) { return AggregateCall.create(bottom.getAggregation(), bottom.isDistinct(), bottom.isApproximate(), false, - bottom.getArgList(), bottom.filterArg, + bottom.rexList, bottom.getArgList(), bottom.filterArg, bottom.distinctKeys, bottom.getCollation(), bottom.getType(), top.getName()); } else { @@ -250,7 +252,7 @@ public interface SqlSplittableAggFunction { if (top.getAggregation().getKind() == bottom.getAggregation().getKind()) { return AggregateCall.create(bottom.getAggregation(), bottom.isDistinct(), bottom.isApproximate(), false, - bottom.getArgList(), bottom.filterArg, + bottom.rexList, bottom.getArgList(), bottom.filterArg, bottom.distinctKeys, bottom.getCollation(), bottom.getType(), top.getName()); } else { @@ -277,9 +279,10 @@ public interface SqlSplittableAggFunction { @Override public @Nullable AggregateCall other(RelDataTypeFactory typeFactory, AggregateCall e) { + final RelDataType type = typeFactory.createSqlType(SqlTypeName.BIGINT); return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false, - false, ImmutableIntList.of(), -1, null, RelCollations.EMPTY, - typeFactory.createSqlType(SqlTypeName.BIGINT), null); + false, ImmutableList.of(), ImmutableIntList.of(), -1, null, + RelCollations.EMPTY, type, null); } @Override public AggregateCall topSplit(RexBuilder rexBuilder, @@ -309,7 +312,7 @@ public interface SqlSplittableAggFunction { } int ordinal = extra.register(node); return AggregateCall.create(getMergeAggFunctionOfTopSplit(), false, false, - false, ImmutableList.of(ordinal), -1, + false, aggregateCall.rexList, ImmutableList.of(ordinal), -1, aggregateCall.distinctKeys, aggregateCall.collation, aggregateCall.type, aggregateCall.name); } @@ -321,7 +324,7 @@ public interface SqlSplittableAggFunction { || topKind == SqlKind.SUM0)) { return AggregateCall.create(bottom.getAggregation(), bottom.isDistinct(), bottom.isApproximate(), false, - bottom.getArgList(), bottom.filterArg, + bottom.rexList, bottom.getArgList(), bottom.filterArg, bottom.distinctKeys, bottom.getCollation(), bottom.getType(), top.getName()); } else { diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlBasicAggFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlBasicAggFunction.java index 95623dfc56..33f9d888f3 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlBasicAggFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlBasicAggFunction.java @@ -58,7 +58,8 @@ public final class SqlBasicAggFunction extends SqlAggFunction { private SqlBasicAggFunction(String name, @Nullable SqlIdentifier sqlIdentifier, SqlKind kind, SqlReturnTypeInference returnTypeInference, @Nullable SqlOperandTypeInference operandTypeInference, - SqlOperandTypeChecker operandTypeChecker, SqlFunctionCategory funcType, + SqlOperandTypeChecker operandTypeChecker, + SqlFunctionCategory funcType, boolean requiresOrder, boolean requiresOver, Optionality requiresGroupOrder, Optionality distinctOptionality, SqlSyntax syntax, boolean allowsNullTreatment, boolean allowsSeparator, @@ -68,7 +69,8 @@ public final class SqlBasicAggFunction extends SqlAggFunction { requireNonNull(operandTypeChecker, "operandTypeChecker"), requireNonNull(funcType, "funcType"), requiresOrder, requiresOver, requiresGroupOrder); - this.distinctOptionality = requireNonNull(distinctOptionality, "distinctOptionality"); + this.distinctOptionality = + requireNonNull(distinctOptionality, "distinctOptionality"); this.syntax = requireNonNull(syntax, "syntax"); this.allowsNullTreatment = allowsNullTreatment; this.allowsSeparator = allowsSeparator; @@ -94,6 +96,10 @@ public final class SqlBasicAggFunction extends SqlAggFunction { //~ Methods ---------------------------------------------------------------- + @Override public <T> @Nullable T unwrap(Class<T> clazz) { + return super.unwrap(clazz); + } + @Override public RelDataType deriveType(SqlValidator validator, SqlValidatorScope scope, SqlCall call) { SqlCall strippedCall = call; @@ -217,4 +223,5 @@ public final class SqlBasicAggFunction extends SqlAggFunction { requiresOver(), groupOrder, distinctOptionality, syntax, allowsNullTreatment, allowsSeparator, percentile); } + } diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java index a0659bfc90..63b78f91ce 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java @@ -1282,11 +1282,11 @@ public class SqlToRelConverter { null, ImmutableList.of( AggregateCall.create(SqlStdOperatorTable.COUNT, false, - false, false, ImmutableList.of(), -1, null, - RelCollations.EMPTY, longType, null), + false, false, ImmutableList.of(), ImmutableList.of(), + -1, null, RelCollations.EMPTY, longType, null), AggregateCall.create(SqlStdOperatorTable.COUNT, false, - false, false, args, -1, null, - RelCollations.EMPTY, longType, null))); + false, false, ImmutableList.of(), args, + -1, null, RelCollations.EMPTY, longType, null))); LogicalJoin join = LogicalJoin.create(bb.root(), aggregate, ImmutableList.of(), rexBuilder.makeLiteral(true), ImmutableSet.of(), JoinRelType.INNER); @@ -6216,6 +6216,7 @@ public class SqlToRelConverter { distinct, approximate, ignoreNulls, + ImmutableList.of(), args, filterArg, distinctKeys, 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 5e3662df81..47a35b8f1c 100644 --- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java +++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java @@ -1352,21 +1352,26 @@ public class RelBuilder { public AggCall aggregateCall(SqlAggFunction aggFunction, boolean distinct, RexNode filter, @Nullable String alias, RexNode... operands) { return aggregateCall(aggFunction, distinct, false, false, filter, null, - ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } @Deprecated // to be removed before 2.0 public AggCall aggregateCall(SqlAggFunction aggFunction, boolean distinct, - boolean approximate, RexNode filter, @Nullable String alias, RexNode... operands) { + boolean approximate, RexNode filter, @Nullable String alias, + RexNode... operands) { return aggregateCall(aggFunction, distinct, approximate, false, filter, - null, ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } @Deprecated // to be removed before 2.0 public AggCall aggregateCall(SqlAggFunction aggFunction, boolean distinct, - RexNode filter, @Nullable String alias, Iterable<? extends RexNode> operands) { + RexNode filter, @Nullable String alias, + Iterable<? extends RexNode> operands) { return aggregateCall(aggFunction, distinct, false, false, filter, null, - ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } @Deprecated // to be removed before 2.0 @@ -1374,7 +1379,8 @@ public class RelBuilder { boolean approximate, RexNode filter, @Nullable String alias, Iterable<? extends RexNode> operands) { return aggregateCall(aggFunction, distinct, approximate, false, filter, - null, ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } /** Creates a call to an aggregate function. @@ -1388,7 +1394,8 @@ public class RelBuilder { public AggCall aggregateCall(SqlAggFunction aggFunction, Iterable<? extends RexNode> operands) { return aggregateCall(aggFunction, false, false, false, null, null, - ImmutableList.of(), null, ImmutableList.copyOf(operands)); + ImmutableList.of(), null, ImmutableList.of(), + ImmutableList.copyOf(operands)); } /** Creates a call to an aggregate function. @@ -1402,7 +1409,8 @@ public class RelBuilder { public AggCall aggregateCall(SqlAggFunction aggFunction, RexNode... operands) { return aggregateCall(aggFunction, false, false, false, null, null, - ImmutableList.of(), null, ImmutableList.copyOf(operands)); + ImmutableList.of(), null, ImmutableList.of(), + ImmutableList.copyOf(operands)); } /** Creates a call to an aggregate function as a copy of an @@ -1411,7 +1419,8 @@ public class RelBuilder { return aggregateCall(a.getAggregation(), a.isDistinct(), a.isApproximate(), a.ignoreNulls(), a.filterArg < 0 ? null : field(a.filterArg), a.distinctKeys == null ? null : fields(a.distinctKeys), - fields(a.collation), a.name, fields(a.getArgList())); + fields(a.collation), a.name, ImmutableList.copyOf(a.rexList), + fields(a.getArgList())); } /** Creates a call to an aggregate function as a copy of an @@ -1423,6 +1432,7 @@ public class RelBuilder { a.distinctKeys == null ? null : fields(Mappings.apply(mapping, a.distinctKeys)), fields(RexUtil.apply(mapping, a.collation)), a.name, + ImmutableList.copyOf(a.rexList), fields(Mappings.apply2(mapping, a.getArgList()))); } @@ -1430,10 +1440,10 @@ public class RelBuilder { protected AggCall aggregateCall(SqlAggFunction aggFunction, boolean distinct, boolean approximate, boolean ignoreNulls, @Nullable RexNode filter, @Nullable ImmutableList<RexNode> distinctKeys, - ImmutableList<RexNode> orderKeys, - @Nullable String alias, ImmutableList<RexNode> operands) { + ImmutableList<RexNode> orderKeys, @Nullable String alias, + ImmutableList<RexNode> preOperands, ImmutableList<RexNode> operands) { return new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeys); + filter, alias, preOperands, operands, distinctKeys, orderKeys); } /** Creates a call to the {@code COUNT} aggregate function. */ @@ -1448,9 +1458,11 @@ public class RelBuilder { /** Creates a call to the {@code COUNT} aggregate function, * optionally distinct and with an alias. */ - public AggCall count(boolean distinct, @Nullable String alias, RexNode... operands) { + public AggCall count(boolean distinct, @Nullable String alias, + RexNode... operands) { return aggregateCall(SqlStdOperatorTable.COUNT, distinct, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } /** Creates a call to the {@code COUNT} aggregate function, @@ -1458,7 +1470,8 @@ public class RelBuilder { public AggCall count(boolean distinct, @Nullable String alias, Iterable<? extends RexNode> operands) { return aggregateCall(SqlStdOperatorTable.COUNT, distinct, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.copyOf(operands)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.copyOf(operands)); } /** Creates a call to the {@code COUNT(*)} aggregate function. */ @@ -1473,9 +1486,11 @@ public class RelBuilder { /** Creates a call to the {@code SUM} aggregate function, * optionally distinct and with an alias. */ - public AggCall sum(boolean distinct, @Nullable String alias, RexNode operand) { + public AggCall sum(boolean distinct, @Nullable String alias, + RexNode operand) { return aggregateCall(SqlStdOperatorTable.SUM, distinct, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.of(operand)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.of(operand)); } /** Creates a call to the {@code AVG} aggregate function. */ @@ -1485,9 +1500,11 @@ public class RelBuilder { /** Creates a call to the {@code AVG} aggregate function, * optionally distinct and with an alias. */ - public AggCall avg(boolean distinct, @Nullable String alias, RexNode operand) { + public AggCall avg(boolean distinct, @Nullable String alias, + RexNode operand) { return aggregateCall(SqlStdOperatorTable.AVG, distinct, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.of(operand)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.of(operand)); } /** Creates a call to the {@code MIN} aggregate function. */ @@ -1499,7 +1516,8 @@ public class RelBuilder { * optionally with an alias. */ public AggCall min(@Nullable String alias, RexNode operand) { return aggregateCall(SqlStdOperatorTable.MIN, false, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.of(operand)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.of(operand)); } /** Creates a call to the {@code MAX} aggregate function, @@ -1511,7 +1529,8 @@ public class RelBuilder { /** Creates a call to the {@code MAX} aggregate function. */ public AggCall max(@Nullable String alias, RexNode operand) { return aggregateCall(SqlStdOperatorTable.MAX, false, false, false, null, - null, ImmutableList.of(), alias, ImmutableList.of(operand)); + null, ImmutableList.of(), alias, ImmutableList.of(), + ImmutableList.of(operand)); } // Methods for patterns @@ -3794,6 +3813,19 @@ public class RelBuilder { return sort(ImmutableList.copyOf(orderKeys)); } + /** Returns a copy of this AggCall with the given pre-operands. + * + * <p>Pre-operands apply at the start of aggregation and are constant for + * the whole query. They do not reference input columns and are typically + * {@link RexLiteral}. An example is + * {@link org.apache.calcite.sql.fun.SqlInternalOperators#LITERAL_AGG}; + * most aggregate functions do not take pre-operands. */ + AggCall preOperands(Iterable<? extends RexNode> preOperands); + + default AggCall preOperands(RexNode... preOperands) { + return preOperands(ImmutableList.copyOf(preOperands)); + } + /** Returns a copy of this AggCall that makes its input values unique by * {@code distinctKeys} before aggregating, as in SQL's * {@code WITHIN DISTINCT} clause. */ @@ -3937,13 +3969,15 @@ public class RelBuilder { private final boolean ignoreNulls; private final @Nullable RexNode filter; private final @Nullable String alias; + private final ImmutableList<RexNode> preOperands; // may be empty private final ImmutableList<RexNode> operands; // may be empty private final @Nullable ImmutableList<RexNode> distinctKeys; // may be empty or null private final ImmutableList<RexNode> orderKeys; // may be empty AggCallImpl(SqlAggFunction aggFunction, boolean distinct, boolean approximate, boolean ignoreNulls, @Nullable RexNode filter, - @Nullable String alias, ImmutableList<RexNode> operands, + @Nullable String alias, ImmutableList<RexNode> preOperands, + ImmutableList<RexNode> operands, @Nullable ImmutableList<RexNode> distinctKeys, ImmutableList<RexNode> orderKeys) { this.aggFunction = requireNonNull(aggFunction, "aggFunction"); @@ -3954,6 +3988,7 @@ public class RelBuilder { this.approximate = approximate; this.ignoreNulls = ignoreNulls; this.alias = alias; + this.preOperands = requireNonNull(preOperands, "preOperands"); this.operands = requireNonNull(operands, "operands"); this.distinctKeys = distinctKeys; this.orderKeys = requireNonNull(orderKeys, "orderKeys"); @@ -3975,6 +4010,14 @@ public class RelBuilder { if (distinct) { b.append("DISTINCT "); } + if (preOperands.size() > 0) { + b.append(preOperands.get(0)); + for (int i = 1; i < preOperands.size(); i++) { + b.append(", "); + b.append(preOperands.get(i)); + } + b.append(operands.size() > 0 ? "; " : ";"); + } if (operands.size() > 0) { b.append(operands.get(0)); for (int i = 1; i < operands.size(); i++) { @@ -4008,7 +4051,8 @@ public class RelBuilder { final RelDataType type = getTypeFactory().createSqlType(SqlTypeName.BOOLEAN); return AggregateCall.create(aggFunction, distinct, approximate, - ignoreNulls, ImmutableList.of(), -1, null, collation, type, alias); + ignoreNulls, ImmutableList.of(), ImmutableList.of(), -1, + null, collation, type, alias); } @Override public AggregateCall aggregateCall(Registrar registrar, @@ -4040,9 +4084,10 @@ public class RelBuilder { .filter(r::fieldIsNullable) .collect(Util.toImmutableList()); } + return AggregateCall.create(aggFunction, distinct, approximate, - ignoreNulls, args, filterArg, distinctKeys, collation, - groupSet.cardinality(), r, null, alias); + ignoreNulls, preOperands, args, filterArg, distinctKeys, + collation, groupSet.cardinality(), r, null, alias); } @Override public void register(Registrar registrar) { @@ -4056,6 +4101,16 @@ public class RelBuilder { registrar.registerExpressions(orderKeys); } + @Override public AggCall preOperands( + Iterable<? extends RexNode> preOperands) { + final ImmutableList<RexNode> preOperandList = + ImmutableList.copyOf(preOperands); + return preOperandList.equals(this.preOperands) + ? this + : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, + filter, alias, preOperandList, operands, distinctKeys, orderKeys); + } + @Override public OverCall over() { return new OverCallImpl(aggFunction, distinct, operands, ignoreNulls, alias); @@ -4067,7 +4122,7 @@ public class RelBuilder { return orderKeyList.equals(this.orderKeys) ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeyList); + filter, alias, preOperands, operands, distinctKeys, orderKeyList); } @Override public AggCall sort(RexNode... orderKeys) { @@ -4080,42 +4135,42 @@ public class RelBuilder { return Objects.equals(distinctKeyList, this.distinctKeys) ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeyList, orderKeys); + filter, alias, preOperands, operands, distinctKeyList, orderKeys); } @Override public AggCall approximate(boolean approximate) { return approximate == this.approximate ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeys); + filter, alias, preOperands, operands, distinctKeys, orderKeys); } @Override public AggCall filter(@Nullable RexNode condition) { return Objects.equals(condition, this.filter) ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - condition, alias, operands, distinctKeys, orderKeys); + condition, alias, preOperands, operands, distinctKeys, orderKeys); } @Override public AggCall as(@Nullable String alias) { return Objects.equals(alias, this.alias) ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeys); + filter, alias, preOperands, operands, distinctKeys, orderKeys); } @Override public AggCall distinct(boolean distinct) { return distinct == this.distinct ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeys); + filter, alias, preOperands, operands, distinctKeys, orderKeys); } @Override public AggCall ignoreNulls(boolean ignoreNulls) { return ignoreNulls == this.ignoreNulls ? this : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls, - filter, alias, operands, distinctKeys, orderKeys); + filter, alias, preOperands, operands, distinctKeys, orderKeys); } } @@ -4161,6 +4216,10 @@ public class RelBuilder { // nothing to do } + @Override public AggCall preOperands(Iterable<? extends RexNode> preOperands) { + throw new UnsupportedOperationException(); + } + @Override public AggCall sort(Iterable<RexNode> orderKeys) { throw new UnsupportedOperationException(); } diff --git a/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java b/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java index 9f8fb3db5a..c53b822b21 100644 --- a/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java +++ b/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java @@ -86,7 +86,7 @@ public class NormalizationTrimFieldTest extends SqlToRelTestBase { final AggregateCall call = AggregateCall.create(count.getAggregation(), count.isDistinct(), count.isApproximate(), - count.ignoreNulls(), ImmutableList.of(3), + count.ignoreNulls(), count.rexList, ImmutableList.of(3), count.filterArg, null, count.collation, count.getType(), count.getName()); final RelNode query = diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java index a2166e2100..65912a6be0 100644 --- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java +++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java @@ -544,10 +544,12 @@ class RelWriterTest { null, ImmutableList.of( AggregateCall.create(SqlStdOperatorTable.COUNT, - true, false, false, ImmutableList.of(1), -1, null, + true, false, false, ImmutableList.of(), + ImmutableList.of(1), -1, null, RelCollations.EMPTY, bigIntType, "c"), AggregateCall.create(SqlStdOperatorTable.COUNT, - false, false, false, ImmutableList.of(), -1, null, + false, false, false, ImmutableList.of(), + ImmutableList.of(), -1, null, RelCollations.EMPTY, bigIntType, "d"))); aggregate.explain(writer); return writer.asString(); diff --git a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java index 3b19d0421f..0caa7ec3e5 100644 --- a/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java +++ b/core/src/test/java/org/apache/calcite/plan/volcano/TraitPropagationTest.java @@ -171,7 +171,8 @@ class TraitPropagationTest { // aggregate on s, count AggregateCall aggCall = AggregateCall.create(SqlStdOperatorTable.COUNT, - false, false, false, Collections.singletonList(1), -1, + false, false, false, ImmutableList.of(), + Collections.singletonList(1), -1, null, RelCollations.EMPTY, sqlBigInt, "cnt"); RelNode agg = new LogicalAggregate(cluster, diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java index f9eaf8fe9a..d0a55e025a 100644 --- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java +++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java @@ -684,8 +684,7 @@ class RelToSqlConverterTest { + "INNER JOIN " + "(SELECT 1 AS \"K\"\n" + "FROM (SELECT COUNT(\"ENAME\") AS \"DUMMY\"\n" - + "FROM \"scott\".\"EMP\") AS \"t0\") AS \"t1\" " - + "ON \"t\".\"K\" = \"t1\".\"K\""); + + "FROM \"scott\".\"EMP\") AS \"t0\") AS \"t1\" ON \"t\".\"K\" = \"t1\".\"K\""); } /** Tests GROUP BY ROLLUP of two columns. The SQL for MySQL has diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java index 10288f440a..eb2ef3b55c 100644 --- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java @@ -1898,8 +1898,8 @@ public class RelMetadataTest { bitSetOf(2, 0), ImmutableList.of(), ImmutableList.of( - AggregateCall.create(SqlStdOperatorTable.COUNT, - false, false, false, ImmutableIntList.of(), + AggregateCall.create(SqlStdOperatorTable.COUNT, false, false, + false, ImmutableList.of(), ImmutableIntList.of(), -1, null, RelCollations.EMPTY, 2, join, null, null))); rowSize = mq.getAverageRowSize(aggregate); columnSizes = mq.getAverageColumnSizes(aggregate);
