You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by mb...@apache.org on 2024/09/20 20:39:35 UTC
(calcite) branch main updated: [CALCITE-6071] RexCall should carry source position information for runtime error reporting
This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new 98b252b36c [CALCITE-6071] RexCall should carry source position information for runtime error reporting
98b252b36c is described below
commit 98b252b36c84c4715c5bbe8c8a65355c103b3f9e
Author: Mihai Budiu <mb...@feldera.com>
AuthorDate: Fri Sep 20 10:27:45 2024 -0700
[CALCITE-6071] RexCall should carry source position information for runtime error reporting
Signed-off-by: Mihai Budiu <mb...@feldera.com>
---
.../calcite/adapter/enumerable/RexImpTable.java | 2 +-
.../apache/calcite/plan/SubstitutionVisitor.java | 15 +-
.../org/apache/calcite/rel/core/AggregateCall.java | 75 +++++--
.../java/org/apache/calcite/rel/core/Window.java | 2 +-
.../apache/calcite/rel/rel2sql/SqlImplementor.java | 2 +-
.../rel/rules/AggregateCaseToFilterRule.java | 11 +-
.../AggregateExpandDistinctAggregatesRule.java | 17 +-
.../rules/AggregateExpandWithinDistinctRule.java | 6 +-
.../rel/rules/AggregateFilterTransposeRule.java | 3 +-
.../rel/rules/AggregateReduceFunctionsRule.java | 120 +++++-----
.../calcite/rel/rules/AggregateRemoveRule.java | 5 +-
.../calcite/rel/rules/AggregateStarTableRule.java | 4 +-
.../rel/rules/AggregateUnionTransposeRule.java | 2 +-
.../rel/rules/ProjectAggregateMergeRule.java | 2 +-
.../calcite/rel/rules/ReduceDecimalsRule.java | 187 +++++++++-------
.../materialize/MaterializedViewAggregateRule.java | 4 +-
.../java/org/apache/calcite/rex/RexBuilder.java | 241 +++++++++++++++++++--
.../main/java/org/apache/calcite/rex/RexCall.java | 26 ++-
.../java/org/apache/calcite/rex/RexCopier.java | 2 +-
.../java/org/apache/calcite/rex/RexSimplify.java | 57 ++---
.../main/java/org/apache/calcite/rex/RexUtil.java | 9 +-
.../calcite/sql/SqlSplittableAggFunction.java | 23 +-
.../org/apache/calcite/sql2rel/AggConverter.java | 1 +
.../apache/calcite/sql2rel/RelDecorrelator.java | 1 +
.../sql2rel/RelStructuredTypeFlattener.java | 8 +-
.../apache/calcite/sql2rel/SqlToRelConverter.java | 40 ++--
.../calcite/sql2rel/StandardConvertletTable.java | 220 ++++++++++---------
.../java/org/apache/calcite/tools/RelBuilder.java | 145 +++++++++++--
.../materialize/NormalizationTrimFieldTest.java | 2 +-
.../apache/calcite/test/fuzzer/RexShrinker.java | 2 +-
30 files changed, 838 insertions(+), 396 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index e8cb71dfaf..1fa5cbff68 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -4781,7 +4781,7 @@ public class RexImpTable {
final ParameterExpression lambdaArg =
Expressions.parameter(translator.typeFactory.getJavaClass(rightComponentType), "el");
final RexCall binaryImplementorRexCall =
- (RexCall) translator.builder.makeCall(binaryOperator, leftRex,
+ (RexCall) translator.builder.makeCall(call.getParserPosition(), binaryOperator, leftRex,
translator.builder.makeDynamicParam(rightComponentType, 0));
final List<RexToLixTranslator.Result> binaryImplementorArgs =
ImmutableList.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 e8e4a46541..20d4f75dc9 100644
--- a/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
+++ b/core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java
@@ -350,7 +350,7 @@ public class SubstitutionVisitor {
if (newOperands.size() < 2) {
return newOperands.values().iterator().next();
}
- return rexBuilder.makeCall(call.getOperator(),
+ return rexBuilder.makeCall(call.getParserPosition(), call.getOperator(),
ImmutableList.copyOf(newOperands.values()));
}
case EQUALS:
@@ -362,7 +362,8 @@ public class SubstitutionVisitor {
RexCall call = (RexCall) condition;
RexNode left = canonizeNode(rexBuilder, call.getOperands().get(0));
RexNode right = canonizeNode(rexBuilder, call.getOperands().get(1));
- call = (RexCall) rexBuilder.makeCall(call.getOperator(), left, right);
+ call =
+ (RexCall) rexBuilder.makeCall(call.getParserPosition(), call.getOperator(), left, right);
if (left.toString().compareTo(right.toString()) <= 0) {
return call;
@@ -384,10 +385,11 @@ public class SubstitutionVisitor {
RexNode right = canonizeNode(rexBuilder, call.getOperands().get(1));
if (left.toString().compareTo(right.toString()) <= 0) {
- return rexBuilder.makeCall(call.getOperator(), left, right);
+ return rexBuilder.makeCall(call.getParserPosition(), call.getOperator(), left, right);
}
- RexNode newCall = rexBuilder.makeCall(call.getOperator(), right, left);
+ RexNode newCall =
+ rexBuilder.makeCall(call.getParserPosition(), call.getOperator(), right, left);
// new call should not be used if its inferred type is not same as old
if (!newCall.getType().equals(call.getType())) {
return call;
@@ -1973,7 +1975,8 @@ public class SubstitutionVisitor {
final SqlAggFunction aggFunction = aggregateCall.getAggregation().getRollup();
if (aggFunction != null) {
newAggCall =
- AggregateCall.create(aggFunction, aggregateCall.isDistinct(),
+ AggregateCall.create(aggregateCall.getParserPosition(),
+ aggFunction, aggregateCall.isDistinct(),
aggregateCall.isApproximate(), aggregateCall.ignoreNulls(),
aggregateCall.rexList,
ImmutableList.of(target.groupSet.cardinality() + i), -1,
@@ -2044,7 +2047,7 @@ public class SubstitutionVisitor {
if (!isAllowBuild) {
return null;
}
- return AggregateCall.create(aggregation,
+ return AggregateCall.create(queryAggCall.getParserPosition(), aggregation,
queryAggCall.isDistinct(), queryAggCall.isApproximate(),
queryAggCall.ignoreNulls(), queryAggCall.rexList,
newArgList, -1, queryAggCall.distinctKeys,
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 687e41c7e7..ddd91b1bed 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
@@ -26,6 +26,7 @@ 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.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.Optionality;
@@ -50,6 +51,14 @@ import static java.util.Objects.requireNonNull;
public class AggregateCall {
//~ Instance fields --------------------------------------------------------
+ /**
+ * Some aggregate calls may produce runtime errors. For these
+ * we need to keep around the original source position information
+ * so that the runtime can produce error messages pointing to
+ * the offending source operation. For "safe" aggregations
+ * this field may be ZERO.
+ */
+ private final SqlParserPos pos;
private final SqlAggFunction aggFunction;
private final boolean distinct;
@@ -84,7 +93,7 @@ public class AggregateCall {
List<Integer> argList,
RelDataType type,
String name) {
- this(aggFunction, distinct, false, false,
+ this(SqlParserPos.ZERO, aggFunction, distinct, false, false,
ImmutableList.of(), argList, -1, null,
RelCollations.EMPTY, type, name);
}
@@ -92,6 +101,9 @@ public class AggregateCall {
/**
* Creates an AggregateCall.
*
+ * @param pos Source position for this aggregate.
+ * Ideally it should only be ZERO when the aggregate
+ * can never fail at runtime.
* @param aggFunction Aggregate function
* @param distinct Whether distinct
* @param approximate Whether approximate
@@ -106,11 +118,12 @@ public class AggregateCall {
* @param type Result type
* @param name Name (may be null)
*/
- private AggregateCall(SqlAggFunction aggFunction, boolean distinct,
+ private AggregateCall(SqlParserPos pos, SqlAggFunction aggFunction, boolean distinct,
boolean approximate, boolean ignoreNulls,
List<RexNode> rexList, List<Integer> argList,
int filterArg, @Nullable ImmutableBitSet distinctKeys,
RelCollation collation, RelDataType type, @Nullable String name) {
+ this.pos = pos;
this.type = requireNonNull(type, "type");
this.name = name;
this.aggFunction = requireNonNull(aggFunction, "aggFunction");
@@ -187,6 +200,17 @@ public class AggregateCall {
@Nullable ImmutableBitSet distinctKeys, RelCollation collation,
int groupCount,
RelNode input, @Nullable RelDataType type, @Nullable String name) {
+ return create(SqlParserPos.ZERO, aggFunction, distinct, approximate,
+ ignoreNulls, rexList, argList, filterArg, distinctKeys, collation, groupCount,
+ input, type, name);
+ }
+
+ public static AggregateCall create(SqlParserPos pos, 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();
@@ -198,7 +222,7 @@ public class AggregateCall {
types, groupCount, filterArg >= 0);
type = aggFunction.inferReturnType(callBinding);
}
- return create(aggFunction, distinct, approximate, ignoreNulls,
+ return create(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -245,9 +269,18 @@ public class AggregateCall {
List<RexNode> rexList, List<Integer> argList, int filterArg,
@Nullable ImmutableBitSet distinctKeys, RelCollation collation,
RelDataType type, @Nullable String name) {
+ return create(SqlParserPos.ZERO, aggFunction, distinct, approximate,
+ ignoreNulls, rexList, argList, filterArg, distinctKeys, collation, type, name);
+ }
+
+ public static AggregateCall create(SqlParserPos pos, SqlAggFunction aggFunction,
+ boolean distinct, boolean approximate, boolean ignoreNulls,
+ 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,
+ return new AggregateCall(pos, aggFunction, distinct2, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -264,7 +297,7 @@ public class AggregateCall {
/** Withs {@link #isDistinct()}. */
public AggregateCall withDistinct(boolean distinct) {
return distinct == this.distinct ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -281,7 +314,7 @@ public class AggregateCall {
/** Withs {@link #isApproximate()}. */
public AggregateCall withApproximate(boolean approximate) {
return approximate == this.approximate ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -297,7 +330,7 @@ public class AggregateCall {
/** Withs {@link #ignoreNulls()}. */
public AggregateCall withIgnoreNulls(boolean ignoreNulls) {
return ignoreNulls == this.ignoreNulls ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -323,7 +356,7 @@ public class AggregateCall {
/** Withs {@link #getCollation()}. */
public AggregateCall withCollation(RelCollation collation) {
return collation.equals(this.collation) ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -341,7 +374,7 @@ public class AggregateCall {
/** Withs {@link #getArgList()}. */
public AggregateCall withArgList(List<Integer> argList) {
return argList.equals(this.argList) ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -349,7 +382,7 @@ public class AggregateCall {
public AggregateCall withDistinctKeys(
@Nullable ImmutableBitSet distinctKeys) {
return Objects.equals(distinctKeys, this.distinctKeys) ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -374,7 +407,7 @@ public class AggregateCall {
/** Withs {@link #name}. */
public AggregateCall withName(@Nullable String name) {
return Objects.equals(name, this.name) ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -435,11 +468,16 @@ public class AggregateCall {
/** Withs {@link #filterArg}. */
public AggregateCall withFilter(int filterArg) {
return filterArg == this.filterArg ? this
- : new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
+ public SqlParserPos getParserPosition() {
+ return this.pos;
+ }
+
@Override public boolean equals(@Nullable Object o) {
+ // Intentionally ignore the position
return o == this
|| o instanceof AggregateCall
&& aggFunction.equals(((AggregateCall) o).aggFunction)
@@ -453,6 +491,7 @@ public class AggregateCall {
}
@Override public int hashCode() {
+ // Ignore the position!
return Objects.hash(aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation);
}
@@ -492,7 +531,7 @@ public class AggregateCall {
@Deprecated // to be removed before 2.0
public AggregateCall copy(List<Integer> argList, int filterArg,
@Nullable ImmutableBitSet distinctKeys, RelCollation collation) {
- return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -500,21 +539,21 @@ public class AggregateCall {
public AggregateCall copy(List<Integer> argList, int filterArg,
RelCollation collation) {
// ignoring distinctKeys is error-prone
- return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@Deprecated // to be removed before 2.0
public AggregateCall copy(List<Integer> argList, int filterArg) {
// ignoring distinctKeys, collation is error-prone
- return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@Deprecated // to be removed before 2.0
public AggregateCall copy(List<Integer> argList) {
// ignoring filterArg, distinctKeys, collation is error-prone
- return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation, type, name);
}
@@ -539,7 +578,7 @@ public class AggregateCall {
&& filterArg == this.filterArg
? type
: null;
- return create(aggFunction, distinct, approximate, ignoreNulls,
+ return create(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, argList, filterArg, distinctKeys, collation,
newGroupKeyCount, input, newType, getName());
}
@@ -547,7 +586,7 @@ public class AggregateCall {
/** Creates a copy of this aggregate call, applying a mapping to its
* arguments. */
public AggregateCall transform(Mappings.TargetMapping mapping) {
- return new AggregateCall(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggregateCall(pos, aggFunction, distinct, approximate, ignoreNulls,
rexList, Mappings.apply2((Mapping) mapping, argList),
hasFilter() ? Mappings.apply(mapping, filterArg) : -1,
distinctKeys == null ? null : distinctKeys.permute(mapping),
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 f1a0418127..7c07bb6f8d 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
@@ -384,7 +384,7 @@ public abstract class Window extends SingleRel implements Hintable {
@Override public AggregateCall get(int index) {
final RexWinAggCall aggCall = aggCalls.get(index);
final SqlAggFunction op = (SqlAggFunction) aggCall.getOperator();
- return AggregateCall.create(op, aggCall.distinct, false,
+ return AggregateCall.create(aggCall.getParserPosition(), op, aggCall.distinct, false,
aggCall.ignoreNulls, ImmutableList.of(),
getProjectOrdinals(aggCall.getOperands()),
-1, null, RelCollations.EMPTY,
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 225b1dc98e..8b26d90bf7 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
@@ -1697,7 +1697,7 @@ public abstract class SqlImplementor {
&& ((RexInputRef) op0).getIndex() >= leftContext.fieldCount) {
// Arguments were of form 'op1 = op0'
final SqlOperator op2 = requireNonNull(call.getOperator().reverse());
- return (RexCall) rexBuilder.makeCall(op2, op1, op0);
+ return (RexCall) rexBuilder.makeCall(call.getParserPosition(), op2, op1, op0);
}
// fall through
default:
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 303b2d2c78..5922d05032 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
@@ -32,6 +32,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlPostfixOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
@@ -186,7 +187,8 @@ public class AggregateCaseToFilterRule
&& RexLiteral.isNullLiteral(arg2)) {
newProjects.add(arg1);
newProjects.add(filter);
- return AggregateCall.create(SqlStdOperatorTable.COUNT, true, false,
+ return AggregateCall.create(
+ call.getParserPosition(), SqlStdOperatorTable.COUNT, true, false,
false, call.rexList, ImmutableList.of(newProjects.size() - 2),
newProjects.size() - 1, null, RelCollations.EMPTY,
call.getType(), call.getName());
@@ -205,12 +207,13 @@ public class AggregateCaseToFilterRule
// C: COUNT(CASE WHEN x = 'foo' THEN 'dummy' END)
// => COUNT() FILTER (x = 'foo')
+ final SqlParserPos pos = call.getParserPosition();
if (kind == SqlKind.COUNT // Case C
&& arg1.isA(SqlKind.LITERAL)
&& !RexLiteral.isNullLiteral(arg1)
&& RexLiteral.isNullLiteral(arg2)) {
newProjects.add(filter);
- return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false,
+ return AggregateCall.create(pos, SqlStdOperatorTable.COUNT, false, false,
false, call.rexList, ImmutableList.of(), newProjects.size() - 1, null,
RelCollations.EMPTY, call.getType(),
call.getName());
@@ -223,7 +226,7 @@ public class AggregateCaseToFilterRule
final RelDataType dataType =
typeFactory.createTypeWithNullability(
typeFactory.createSqlType(SqlTypeName.BIGINT), false);
- return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false,
+ return AggregateCall.create(pos, SqlStdOperatorTable.COUNT, false, false,
false, call.rexList, ImmutableList.of(), newProjects.size() - 1, null,
RelCollations.EMPTY, dataType, call.getName());
} else if ((RexLiteral.isNullLiteral(arg2) // Case A1
@@ -232,7 +235,7 @@ public class AggregateCaseToFilterRule
&& isIntLiteral(arg2, BigDecimal.ZERO))) {
newProjects.add(arg1);
newProjects.add(filter);
- return AggregateCall.create(call.getAggregation(), false,
+ return AggregateCall.create(pos, call.getAggregation(), false,
false, false, call.rexList, ImmutableList.of(newProjects.size() - 2),
newProjects.size() - 1, null, RelCollations.EMPTY,
call.getType(), call.getName());
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 865f047a4f..cfd990a315 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
@@ -334,7 +334,7 @@ public final class AggregateExpandDistinctAggregatesRule
// as-is all the non-distinct aggregates
if (!aggCall.isDistinct()) {
final AggregateCall newCall =
- AggregateCall.create(aggCall.getAggregation(), false,
+ AggregateCall.create(aggCall.getParserPosition(), aggCall.getAggregation(), false,
aggCall.isApproximate(), aggCall.ignoreNulls(), aggCall.rexList,
aggCall.getArgList(), -1, aggCall.distinctKeys,
aggCall.collation, bottomGroupSet.cardinality(),
@@ -360,7 +360,8 @@ public final class AggregateExpandDistinctAggregatesRule
newArgList.add(bottomGroups.headSet(arg, false).size());
}
newCall =
- AggregateCall.create(aggCall.getAggregation(),
+ AggregateCall.create(aggCall.getParserPosition(),
+ aggCall.getAggregation(),
false,
aggCall.isApproximate(),
aggCall.ignoreNulls(),
@@ -380,14 +381,16 @@ public final class AggregateExpandDistinctAggregatesRule
final List<Integer> newArgs = ImmutableList.of(arg);
if (aggCall.getAggregation().getKind() == SqlKind.COUNT) {
newCall =
- AggregateCall.create(new SqlSumEmptyIsZeroAggFunction(), false,
+ AggregateCall.create(aggCall.getParserPosition(),
+ new SqlSumEmptyIsZeroAggFunction(), false,
aggCall.isApproximate(), aggCall.ignoreNulls(),
aggCall.rexList, newArgs, -1, aggCall.distinctKeys,
aggCall.collation, originalGroupSet.cardinality(),
relBuilder.peek(), null, aggCall.getName());
} else {
newCall =
- AggregateCall.create(aggCall.getAggregation(), false,
+ AggregateCall.create(aggCall.getParserPosition(),
+ aggCall.getAggregation(), false,
aggCall.isApproximate(), aggCall.ignoreNulls(),
aggCall.rexList, newArgs, -1, aggCall.distinctKeys,
aggCall.collation, originalGroupSet.cardinality(),
@@ -540,7 +543,7 @@ public final class AggregateExpandDistinctAggregatesRule
"filters.get(of(newGroupSet, aggCall.filterArg))");
}
final AggregateCall newCall =
- AggregateCall.create(aggregation, false,
+ AggregateCall.create(aggCall.getParserPosition(), aggregation, false,
aggCall.isApproximate(), aggCall.ignoreNulls(),
aggCall.rexList, newArgList, newFilterArg,
aggCall.distinctKeys, aggCall.collation,
@@ -755,7 +758,7 @@ public final class AggregateExpandDistinctAggregatesRule
newArgs.add(requireNonNull(sourceOf.get(arg), () -> "sourceOf.get(" + arg + ")"));
}
final AggregateCall newAggCall =
- AggregateCall.create(aggCall.getAggregation(), false,
+ AggregateCall.create(aggCall.getParserPosition(), aggCall.getAggregation(), false,
aggCall.isApproximate(), aggCall.ignoreNulls(), aggCall.rexList,
newArgs, -1, aggCall.distinctKeys, aggCall.collation,
aggCall.getType(), aggCall.getName());
@@ -843,7 +846,7 @@ public final class AggregateExpandDistinctAggregatesRule
() -> "sourceOf.get(" + arg + ")"));
}
final AggregateCall newAggCall =
- AggregateCall.create(aggCall.getAggregation(), false,
+ AggregateCall.create(aggCall.getParserPosition(), aggCall.getAggregation(), false,
aggCall.isApproximate(), aggCall.ignoreNulls(),
aggCall.rexList, newArgs, -1,
aggCall.distinctKeys, aggCall.collation,
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandWithinDistinctRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandWithinDistinctRule.java
index 50f43771db..a47a68ca93 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandWithinDistinctRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateExpandWithinDistinctRule.java
@@ -347,7 +347,7 @@ public class AggregateExpandWithinDistinctRule
Ord.forEach(aggCallList, (c, i) -> {
if (c.distinctKeys == null) {
RelBuilder.AggCall aggCall =
- b.aggregateCall(c.getAggregation(), b.fields(c.getArgList()));
+ b.aggregateCall(c.getParserPosition(), c.getAggregation(), b.fields(c.getArgList()));
registrar.registerAgg(i,
c.hasFilter()
? aggCall.filter(b.field(c.filterArg))
@@ -411,7 +411,7 @@ public class AggregateExpandWithinDistinctRule
RelBuilder.AggCall aggCall;
if (c.distinctKeys == null) {
aggCall =
- b.aggregateCall(SqlStdOperatorTable.MIN,
+ b.aggregateCall(c.getParserPosition(), SqlStdOperatorTable.MIN,
b.field(registrar.getAgg(i)));
} else {
// The inputs to this aggregate are outputs from MIN() calls from the
@@ -423,7 +423,7 @@ public class AggregateExpandWithinDistinctRule
// ignore null inputs, we add a filter based on a COUNT() in the inner
// aggregate.
aggCall =
- b.aggregateCall(c.getAggregation(),
+ b.aggregateCall(c.getParserPosition(), c.getAggregation(),
b.fields(registrar.fields(c.getArgList(), c.filterArg)));
if (mustBeCounted(c)) {
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 43524a2900..105e4096dc 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
@@ -145,7 +145,8 @@ public class AggregateFilterTransposeRule
return;
}
topAggCallList.add(
- AggregateCall.create(rollup, aggregateCall.isDistinct(),
+ AggregateCall.create(aggregateCall.getParserPosition(),
+ rollup, aggregateCall.isDistinct(),
aggregateCall.isApproximate(), aggregateCall.ignoreNulls(),
aggregateCall.rexList, ImmutableList.of(i++), -1,
aggregateCall.distinctKeys, aggregateCall.collation,
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 ec40844ab2..741164e342 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
@@ -34,6 +34,7 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.CompositeList;
@@ -375,7 +376,8 @@ public class AggregateReduceFunctionsRule
new Aggregate.AggCallBinding(typeFactory, aggFunction,
ImmutableList.of(), ImmutableList.of(operandType),
oldAggRel.getGroupCount(), filter >= 0);
- return AggregateCall.create(aggFunction,
+ return AggregateCall.create(oldCall.getParserPosition(),
+ aggFunction,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -396,8 +398,9 @@ public class AggregateReduceFunctionsRule
@SuppressWarnings("unused") List<RexNode> inputExprs) {
final int nGroups = oldAggRel.getGroupCount();
final RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
+ final SqlParserPos pos = oldCall.getParserPosition();
final AggregateCall sumCall =
- AggregateCall.create(SqlStdOperatorTable.SUM,
+ AggregateCall.create(pos, SqlStdOperatorTable.SUM,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -411,7 +414,7 @@ public class AggregateReduceFunctionsRule
null,
null);
final AggregateCall countCall =
- AggregateCall.create(SqlStdOperatorTable.COUNT,
+ AggregateCall.create(pos, SqlStdOperatorTable.COUNT,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -444,10 +447,10 @@ public class AggregateReduceFunctionsRule
final RelDataType avgType =
typeFactory.createTypeWithNullability(oldCall.getType(),
numeratorRef.getType().isNullable());
- numeratorRef = rexBuilder.ensureType(avgType, numeratorRef, true);
+ numeratorRef = rexBuilder.ensureType(pos, avgType, numeratorRef, true);
final RexNode divideRef =
- rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
- return rexBuilder.makeCast(oldCall.getType(), divideRef);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.DIVIDE, numeratorRef, denominatorRef);
+ return rexBuilder.makeCast(pos, oldCall.getType(), divideRef);
}
private static RexNode reduceSum(
@@ -456,16 +459,17 @@ public class AggregateReduceFunctionsRule
List<AggregateCall> newCalls,
Map<AggregateCall, RexNode> aggCallMapping) {
final int nGroups = oldAggRel.getGroupCount();
+ final SqlParserPos pos = oldCall.getParserPosition();
RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
final AggregateCall sumZeroCall =
- AggregateCall.create(SqlStdOperatorTable.SUM0, oldCall.isDistinct(),
+ AggregateCall.create(pos, SqlStdOperatorTable.SUM0, oldCall.isDistinct(),
oldCall.isApproximate(), oldCall.ignoreNulls(), oldCall.rexList,
oldCall.getArgList(), oldCall.filterArg, oldCall.distinctKeys,
oldCall.collation, oldAggRel.getGroupCount(), oldAggRel.getInput(),
null, oldCall.name);
final AggregateCall countCall =
- AggregateCall.create(SqlStdOperatorTable.COUNT,
+ AggregateCall.create(pos, SqlStdOperatorTable.COUNT,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -499,8 +503,8 @@ public class AggregateReduceFunctionsRule
newCalls,
aggCallMapping,
oldAggRel.getInput()::fieldIsNullable);
- return rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS,
countRef, rexBuilder.makeExactLiteral(BigDecimal.ZERO)),
rexBuilder.makeNullLiteral(sumZeroRef.getType()),
sumZeroRef);
@@ -529,6 +533,7 @@ public class AggregateReduceFunctionsRule
final RelOptCluster cluster = oldAggRel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
+ final SqlParserPos pos = oldCall.getParserPosition();
assert oldCall.getArgList().size() == 1 : oldCall.getArgList();
final int argOrdinal = oldCall.getArgList().get(0);
@@ -538,10 +543,10 @@ public class AggregateReduceFunctionsRule
fieldIsNullable.test(argOrdinal));
final RexNode argRef =
- rexBuilder.ensureType(oldCallType, inputExprs.get(argOrdinal), true);
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(argOrdinal), true);
final RexNode argSquared =
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argRef, argRef);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, argRef, argRef);
final int argSquaredOrdinal = lookupOrAdd(inputExprs, argSquared);
final AggregateCall sumArgSquaredAggCall =
@@ -556,7 +561,7 @@ public class AggregateReduceFunctionsRule
oldAggRel.getInput()::fieldIsNullable);
final AggregateCall sumArgAggCall =
- AggregateCall.create(SqlStdOperatorTable.SUM,
+ AggregateCall.create(pos, SqlStdOperatorTable.SUM,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -576,13 +581,13 @@ public class AggregateReduceFunctionsRule
newCalls,
aggCallMapping,
oldAggRel.getInput()::fieldIsNullable);
- final RexNode sumArgCast = rexBuilder.ensureType(oldCallType, sumArg, true);
+ final RexNode sumArgCast = rexBuilder.ensureType(pos, oldCallType, sumArg, true);
final RexNode sumSquaredArg =
- rexBuilder.makeCall(
+ rexBuilder.makeCall(pos,
SqlStdOperatorTable.MULTIPLY, sumArgCast, sumArgCast);
final AggregateCall countArgAggCall =
- AggregateCall.create(SqlStdOperatorTable.COUNT,
+ AggregateCall.create(pos, SqlStdOperatorTable.COUNT,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -604,20 +609,20 @@ public class AggregateReduceFunctionsRule
oldAggRel.getInput()::fieldIsNullable);
final RexNode div =
- divide(biased, rexBuilder, sumArgSquared, sumSquaredArg, countArg);
+ divide(pos, biased, rexBuilder, sumArgSquared, sumSquaredArg, countArg);
final RexNode result;
if (sqrt) {
final RexNode half =
rexBuilder.makeExactLiteral(new BigDecimal("0.5"));
result =
- rexBuilder.makeCall(
+ rexBuilder.makeCall(pos,
SqlStdOperatorTable.POWER, div, half);
} else {
result = div;
}
- return rexBuilder.makeCast(
+ return rexBuilder.makeCast(pos,
oldCall.getType(), result);
}
@@ -635,7 +640,7 @@ public class AggregateReduceFunctionsRule
if (refByGroup.getType().equals(oldCall.getType())) {
return refByGroup;
} else {
- return rexBuilder.makeCast(oldCall.getType(), refByGroup);
+ return rexBuilder.makeCast(oldCall.getParserPosition(), oldCall.getType(), refByGroup);
}
}
@@ -647,7 +652,7 @@ public class AggregateReduceFunctionsRule
int argOrdinal,
int filterArg) {
final AggregateCall aggregateCall =
- AggregateCall.create(SqlStdOperatorTable.SUM,
+ AggregateCall.create(oldCall.getParserPosition(), SqlStdOperatorTable.SUM,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -693,7 +698,8 @@ public class AggregateReduceFunctionsRule
ImmutableIntList argOrdinals,
int filterArg) {
final AggregateCall countArgAggCall =
- AggregateCall.create(SqlStdOperatorTable.REGR_COUNT,
+ AggregateCall.create(oldCall.getParserPosition(),
+ SqlStdOperatorTable.REGR_COUNT,
oldCall.isDistinct(),
oldCall.isApproximate(),
oldCall.ignoreNulls(),
@@ -727,6 +733,7 @@ public class AggregateReduceFunctionsRule
// sum(y * y, x) - sum(y, x) * sum(y, x) / regr_count(x, y)
//
+ final SqlParserPos pos = oldCall.getParserPosition();
final RelOptCluster cluster = oldAggRel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
@@ -739,28 +746,28 @@ public class AggregateReduceFunctionsRule
|| fieldIsNullable.test(nullFilterIndex));
final RexNode argX =
- rexBuilder.ensureType(oldCallType, inputExprs.get(xIndex), true);
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(xIndex), true);
final RexNode argY =
- rexBuilder.ensureType(oldCallType, inputExprs.get(yIndex), true);
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(yIndex), true);
final RexNode argNullFilter =
- rexBuilder.ensureType(oldCallType, inputExprs.get(nullFilterIndex), true);
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(nullFilterIndex), true);
- final RexNode argXArgY = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argX, argY);
+ final RexNode argXArgY = rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, argX, argY);
final int argSquaredOrdinal = lookupOrAdd(inputExprs, argXArgY);
final RexNode argXAndYNotNullFilter =
- rexBuilder.makeCall(SqlStdOperatorTable.AND,
- rexBuilder.makeCall(SqlStdOperatorTable.AND,
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argX),
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argY)),
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argNullFilter));
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.AND,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.AND,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NOT_NULL, argX),
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NOT_NULL, argY)),
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NOT_NULL, argNullFilter));
final int argXAndYNotNullFilterOrdinal =
lookupOrAdd(inputExprs, argXAndYNotNullFilter);
final RexNode sumXY =
getSumAggregatedRexNodeWithBinding(oldAggRel, oldCall, newCalls,
aggCallMapping, argXArgY.getType(),
argSquaredOrdinal, argXAndYNotNullFilterOrdinal);
- final RexNode sumXYCast = rexBuilder.ensureType(oldCallType, sumXY, true);
+ final RexNode sumXYCast = rexBuilder.ensureType(pos, oldCallType, sumXY, true);
final RexNode sumX =
getSumAggregatedRexNode(oldAggRel, oldCall, newCalls, aggCallMapping,
@@ -771,7 +778,7 @@ public class AggregateReduceFunctionsRule
aggCallMapping, rexBuilder, yIndex, argXAndYNotNullFilterOrdinal);
final RexNode sumXSumY =
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumX, sumY);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, sumX, sumY);
final RexNode countArg =
getRegrCountRexNode(oldAggRel, oldCall, newCalls, aggCallMapping,
@@ -780,15 +787,15 @@ public class AggregateReduceFunctionsRule
RexLiteral zero = rexBuilder.makeExactLiteral(BigDecimal.ZERO);
RexNode nul = rexBuilder.makeNullLiteral(zero.getType());
final RexNode avgSumXSumY =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, zero),
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS, countArg, zero),
nul,
- rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumXSumY, countArg));
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.DIVIDE, sumXSumY, countArg));
final RexNode avgSumXSumYCast =
- rexBuilder.ensureType(oldCallType, avgSumXSumY, true);
+ rexBuilder.ensureType(pos, oldCallType, avgSumXSumY, true);
final RexNode result =
- rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumXYCast, avgSumXSumYCast);
- return rexBuilder.makeCast(oldCall.getType(), result);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MINUS, sumXYCast, avgSumXSumYCast);
+ return rexBuilder.makeCast(pos, oldCall.getType(), result);
}
private static RexNode reduceCovariance(
@@ -805,6 +812,7 @@ public class AggregateReduceFunctionsRule
// covar_samp(x, y) ==>
// (sum(x * y) - sum(x) * sum(y) / regr_count(x, y))
// / regr_count(count(x, y) - 1, 0)
+ final SqlParserPos pos = oldCall.getParserPosition();
final RelOptCluster cluster = oldAggRel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
@@ -816,16 +824,18 @@ public class AggregateReduceFunctionsRule
typeFactory.createTypeWithNullability(oldCall.getType(),
fieldIsNullable.test(argXOrdinal)
|| fieldIsNullable.test(argYOrdinal));
- final RexNode argX = rexBuilder.ensureType(oldCallType, inputExprs.get(argXOrdinal), true);
- final RexNode argY = rexBuilder.ensureType(oldCallType, inputExprs.get(argYOrdinal), true);
+ final RexNode argX =
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(argXOrdinal), true);
+ final RexNode argY =
+ rexBuilder.ensureType(pos, oldCallType, inputExprs.get(argYOrdinal), true);
final RexNode argXAndYNotNullFilter =
- rexBuilder.makeCall(SqlStdOperatorTable.AND,
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argX),
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, argY));
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.AND,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NOT_NULL, argX),
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NOT_NULL, argY));
final int argXAndYNotNullFilterOrdinal =
lookupOrAdd(inputExprs, argXAndYNotNullFilter);
final RexNode argXY =
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, argX, argY);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, argX, argY);
final int argXYOrdinal = lookupOrAdd(inputExprs, argXY);
final RexNode sumXY =
getSumAggregatedRexNodeWithBinding(oldAggRel, oldCall, newCalls,
@@ -840,22 +850,22 @@ public class AggregateReduceFunctionsRule
aggCallMapping, rexBuilder, argYOrdinal,
argXAndYNotNullFilterOrdinal);
final RexNode sumXSumY =
- rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, sumX, sumY);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, sumX, sumY);
final RexNode countArg =
getRegrCountRexNode(oldAggRel, oldCall, newCalls,
aggCallMapping, ImmutableIntList.of(argXOrdinal, argYOrdinal),
argXAndYNotNullFilterOrdinal);
final RexNode result =
- divide(biased, rexBuilder, sumXY, sumXSumY, countArg);
- return rexBuilder.makeCast(oldCall.getType(), result);
+ divide(pos, biased, rexBuilder, sumXY, sumXSumY, countArg);
+ return rexBuilder.makeCast(pos, oldCall.getType(), result);
}
- private static RexNode divide(boolean biased, RexBuilder rexBuilder,
+ private static RexNode divide(SqlParserPos pos, boolean biased, RexBuilder rexBuilder,
RexNode sumXY, RexNode sumXSumY, RexNode countArg) {
final RexNode avgSumSquaredArg =
- rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, sumXSumY, countArg);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.DIVIDE, sumXSumY, countArg);
final RexNode diff =
- rexBuilder.makeCall(SqlStdOperatorTable.MINUS, sumXY, avgSumSquaredArg);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MINUS, sumXY, avgSumSquaredArg);
final RexNode denominator;
if (biased) {
denominator = countArg;
@@ -863,14 +873,14 @@ public class AggregateReduceFunctionsRule
final RexLiteral one = rexBuilder.makeExactLiteral(BigDecimal.ONE);
final RexNode nul = rexBuilder.makeNullLiteral(countArg.getType());
final RexNode countMinusOne =
- rexBuilder.makeCall(SqlStdOperatorTable.MINUS, countArg, one);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.MINUS, countArg, one);
final RexNode countEqOne =
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, countArg, one);
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS, countArg, one);
denominator =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE, countEqOne, nul,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE, countEqOne, nul,
countMinusOne);
}
- return rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE, diff, denominator);
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.DIVIDE, diff, denominator);
}
/**
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java
index 64186116bb..c4d406af21 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateRemoveRule.java
@@ -133,7 +133,7 @@ public class AggregateRemoveRule
aggregate.getGroupSet(), aggregate.groupSets, aggCall);
if (constant != null) {
final RexNode cast =
- rexBuilder.ensureType(aggCall.type, constant, false);
+ rexBuilder.ensureType(aggCall.getParserPosition(), aggCall.type, constant, false);
projects.add(cast);
continue;
}
@@ -143,7 +143,8 @@ public class AggregateRemoveRule
final RexNode singleton =
splitter.singleton(rexBuilder, input.getRowType(), aggCall);
final RexNode cast =
- rexBuilder.ensureType(aggCall.type, singleton, false);
+ rexBuilder.ensureType(
+ aggCall.getParserPosition(), aggCall.type, singleton, false);
projects.add(cast);
}
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 523c00bb8a..5136937f6e 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
@@ -214,7 +214,7 @@ public class AggregateStarTableRule
if (roll == null) {
break tryRoll;
}
- return AggregateCall.create(roll, false, call.isApproximate(),
+ return AggregateCall.create(call.getParserPosition(), roll, false, call.isApproximate(),
call.ignoreNulls(), call.rexList, ImmutableList.of(offset + i), -1,
call.distinctKeys, call.collation,
groupCount, relBuilder.peek(), null, call.name);
@@ -231,7 +231,7 @@ public class AggregateStarTableRule
}
newArgs.add(z);
}
- return AggregateCall.create(aggregation, false,
+ return AggregateCall.create(call.getParserPosition(), aggregation, false,
call.isApproximate(), call.ignoreNulls(), call.rexList,
newArgs, -1, call.distinctKeys, call.collation,
groupCount, relBuilder.peek(), null, call.name);
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 32df27a641..4721d6997c 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
@@ -213,7 +213,7 @@ public class AggregateUnionTransposeRule
aggType = origCall.getType();
}
AggregateCall newCall =
- AggregateCall.create(aggFun, origCall.isDistinct(),
+ AggregateCall.create(ord.e.getParserPosition(), aggFun, origCall.isDistinct(),
origCall.isApproximate(), origCall.ignoreNulls(),
origCall.rexList, ImmutableList.of(groupCount + ord.i), -1,
origCall.distinctKeys, origCall.collation,
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 3c2f5e404c..42b209fa2d 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
@@ -164,7 +164,7 @@ public class ProjectAggregateMergeRule
private static int findSum0(RelDataTypeFactory typeFactory, AggregateCall sum,
List<AggregateCall> aggCallList) {
final AggregateCall sum0 =
- AggregateCall.create(SqlStdOperatorTable.SUM0, sum.isDistinct(),
+ AggregateCall.create(sum.getParserPosition(), SqlStdOperatorTable.SUM0, sum.isDistinct(),
sum.isApproximate(), sum.ignoreNulls(), sum.rexList,
sum.getArgList(), sum.filterArg, sum.distinctKeys, sum.collation,
typeFactory.createTypeWithNullability(sum.type, false), null);
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
index e68cc2902b..28cb1cc02e 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceDecimalsRule.java
@@ -34,6 +34,7 @@ import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.tools.RelBuilderFactory;
@@ -414,7 +415,7 @@ public class ReduceDecimalsRule
* @param scale a value from zero to max precision - 1
* @return value * 10^scale as an exact numeric value
*/
- protected RexNode scaleUp(RexNode value, int scale) {
+ protected RexNode scaleUp(SqlParserPos pos, RexNode value, int scale) {
assert scale >= 0;
assert scale
< builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
@@ -422,6 +423,7 @@ public class ReduceDecimalsRule
return value;
}
return builder.makeCall(
+ pos,
SqlStdOperatorTable.MULTIPLY,
value,
makeScaleFactor(scale));
@@ -438,7 +440,7 @@ public class ReduceDecimalsRule
* @return value/10^scale, rounded away from zero and returned as an
* exact numeric value
*/
- protected RexNode scaleDown(RexNode value, int scale) {
+ protected RexNode scaleDown(SqlParserPos pos, RexNode value, int scale) {
final int maxPrecision =
builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
assert scale >= 0 && scale <= maxPrecision;
@@ -448,12 +450,12 @@ public class ReduceDecimalsRule
if (scale == maxPrecision) {
long half = BigInteger.TEN.pow(scale - 1).longValue() * 5;
return makeCase(
- builder.makeCall(
+ builder.makeCall(pos,
SqlStdOperatorTable.GREATER_THAN_OR_EQUAL,
value,
makeExactLiteral(half)),
makeExactLiteral(1),
- builder.makeCall(
+ builder.makeCall(pos,
SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
value,
makeExactLiteral(-half)),
@@ -463,13 +465,13 @@ public class ReduceDecimalsRule
RexNode roundFactor = makeRoundFactor(scale);
RexNode roundValue =
makeCase(
- builder.makeCall(
+ builder.makeCall(pos,
SqlStdOperatorTable.GREATER_THAN,
value,
makeExactLiteral(0)),
- makePlus(value, roundFactor),
- makeMinus(value, roundFactor));
- return makeDivide(
+ makePlus(pos, value, roundFactor),
+ makeMinus(pos, value, roundFactor));
+ return makeDivide(pos,
roundValue,
makeScaleFactor(scale));
}
@@ -483,15 +485,16 @@ public class ReduceDecimalsRule
* @param scale a value from zero to max precision
* @return value/10^scale as a double precision value
*/
- protected RexNode scaleDownDouble(RexNode value, int scale) {
+ protected RexNode scaleDownDouble(SqlParserPos pos, RexNode value, int scale) {
assert scale >= 0;
assert scale
<= builder.getTypeFactory().getTypeSystem().getMaxNumericPrecision();
- RexNode cast = ensureType(real8, value);
+ RexNode cast = ensureType(pos, real8, value);
if (scale == 0) {
return cast;
}
return makeDivide(
+ pos,
cast,
makeApproxScaleFactor(scale));
}
@@ -513,7 +516,7 @@ public class ReduceDecimalsRule
* @return value * 10^scale, returned as an exact or approximate value
* corresponding to the input value
*/
- protected RexNode ensureScale(RexNode value, int scale, int required) {
+ protected RexNode ensureScale(SqlParserPos pos, RexNode value, int scale, int required) {
final RelDataTypeSystem typeSystem =
builder.getTypeFactory().getTypeSystem();
final int maxPrecision = typeSystem.getMaxNumericPrecision();
@@ -525,6 +528,7 @@ public class ReduceDecimalsRule
int scaleDiff = required - scale;
if (SqlTypeUtil.isApproximateNumeric(value.getType())) {
return makeMultiply(
+ pos,
value,
makeApproxScaleFactor(scaleDiff));
}
@@ -537,7 +541,7 @@ public class ReduceDecimalsRule
+ "source type is too large to be encoded by the "
+ "target type");
}
- return scaleUp(value, scaleDiff);
+ return scaleUp(pos, value, scaleDiff);
}
/**
@@ -546,9 +550,9 @@ public class ReduceDecimalsRule
* @param decimalNode the decimal value as an opaque type
* @return an integer representation of the decimal value
*/
- protected RexNode decodeValue(RexNode decimalNode) {
+ protected RexNode decodeValue(SqlParserPos pos, RexNode decimalNode) {
assert SqlTypeUtil.isDecimal(decimalNode.getType());
- return builder.decodeIntervalOrDecimal(decimalNode);
+ return builder.decodeIntervalOrDecimal(pos, decimalNode);
}
/**
@@ -562,7 +566,7 @@ public class ReduceDecimalsRule
protected RexNode accessValue(RexNode node) {
assert SqlTypeUtil.isNumeric(node.getType());
if (SqlTypeUtil.isDecimal(node.getType())) {
- return decodeValue(node);
+ return decodeValue(SqlParserPos.ZERO, node);
}
return node;
}
@@ -577,8 +581,8 @@ public class ReduceDecimalsRule
* @param decimalType type integer will be reinterpreted as
* @return the integer representation reinterpreted as a decimal type
*/
- protected RexNode encodeValue(RexNode value, RelDataType decimalType) {
- return encodeValue(value, decimalType, false);
+ protected RexNode encodeValue(SqlParserPos pos, RexNode value, RelDataType decimalType) {
+ return encodeValue(pos, value, decimalType, false);
}
/**
@@ -598,11 +602,12 @@ public class ReduceDecimalsRule
* @return the integer reinterpreted as an opaque decimal type
*/
protected RexNode encodeValue(
+ SqlParserPos pos,
RexNode value,
RelDataType decimalType,
boolean checkOverflow) {
return builder.encodeIntervalOrDecimal(
- value, decimalType, checkOverflow);
+ pos, value, decimalType, checkOverflow);
}
/**
@@ -616,8 +621,8 @@ public class ReduceDecimalsRule
* @param node expression
* @return a casted expression or the original expression
*/
- protected RexNode ensureType(RelDataType type, RexNode node) {
- return ensureType(type, node, true);
+ protected RexNode ensureType(SqlParserPos pos, RelDataType type, RexNode node) {
+ return ensureType(pos, type, node, true);
}
/**
@@ -633,10 +638,11 @@ public class ReduceDecimalsRule
* @return a casted expression or the original expression
*/
protected RexNode ensureType(
+ SqlParserPos pos,
RelDataType type,
RexNode node,
boolean matchNullability) {
- return builder.ensureType(type, node, matchNullability);
+ return builder.ensureType(pos, type, node, matchNullability);
}
protected RexNode makeCase(
@@ -666,36 +672,44 @@ public class ReduceDecimalsRule
}
protected RexNode makePlus(
+ SqlParserPos pos,
RexNode a,
RexNode b) {
return builder.makeCall(
+ pos,
SqlStdOperatorTable.PLUS,
a,
b);
}
protected RexNode makeMinus(
+ SqlParserPos pos,
RexNode a,
RexNode b) {
return builder.makeCall(
+ pos,
SqlStdOperatorTable.MINUS,
a,
b);
}
protected RexNode makeDivide(
+ SqlParserPos pos,
RexNode a,
RexNode b) {
return builder.makeCall(
+ pos,
SqlStdOperatorTable.DIVIDE_INTEGER,
a,
b);
}
protected RexNode makeMultiply(
+ SqlParserPos pos,
RexNode a,
RexNode b) {
return builder.makeCall(
+ pos,
SqlStdOperatorTable.MULTIPLY,
a,
b);
@@ -739,26 +753,27 @@ public class ReduceDecimalsRule
assert SqlTypeUtil.isDecimal(fromType)
|| SqlTypeUtil.isDecimal(toType);
+ SqlParserPos pos = call.getParserPosition();
if (SqlTypeUtil.isIntType(toType)) {
// decimal to int
- return ensureType(
+ return ensureType(pos,
toType,
- scaleDown(
- decodeValue(operand),
+ scaleDown(pos,
+ decodeValue(pos, operand),
fromType.getScale()),
false);
} else if (SqlTypeUtil.isApproximateNumeric(toType)) {
// decimal to floating point
- return ensureType(
+ return ensureType(pos,
toType,
- scaleDownDouble(
- decodeValue(operand),
+ scaleDownDouble(pos,
+ decodeValue(pos, operand),
fromType.getScale()),
false);
} else if (SqlTypeUtil.isApproximateNumeric(fromType)) {
// real to decimal
- return encodeValue(
- ensureScale(
+ return encodeValue(pos,
+ ensureScale(pos,
operand,
0,
toType.getScale()),
@@ -784,8 +799,8 @@ public class ReduceDecimalsRule
if (SqlTypeUtil.isIntType(fromType)) {
// int to decimal
- return encodeValue(
- ensureScale(
+ return encodeValue(pos,
+ ensureScale(pos,
operand,
0,
toType.getScale()),
@@ -795,20 +810,20 @@ public class ReduceDecimalsRule
SqlTypeUtil.isDecimal(fromType)
&& SqlTypeUtil.isDecimal(toType)) {
// decimal to decimal
- RexNode value = decodeValue(operand);
+ RexNode value = decodeValue(pos, operand);
RexNode scaled;
if (fromScale <= toScale) {
- scaled = ensureScale(value, fromScale, toScale);
+ scaled = ensureScale(pos, value, fromScale, toScale);
} else {
if (toDigits == fromDigits) {
// rounding away from zero may cause an overflow
// for example: cast(9.99 as decimal(2,1))
checkOverflow = true;
}
- scaled = scaleDown(value, fromScale - toScale);
+ scaled = scaleDown(pos, value, fromScale - toScale);
}
- return encodeValue(scaled, toType, checkOverflow);
+ return encodeValue(pos, scaled, toType, checkOverflow);
} else {
throw Util.needToImplement(
"Reduce decimal cast from " + fromType + " to " + toType);
@@ -830,6 +845,7 @@ public class ReduceDecimalsRule
}
@Override public RexNode expand(RexCall call) {
+ final SqlParserPos pos = call.getParserPosition();
List<RexNode> operands = call.operands;
assert operands.size() == 2;
RelDataType typeA = operands.get(0).getType();
@@ -843,13 +859,13 @@ public class ReduceDecimalsRule
if (SqlTypeUtil.isApproximateNumeric(typeA)) {
newOperands =
ImmutableList.of(operands.get(0),
- ensureType(real8, operands.get(1)));
+ ensureType(pos, real8, operands.get(1)));
} else {
newOperands =
- ImmutableList.of(ensureType(real8, operands.get(0)),
+ ImmutableList.of(ensureType(pos, real8, operands.get(0)),
operands.get(1));
}
- return builder.makeCall(
+ return builder.makeCall(pos,
call.getOperator(),
newOperands);
}
@@ -896,15 +912,16 @@ public class ReduceDecimalsRule
private RexNode expandPlusMinus(RexCall call, List<RexNode> operands) {
RelDataType outType = call.getType();
+ final SqlParserPos pos = call.getParserPosition();
int outScale = outType.getScale();
- return encodeValue(
- builder.makeCall(
+ return encodeValue(pos,
+ builder.makeCall(pos,
call.getOperator(),
- ensureScale(
+ ensureScale(pos,
accessValue(operands.get(0)),
scaleA,
outScale),
- ensureScale(
+ ensureScale(pos,
accessValue(operands.get(1)),
scaleB,
outScale)),
@@ -913,22 +930,24 @@ public class ReduceDecimalsRule
private RexNode expandDivide(RexCall call, List<RexNode> operands) {
RelDataType outType = call.getType();
+ final SqlParserPos pos = call.getParserPosition();
RexNode dividend =
- builder.makeCall(
+ builder.makeCall(pos,
call.getOperator(),
- ensureType(
+ ensureType(pos,
real8,
accessValue(operands.get(0))),
ensureType(
+ pos,
real8,
accessValue(operands.get(1))));
int scaleDifference = outType.getScale() - scaleA + scaleB;
RexNode rescale =
- builder.makeCall(
+ builder.makeCall(pos,
SqlStdOperatorTable.MULTIPLY,
dividend,
makeApproxScaleFactor(scaleDifference));
- return encodeValue(rescale, outType);
+ return encodeValue(pos, rescale, outType);
}
private RexNode expandTimes(RexCall call, List<RexNode> operands) {
@@ -936,6 +955,7 @@ public class ReduceDecimalsRule
// a number with scale = scaleA + scaleB. If the result type has
// a lower scale, then the number should be scaled down.
int divisor = scaleA + scaleB - call.getType().getScale();
+ final SqlParserPos pos = call.getParserPosition();
if (builder.getTypeFactory().getTypeSystem().shouldUseDoubleMultiplication(
builder.getTypeFactory(),
@@ -945,17 +965,17 @@ public class ReduceDecimalsRule
// cast (a as double) * cast (b as double)
// / 10^divisor
RexNode division =
- makeDivide(
- makeMultiply(
- ensureType(real8, accessValue(operands.get(0))),
- ensureType(real8, accessValue(operands.get(1)))),
+ makeDivide(pos,
+ makeMultiply(pos,
+ ensureType(pos, real8, accessValue(operands.get(0))),
+ ensureType(pos, real8, accessValue(operands.get(1)))),
makeApproxLiteral(BigDecimal.TEN.pow(divisor)));
- return encodeValue(division, call.getType(), true);
+ return encodeValue(pos, division, call.getType(), true);
} else {
// Exact implementation: scaleDown(a * b)
- return encodeValue(
- scaleDown(
- builder.makeCall(
+ return encodeValue(pos,
+ scaleDown(pos,
+ builder.makeCall(pos,
call.getOperator(),
accessValue(operands.get(0)),
accessValue(operands.get(1))),
@@ -965,20 +985,22 @@ public class ReduceDecimalsRule
}
private RexNode expandComparison(RexCall call, List<RexNode> operands) {
+ final SqlParserPos pos = call.getParserPosition();
int commonScale = Math.max(scaleA, scaleB);
- return builder.makeCall(
+ return builder.makeCall(pos,
call.getOperator(),
- ensureScale(
+ ensureScale(pos,
accessValue(operands.get(0)),
scaleA,
commonScale),
- ensureScale(
+ ensureScale(pos,
accessValue(operands.get(1)),
scaleB,
commonScale));
}
private RexNode expandMod(RexCall call, List<RexNode> operands) {
+ final SqlParserPos pos = call.getParserPosition();
assert SqlTypeUtil.isExactNumeric(requireNonNull(typeA, "typeA"));
assert SqlTypeUtil.isExactNumeric(requireNonNull(typeB, "typeB"));
if (scaleA != 0 || scaleB != 0) {
@@ -986,15 +1008,15 @@ public class ReduceDecimalsRule
.ex();
}
RexNode result =
- builder.makeCall(
+ builder.makeCall(pos,
call.getOperator(),
accessValue(operands.get(0)),
accessValue(operands.get(1)));
RelDataType retType = call.getType();
if (SqlTypeUtil.isDecimal(retType)) {
- return encodeValue(result, retType);
+ return encodeValue(pos, result, retType);
}
- return ensureType(
+ return ensureType(pos,
call.getType(),
result);
}
@@ -1018,9 +1040,10 @@ public class ReduceDecimalsRule
@Override public RexNode expand(RexCall call) {
assert call.getOperator() == SqlStdOperatorTable.FLOOR;
+ final SqlParserPos pos = call.getParserPosition();
RexNode decValue = call.operands.get(0);
int scale = decValue.getType().getScale();
- RexNode value = decodeValue(decValue);
+ RexNode value = decodeValue(pos, decValue);
final RelDataTypeSystem typeSystem =
builder.getTypeFactory().getTypeSystem();
@@ -1039,12 +1062,12 @@ public class ReduceDecimalsRule
rewrite =
makeCase(
makeIsNegative(value),
- makeDivide(
- makePlus(value, round),
+ makeDivide(pos,
+ makePlus(pos, value, round),
scaleFactor),
- makeDivide(value, scaleFactor));
+ makeDivide(pos, value, scaleFactor));
}
- return encodeValue(
+ return encodeValue(pos,
rewrite,
call.getType());
}
@@ -1068,9 +1091,10 @@ public class ReduceDecimalsRule
@Override public RexNode expand(RexCall call) {
assert call.getOperator() == SqlStdOperatorTable.CEIL;
+ final SqlParserPos pos = call.getParserPosition();
RexNode decValue = call.operands.get(0);
int scale = decValue.getType().getScale();
- RexNode value = decodeValue(decValue);
+ RexNode value = decodeValue(pos, decValue);
final RelDataTypeSystem typeSystem =
builder.getTypeFactory().getTypeSystem();
@@ -1089,12 +1113,12 @@ public class ReduceDecimalsRule
rewrite =
makeCase(
makeIsPositive(value),
- makeDivide(
- makePlus(value, round),
+ makeDivide(pos,
+ makePlus(pos, value, round),
scaleFactor),
- makeDivide(value, scaleFactor));
+ makeDivide(pos, value, scaleFactor));
}
- return encodeValue(
+ return encodeValue(pos,
rewrite,
call.getType());
}
@@ -1118,7 +1142,8 @@ public class ReduceDecimalsRule
}
@Override public RexNode expand(RexCall call) {
- RelDataType retType = call.getType();
+ final SqlParserPos pos = call.getParserPosition();
+ final RelDataType retType = call.getType();
int argCount = call.operands.size();
ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
@@ -1128,17 +1153,17 @@ public class ReduceDecimalsRule
opBuilder.add(call.operands.get(i));
continue;
}
- RexNode expr = ensureType(retType, call.operands.get(i), false);
+ RexNode expr = ensureType(pos, retType, call.operands.get(i), false);
if (SqlTypeUtil.isDecimal(retType)) {
- expr = decodeValue(expr);
+ expr = decodeValue(pos, expr);
}
opBuilder.add(expr);
}
RexNode newCall =
- builder.makeCall(retType, call.getOperator(), opBuilder.build());
+ builder.makeCall(pos, retType, call.getOperator(), opBuilder.build());
if (SqlTypeUtil.isDecimal(retType)) {
- newCall = encodeValue(newCall, retType);
+ newCall = encodeValue(pos, newCall, retType);
}
return newCall;
}
@@ -1159,6 +1184,7 @@ public class ReduceDecimalsRule
}
@Override public RexNode expand(RexCall call) {
+ final SqlParserPos pos = call.getParserPosition();
ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
for (RexNode operand : call.operands) {
if (SqlTypeUtil.isNumeric(operand.getType())) {
@@ -1169,10 +1195,10 @@ public class ReduceDecimalsRule
}
RexNode newCall =
- builder.makeCall(call.getType(), call.getOperator(),
+ builder.makeCall(pos, call.getType(), call.getOperator(),
opBuilder.build());
if (SqlTypeUtil.isDecimal(call.getType())) {
- return encodeValue(
+ return encodeValue(pos,
newCall,
call.getType());
} else {
@@ -1212,24 +1238,25 @@ public class ReduceDecimalsRule
public abstract RelDataType getArgType(RexCall call, int ordinal);
@Override public RexNode expand(RexCall call) {
+ final SqlParserPos pos = call.getParserPosition();
ImmutableList.Builder<RexNode> opBuilder = ImmutableList.builder();
for (Ord<RexNode> operand : Ord.zip(call.operands)) {
RelDataType targetType = getArgType(call, operand.i);
if (SqlTypeUtil.isDecimal(operand.e.getType())) {
- opBuilder.add(ensureType(targetType, operand.e, true));
+ opBuilder.add(ensureType(pos, targetType, operand.e, true));
} else {
opBuilder.add(operand.e);
}
}
RexNode ret =
- builder.makeCall(
+ builder.makeCall(pos,
call.getType(),
call.getOperator(),
opBuilder.build());
ret =
- ensureType(
+ ensureType(pos,
call.getType(),
ret,
true);
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
index 579efc3336..e6cf9e1058 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/materialize/MaterializedViewAggregateRule.java
@@ -348,7 +348,7 @@ public abstract class MaterializedViewAggregateRule<C extends MaterializedViewAg
rexBuilder.makeInputRef(relBuilder.peek(),
aggregate.getGroupCount() + i);
aggregateCalls.add(
- relBuilder.aggregateCall(rollupAgg, operand)
+ relBuilder.aggregateCall(aggCall.getParserPosition(), rollupAgg, operand)
.distinct(aggCall.isDistinct())
.approximate(aggCall.isApproximate())
.as(aggCall.name));
@@ -606,7 +606,7 @@ public abstract class MaterializedViewAggregateRule<C extends MaterializedViewAg
queryAggregate.getGroupCount() + aggregateCalls.size());
final RexInputRef operand = rexBuilder.makeInputRef(input, k);
aggregateCalls.add(
- relBuilder.aggregateCall(rollupAgg, operand)
+ relBuilder.aggregateCall(queryAggCall.getParserPosition(), rollupAgg, operand)
.approximate(queryAggCall.isApproximate())
.distinct(queryAggCall.isDistinct())
.as(queryAggCall.name));
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index 18252de644..5cc4b21170 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -37,6 +37,7 @@ import org.apache.calcite.sql.SqlUtil;
import org.apache.calcite.sql.fun.SqlCountAggFunction;
import org.apache.calcite.sql.fun.SqlLibraryOperators;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.ArraySqlType;
import org.apache.calcite.sql.type.MapSqlType;
import org.apache.calcite.sql.type.MultisetSqlType;
@@ -257,33 +258,79 @@ public class RexBuilder {
RelDataType returnType,
SqlOperator op,
List<RexNode> exprs) {
- return new RexCall(returnType, op, exprs);
+ return makeCall(SqlParserPos.ZERO, returnType, op, exprs);
+ }
+
+ /**
+ * Creates a call with a list of arguments and a predetermined type.
+ *
+ * @param pos should be different from ZERO if the call can
+ * fail at runtime.
+ */
+ public RexNode makeCall(
+ SqlParserPos pos,
+ RelDataType returnType,
+ SqlOperator op,
+ List<RexNode> exprs) {
+ return new RexCall(pos, returnType, op, exprs);
}
/**
* Creates a call with an array of arguments.
*
* <p>If you already know the return type of the call, then
- * {@link #makeCall(org.apache.calcite.rel.type.RelDataType, org.apache.calcite.sql.SqlOperator, java.util.List)}
+ * {@link #makeCall(SqlParserPos, RelDataType, SqlOperator, List)}
* is preferred.
*/
public RexNode makeCall(
SqlOperator op,
List<? extends RexNode> exprs) {
+ return makeCall(SqlParserPos.ZERO, op, exprs);
+ }
+
+ /**
+ * Creates a call with an array of arguments.
+ *
+ * @param pos should be different from ZERO if the call can
+ * fail at runtime.
+ *
+ * <p>If you already know the return type of the call, then
+ * {@link #makeCall(SqlParserPos, RelDataType, SqlOperator, List)}
+ * is preferred.
+ */
+ public RexNode makeCall(
+ SqlParserPos pos, SqlOperator op,
+ List<? extends RexNode> exprs) {
final RelDataType type = deriveReturnType(op, exprs);
- return new RexCall(type, op, exprs);
+ return new RexCall(pos, type, op, exprs);
+ }
+
+ /**
+ * Creates a call with a list of arguments.
+ *
+ * <p>Equivalent to
+ * <code>makeCall(ZERO, op, exprList.toArray(new RexNode[exprList.size()]))</code>.
+ */
+ public final RexNode makeCall(
+ SqlOperator op,
+ RexNode... exprs) {
+ return makeCall(SqlParserPos.ZERO, op, exprs);
}
/**
* Creates a call with a list of arguments.
*
+ * @param pos should be different from ZERO if the call can
+ * fail at runtime.
+ *
* <p>Equivalent to
- * <code>makeCall(op, exprList.toArray(new RexNode[exprList.size()]))</code>.
+ * <code>makeCall(pos, op, exprList.toArray(new RexNode[exprList.size()]))</code>.
*/
public final RexNode makeCall(
+ SqlParserPos pos,
SqlOperator op,
RexNode... exprs) {
- return makeCall(op, ImmutableList.copyOf(exprs));
+ return makeCall(pos, op, ImmutableList.copyOf(exprs));
}
/**
@@ -585,6 +632,21 @@ public class RexBuilder {
return makeCast(type, exp, false, false, constantNull);
}
+ /**
+ * Creates a call to the CAST operator.
+ *
+ * @param pos Parser position of the cast.
+ * @param type Type to cast to
+ * @param exp Expression being cast
+ * @return Call to CAST operator
+ */
+ public RexNode makeCast(
+ SqlParserPos pos,
+ RelDataType type,
+ RexNode exp) {
+ return makeCast(pos, type, exp, false, false, constantNull);
+ }
+
@Deprecated // to be removed before 2.0
public RexNode makeCast(
RelDataType type,
@@ -593,6 +655,31 @@ public class RexBuilder {
return makeCast(type, exp, matchNullability, false, constantNull);
}
+ /**
+ * Creates a call to the CAST operator, expanding if possible, and optionally
+ * also preserving nullability, and optionally in safe mode.
+ *
+ * <p>Tries to expand the cast, and therefore the result may be something
+ * other than a {@link RexCall} to the CAST operator, such as a
+ * {@link RexLiteral}.
+ *
+ * @param pos Parser position
+ * @param type Type to cast to
+ * @param exp Expression being cast
+ * @param matchNullability Whether to ensure the result has the same
+ * nullability as {@code type}
+ * @param safe Whether to return NULL if cast fails
+ * @return Call to CAST operator
+ */
+ public RexNode makeCast(
+ SqlParserPos pos,
+ RelDataType type,
+ RexNode exp,
+ boolean matchNullability,
+ boolean safe) {
+ return makeCast(pos, type, exp, matchNullability, safe, constantNull);
+ }
+
/**
* Creates a call to the CAST operator, expanding if possible, and optionally
* also preserving nullability, and optionally in safe mode.
@@ -639,6 +726,33 @@ public class RexBuilder {
boolean matchNullability,
boolean safe,
RexLiteral format) {
+ return makeCast(SqlParserPos.ZERO, type, exp, matchNullability, safe, format);
+ }
+
+ /**
+ * Creates a call to the CAST operator, expanding if possible, and optionally
+ * also preserving nullability, and optionally in safe mode.
+ *
+ * <p>Tries to expand the cast, and therefore the result may be something
+ * other than a {@link RexCall} to the CAST operator, such as a
+ * {@link RexLiteral}.
+ *
+ * @param pos Parser position
+ * @param type Type to cast to
+ * @param exp Expression being cast
+ * @param matchNullability Whether to ensure the result has the same
+ * nullability as {@code type}
+ * @param safe Whether to return NULL if cast fails
+ * @param format Type Format to cast into
+ * @return Call to CAST operator
+ */
+ public RexNode makeCast(
+ SqlParserPos pos,
+ RelDataType type,
+ RexNode exp,
+ boolean matchNullability,
+ boolean safe,
+ RexLiteral format) {
final SqlTypeName sqlType = type.getSqlTypeName();
if (exp instanceof RexLiteral) {
RexLiteral literal = (RexLiteral) exp;
@@ -705,13 +819,13 @@ public class RexBuilder {
if (type.isNullable()
&& !literal2.getType().isNullable()
&& matchNullability) {
- return makeAbstractCast(type, literal2, safe, format);
+ return makeAbstractCast(pos, type, literal2, safe, format);
}
return literal2;
}
} else if (SqlTypeUtil.isExactNumeric(type)
&& SqlTypeUtil.isInterval(exp.getType())) {
- return makeCastIntervalToExact(type, exp);
+ return makeCastIntervalToExact(pos, type, exp);
} else if (sqlType == SqlTypeName.BOOLEAN
&& SqlTypeUtil.isExactNumeric(exp.getType())) {
return makeCastExactToBoolean(type, exp);
@@ -719,7 +833,7 @@ public class RexBuilder {
&& SqlTypeUtil.isExactNumeric(type)) {
return makeCastBooleanToExact(type, exp);
}
- return makeAbstractCast(type, exp, safe, format);
+ return makeAbstractCast(pos, type, exp, safe, format);
}
/** Returns the lowest granularity unit for the given unit.
@@ -824,18 +938,23 @@ public class RexBuilder {
casted, makeNullLiteral(toType)));
}
- private RexNode makeCastIntervalToExact(RelDataType toType, RexNode exp) {
+ private RexNode makeCastIntervalToExact(SqlParserPos pos, RelDataType toType, RexNode exp) {
final TimeUnit endUnit = exp.getType().getSqlTypeName().getEndUnit();
final TimeUnit baseUnit = baseUnit(exp.getType().getSqlTypeName());
final BigDecimal multiplier = baseUnit.multiplier;
final BigDecimal divider = endUnit.multiplier;
RexNode value =
- multiplyDivide(decodeIntervalOrDecimal(exp), multiplier, divider);
- return ensureType(toType, value, false);
+ multiplyDivide(pos, decodeIntervalOrDecimal(pos, exp), multiplier, divider);
+ return ensureType(pos, toType, value, false);
}
public RexNode multiplyDivide(RexNode e, BigDecimal multiplier,
BigDecimal divider) {
+ return multiplyDivide(SqlParserPos.ZERO, e, multiplier, divider);
+ }
+
+ public RexNode multiplyDivide(SqlParserPos pos, RexNode e, BigDecimal multiplier,
+ BigDecimal divider) {
assert multiplier.signum() > 0;
assert divider.signum() > 0;
switch (multiplier.compareTo(divider)) {
@@ -843,12 +962,12 @@ public class RexBuilder {
return e;
case 1:
// E.g. multiplyDivide(e, 1000, 10) ==> e * 100
- return makeCall(SqlStdOperatorTable.MULTIPLY, e,
+ return makeCall(pos, SqlStdOperatorTable.MULTIPLY, e,
makeExactLiteral(
multiplier.divide(divider, RoundingMode.UNNECESSARY)));
case -1:
// E.g. multiplyDivide(e, 10, 1000) ==> e / 100
- return makeCall(SqlStdOperatorTable.DIVIDE_INTEGER, e,
+ return makeCall(pos, SqlStdOperatorTable.DIVIDE_INTEGER, e,
makeExactLiteral(
divider.divide(multiplier, RoundingMode.UNNECESSARY)));
default:
@@ -876,10 +995,18 @@ public class RexBuilder {
RexNode value,
RelDataType type,
boolean checkOverflow) {
+ return encodeIntervalOrDecimal(SqlParserPos.ZERO, value, type, checkOverflow);
+ }
+
+ public RexNode encodeIntervalOrDecimal(
+ SqlParserPos pos,
+ RexNode value,
+ RelDataType type,
+ boolean checkOverflow) {
RelDataType bigintType =
typeFactory.createSqlType(SqlTypeName.BIGINT);
- RexNode cast = ensureType(bigintType, value, true);
- return makeReinterpretCast(type, cast, makeLiteral(checkOverflow));
+ RexNode cast = ensureType(pos, bigintType, value, true);
+ return makeReinterpretCast(pos, type, cast, makeLiteral(checkOverflow));
}
/**
@@ -889,10 +1016,14 @@ public class RexBuilder {
* @return an integer representation of the decimal value
*/
public RexNode decodeIntervalOrDecimal(RexNode node) {
+ return decodeIntervalOrDecimal(SqlParserPos.ZERO, node);
+ }
+
+ public RexNode decodeIntervalOrDecimal(SqlParserPos pos, RexNode node) {
assert SqlTypeUtil.isDecimal(node.getType())
|| SqlTypeUtil.isInterval(node.getType());
RelDataType bigintType = typeFactory.createSqlType(SqlTypeName.BIGINT);
- return makeReinterpretCast(
+ return makeReinterpretCast(pos,
matchNullability(bigintType, node), node, makeLiteral(false));
}
@@ -910,10 +1041,24 @@ public class RexBuilder {
* @return Call to CAST operator
*/
public RexNode makeAbstractCast(RelDataType type, RexNode exp, boolean safe) {
+ return makeAbstractCast(SqlParserPos.ZERO, type, exp, safe);
+ }
+
+ /**
+ * Creates a call to CAST or SAFE_CAST operator.
+ *
+ * @param pos Parser position.
+ * @param type Type to cast to
+ * @param exp Expression being cast
+ * @param safe Whether to return NULL if cast fails
+ * @return Call to CAST operator
+ * Casts can fail at runtime, so we expect position information.
+ */
+ public RexNode makeAbstractCast(SqlParserPos pos, RelDataType type, RexNode exp, boolean safe) {
final SqlOperator operator =
safe ? SqlLibraryOperators.SAFE_CAST
: SqlStdOperatorTable.CAST;
- return new RexCall(type, operator, ImmutableList.of(exp));
+ return new RexCall(pos, type, operator, ImmutableList.of(exp));
}
/**
@@ -926,24 +1071,56 @@ public class RexBuilder {
* @return Call to CAST operator
*/
public RexNode makeAbstractCast(RelDataType type, RexNode exp, boolean safe, RexLiteral format) {
+ return makeAbstractCast(SqlParserPos.ZERO, type, exp, safe, format);
+ }
+
+ /**
+ * Creates a call to CAST or SAFE_CAST operator with a FORMAT clause.
+ *
+ * @param pos Parser position
+ * @param type Type to cast to
+ * @param exp Expression being cast
+ * @param safe Whether to return NULL if cast fails
+ * @param format Conversion format for target type
+ * @return Call to CAST operator
+ */
+ public RexNode makeAbstractCast(
+ SqlParserPos pos, RelDataType type, RexNode exp, boolean safe, RexLiteral format) {
final SqlOperator operator =
safe ? SqlLibraryOperators.SAFE_CAST
: SqlStdOperatorTable.CAST;
if (format.isNull()) {
- return new RexCall(type, operator, ImmutableList.of(exp));
+ return new RexCall(pos, type, operator, ImmutableList.of(exp));
}
- return new RexCall(type, operator, ImmutableList.of(exp, format));
+ return new RexCall(pos, type, operator, ImmutableList.of(exp, format));
+ }
+
+ /**
+ * Makes a reinterpret cast.
+ *
+ * @param type type returned by the cast
+ * @param exp expression to be casted
+ * @param checkOverflow whether an overflow check is required
+ * @return a RexCall with two operands and a special return type
+ */
+ public RexNode makeReinterpretCast(
+ RelDataType type,
+ RexNode exp,
+ RexNode checkOverflow) {
+ return makeReinterpretCast(SqlParserPos.ZERO, type, exp, checkOverflow);
}
/**
* Makes a reinterpret cast.
*
+ * @param pos parser position
* @param type type returned by the cast
* @param exp expression to be cast
* @param checkOverflow whether an overflow check is required
* @return a RexCall with two operands and a special return type
*/
public RexNode makeReinterpretCast(
+ SqlParserPos pos,
RelDataType type,
RexNode exp,
RexNode checkOverflow) {
@@ -954,6 +1131,7 @@ public class RexBuilder {
args = ImmutableList.of(exp);
}
return new RexCall(
+ pos,
type,
SqlStdOperatorTable.REINTERPRET,
args);
@@ -986,7 +1164,7 @@ public class RexBuilder {
}
final RelDataType type2 =
typeFactory.createTypeWithNullability(type, nullability);
- return makeAbstractCast(type2, exp, false);
+ return makeAbstractCast(SqlParserPos.ZERO, type2, exp, false);
}
/**
@@ -1319,6 +1497,27 @@ public class RexBuilder {
RelDataType type,
RexNode node,
boolean matchNullability) {
+ return ensureType(SqlParserPos.ZERO, type, node, matchNullability);
+ }
+
+ /**
+ * Ensures expression is interpreted as a specified type. The returned
+ * expression may be wrapped with a cast.
+ *
+ * @param pos parser position
+ * @param type desired type
+ * @param node expression
+ * @param matchNullability whether to correct nullability of specified
+ * type to match the expression; this usually should
+ * be true, except for explicit casts which can
+ * override default nullability
+ * @return a casted expression or the original expression
+ */
+ public RexNode ensureType(
+ SqlParserPos pos,
+ RelDataType type,
+ RexNode node,
+ boolean matchNullability) {
RelDataType targetType = type;
if (matchNullability) {
targetType = matchNullability(type, node);
@@ -1331,7 +1530,7 @@ public class RexBuilder {
}
if (!node.getType().equals(targetType)) {
- return makeCast(targetType, node);
+ return makeCast(pos, targetType, node);
}
return node;
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexCall.java b/core/src/main/java/org/apache/calcite/rex/RexCall.java
index b8089f775d..ecd3cccb2c 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCall.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCall.java
@@ -21,6 +21,7 @@ import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.SqlSyntax;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.util.Litmus;
@@ -56,6 +57,12 @@ public class RexCall extends RexNode {
//~ Instance fields --------------------------------------------------------
+ /** In the calls which can produce runtime errors we carry
+ * the source position, so the backend can produce runtime error messages
+ * pointing to the original source position.
+ * For calls that are can never generate runtime failures, this field may
+ * be ZERO. Note that some optimizations may "lost" position information. */
+ public final SqlParserPos pos;
public final SqlOperator op;
public final ImmutableList<RexNode> operands;
public final RelDataType type;
@@ -74,9 +81,11 @@ public class RexCall extends RexNode {
//~ Constructors -----------------------------------------------------------
protected RexCall(
+ SqlParserPos pos,
RelDataType type,
SqlOperator operator,
List<? extends RexNode> operands) {
+ this.pos = pos;
this.type = requireNonNull(type, "type");
this.op = requireNonNull(operator, "operator");
this.operands = ImmutableList.copyOf(operands);
@@ -85,6 +94,13 @@ public class RexCall extends RexNode {
assert operator.kind != SqlKind.IN || this instanceof RexSubQuery;
}
+ protected RexCall(
+ RelDataType type,
+ SqlOperator operator,
+ List<? extends RexNode> operands) {
+ this(SqlParserPos.ZERO, type, operator, operands);
+ }
+
//~ Methods ----------------------------------------------------------------
/**
@@ -176,6 +192,10 @@ public class RexCall extends RexNode {
return sb.toString();
}
+ public SqlParserPos getParserPosition() {
+ return this.pos;
+ }
+
@Override public final String toString() {
return computeDigest(digestWithType());
}
@@ -211,7 +231,7 @@ public class RexCall extends RexNode {
case CAST:
return operands.get(0).isAlwaysTrue();
case SEARCH:
- final Sarg sarg = ((RexLiteral) operands.get(1)).getValueAs(Sarg.class);
+ final Sarg<?> sarg = ((RexLiteral) operands.get(1)).getValueAs(Sarg.class);
return requireNonNull(sarg, "sarg").isAll()
&& (sarg.nullAs == RexUnknownAs.TRUE
|| !operands.get(0).getType().isNullable());
@@ -233,7 +253,7 @@ public class RexCall extends RexNode {
case CAST:
return operands.get(0).isAlwaysFalse();
case SEARCH:
- final Sarg sarg = ((RexLiteral) operands.get(1)).getValueAs(Sarg.class);
+ final Sarg<?> sarg = ((RexLiteral) operands.get(1)).getValueAs(Sarg.class);
return requireNonNull(sarg, "sarg").isNone()
&& (sarg.nullAs == RexUnknownAs.FALSE
|| !operands.get(0).getType().isNullable());
@@ -270,7 +290,7 @@ public class RexCall extends RexNode {
* @return New call
*/
public RexCall clone(RelDataType type, List<RexNode> operands) {
- return new RexCall(type, op, operands);
+ return new RexCall(pos, type, op, operands);
}
private Pair<SqlOperator, List<RexNode>> getNormalized() {
diff --git a/core/src/main/java/org/apache/calcite/rex/RexCopier.java b/core/src/main/java/org/apache/calcite/rex/RexCopier.java
index e73a68d5f6..1f5700e482 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCopier.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCopier.java
@@ -57,7 +57,7 @@ class RexCopier extends RexShuttle {
@Override public RexNode visitCall(final RexCall call) {
final boolean[] update = null;
- return builder.makeCall(copy(call.getType()),
+ return builder.makeCall(call.getParserPosition(), copy(call.getType()),
call.getOperator(),
visitList(call.getOperands(), update));
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
index 6909d35c96..e05f9640f1 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -399,7 +399,7 @@ public class RexSimplify {
if (e.operands.equals(operands)) {
return e;
}
- return rexBuilder.makeCall(e.getType(), e.getOperator(), operands);
+ return rexBuilder.makeCall(e.getParserPosition(), e.getType(), e.getOperator(), operands);
}
/**
@@ -449,7 +449,7 @@ public class RexSimplify {
// return the other operand.
RexNode other = e.getOperands().get((zeroIndex + 1) % 2);
return other.getType().equals(e.getType())
- ? other : rexBuilder.makeCast(e.getType(), other);
+ ? other : rexBuilder.makeCast(e.getParserPosition(), e.getType(), other);
}
return simplifyGenericNode(e);
}
@@ -459,7 +459,7 @@ public class RexSimplify {
if (zeroIndex == 1) {
RexNode leftOperand = e.getOperands().get(0);
return leftOperand.getType().equals(e.getType())
- ? leftOperand : rexBuilder.makeCast(e.getType(), leftOperand);
+ ? leftOperand : rexBuilder.makeCast(e.getParserPosition(), e.getType(), leftOperand);
}
return simplifyGenericNode(e);
}
@@ -470,7 +470,7 @@ public class RexSimplify {
// return the other operand.
RexNode other = e.getOperands().get((oneIndex + 1) % 2);
return other.getType().equals(e.getType())
- ? other : rexBuilder.makeCast(e.getType(), other);
+ ? other : rexBuilder.makeCast(e.getParserPosition(), e.getType(), other);
}
return simplifyGenericNode(e);
}
@@ -480,7 +480,7 @@ public class RexSimplify {
if (oneIndex == 1) {
RexNode leftOperand = e.getOperands().get(0);
return leftOperand.getType().equals(e.getType())
- ? leftOperand : rexBuilder.makeCast(e.getType(), leftOperand);
+ ? leftOperand : rexBuilder.makeCast(e.getParserPosition(), e.getType(), leftOperand);
}
return simplifyGenericNode(e);
}
@@ -491,8 +491,9 @@ public class RexSimplify {
if ("%".equals(literal.getValueAs(String.class))) {
// "x LIKE '%'" simplifies to "x = x"
final RexNode x = e.operands.get(0);
- return simplify(rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, x, x),
- unknownAs);
+ return simplify(
+ rexBuilder.makeCall(
+ e.getParserPosition(), SqlStdOperatorTable.EQUALS, x, x), unknownAs);
}
}
return simplifyGenericNode(e);
@@ -522,18 +523,18 @@ public class RexSimplify {
case LESS_THAN_OR_EQUAL:
// "x = x" simplifies to "null or x is not null" (similarly <= and >=)
newExpr =
- rexBuilder.makeCall(SqlStdOperatorTable.OR,
+ rexBuilder.makeCall(e.getParserPosition(), SqlStdOperatorTable.OR,
rexBuilder.makeNullLiteral(e.getType()),
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, o0));
+ rexBuilder.makeCall(e.getParserPosition(), SqlStdOperatorTable.IS_NOT_NULL, o0));
return simplify(newExpr, unknownAs);
case NOT_EQUALS:
case LESS_THAN:
case GREATER_THAN:
// "x != x" simplifies to "null and x is null" (similarly < and >)
newExpr =
- rexBuilder.makeCall(SqlStdOperatorTable.AND,
+ rexBuilder.makeCall(e.getParserPosition(), SqlStdOperatorTable.AND,
rexBuilder.makeNullLiteral(e.getType()),
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, o0));
+ rexBuilder.makeCall(e.getParserPosition(), SqlStdOperatorTable.IS_NULL, o0));
return simplify(newExpr, unknownAs);
default:
// unknown kind
@@ -541,7 +542,9 @@ public class RexSimplify {
}
if (o0.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
- Comparison cmp = Comparison.of(rexBuilder.makeCall(e.getOperator(), o0, o1), node -> true);
+ Comparison cmp =
+ Comparison.of(
+ rexBuilder.makeCall(e.getParserPosition(), e.getOperator(), o0, o1), node -> true);
if (cmp != null) {
if (cmp.literal.isAlwaysTrue()) {
switch (cmp.kind) {
@@ -635,7 +638,7 @@ public class RexSimplify {
if (operands.equals(e.operands)) {
e2 = e;
} else {
- e2 = rexBuilder.makeCall(e.op, operands);
+ e2 = rexBuilder.makeCall(e.getParserPosition(), e.op, operands);
}
return simplifyUsingPredicates(e2, clazz);
}
@@ -772,7 +775,8 @@ public class RexSimplify {
newOperands.add(simplify(not(operand), unknownAs));
}
return simplify(
- rexBuilder.makeCall(SqlStdOperatorTable.OR, newOperands), unknownAs);
+ rexBuilder.makeCall(
+ call.getParserPosition(), SqlStdOperatorTable.OR, newOperands), unknownAs);
case OR:
// NOT distributivity for OR
@@ -781,7 +785,8 @@ public class RexSimplify {
newOperands.add(simplify(not(operand), unknownAs));
}
return simplify(
- rexBuilder.makeCall(SqlStdOperatorTable.AND, newOperands), unknownAs);
+ rexBuilder.makeCall(
+ call.getParserPosition(), SqlStdOperatorTable.AND, newOperands), unknownAs);
case CASE:
newOperands = new ArrayList<>();
@@ -795,7 +800,8 @@ public class RexSimplify {
}
}
return simplify(
- rexBuilder.makeCall(SqlStdOperatorTable.CASE, newOperands), unknownAs);
+ rexBuilder.makeCall(
+ call.getParserPosition(), SqlStdOperatorTable.CASE, newOperands), unknownAs);
case IN:
case NOT_IN:
@@ -806,13 +812,14 @@ public class RexSimplify {
final SqlKind negateKind = a.getKind().negate();
if (a.getKind() != negateKind) {
return simplify(
- rexBuilder.makeCall(RexUtil.op(negateKind),
+ rexBuilder.makeCall(
+ call.getParserPosition(), RexUtil.op(negateKind),
((RexCall) a).getOperands()), unknownAs);
}
final SqlKind negateKind2 = a.getKind().negateNullSafe();
if (a.getKind() != negateKind2) {
return simplify(
- rexBuilder.makeCall(RexUtil.op(negateKind2),
+ rexBuilder.makeCall(call.getParserPosition(), RexUtil.op(negateKind2),
((RexCall) a).getOperands()), unknownAs);
}
}
@@ -1213,7 +1220,7 @@ public class RexSimplify {
if (sameTypeOrNarrowsNullability(caseType, value.getType())) {
return value;
} else {
- return rexBuilder.makeAbstractCast(caseType, value, false);
+ return rexBuilder.makeAbstractCast(call.getParserPosition(), caseType, value, false);
}
}
@@ -1228,7 +1235,7 @@ public class RexSimplify {
if (!simplified.getType().isNullable()) {
return simplified;
} else {
- return rexBuilder.makeCast(call.getType(), simplified);
+ return rexBuilder.makeCast(call.getParserPosition(), call.getType(), simplified);
}
}
}
@@ -1237,7 +1244,7 @@ public class RexSimplify {
if (newOperands.equals(call.getOperands())) {
return call;
}
- return rexBuilder.makeCall(SqlStdOperatorTable.CASE, newOperands);
+ return rexBuilder.makeCall(call.getParserPosition(), SqlStdOperatorTable.CASE, newOperands);
}
/**
@@ -2244,7 +2251,7 @@ public class RexSimplify {
|| operand.getType().getSqlTypeName() != SqlTypeName.CHAR)
&& SqlTypeCoercionRule.instance()
.canApplyFrom(intExpr.getType().getSqlTypeName(), e.getType().getSqlTypeName())) {
- return rexBuilder.makeCast(e.getType(), intExpr);
+ return rexBuilder.makeCast(e.getParserPosition(), e.getType(), intExpr);
}
}
final boolean safe = e.getKind() == SqlKind.SAFE_CAST;
@@ -2258,7 +2265,7 @@ public class RexSimplify {
// makeCast and canRemoveCastFromLiteral have the same logic, so we are
// sure to be able to remove the cast.
if (rexBuilder.canRemoveCastFromLiteral(e.getType(), value, typeName)) {
- return rexBuilder.makeCast(e.getType(), operand);
+ return rexBuilder.makeCast(e.getParserPosition(), e.getType(), operand);
}
// Next, try to convert the value to a different type,
@@ -2277,7 +2284,7 @@ public class RexSimplify {
}
final List<RexNode> reducedValues = new ArrayList<>();
final RexNode simplifiedExpr = e.operandCount() == 2
- ? rexBuilder.makeCast(e.getType(), operand, safe, safe,
+ ? rexBuilder.makeCast(e.getParserPosition(), e.getType(), operand, safe, safe,
(RexLiteral) e.getOperands().get(1))
: rexBuilder.makeCast(e.getType(), operand, safe, safe);
executor.reduce(rexBuilder, ImmutableList.of(simplifiedExpr), reducedValues);
@@ -2294,7 +2301,7 @@ public class RexSimplify {
return e;
} else {
return e.operands.size() > 1
- ? rexBuilder.makeCast(e.getType(), operand, safe, safe,
+ ? rexBuilder.makeCast(e.getParserPosition(), e.getType(), operand, safe, safe,
(RexLiteral) e.getOperands().get(1))
: rexBuilder.makeCast(e.getType(), operand, safe, safe);
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index 227e6e3701..dce7cc5390 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -1592,7 +1592,7 @@ public class RexUtil {
final SqlOperator op = call.getOperator();
final List<RexNode> flattenedOperands = flatten(call.getOperands(), op);
if (!isFlat(call.getOperands(), op)) {
- return rexBuilder.makeCall(call.getType(), op, flattenedOperands);
+ return rexBuilder.makeCall(call.getParserPosition(), call.getType(), op, flattenedOperands);
}
}
return node;
@@ -2036,8 +2036,7 @@ public class RexUtil {
}
private static RexNode addNot(RexNode e) {
- return new RexCall(e.getType(), SqlStdOperatorTable.NOT,
- ImmutableList.of(e));
+ return new RexCall(e.getType(), SqlStdOperatorTable.NOT, ImmutableList.of(e));
}
@API(since = "1.27.0", status = API.Status.EXPERIMENTAL)
@@ -2114,7 +2113,7 @@ public class RexUtil {
case LESS_THAN_OR_EQUAL:
case GREATER_THAN_OR_EQUAL:
final SqlOperator op = op(call.getKind().negateNullSafe());
- return rexBuilder.makeCall(op, call.getOperands());
+ return rexBuilder.makeCall(call.getParserPosition(), op, call.getOperands());
default:
break;
}
@@ -2130,7 +2129,7 @@ public class RexUtil {
case LESS_THAN_OR_EQUAL:
case GREATER_THAN_OR_EQUAL:
final SqlOperator op = requireNonNull(call.getOperator().reverse());
- return rexBuilder.makeCall(op, Lists.reverse(call.getOperands()));
+ return rexBuilder.makeCall(call.getParserPosition(), op, Lists.reverse(call.getOperands()));
default:
return null;
}
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 d10c9f88d0..1918ef6701 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlSplittableAggFunction.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.mapping.Mappings;
@@ -114,7 +115,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
@Override public @Nullable AggregateCall other(RelDataTypeFactory typeFactory,
AggregateCall e) {
final RelDataType type = typeFactory.createSqlType(SqlTypeName.BIGINT);
- return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false,
+ return AggregateCall.create(e.getParserPosition(), SqlStdOperatorTable.COUNT, false, false,
false, ImmutableList.of(), ImmutableIntList.of(), -1, null,
RelCollations.EMPTY, type, null);
}
@@ -123,6 +124,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
Registry<RexNode> extra, int offset, RelDataType inputRowType,
AggregateCall aggregateCall, int leftSubTotal, int rightSubTotal) {
final List<RexNode> merges = new ArrayList<>();
+ final SqlParserPos pos = aggregateCall.getParserPosition();
if (leftSubTotal >= 0) {
merges.add(
rexBuilder.makeInputRef(aggregateCall.type, leftSubTotal));
@@ -137,13 +139,13 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
node = merges.get(0);
break;
case 2:
- node = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, merges);
+ node = rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, merges);
break;
default:
throw new AssertionError("unexpected count " + merges);
}
int ordinal = extra.register(node);
- return AggregateCall.create(SqlStdOperatorTable.SUM0, false, false,
+ return AggregateCall.create(pos, SqlStdOperatorTable.SUM0, false, false,
false, aggregateCall.rexList, ImmutableList.of(ordinal), -1,
aggregateCall.distinctKeys, aggregateCall.collation,
aggregateCall.type, aggregateCall.name);
@@ -183,7 +185,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
if (bottom.getAggregation().getKind() == SqlKind.COUNT
&& (top.getAggregation().getKind() == SqlKind.SUM
|| top.getAggregation().getKind() == SqlKind.SUM0)) {
- return AggregateCall.create(bottom.getAggregation(),
+ return AggregateCall.create(top.getParserPosition(), bottom.getAggregation(),
bottom.isDistinct(), bottom.isApproximate(), false,
bottom.rexList, bottom.getArgList(), bottom.filterArg,
bottom.distinctKeys, bottom.getCollation(),
@@ -228,7 +230,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
@Override public @Nullable AggregateCall merge(AggregateCall top, AggregateCall bottom) {
if (top.getAggregation().getKind() == bottom.getAggregation().getKind()) {
- return AggregateCall.create(bottom.getAggregation(),
+ return AggregateCall.create(top.getParserPosition(), bottom.getAggregation(),
bottom.isDistinct(), bottom.isApproximate(), false,
bottom.rexList, bottom.getArgList(), bottom.filterArg,
bottom.distinctKeys, bottom.getCollation(),
@@ -258,7 +260,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
@Override public @Nullable AggregateCall other(RelDataTypeFactory typeFactory,
AggregateCall e) {
final RelDataType type = typeFactory.createSqlType(SqlTypeName.BIGINT);
- return AggregateCall.create(SqlStdOperatorTable.COUNT, false, false,
+ return AggregateCall.create(e.getParserPosition(), SqlStdOperatorTable.COUNT, false, false,
false, ImmutableList.of(), ImmutableIntList.of(), -1, null,
RelCollations.EMPTY, type, null);
}
@@ -267,6 +269,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
Registry<RexNode> extra, int offset, RelDataType inputRowType,
AggregateCall aggregateCall, int leftSubTotal, int rightSubTotal) {
final List<RexNode> merges = new ArrayList<>();
+ final SqlParserPos pos = aggregateCall.getParserPosition();
final List<RelDataTypeField> fieldList = inputRowType.getFieldList();
if (leftSubTotal >= 0) {
final RelDataType type = fieldList.get(leftSubTotal).getType();
@@ -282,14 +285,14 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
node = merges.get(0);
break;
case 2:
- node = rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, merges);
- node = rexBuilder.makeAbstractCast(aggregateCall.type, node, false);
+ node = rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, merges);
+ node = rexBuilder.makeAbstractCast(pos, aggregateCall.type, node, false);
break;
default:
throw new AssertionError("unexpected count " + merges);
}
int ordinal = extra.register(node);
- return AggregateCall.create(getMergeAggFunctionOfTopSplit(), false, false,
+ return AggregateCall.create(pos, getMergeAggFunctionOfTopSplit(), false, false,
false, aggregateCall.rexList, ImmutableList.of(ordinal), -1,
aggregateCall.distinctKeys, aggregateCall.collation,
aggregateCall.type, aggregateCall.name);
@@ -300,7 +303,7 @@ public interface SqlSplittableAggFunction extends SqlSingletonAggFunction {
if (topKind == bottom.getAggregation().getKind()
&& (topKind == SqlKind.SUM
|| topKind == SqlKind.SUM0)) {
- return AggregateCall.create(bottom.getAggregation(),
+ return AggregateCall.create(top.getParserPosition(), bottom.getAggregation(),
bottom.isDistinct(), bottom.isApproximate(), false,
bottom.rexList, bottom.getArgList(), bottom.filterArg,
bottom.distinctKeys, bottom.getCollation(),
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/AggConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/AggConverter.java
index 56c3d027f0..6193c33df4 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/AggConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/AggConverter.java
@@ -539,6 +539,7 @@ class AggConverter implements SqlVisitor<Void> {
}
final AggregateCall aggCall =
AggregateCall.create(
+ call.getParserPosition(),
aggFunction,
distinct,
approximate,
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 1a63cf2d58..b78403a90b 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -1843,6 +1843,7 @@ public class RelDecorrelator implements ReflectiveVisitor {
}
newCall =
rexBuilder.makeCall(
+ call.getParserPosition(),
newType,
operator,
clonedOperands);
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
index 3f2a659a15..b1a7a230a7 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
@@ -700,8 +700,9 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
// NOTE jvs 10-Feb-2005: This is a lame hack to keep special
// functions which return row types working.
RexNode newExp = exp;
- List<RexNode> operands = ((RexCall) exp).getOperands();
- SqlOperator operator = ((RexCall) exp).getOperator();
+ RexCall expCall = (RexCall) exp;
+ List<RexNode> operands = expCall.getOperands();
+ SqlOperator operator = expCall.getOperator();
if (operator == SqlStdOperatorTable.ITEM
&& operands.get(0).getType().isStruct()
@@ -747,7 +748,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
}
} else {
newExp =
- rexBuilder.makeCall(exp.getType(), operator,
+ rexBuilder.makeCall(expCall.getParserPosition(), exp.getType(), operator,
shuttle.visitList(operands));
// flatten call result type
flattenResultTypeOfRexCall(newExp, fieldName, flattenedExps);
@@ -983,6 +984,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
RexNode input = rexCall.getOperands().get(0).accept(this);
RelDataType targetType = removeDistinct(rexCall.getType());
return rexBuilder.makeCast(
+ rexCall.getParserPosition(),
targetType,
input);
}
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 b4f572d04c..65067c3b3c 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -1311,10 +1311,10 @@ public class SqlToRelConverter {
ImmutableBitSet.of(),
null,
ImmutableList.of(
- AggregateCall.create(SqlStdOperatorTable.COUNT, false,
+ AggregateCall.create(call.getParserPosition(), SqlStdOperatorTable.COUNT, false,
false, false, ImmutableList.of(), ImmutableList.of(),
-1, null, RelCollations.EMPTY, longType, null),
- AggregateCall.create(SqlStdOperatorTable.COUNT, false,
+ AggregateCall.create(call.getParserPosition(), SqlStdOperatorTable.COUNT, false,
false, false, ImmutableList.of(), args,
-1, null, RelCollations.EMPTY, longType, null)));
LogicalJoin join =
@@ -2327,7 +2327,7 @@ public class SqlToRelConverter {
bb.window = window;
RexNode rexAgg = exprConverter.convertCall(bb, aggCall);
rexAgg =
- rexBuilder.ensureType(
+ rexBuilder.ensureType(call.getParserPosition(),
validator().getValidatedNodeType(call), rexAgg, false);
// Walk over the tree and apply 'over' to all agg functions. This is
@@ -2607,7 +2607,7 @@ public class SqlToRelConverter {
RexNode arg = requireNonNull(node.accept(this), node::toString);
newOperands.add(arg);
}
- return rexBuilder.makeCall(
+ return rexBuilder.makeCall(call.getParserPosition(),
validator().getUnknownType(), call.getOperator(), newOperands);
}
@@ -2657,15 +2657,16 @@ public class SqlToRelConverter {
final RexNode after;
if (afterMatch instanceof SqlCall) {
- List<SqlNode> operands = ((SqlCall) afterMatch).getOperandList();
- SqlOperator operator = ((SqlCall) afterMatch).getOperator();
+ final SqlCall afterCall = (SqlCall) afterMatch;
+ List<SqlNode> operands = afterCall.getOperandList();
+ SqlOperator operator = afterCall.getOperator();
assert operands.size() == 1;
SqlIdentifier id = (SqlIdentifier) operands.get(0);
assert patternVarsSet.contains(id.getSimple())
: id.getSimple() + " not defined in pattern";
RexNode rex = rexBuilder.makeLiteral(id.getSimple());
after =
- rexBuilder.makeCall(validator().getUnknownType(), operator,
+ rexBuilder.makeCall(afterCall.getParserPosition(), validator().getUnknownType(), operator,
ImmutableList.of(rex));
} else {
after = matchBb.convertExpression(afterMatch);
@@ -5733,7 +5734,8 @@ public class SqlToRelConverter {
}
requireNonNull(subQuery, "subQuery");
rex = requireNonNull(subQuery.expr);
- return StandardConvertletTable.castToValidatedType(expr, rex,
+ return StandardConvertletTable.castToValidatedType(
+ expr.getParserPosition(), expr, rex,
validator(), rexBuilder, false);
case SELECT:
@@ -6161,13 +6163,15 @@ public class SqlToRelConverter {
exprs.set(
0,
reinterpretCast
- ? rexBuilder.makeReinterpretCast(histogramType, exprs.get(0),
+ ? rexBuilder.makeReinterpretCast(
+ call.getParserPosition(), histogramType, exprs.get(0),
rexBuilder.makeLiteral(false))
- : rexBuilder.makeCast(histogramType, exprs.get(0)));
+ : rexBuilder.makeCast(call.getParserPosition(), histogramType, exprs.get(0)));
}
RexNode over =
- relBuilder.aggregateCall(SqlStdOperatorTable.HISTOGRAM_AGG, exprs)
+ relBuilder.aggregateCall(
+ call.getParserPosition(), SqlStdOperatorTable.HISTOGRAM_AGG, exprs)
.distinct(distinct)
.ignoreNulls(ignoreNulls)
.over()
@@ -6181,7 +6185,7 @@ public class SqlToRelConverter {
.toRex();
RexNode histogramCall =
- rexBuilder.makeCall(
+ rexBuilder.makeCall(call.getParserPosition(),
histogramType,
histogramOp,
ImmutableList.of(over));
@@ -6191,13 +6195,13 @@ public class SqlToRelConverter {
if (histogramType != type) {
if (reinterpretCast) {
histogramCall =
- rexBuilder.makeReinterpretCast(
+ rexBuilder.makeReinterpretCast(call.getParserPosition(),
type,
histogramCall,
rexBuilder.makeLiteral(false));
} else {
histogramCall =
- rexBuilder.makeCast(type, histogramCall);
+ rexBuilder.makeCast(call.getParserPosition(), type, histogramCall);
}
}
@@ -6205,7 +6209,7 @@ public class SqlToRelConverter {
} else {
boolean nullWhenCountZero = aggOp == SqlStdOperatorTable.SUM
&& type.isNullable();
- return relBuilder.aggregateCall(aggOp, exprs)
+ return relBuilder.aggregateCall(call.getParserPosition(), aggOp, exprs)
.distinct(distinct)
.ignoreNulls(ignoreNulls)
.over()
@@ -6614,7 +6618,8 @@ public class SqlToRelConverter {
builder.add(call.operands.get(i));
}
}
- return rexBuilder.makeCall(SqlStdOperatorTable.JSON_OBJECT, builder.build());
+ return rexBuilder.makeCall(
+ call.getParserPosition(), SqlStdOperatorTable.JSON_OBJECT, builder.build());
}
if (call.getOperator() == SqlStdOperatorTable.JSON_ARRAY) {
final ImmutableList.Builder<RexNode> builder = ImmutableList.builder();
@@ -6622,7 +6627,8 @@ public class SqlToRelConverter {
for (int i = 1; i < call.operands.size(); ++i) {
builder.add(forceChildJsonType(call.operands.get(i)));
}
- return rexBuilder.makeCall(SqlStdOperatorTable.JSON_ARRAY, builder.build());
+ return rexBuilder.makeCall(
+ call.getParserPosition(), SqlStdOperatorTable.JSON_ARRAY, builder.build());
}
return super.visitCall(call);
}
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index 8af3b87e40..216c34fd71 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -177,7 +177,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
(RexCall) StandardConvertletTable.this.convertCall(cx, call);
if (e.getOperands().size() == 1
&& SqlTypeUtil.isString(e.getOperands().get(0).getType())) {
- return cx.getRexBuilder().makeCast(e.type, e.getOperands().get(0));
+ return cx.getRexBuilder().makeCast(
+ e.getParserPosition(), e.type, e.getOperands().get(0));
}
return e;
});
@@ -403,7 +404,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
cx.getTypeFactory().createTypeWithNullability(
cx.getTypeFactory().createSqlType(SqlTypeName.BOOLEAN), right.getType().isNullable()
|| left.getType().isNullable() || rightComponentType.isNullable());
- return rexBuilder.makeCall(returnType, call.getOperator(), ImmutableList.of(left, right));
+ return rexBuilder.makeCall(call.getParserPosition(), returnType,
+ call.getOperator(), ImmutableList.of(left, right));
}
/** Converts a call to the {@code NVL} function (and also its synonym,
@@ -417,15 +419,15 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final RelDataType type =
cx.getValidator().getValidatedNodeType(call);
// Preserve Operand Nullability
- return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE,
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.CASE,
ImmutableList.of(
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
+ rexBuilder.makeCall(call.getParserPosition(), SqlStdOperatorTable.IS_NOT_NULL,
operand0),
- rexBuilder.makeCast(
+ rexBuilder.makeCast(call.getParserPosition(),
cx.getTypeFactory()
.createTypeWithNullability(type, operand0.getType().isNullable()),
operand0),
- rexBuilder.makeCast(
+ rexBuilder.makeCast(call.getParserPosition(),
cx.getTypeFactory()
.createTypeWithNullability(type, operand1.getType().isNullable()),
operand1)));
@@ -485,7 +487,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
throw new UnsupportedOperationException("Position does not accept "
+ call.operandCount() + " operands");
}
- return rexBuilder.makeCall(type, SqlStdOperatorTable.POSITION, exprs);
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.POSITION, exprs);
}
/** Converts a call to the DECODE function. */
@@ -507,7 +509,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
} else {
exprs.add(rexBuilder.makeNullLiteral(type));
}
- return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, exprs);
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.CASE, exprs);
}
/** Converts a call to the IF function.
@@ -519,7 +521,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
convertOperands(cx, call, SqlOperandTypeChecker.Consistency.NONE);
final RelDataType type =
cx.getValidator().getValidatedNodeType(call);
- return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, operands);
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.CASE, operands);
}
/** Converts an interval expression to a numeric multiplied by an interval
@@ -560,22 +562,22 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
return rexBuilder.makeCall(SqlStdOperatorTable.AND, a0, a1);
}
- private static RexNode divideInt(RexBuilder rexBuilder, RexNode a0,
+ private static RexNode divideInt(SqlParserPos pos, RexBuilder rexBuilder, RexNode a0,
RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE_INTEGER, a0, a1);
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.DIVIDE_INTEGER, a0, a1);
}
- private static RexNode plus(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.PLUS, a0, a1);
+ private static RexNode plus(SqlParserPos pos, RexBuilder rexBuilder, RexNode a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, a0, a1);
}
- private static RexNode minus(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.MINUS, a0, a1);
+ private static RexNode minus(SqlParserPos pos, RexBuilder rexBuilder, RexNode a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.MINUS, a0, a1);
}
- private static RexNode multiply(RexBuilder rexBuilder, RexNode a0,
+ private static RexNode multiply(SqlParserPos pos, RexBuilder rexBuilder, RexNode a0,
RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.MULTIPLY, a0, a1);
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.MULTIPLY, a0, a1);
}
private static RexNode case_(RexBuilder rexBuilder, RexNode... args) {
@@ -628,9 +630,10 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
rexBuilder.deriveReturnType(call.getOperator(), exprList);
for (int i : elseArgs(exprList.size())) {
exprList.set(i,
- rexBuilder.ensureType(type, exprList.get(i), false));
+ rexBuilder.ensureType(
+ call.getParserPosition(), type, exprList.get(i), false));
}
- return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, exprList);
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.CASE, exprList);
}
public RexNode convertMultiset(
@@ -662,7 +665,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// then '$SLICE(<ms>) has type 'INTEGER MULTISET'.
// This will be removed as the expression is translated.
expr =
- cx.getRexBuilder().makeCall(originalType, SqlStdOperatorTable.SLICE,
+ cx.getRexBuilder().makeCall(
+ call.getParserPosition(), originalType, SqlStdOperatorTable.SLICE,
ImmutableList.of(expr));
}
return expr;
@@ -744,8 +748,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
RexLiteral castedInterval =
rexBuilder.makeIntervalLiteral(sourceValue,
intervalQualifier);
- return castToValidatedType(call, castedInterval, validator, rexBuilder,
- safe);
+ return castToValidatedType(
+ call.getParserPosition(), call, castedInterval, validator, rexBuilder, safe);
} else if (left instanceof SqlNumericLiteral) {
RexLiteral sourceInterval =
(RexLiteral) cx.convertExpression(left);
@@ -757,11 +761,12 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
rexBuilder.makeIntervalLiteral(
SqlFunctions.multiply(sourceValue, multiplier),
intervalQualifier);
- return castToValidatedType(call, castedInterval, validator, rexBuilder,
- safe);
+ return castToValidatedType(
+ call.getParserPosition(), call, castedInterval, validator, rexBuilder, safe);
}
RexNode value = cx.convertExpression(left);
- return castToValidatedType(call, value, validator, rexBuilder, safe);
+ return castToValidatedType(
+ call.getParserPosition(), call, value, validator, rexBuilder, safe);
}
final SqlDataTypeSpec dataType = (SqlDataTypeSpec) right;
@@ -799,11 +804,12 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
type = typeFactory.createTypeWithNullability(type, isn);
}
}
- return rexBuilder.makeCast(type, arg, safe, safe, formatArg);
+ return rexBuilder.makeCast(call.getParserPosition(), type, arg, safe, safe, formatArg);
}
protected RexNode convertFloorCeil(SqlRexContext cx, SqlCall call) {
final boolean floor = call.getKind() == SqlKind.FLOOR;
+ final SqlParserPos pos = call.getParserPosition();
// Rewrite floor, ceil of interval
if (call.operandCount() == 1
&& call.operand(0) instanceof SqlIntervalLiteral) {
@@ -821,19 +827,19 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
RexNode pad =
rexBuilder.makeExactLiteral(val.subtract(BigDecimal.ONE));
RexNode cast =
- rexBuilder.makeReinterpretCast(rexInterval.getType(), pad,
+ rexBuilder.makeReinterpretCast(pos, rexInterval.getType(), pad,
rexBuilder.makeLiteral(false));
RexNode sum =
- floor ? minus(rexBuilder, rexInterval, cast)
- : plus(rexBuilder, rexInterval, cast);
+ floor ? minus(pos, rexBuilder, rexInterval, cast)
+ : plus(pos, rexBuilder, rexInterval, cast);
RexNode kase = floor
? case_(rexBuilder, rexInterval, cond, sum)
: case_(rexBuilder, sum, cond, rexInterval);
RexNode factor = rexBuilder.makeExactLiteral(val);
- RexNode div = divideInt(rexBuilder, kase, factor);
- return multiply(rexBuilder, div, factor);
+ RexNode div = divideInt(pos, rexBuilder, kase, factor);
+ return multiply(pos, rexBuilder, div, factor);
}
// normal floor, ceil function
@@ -843,11 +849,12 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
protected RexNode convertCharset(
@UnknownInitialization StandardConvertletTable this,
SqlRexContext cx, SqlCall call) {
+ final SqlParserPos pos = call.getParserPosition();
final SqlNode expr = call.operand(0);
final String srcCharset = call.operand(1).toString();
final String destCharset = call.operand(2).toString();
final RexBuilder rexBuilder = cx.getRexBuilder();
- return rexBuilder.makeCall(SqlStdOperatorTable.CONVERT,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.CONVERT,
cx.convertExpression(expr),
rexBuilder.makeLiteral(srcCharset),
rexBuilder.makeLiteral(destCharset));
@@ -856,10 +863,11 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
protected RexNode translateCharset(
@UnknownInitialization StandardConvertletTable this,
SqlRexContext cx, SqlCall call) {
+ final SqlParserPos pos = call.getParserPosition();
final SqlNode expr = call.operand(0);
final String transcodingName = call.operand(1).toString();
final RexBuilder rexBuilder = cx.getRexBuilder();
- return rexBuilder.makeCall(SqlStdOperatorTable.TRANSLATE,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.TRANSLATE,
cx.convertExpression(expr),
rexBuilder.makeLiteral(transcodingName));
}
@@ -877,16 +885,17 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
}
@SuppressWarnings("unused")
- private static RexNode mod(RexBuilder rexBuilder, RelDataType resType, RexNode res,
+ private static RexNode mod(SqlParserPos pos, RexBuilder rexBuilder,
+ RelDataType resType, RexNode res,
BigDecimal val) {
if (val.equals(BigDecimal.ONE)) {
return res;
}
- return rexBuilder.makeCall(SqlStdOperatorTable.MOD, res,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.MOD, res,
rexBuilder.makeExactLiteral(val, resType));
}
- private static RexNode divide(RexBuilder rexBuilder, RexNode res,
+ private static RexNode divide(SqlParserPos pos, RexBuilder rexBuilder, RexNode res,
BigDecimal val) {
if (val.equals(BigDecimal.ONE)) {
return res;
@@ -898,13 +907,13 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
try {
final BigDecimal reciprocal =
BigDecimal.ONE.divide(val, RoundingMode.UNNECESSARY);
- return multiply(rexBuilder, res,
+ return multiply(pos, rexBuilder, res,
rexBuilder.makeExactLiteral(reciprocal));
} catch (ArithmeticException e) {
// ignore - reciprocal is not an integer
}
}
- return divideInt(rexBuilder, res, rexBuilder.makeExactLiteral(val));
+ return divideInt(pos, rexBuilder, res, rexBuilder.makeExactLiteral(val));
}
public RexNode convertDatetimeMinus(
@@ -919,7 +928,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final RelDataType resType =
cx.getValidator().getValidatedNodeType(call);
- return rexBuilder.makeCall(resType, op, exprs.subList(0, 2));
+ return rexBuilder.makeCall(call.getParserPosition(), resType, op, exprs.subList(0, 2));
}
public RexNode convertFunction(
@@ -936,7 +945,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
if (returnType == null) {
returnType = cx.getRexBuilder().deriveReturnType(fun, exprs);
}
- return cx.getRexBuilder().makeCall(returnType, fun, exprs);
+ return cx.getRexBuilder().makeCall(call.getParserPosition(), returnType, fun, exprs);
}
public RexNode convertWindowFunction(
@@ -953,7 +962,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
if (returnType == null) {
returnType = cx.getRexBuilder().deriveReturnType(fun, exprs);
}
- return cx.getRexBuilder().makeCall(returnType, fun, exprs);
+ return cx.getRexBuilder().makeCall(call.getParserPosition(), returnType, fun, exprs);
}
public RexNode convertJsonValueFunction(
@@ -994,7 +1003,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
convertOperands(cx, call, operands, SqlOperandTypeChecker.Consistency.NONE);
RelDataType returnType = cx.getValidator().getValidatedNodeTypeIfKnown(call);
requireNonNull(returnType, () -> "Unable to get type of " + call);
- return cx.getRexBuilder().makeCall(returnType, fun, exprs);
+ return cx.getRexBuilder().makeCall(call.getParserPosition(), returnType, fun, exprs);
}
public RexNode convertSequenceValue(
@@ -1008,7 +1017,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final String key = Util.listToString(id.names);
RelDataType returnType =
cx.getValidator().getValidatedNodeType(call);
- return cx.getRexBuilder().makeCall(returnType, fun,
+ return cx.getRexBuilder().makeCall(call.getParserPosition(), returnType, fun,
ImmutableList.of(cx.getRexBuilder().makeLiteral(key)));
}
@@ -1035,7 +1044,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
};
returnType = fun.inferReturnType(binding);
}
- return cx.getRexBuilder().makeCall(returnType, fun, exprs);
+ return cx.getRexBuilder().makeCall(call.getParserPosition(), returnType, fun, exprs);
}
private static RexNode makeConstructorCall(
@@ -1109,7 +1118,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
}
}
RelDataType type = rexBuilder.deriveReturnType(op, exprs);
- return rexBuilder.makeCall(type, op, RexUtil.flatten(exprs, op));
+ return rexBuilder.makeCall(call.getParserPosition(), type, op, RexUtil.flatten(exprs, op));
}
/**
@@ -1146,11 +1155,11 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final RexCall call1 = (RexCall) expr1;
final List<RexNode> eqList = new ArrayList<>();
Pair.forEach(call0.getOperands(), call1.getOperands(), (x, y) ->
- eqList.add(rexBuilder.makeCall(op, x, y)));
+ eqList.add(rexBuilder.makeCall(call.getParserPosition(), op, x, y)));
return RexUtil.composeConjunction(rexBuilder, eqList);
}
}
- return rexBuilder.makeCall(type, op, RexUtil.flatten(exprs, op));
+ return rexBuilder.makeCall(call.getParserPosition(), type, op, RexUtil.flatten(exprs, op));
}
private static List<Integer> elseArgs(int count) {
@@ -1196,7 +1205,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final List<RexNode> oldExprs = new ArrayList<>(exprs);
exprs.clear();
Pair.forEach(oldExprs, operandTypes, (expr, type) ->
- exprs.add(cx.getRexBuilder().ensureType(type, expr, true)));
+ exprs.add(cx.getRexBuilder().ensureType(call.getParserPosition(), type, expr, true)));
}
if (exprs.size() > 1) {
final RelDataType type =
@@ -1205,7 +1214,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final List<RexNode> oldExprs = new ArrayList<>(exprs);
exprs.clear();
for (RexNode expr : oldExprs) {
- exprs.add(cx.getRexBuilder().ensureType(type, expr, true));
+ exprs.add(cx.getRexBuilder().ensureType(call.getParserPosition(), type, expr, true));
}
}
}
@@ -1289,7 +1298,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
break;
}
}
- return rexBuilder.makeCall(rex.getType(),
+ return rexBuilder.makeCall(call.getParserPosition(), rex.getType(),
SqlStdOperatorTable.DATETIME_PLUS, operands);
default:
return rex;
@@ -1351,7 +1360,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final SqlBetweenOperator betweenOp =
(SqlBetweenOperator) call.getOperator();
if (betweenOp.isNegated()) {
- res = rexBuilder.makeCall(SqlStdOperatorTable.NOT, res);
+ res = rexBuilder.makeCall(call.getParserPosition(), SqlStdOperatorTable.NOT, res);
}
return res;
}
@@ -1424,7 +1433,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
}
final RelDataType type =
rexBuilder.deriveReturnType(SqlStdOperatorTable.COLUMN_LIST, columns);
- return rexBuilder.makeCall(type, SqlStdOperatorTable.COLUMN_LIST, columns);
+ return rexBuilder.makeCall(
+ call.getParserPosition(), type, SqlStdOperatorTable.COLUMN_LIST, columns);
}
/**
@@ -1516,14 +1526,14 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
SqlRexContext cx,
SqlCall call,
RexNode value) {
- return castToValidatedType(call, value, cx.getValidator(),
+ return castToValidatedType(call.getParserPosition(), call, value, cx.getValidator(),
cx.getRexBuilder(), false);
}
@Deprecated // to be removed before 2.0
public static RexNode castToValidatedType(SqlNode node, RexNode e,
SqlValidator validator, RexBuilder rexBuilder) {
- return castToValidatedType(node, e, validator, rexBuilder, false);
+ return castToValidatedType(node.getParserPosition(), node, e, validator, rexBuilder, false);
}
/**
@@ -1531,13 +1541,13 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
* was already of the validated type, then the value is returned without an
* additional cast.
*/
- public static RexNode castToValidatedType(SqlNode node, RexNode e,
+ public static RexNode castToValidatedType(SqlParserPos pos, SqlNode node, RexNode e,
SqlValidator validator, RexBuilder rexBuilder, boolean safe) {
final RelDataType type = validator.getValidatedNodeType(node);
if (e.getType() == type) {
return e;
}
- return rexBuilder.makeCast(type, e, safe, safe);
+ return rexBuilder.makeCast(pos, type, e, safe, safe);
}
/** Convertlet that handles {@code COVAR_POP}, {@code COVAR_SAMP},
@@ -1574,7 +1584,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
throw Util.unexpected(kind);
}
RexNode rex = cx.convertExpression(expr);
- return cx.getRexBuilder().ensureType(type, rex, true);
+ return cx.getRexBuilder().ensureType(call.getParserPosition(), type, rex, true);
}
private static SqlNode expandRegrSzz(
@@ -1706,7 +1716,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
throw Util.unexpected(kind);
}
RexNode rex = cx.convertExpression(expr);
- return cx.getRexBuilder().ensureType(type, rex, true);
+ return cx.getRexBuilder().ensureType(call.getParserPosition(), type, rex, true);
}
private static SqlNode expandAvg(
@@ -1856,7 +1866,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final RexBuilder rexBuilder = cx.getRexBuilder();
final RexNode operand =
cx.convertExpression(call.getOperandList().get(0));
- return rexBuilder.makeCall(SqlStdOperatorTable.TRIM,
+ return rexBuilder.makeCall(call.getParserPosition(), SqlStdOperatorTable.TRIM,
rexBuilder.makeFlag(flag), rexBuilder.makeLiteral(" "), operand);
}
}
@@ -1897,7 +1907,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final List<RexNode> list = new ArrayList<>();
final List<RexNode> orList = new ArrayList<>();
for (RexNode expr : exprs) {
- orList.add(rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, expr));
+ orList.add(
+ rexBuilder.makeCall(call.getParserPosition(), SqlStdOperatorTable.IS_NULL, expr));
}
list.add(RexUtil.composeDisjunction(rexBuilder, orList));
list.add(rexBuilder.makeNullLiteral(type));
@@ -1906,13 +1917,13 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final List<RexNode> andList = new ArrayList<>();
for (int j = i + 1; j < exprs.size(); j++) {
final RexNode expr2 = exprs.get(j);
- andList.add(rexBuilder.makeCall(op, expr, expr2));
+ andList.add(rexBuilder.makeCall(call.getParserPosition(), op, expr, expr2));
}
list.add(RexUtil.composeConjunction(rexBuilder, andList));
list.add(expr);
}
list.add(exprs.get(exprs.size() - 1));
- return rexBuilder.makeCall(type, SqlStdOperatorTable.CASE, list);
+ return rexBuilder.makeCall(call.getParserPosition(), type, SqlStdOperatorTable.CASE, list);
}
}
@@ -2040,6 +2051,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// FOR CASE WHEN length < 0 THEN 0 ELSE length END)
final RexBuilder rexBuilder = cx.getRexBuilder();
+ final SqlParserPos pos = call.getParserPosition();
final List<RexNode> exprs =
convertOperands(cx, call, SqlOperandTypeChecker.Consistency.NONE);
final RexNode value = exprs.get(0);
@@ -2049,10 +2061,10 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final RexLiteral oneLiteral = rexBuilder.makeLiteral(1, startType);
final RexNode valueLength =
SqlTypeUtil.isBinary(value.getType())
- ? rexBuilder.makeCall(SqlStdOperatorTable.OCTET_LENGTH, value)
- : rexBuilder.makeCall(SqlStdOperatorTable.CHAR_LENGTH, value);
+ ? rexBuilder.makeCall(pos, SqlStdOperatorTable.OCTET_LENGTH, value)
+ : rexBuilder.makeCall(pos, SqlStdOperatorTable.CHAR_LENGTH, value);
final RexNode valueLengthPlusOne =
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, valueLength,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, valueLength,
oneLiteral);
final RexNode newStart;
@@ -2060,8 +2072,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
case POSTGRESQL:
if (call.operandCount() == 2) {
newStart =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN, start,
oneLiteral),
oneLiteral, start);
} else {
@@ -2070,37 +2082,37 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
break;
case BIG_QUERY:
newStart =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS, start,
zeroLiteral),
oneLiteral,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN, start,
zeroLiteral),
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, start,
valueLengthPlusOne),
start);
break;
default:
newStart =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS, start,
zeroLiteral),
library == SqlLibrary.MYSQL ? valueLengthPlusOne : oneLiteral,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN,
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, start,
valueLengthPlusOne),
oneLiteral),
valueLengthPlusOne,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN, start,
zeroLiteral),
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, start,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, start,
valueLengthPlusOne),
start);
break;
}
if (call.operandCount() == 2) {
- return rexBuilder.makeCall(SqlStdOperatorTable.SUBSTRING, value,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.SUBSTRING, value,
newStart);
}
@@ -2113,19 +2125,19 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
break;
default:
newLength =
- rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, length,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN, length,
zeroLiteral),
zeroLiteral, length);
}
final RexNode substringCall =
- rexBuilder.makeCall(SqlStdOperatorTable.SUBSTRING, value, newStart,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.SUBSTRING, value, newStart,
newLength);
switch (library) {
case BIG_QUERY:
- return rexBuilder.makeCall(SqlStdOperatorTable.CASE,
- rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN,
- rexBuilder.makeCall(SqlStdOperatorTable.PLUS, start,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.CASE,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN,
+ rexBuilder.makeCall(pos, SqlStdOperatorTable.PLUS, start,
valueLengthPlusOne), oneLiteral),
value, substringCall);
default:
@@ -2144,6 +2156,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// => timestamp + interval
// "timestamp" may be of type TIMESTAMP or TIMESTAMP WITH LOCAL TIME ZONE.
final RexBuilder rexBuilder = cx.getRexBuilder();
+ final SqlParserPos pos = call.getParserPosition();
SqlIntervalQualifier qualifier;
final RexNode op1;
final RexNode op2;
@@ -2204,8 +2217,8 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// If the TIMESTAMPADD call has type TIMESTAMP and op2 has type DATE
// (which can happen for sub-day time frames such as HOUR), cast op2 to
// TIMESTAMP.
- final RexNode op2b = rexBuilder.makeCast(type, op2);
- return rexBuilder.makeCall(type, SqlStdOperatorTable.TIMESTAMP_ADD,
+ final RexNode op2b = rexBuilder.makeCast(pos, type, op2);
+ return rexBuilder.makeCall(pos, type, SqlStdOperatorTable.TIMESTAMP_ADD,
ImmutableList.of(timeFrameName, op1, op2b));
}
@@ -2220,19 +2233,19 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
case MICROSECOND:
case NANOSECOND:
interval2Add =
- divide(rexBuilder,
- multiply(rexBuilder,
+ divide(pos, rexBuilder,
+ multiply(pos, rexBuilder,
rexBuilder.makeIntervalLiteral(BigDecimal.ONE, qualifier), op1),
BigDecimal.ONE.divide(unit.multiplier,
RoundingMode.UNNECESSARY));
break;
default:
interval2Add =
- multiply(rexBuilder,
+ multiply(pos, rexBuilder,
rexBuilder.makeIntervalLiteral(unit.multiplier, qualifier), op1);
}
- return rexBuilder.makeCall(SqlStdOperatorTable.DATETIME_PLUS,
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.DATETIME_PLUS,
op2, interval2Add);
}
}
@@ -2243,13 +2256,14 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
private static class TruncConvertlet implements SqlRexConvertlet {
@Override public RexNode convertCall(SqlRexContext cx, SqlCall call) {
final RexBuilder rexBuilder = cx.getRexBuilder();
+ final SqlParserPos pos = call.getParserPosition();
RexNode op1 = cx.convertExpression(call.operand(0));
RexNode op2 = cx.convertExpression(call.operand(1));
if (op1.getType().getSqlTypeName() == SqlTypeName.DATE) {
RelDataType type = cx.getValidator().getValidatedNodeType(call);
- op1 = cx.getRexBuilder().makeCast(type, op1);
+ op1 = cx.getRexBuilder().makeCast(pos, type, op1);
}
- return rexBuilder.makeCall(call.getOperator(), op1, op2);
+ return rexBuilder.makeCall(pos, call.getOperator(), op1, op2);
}
}
@@ -2259,6 +2273,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// TIMESTAMP_SUB(timestamp, interval)
// => timestamp - count * INTERVAL '1' UNIT
final RexBuilder rexBuilder = cx.getRexBuilder();
+ final SqlParserPos pos = call.getParserPosition();
final SqlBasicCall operandCall = call.operand(1);
SqlIntervalQualifier qualifier = operandCall.operand(1);
final RexNode op1 = cx.convertExpression(operandCall.operand(0));
@@ -2272,19 +2287,19 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
case MICROSECOND:
case NANOSECOND:
interval2Sub =
- divide(rexBuilder,
- multiply(rexBuilder,
+ divide(pos, rexBuilder,
+ multiply(pos, rexBuilder,
rexBuilder.makeIntervalLiteral(BigDecimal.ONE, qualifier), op1),
BigDecimal.ONE.divide(unit.multiplier,
RoundingMode.UNNECESSARY));
break;
default:
interval2Sub =
- multiply(rexBuilder,
+ multiply(pos, rexBuilder,
rexBuilder.makeIntervalLiteral(unit.multiplier, qualifier), op1);
}
- return rexBuilder.makeCall(SqlInternalOperators.MINUS_DATE2,
+ return rexBuilder.makeCall(pos, SqlInternalOperators.MINUS_DATE2,
op2, interval2Sub);
}
}
@@ -2316,6 +2331,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final boolean preTruncate;
final RexNode op1;
final RexNode op2;
+ final SqlParserPos pos = call.getParserPosition();
if (call.operand(0).getKind() == SqlKind.INTERVAL_QUALIFIER) {
qualifier = call.operand(0);
preTruncate = false;
@@ -2342,11 +2358,11 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// computing the difference.
if (preTruncate) {
truncateFn = e ->
- rexBuilder.makeCall(e.getType(),
+ rexBuilder.makeCall(pos, e.getType(),
SqlLibraryOperators.TIMESTAMP_TRUNC,
ImmutableList.of(e, timeFrameName));
}
- return rexBuilder.makeCall(cx.getValidator().getValidatedNodeType(call),
+ return rexBuilder.makeCall(pos, cx.getValidator().getValidatedNodeType(call),
SqlStdOperatorTable.TIMESTAMP_DIFF,
ImmutableList.of(timeFrameName, truncateFn.apply(op1),
truncateFn.apply(op2)));
@@ -2358,7 +2374,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
// should be returned.
final RexNode timeUnit = cx.convertExpression(qualifier);
truncateFn = e ->
- rexBuilder.makeCall(e.getType(),
+ rexBuilder.makeCall(call.getParserPosition(), e.getType(),
SqlLibraryOperators.TIMESTAMP_TRUNC,
ImmutableList.of(e, timeUnit));
}
@@ -2399,15 +2415,15 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
typeFactory.createSqlIntervalType(qualifier),
op1.getType().isNullable() || op2.getType().isNullable());
final RexNode call2 =
- rexBuilder.makeCall(intervalType,
+ rexBuilder.makeCall(pos, intervalType,
SqlStdOperatorTable.MINUS_DATE,
ImmutableList.of(truncateFn.apply(op2), truncateFn.apply(op1)));
final RelDataType intType =
typeFactory.createTypeWithNullability(
typeFactory.createSqlType(sqlTypeName),
SqlTypeUtil.containsNullable(call2.getType()));
- RexNode e = rexBuilder.makeCast(intType, call2);
- return rexBuilder.multiplyDivide(e, multiplier, divider);
+ RexNode e = rexBuilder.makeCast(pos, intType, call2);
+ return rexBuilder.multiplyDivide(pos, e, multiplier, divider);
}
}
}
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 583052659b..86472f9d22 100644
--- a/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
+++ b/core/src/main/java/org/apache/calcite/tools/RelBuilder.java
@@ -102,6 +102,7 @@ import org.apache.calcite.sql.fun.SqlInternalOperators;
import org.apache.calcite.sql.fun.SqlLikeOperator;
import org.apache.calcite.sql.fun.SqlQuantifyOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.type.SqlReturnTypeInference;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.TableFunctionReturnTypeInference;
@@ -736,7 +737,7 @@ public class RelBuilder {
}
/** Creates a call to a scalar operator. */
- private RexCall call(SqlOperator operator, List<RexNode> operandList) {
+ private RexCall call(SqlParserPos pos, SqlOperator operator, List<RexNode> operandList) {
switch (operator.getKind()) {
case LIKE:
case SIMILAR:
@@ -755,13 +756,13 @@ public class RelBuilder {
}
final RexBuilder builder = cluster.getRexBuilder();
final RelDataType type = builder.deriveReturnType(operator, operandList);
- return (RexCall) builder.makeCall(type, operator, operandList);
+ return (RexCall) builder.makeCall(pos, type, operator, operandList);
}
/** Creates a call to a scalar operator. */
public RexNode call(SqlOperator operator,
Iterable<? extends RexNode> operands) {
- return call(operator, ImmutableList.copyOf(operands));
+ return call(SqlParserPos.ZERO, operator, ImmutableList.copyOf(operands));
}
/** Creates an IN predicate with a list of values.
@@ -1164,25 +1165,43 @@ public class RelBuilder {
/** Creates an expression that casts an expression to a given type. */
public RexNode cast(RexNode expr, SqlTypeName typeName) {
+ return cast(SqlParserPos.ZERO, expr, typeName);
+ }
+
+ /** Creates an expression that casts an expression to a given type. */
+ public RexNode cast(SqlParserPos pos, RexNode expr, SqlTypeName typeName) {
final RelDataType type = cluster.getTypeFactory().createSqlType(typeName);
- return cluster.getRexBuilder().makeCast(type, expr);
+ return cluster.getRexBuilder().makeCast(pos, type, expr);
}
/** Creates an expression that casts an expression to a type with a given name
* and precision or length. */
public RexNode cast(RexNode expr, SqlTypeName typeName, int precision) {
+ return cast(SqlParserPos.ZERO, expr, typeName, precision);
+ }
+
+ /** Creates an expression that casts an expression to a type with a given name
+ * and precision or length. */
+ public RexNode cast(SqlParserPos pos, RexNode expr, SqlTypeName typeName, int precision) {
final RelDataType type =
cluster.getTypeFactory().createSqlType(typeName, precision);
- return cluster.getRexBuilder().makeCast(type, expr);
+ return cluster.getRexBuilder().makeCast(pos, type, expr);
}
/** Creates an expression that casts an expression to a type with a given
* name, precision and scale. */
public RexNode cast(RexNode expr, SqlTypeName typeName, int precision,
int scale) {
+ return cast(SqlParserPos.ZERO, expr, typeName, precision, scale);
+ }
+
+ /** Creates an expression that casts an expression to a type with a given
+ * name, precision and scale. */
+ public RexNode cast(SqlParserPos pos, RexNode expr, SqlTypeName typeName, int precision,
+ int scale) {
final RelDataType type =
cluster.getTypeFactory().createSqlType(typeName, precision, scale);
- return cluster.getRexBuilder().makeCast(type, expr);
+ return cluster.getRexBuilder().makeCast(pos, type, expr);
}
/**
@@ -1429,6 +1448,36 @@ public class RelBuilder {
ImmutableList.copyOf(operands));
}
+ /** Creates a call to an aggregate function.
+ *
+ * <p>To add other operands, apply
+ * {@link AggCall#distinct()},
+ * {@link AggCall#approximate(boolean)},
+ * {@link AggCall#filter(RexNode...)},
+ * {@link AggCall#sort},
+ * {@link AggCall#as} to the result. */
+ public AggCall aggregateCall(SqlParserPos pos, SqlAggFunction aggFunction,
+ Iterable<? extends RexNode> operands) {
+ return aggregateCall(pos, aggFunction, false, false, false, null, null,
+ ImmutableList.of(), null, ImmutableList.of(),
+ ImmutableList.copyOf(operands));
+ }
+
+ /** Creates a call to an aggregate function.
+ *
+ * <p>To add other operands, apply
+ * {@link AggCall#distinct()},
+ * {@link AggCall#approximate(boolean)},
+ * {@link AggCall#filter(RexNode...)},
+ * {@link AggCall#sort},
+ * {@link AggCall#as} to the result. */
+ public AggCall aggregateCall(SqlParserPos pos, SqlAggFunction aggFunction,
+ RexNode... operands) {
+ return aggregateCall(pos, aggFunction, false, false, false, null, null,
+ ImmutableList.of(), null, ImmutableList.of(),
+ ImmutableList.copyOf(operands));
+ }
+
/** Creates a call to an aggregate function.
*
* <p>To add other operands, apply
@@ -1447,7 +1496,8 @@ public class RelBuilder {
/** Creates a call to an aggregate function as a copy of an
* {@link AggregateCall}. */
public AggCall aggregateCall(AggregateCall a) {
- return aggregateCall(a.getAggregation(), a.isDistinct(), a.isApproximate(),
+ return aggregateCall(a.getParserPosition(),
+ 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, ImmutableList.copyOf(a.rexList),
@@ -1457,7 +1507,8 @@ public class RelBuilder {
/** Creates a call to an aggregate function as a copy of an
* {@link AggregateCall}, applying a mapping. */
public AggCall aggregateCall(AggregateCall a, Mapping mapping) {
- return aggregateCall(a.getAggregation(), a.isDistinct(), a.isApproximate(),
+ return aggregateCall(a.getParserPosition(),
+ a.getAggregation(), a.isDistinct(), a.isApproximate(),
a.ignoreNulls(),
a.filterArg < 0 ? null : field(Mappings.apply(mapping, a.filterArg)),
a.distinctKeys == null ? null
@@ -1473,7 +1524,17 @@ public class RelBuilder {
@Nullable ImmutableList<RexNode> distinctKeys,
ImmutableList<RexNode> orderKeys, @Nullable String alias,
ImmutableList<RexNode> preOperands, ImmutableList<RexNode> operands) {
- return new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ return new AggCallImpl(SqlParserPos.ZERO, aggFunction, distinct, approximate, ignoreNulls,
+ filter, alias, preOperands, operands, distinctKeys, orderKeys);
+ }
+
+ /** Creates a call to an aggregate function with all applicable operands. */
+ protected AggCall aggregateCall(SqlParserPos pos, SqlAggFunction aggFunction, boolean distinct,
+ boolean approximate, boolean ignoreNulls, @Nullable RexNode filter,
+ @Nullable ImmutableList<RexNode> distinctKeys,
+ ImmutableList<RexNode> orderKeys, @Nullable String alias,
+ ImmutableList<RexNode> preOperands, ImmutableList<RexNode> operands) {
+ return new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeys, orderKeys);
}
@@ -1515,6 +1576,11 @@ public class RelBuilder {
return sum(false, null, operand);
}
+ /** Creates a call to the {@code SUM} aggregate function. */
+ public AggCall sum(SqlParserPos pos, RexNode operand) {
+ return sum(pos, false, null, operand);
+ }
+
/** Creates a call to the {@code SUM} aggregate function,
* optionally distinct and with an alias. */
public AggCall sum(boolean distinct, @Nullable String alias,
@@ -1524,16 +1590,39 @@ public class RelBuilder {
ImmutableList.of(operand));
}
+ /** Creates a call to the {@code SUM} aggregate function,
+ * optionally distinct and with an alias. */
+ public AggCall sum(SqlParserPos pos, boolean distinct, @Nullable String alias,
+ RexNode operand) {
+ return aggregateCall(pos, SqlStdOperatorTable.SUM, distinct, false, false, null,
+ null, ImmutableList.of(), alias, ImmutableList.of(),
+ ImmutableList.of(operand));
+ }
+
/** Creates a call to the {@code AVG} aggregate function. */
public AggCall avg(RexNode operand) {
return avg(false, null, operand);
}
+ /** Creates a call to the {@code AVG} aggregate function. */
+ public AggCall avg(SqlParserPos pos, RexNode operand) {
+ return avg(pos, false, null, operand);
+ }
+
/** 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) {
- return aggregateCall(SqlStdOperatorTable.AVG, distinct, false, false, null,
+ return aggregateCall(SqlParserPos.ZERO, SqlStdOperatorTable.AVG, distinct, false, false, null,
+ null, ImmutableList.of(), alias, ImmutableList.of(),
+ ImmutableList.of(operand));
+ }
+
+ /** Creates a call to the {@code AVG} aggregate function,
+ * optionally distinct and with an alias. */
+ public AggCall avg(SqlParserPos pos, boolean distinct, @Nullable String alias,
+ RexNode operand) {
+ return aggregateCall(pos, SqlStdOperatorTable.AVG, distinct, false, false, null,
null, ImmutableList.of(), alias, ImmutableList.of(),
ImmutableList.of(operand));
}
@@ -1766,7 +1855,7 @@ public class RelBuilder {
inputs.add(0, build());
}
- final RexCall call = call(operator, ImmutableList.copyOf(operands));
+ final RexCall call = call(SqlParserPos.ZERO, operator, ImmutableList.copyOf(operands));
final RelNode functionScan =
struct.tableFunctionScanFactory.createTableFunctionScan(cluster,
inputs, call, null, getColumnMappings(operator));
@@ -4055,6 +4144,8 @@ public class RelBuilder {
*
* @see RelBuilder#aggregateCall */
public interface AggCall {
+ SqlParserPos getPosition();
+
/** Returns a copy of this AggCall that applies a filter before aggregating
* values. */
AggCall filter(@Nullable RexNode condition);
@@ -4223,6 +4314,7 @@ public class RelBuilder {
/** Implementation of {@link AggCall}. */
private class AggCallImpl implements AggCallPlus {
+ private final SqlParserPos pos;
private final SqlAggFunction aggFunction;
private final boolean distinct;
private final boolean approximate;
@@ -4234,12 +4326,13 @@ public class RelBuilder {
private final @Nullable ImmutableList<RexNode> distinctKeys; // may be empty or null
private final ImmutableList<RexNode> orderKeys; // may be empty
- AggCallImpl(SqlAggFunction aggFunction, boolean distinct,
+ AggCallImpl(SqlParserPos pos, SqlAggFunction aggFunction, boolean distinct,
boolean approximate, boolean ignoreNulls, @Nullable RexNode filter,
@Nullable String alias, ImmutableList<RexNode> preOperands,
ImmutableList<RexNode> operands,
@Nullable ImmutableList<RexNode> distinctKeys,
ImmutableList<RexNode> orderKeys) {
+ this.pos = pos;
this.aggFunction = requireNonNull(aggFunction, "aggFunction");
// If the aggregate function ignores DISTINCT,
// make the DISTINCT flag FALSE.
@@ -4263,6 +4356,10 @@ public class RelBuilder {
this.filter = filter;
}
+ @Override public SqlParserPos getPosition() {
+ return pos;
+ }
+
@Override public String toString() {
final StringBuilder b = new StringBuilder();
b.append(aggFunction.getName())
@@ -4310,7 +4407,7 @@ public class RelBuilder {
final RelCollation collation = RelCollations.EMPTY;
final RelDataType type =
getTypeFactory().createSqlType(SqlTypeName.BOOLEAN);
- return AggregateCall.create(aggFunction, distinct, approximate,
+ return AggregateCall.create(pos, aggFunction, distinct, approximate,
ignoreNulls, preOperands, ImmutableList.of(), -1,
null, collation, type, alias);
}
@@ -4346,7 +4443,7 @@ public class RelBuilder {
.collect(toImmutableList());
}
- return AggregateCall.create(aggFunction, distinct, approximate,
+ return AggregateCall.create(pos, aggFunction, distinct, approximate,
ignoreNulls, preOperands, args, filterArg, distinctKeys,
collation, groupSet.cardinality(), r, null, alias);
}
@@ -4368,7 +4465,7 @@ public class RelBuilder {
ImmutableList.copyOf(preOperands);
return preOperandList.equals(this.preOperands)
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperandList, operands, distinctKeys, orderKeys);
}
@@ -4382,7 +4479,7 @@ public class RelBuilder {
ImmutableList.copyOf(orderKeys);
return orderKeyList.equals(this.orderKeys)
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeys, orderKeyList);
}
@@ -4395,42 +4492,42 @@ public class RelBuilder {
distinctKeys == null ? null : ImmutableList.copyOf(distinctKeys);
return Objects.equals(distinctKeyList, this.distinctKeys)
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeyList, orderKeys);
}
@Override public AggCall approximate(boolean approximate) {
return approximate == this.approximate
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
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,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
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,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeys, orderKeys);
}
@Override public AggCall distinct(boolean distinct) {
return distinct == this.distinct
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeys, orderKeys);
}
@Override public AggCall ignoreNulls(boolean ignoreNulls) {
return ignoreNulls == this.ignoreNulls
? this
- : new AggCallImpl(aggFunction, distinct, approximate, ignoreNulls,
+ : new AggCallImpl(pos, aggFunction, distinct, approximate, ignoreNulls,
filter, alias, preOperands, operands, distinctKeys, orderKeys);
}
}
@@ -4452,6 +4549,10 @@ public class RelBuilder {
aggregateCall.name);
}
+ @Override public SqlParserPos getPosition() {
+ return this.aggregateCall.getParserPosition();
+ }
+
@Override public String toString() {
return aggregateCall.toString();
}
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 c53b822b21..06cb1c5de9 100644
--- a/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java
+++ b/core/src/test/java/org/apache/calcite/materialize/NormalizationTrimFieldTest.java
@@ -84,7 +84,7 @@ public class NormalizationTrimFieldTest extends SqlToRelTestBase {
final ImmutableBitSet groupSet = ImmutableBitSet.of(4);
final AggregateCall count = aggregate.getAggCallList().get(0);
final AggregateCall call =
- AggregateCall.create(count.getAggregation(),
+ AggregateCall.create(count.getParserPosition(), count.getAggregation(),
count.isDistinct(), count.isApproximate(),
count.ignoreNulls(), count.rexList, ImmutableList.of(3),
count.filterArg, null, count.collation,
diff --git a/core/src/test/java/org/apache/calcite/test/fuzzer/RexShrinker.java b/core/src/test/java/org/apache/calcite/test/fuzzer/RexShrinker.java
index 9cf470fdd1..84272d0de6 100644
--- a/core/src/test/java/org/apache/calcite/test/fuzzer/RexShrinker.java
+++ b/core/src/test/java/org/apache/calcite/test/fuzzer/RexShrinker.java
@@ -76,7 +76,7 @@ public class RexShrinker extends RexShuttle {
if (res != null) {
didWork = true;
if (!res.getType().equals(type)) {
- return rexBuilder.makeCast(type, res);
+ return rexBuilder.makeCast(call.getParserPosition(), type, res);
}
return res;
}