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 541bae86cc Carry source position information through more code rewrites
541bae86cc is described below
commit 541bae86cc49784d085ec6c8cae4e406f0673373
Author: Mihai Budiu <[email protected]>
AuthorDate: Wed Dec 3 14:27:15 2025 -0800
Carry source position information through more code rewrites
Signed-off-by: Mihai Budiu <[email protected]>
---
.../java/org/apache/calcite/rex/RexSimplify.java | 45 ++++----
.../main/java/org/apache/calcite/rex/RexUtil.java | 11 +-
.../calcite/sql2rel/StandardConvertletTable.java | 120 +++++++++++----------
3 files changed, 97 insertions(+), 79 deletions(-)
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 bb7ccf7050..7065c25c5c 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -358,7 +358,7 @@ RexNode isNotFalse(RexNode e) {
? isNotTrue(((RexCall) e).operands.get(0))
: predicates.isEffectivelyNotNull(e)
? e // would "CAST(e AS BOOLEAN NOT NULL)" better?
- : rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_FALSE, e);
+ : rexBuilder.makeCall(RexUtil.getPos(e),
SqlStdOperatorTable.IS_NOT_FALSE, e);
}
/** Applies IS NOT TRUE to an expression. */
@@ -371,7 +371,7 @@ RexNode isNotTrue(RexNode e) {
? isNotFalse(((RexCall) e).operands.get(0))
: predicates.isEffectivelyNotNull(e)
? not(e)
- : rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_TRUE, e);
+ : rexBuilder.makeCall(RexUtil.getPos(e),
SqlStdOperatorTable.IS_NOT_TRUE, e);
}
/** Applies IS TRUE to an expression. */
@@ -384,7 +384,7 @@ RexNode isTrue(RexNode e) {
? isFalse(((RexCall) e).operands.get(0))
: predicates.isEffectivelyNotNull(e)
? e // would "CAST(e AS BOOLEAN NOT NULL)" better?
- : rexBuilder.makeCall(SqlStdOperatorTable.IS_TRUE, e);
+ : rexBuilder.makeCall(RexUtil.getPos(e), SqlStdOperatorTable.IS_TRUE,
e);
}
/** Applies IS FALSE to an expression. */
@@ -397,7 +397,7 @@ RexNode isFalse(RexNode e) {
? isTrue(((RexCall) e).operands.get(0))
: predicates.isEffectivelyNotNull(e)
? not(e)
- : rexBuilder.makeCall(SqlStdOperatorTable.IS_FALSE, e);
+ : rexBuilder.makeCall(RexUtil.getPos(e), SqlStdOperatorTable.IS_FALSE,
e);
}
/**
@@ -1131,13 +1131,13 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
// because of null values.
final SqlOperator notKind = RexUtil.op(kind.negateNullSafe());
final RexNode arg = ((RexCall) a).operands.get(0);
- return simplify(rexBuilder.makeCall(notKind, arg), UNKNOWN);
+ return simplify(rexBuilder.makeCall(RexUtil.getPos(a), notKind, arg),
UNKNOWN);
default:
break;
}
final RexNode a2 = simplify(a, UNKNOWN);
if (a != a2) {
- return rexBuilder.makeCall(RexUtil.op(kind), ImmutableList.of(a2));
+ return rexBuilder.makeCall(RexUtil.getPos(a), RexUtil.op(kind),
ImmutableList.of(a2));
}
return null; // cannot be simplified
}
@@ -1154,11 +1154,12 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
return rexBuilder.makeLiteral(true);
}
RexNode simplifiedResult = null;
+ SqlParserPos pos = RexUtil.getPos(a);
if (RexUtil.isLosslessCast(a)) {
a = RexUtil.removeCast(a);
// to keep this simplification, we must return IS NOT NULL(a),
// even if we cannot do anything else
- simplifiedResult = rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
a);
+ simplifiedResult = rexBuilder.makeCall(pos,
SqlStdOperatorTable.IS_NOT_NULL, a);
}
if (predicates.pulledUpPredicates.contains(a)) {
return rexBuilder.makeLiteral(true);
@@ -1180,7 +1181,7 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
final RexNode simplified = simplifyIsNotNull(operand);
if (simplified == null) {
operands.add(
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, operand));
+ rexBuilder.makeCall(RexUtil.getPos(a),
SqlStdOperatorTable.IS_NOT_NULL, operand));
} else if (simplified.isAlwaysFalse()) {
return rexBuilder.makeLiteral(false);
} else {
@@ -1208,6 +1209,7 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
// For example, given
// "(CASE WHEN FALSE THEN 1 ELSE 2) IS NULL" we first simplify the
// argument to "2", and only then we can simplify "2 IS NULL" to "FALSE".
+ SqlParserPos pos = RexUtil.getPos(a);
a = simplify(a, UNKNOWN);
boolean isSafe = isSafeExpression(a);
if (!a.getType().isNullable() && isSafe) {
@@ -1218,7 +1220,7 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
a = RexUtil.removeCast(a);
// to keep this simplification, we must return IS NULL(a),
// even if we cannot do anything else
- simplifiedResult = rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, a);
+ simplifiedResult = rexBuilder.makeCall(pos, SqlStdOperatorTable.IS_NULL,
a);
}
if (RexUtil.isNull(a)) {
return rexBuilder.makeLiteral(true);
@@ -1240,7 +1242,7 @@ private RexNode simplifyIs(RexCall call, RexUnknownAs
unknownAs) {
final RexNode simplified = simplifyIsNull(operand);
if (simplified == null) {
operands.add(
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, operand));
+ rexBuilder.makeCall(RexUtil.getPos(a),
SqlStdOperatorTable.IS_NULL, operand));
} else {
operands.add(simplified);
}
@@ -1359,7 +1361,9 @@ && isSafeExpression(newCond)) {
// in this case, last branch and new branch have the same conclusion,
// hence we create a new composite condition and we do not add it to
// the final branches for the time being
- newCond = rexBuilder.makeCall(SqlStdOperatorTable.OR,
lastBranch.cond, newCond);
+ newCond =
+ rexBuilder.makeCall(call.getParserPosition(),
SqlStdOperatorTable.OR,
+ lastBranch.cond, newCond);
conditionNeedsSimplify = true;
} else {
// if we reach here, the new branch is not mergeable with the last
one,
@@ -1811,7 +1815,8 @@ RexNode simplifyAnd2(List<RexNode> terms, List<RexNode>
notTerms) {
for (RexNode notSatisfiableNullable : notSatisfiableNullables) {
terms.add(
simplifyIs((RexCall)
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL,
notSatisfiableNullable), UNKNOWN));
+ rexBuilder.makeCall(RexUtil.getPos(notSatisfiableNullable),
+ SqlStdOperatorTable.IS_NULL, notSatisfiableNullable),
UNKNOWN));
}
}
// Add the NOT disjunctions back in.
@@ -2059,7 +2064,7 @@ private <C extends Comparable<C>> RexNode
simplifyAnd2ForUnknownAsFalse(
for (RexNode operand : notNullOperands) {
if (!strongOperands.contains(operand)) {
terms.add(
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, operand));
+ rexBuilder.makeCall(RexUtil.getPos(operand),
SqlStdOperatorTable.IS_NOT_NULL, operand));
}
}
return RexUtil.composeConjunction(rexBuilder, terms);
@@ -2096,7 +2101,7 @@ private <C extends Comparable<C>> RexNode
simplifyUsingPredicates(RexNode e,
// Range is always satisfied given these predicates; but nullability
might
// be problematic
return simplify(
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, comparison.ref),
+ rexBuilder.makeCall(RexUtil.getPos(e),
SqlStdOperatorTable.IS_NOT_NULL, comparison.ref),
RexUnknownAs.UNKNOWN);
} else if (rangeSet2.asRanges().size() == 1
&& Iterables.getOnlyElement(rangeSet2.asRanges()).hasLowerBound()
@@ -2105,7 +2110,7 @@ private <C extends Comparable<C>> RexNode
simplifyUsingPredicates(RexNode e,
.equals(Iterables.getOnlyElement(rangeSet2.asRanges()).upperEndpoint())) {
final Range<C> r = Iterables.getOnlyElement(rangeSet2.asRanges());
// range is now a point; it's worth simplifying
- return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, comparison.ref,
+ return rexBuilder.makeCall(RexUtil.getPos(e),
SqlStdOperatorTable.EQUALS, comparison.ref,
rexBuilder.makeLiteral(r.lowerEndpoint(),
comparison.literal.getType(), comparison.literal.getTypeName()));
} else {
@@ -2280,13 +2285,13 @@ private RexNode simplifyOrs(List<RexNode> terms,
RexUnknownAs unknownAs) {
&& comparable1.compareTo(comparable2) != 0) {
// X <> A OR X <> B => X IS NOT NULL OR NULL
final RexNode isNotNull =
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
+ rexBuilder.makeCall(RexUtil.getPos(term),
SqlStdOperatorTable.IS_NOT_NULL,
notEqualsComparison.ref);
final RexNode constantNull =
rexBuilder.makeNullLiteral(trueLiteral.getType());
final RexNode newCondition =
simplify(
- rexBuilder.makeCall(SqlStdOperatorTable.OR, isNotNull,
+ rexBuilder.makeCall(RexUtil.getPos(term),
SqlStdOperatorTable.OR, isNotNull,
constantNull),
unknownAs);
if (newCondition.isAlwaysTrue()) {
@@ -2317,7 +2322,7 @@ private RexNode simplifyOrs(List<RexNode> terms,
RexUnknownAs unknownAs) {
}
final RexNode isNotNull =
- rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, x);
+ rexBuilder.makeCall(RexUtil.getPos(term),
SqlStdOperatorTable.IS_NOT_NULL, x);
terms.set(terms.indexOf(x), simplifyIs((RexCall) isNotNull,
unknownAs));
terms.set(i, rexBuilder.makeNullLiteral(x.getType()));
i--;
@@ -2635,6 +2640,7 @@ private RexNode simplifyTrim(RexCall e) {
&& trimType.equals(simplify(childNode.operands.get(0)))
&& trimed.equals(simplify(childNode.operands.get(1)))) {
return simplifyTrim(childNode);
+
}
}
@@ -2642,8 +2648,7 @@ private RexNode simplifyTrim(RexCall e) {
rexNodes.add(trimType);
rexNodes.add(trimed);
rexNodes.add(simplify(e.operands.get(2)));
- RexNode rexNode = rexBuilder.makeCall(e.getType(), e.getOperator(),
rexNodes);
- return rexNode;
+ return rexBuilder.makeCall(e.getParserPosition(), e.getType(),
e.getOperator(), rexNodes);
}
/** Method that returns whether we can rollup from inner time unit
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 5904bba922..8c45ffc97a 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -2379,6 +2379,15 @@ public static com.google.common.base.Function<RexNode,
RexNode> notFn(
return e -> not(rexBuilder, e);
}
+ /** If the RexNode contains position information, return it.
+ * Otherwise, return SqlParserPos.ZERO. */
+ public static SqlParserPos getPos(RexNode e) {
+ if (e instanceof RexCall) {
+ return ((RexCall) e).getParserPosition();
+ }
+ return SqlParserPos.ZERO;
+ }
+
/** Applies NOT to an expression.
*
* <p>Unlike {@link #not}, may strengthen the type from {@code BOOLEAN}
@@ -2390,7 +2399,7 @@ static RexNode not(final RexBuilder rexBuilder, RexNode
input) {
? rexBuilder.makeLiteral(true)
: input.getKind() == SqlKind.NOT
? ((RexCall) input).operands.get(0)
- : rexBuilder.makeCall(SqlStdOperatorTable.NOT, input);
+ : rexBuilder.makeCall(getPos(input), SqlStdOperatorTable.NOT, input);
}
/** Returns whether an expression contains a {@link RexCorrelVariable}. */
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 7112fda4a8..e8b1bcbd7a 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -252,29 +252,29 @@ private StandardConvertletTable() {
// Expand "x NOT LIKE y" into "NOT (x LIKE y)"
registerOp(SqlStdOperatorTable.NOT_LIKE,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO,
- SqlStdOperatorTable.LIKE.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.NOT.createCall(call.getParserPosition(),
+ SqlStdOperatorTable.LIKE.createCall(call.getParserPosition(),
call.getOperandList()))));
// Expand "x NOT ILIKE y" into "NOT (x ILIKE y)"
registerOp(SqlLibraryOperators.NOT_ILIKE,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO,
- SqlLibraryOperators.ILIKE.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.NOT.createCall(call.getParserPosition(),
+ SqlLibraryOperators.ILIKE.createCall(call.getParserPosition(),
call.getOperandList()))));
// Expand "x NOT RLIKE y" into "NOT (x RLIKE y)"
registerOp(SqlLibraryOperators.NOT_RLIKE,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO,
- SqlLibraryOperators.RLIKE.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.NOT.createCall(call.getParserPosition(),
+ SqlLibraryOperators.RLIKE.createCall(call.getParserPosition(),
call.getOperandList()))));
// Expand "x NOT SIMILAR y" into "NOT (x SIMILAR y)"
registerOp(SqlStdOperatorTable.NOT_SIMILAR_TO,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.NOT.createCall(SqlParserPos.ZERO,
- SqlStdOperatorTable.SIMILAR_TO.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.NOT.createCall(call.getParserPosition(),
+
SqlStdOperatorTable.SIMILAR_TO.createCall(call.getParserPosition(),
call.getOperandList()))));
// Unary "+" has no effect, so expand "+ x" into "x".
@@ -312,7 +312,7 @@ private StandardConvertletTable() {
// "SQRT(x)" is equivalent to "POWER(x, .5)"
registerOp(SqlStdOperatorTable.SQRT,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.POWER.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.POWER.createCall(call.getParserPosition(),
call.operand(0),
SqlLiteral.createExactNumeric("0.5", SqlParserPos.ZERO))));
@@ -320,7 +320,7 @@ private StandardConvertletTable() {
// "POSITION(substring IN string)"
registerOp(SqlLibraryOperators.STRPOS,
(cx, call) -> cx.convertExpression(
- SqlStdOperatorTable.POSITION.createCall(SqlParserPos.ZERO,
+ SqlStdOperatorTable.POSITION.createCall(call.getParserPosition(),
call.operand(1), call.operand(0))));
// "INSTR(string, substring, position, occurrence) is equivalent to
@@ -388,7 +388,7 @@ private StandardConvertletTable() {
if (!getComponentTypeOrThrow(type).isStruct()) {
return cx.convertExpression(
SqlStdOperatorTable.ELEMENT_SLICE.createCall(
- SqlParserPos.ZERO, operand));
+ call.getParserPosition(), operand));
}
// fallback on default behavior
@@ -404,7 +404,7 @@ private StandardConvertletTable() {
final SqlNode operand = call.operand(0);
final RexNode expr =
cx.convertExpression(
- SqlStdOperatorTable.ELEMENT.createCall(SqlParserPos.ZERO,
+
SqlStdOperatorTable.ELEMENT.createCall(call.getParserPosition(),
operand));
return cx.getRexBuilder().makeFieldAccess(expr, 0);
});
@@ -559,25 +559,25 @@ private static RexNode convertInterval(SqlRexContext cx,
SqlCall call) {
//~ Methods ----------------------------------------------------------------
- private static RexNode or(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.OR, a0, a1);
+ private static RexNode or(SqlParserPos pos, RexBuilder rexBuilder, RexNode
a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.OR, a0, a1);
}
- private static RexNode eq(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, a0, a1);
+ private static RexNode eq(SqlParserPos pos, RexBuilder rexBuilder, RexNode
a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.EQUALS, a0, a1);
}
- private static RexNode ge(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, a0,
+ private static RexNode ge(SqlParserPos pos, RexBuilder rexBuilder, RexNode
a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.GREATER_THAN_OR_EQUAL,
a0,
a1);
}
- private static RexNode le(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, a0, a1);
+ private static RexNode le(SqlParserPos pos, RexBuilder rexBuilder, RexNode
a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.LESS_THAN_OR_EQUAL,
a0, a1);
}
- private static RexNode and(RexBuilder rexBuilder, RexNode a0, RexNode a1) {
- return rexBuilder.makeCall(SqlStdOperatorTable.AND, a0, a1);
+ private static RexNode and(SqlParserPos pos, RexBuilder rexBuilder, RexNode
a0, RexNode a1) {
+ return rexBuilder.makeCall(pos, SqlStdOperatorTable.AND, a0, a1);
}
private static RexNode divideInt(SqlParserPos pos, RexBuilder rexBuilder,
RexNode a0,
@@ -749,7 +749,7 @@ protected RexNode convertCast(
final SqlNode left = call.operand(0);
final SqlNode right = call.operand(1);
final SqlLiteral format = call.getOperandList().size() > 2
- ? call.operand(2) : SqlLiteral.createNull(SqlParserPos.ZERO);
+ ? call.operand(2) : SqlLiteral.createNull(call.getParserPosition());
final RexBuilder rexBuilder = cx.getRexBuilder();
final RexNode arg = cx.convertExpression(left);
@@ -840,7 +840,7 @@ protected RexNode convertFloorCeil(SqlRexContext cx,
SqlCall call) {
final RexBuilder rexBuilder = cx.getRexBuilder();
RexNode zero = rexBuilder.makeExactLiteral(BigDecimal.valueOf(0));
- RexNode cond = ge(rexBuilder, rexInterval, zero);
+ RexNode cond = ge(pos, rexBuilder, rexInterval, zero);
RexNode pad =
rexBuilder.makeExactLiteral(val.subtract(BigDecimal.ONE));
@@ -1428,9 +1428,10 @@ public RexNode convertBetween(
final RexNode z = list.get(SqlBetweenOperator.UPPER_OPERAND);
final RexBuilder rexBuilder = cx.getRexBuilder();
- RexNode ge1 = ge(rexBuilder, x, y);
- RexNode le1 = le(rexBuilder, x, z);
- RexNode and1 = and(rexBuilder, ge1, le1);
+ final SqlParserPos pos = call.getParserPosition();
+ RexNode ge1 = ge(pos, rexBuilder, x, y);
+ RexNode le1 = le(pos, rexBuilder, x, z);
+ RexNode and1 = and(pos, rexBuilder, ge1, le1);
RexNode res;
final SqlBetweenOperator.Flag symmetric = op.flag;
@@ -1439,10 +1440,10 @@ public RexNode convertBetween(
res = and1;
break;
case SYMMETRIC:
- RexNode ge2 = ge(rexBuilder, x, z);
- RexNode le2 = le(rexBuilder, x, y);
- RexNode and2 = and(rexBuilder, ge2, le2);
- res = or(rexBuilder, and1, and2);
+ RexNode ge2 = ge(pos, rexBuilder, x, z);
+ RexNode le2 = le(pos, rexBuilder, x, y);
+ RexNode and2 = and(pos, rexBuilder, ge2, le2);
+ res = or(pos, rexBuilder, and1, and2);
break;
default:
throw Util.unexpected(symmetric);
@@ -1551,34 +1552,35 @@ public RexNode convertOverlaps(
// Sort end points into start and end, such that (s0 <= e0) and (s1 <= e1).
final RexBuilder rexBuilder = cx.getRexBuilder();
- RexNode leftSwap = le(rexBuilder, r0, r1);
+ final SqlParserPos pos = call.getParserPosition();
+ RexNode leftSwap = le(pos, rexBuilder, r0, r1);
final RexNode s0 = case_(rexBuilder, leftSwap, r0, r1);
final RexNode e0 = case_(rexBuilder, leftSwap, r1, r0);
- RexNode rightSwap = le(rexBuilder, r2, r3);
+ RexNode rightSwap = le(pos, rexBuilder, r2, r3);
final RexNode s1 = case_(rexBuilder, rightSwap, r2, r3);
final RexNode e1 = case_(rexBuilder, rightSwap, r3, r2);
// (e0 >= s1) AND (e1 >= s0)
switch (op.kind) {
case OVERLAPS:
- return and(rexBuilder,
- ge(rexBuilder, e0, s1),
- ge(rexBuilder, e1, s0));
+ return and(pos, rexBuilder,
+ ge(pos, rexBuilder, e0, s1),
+ ge(pos, rexBuilder, e1, s0));
case CONTAINS:
- return and(rexBuilder,
- le(rexBuilder, s0, s1),
- ge(rexBuilder, e0, e1));
+ return and(pos, rexBuilder,
+ le(pos, rexBuilder, s0, s1),
+ ge(pos, rexBuilder, e0, e1));
case PERIOD_EQUALS:
- return and(rexBuilder,
- eq(rexBuilder, s0, s1),
- eq(rexBuilder, e0, e1));
+ return and(pos, rexBuilder,
+ eq(pos, rexBuilder, s0, s1),
+ eq(pos, rexBuilder, e0, e1));
case PRECEDES:
- return le(rexBuilder, e0, s1);
+ return le(pos, rexBuilder, e0, s1);
case IMMEDIATELY_PRECEDES:
- return eq(rexBuilder, e0, s1);
+ return eq(pos, rexBuilder, e0, s1);
case SUCCEEDS:
- return ge(rexBuilder, s0, e1);
+ return ge(pos, rexBuilder, s0, e1);
case IMMEDIATELY_SUCCEEDS:
- return eq(rexBuilder, s0, e1);
+ return eq(pos, rexBuilder, s0, e1);
default:
throw new AssertionError(op);
}
@@ -1657,18 +1659,19 @@ private static class RegrCovarianceConvertlet
implements SqlRexConvertlet {
final SqlNode expr;
final RelDataType type =
cx.getValidator().getValidatedNodeType(call);
+ final SqlParserPos pos = call.getParserPosition();
switch (kind) {
case COVAR_POP:
- expr = expandCovariance(arg1, arg2, null, type, cx, true);
+ expr = expandCovariance(pos, arg1, arg2, null, type, cx, true);
break;
case COVAR_SAMP:
- expr = expandCovariance(arg1, arg2, null, type, cx, false);
+ expr = expandCovariance(pos, arg1, arg2, null, type, cx, false);
break;
case REGR_SXX:
- expr = expandRegrSzz(arg2, arg1, type, cx, true);
+ expr = expandRegrSzz(pos, arg2, arg1, type, cx, true);
break;
case REGR_SYY:
- expr = expandRegrSzz(arg1, arg2, type, cx, true);
+ expr = expandRegrSzz(pos, arg1, arg2, type, cx, true);
break;
default:
throw Util.unexpected(kind);
@@ -1678,13 +1681,13 @@ private static class RegrCovarianceConvertlet
implements SqlRexConvertlet {
}
private static SqlNode expandRegrSzz(
+ final SqlParserPos pos,
final SqlNode arg1, final SqlNode arg2,
final RelDataType avgType, final SqlRexContext cx, boolean variance) {
- final SqlParserPos pos = SqlParserPos.ZERO;
final SqlNode count =
SqlStdOperatorTable.REGR_COUNT.createCall(pos, arg1, arg2);
final SqlNode varPop =
- expandCovariance(arg1, variance ? arg1 : arg2, arg2, avgType, cx,
true);
+ expandCovariance(pos, arg1, variance ? arg1 : arg2, arg2, avgType,
cx, true);
final RexNode varPopRex = cx.convertExpression(varPop);
final SqlNode varPopCast;
varPopCast = getCastedSqlNode(varPop, avgType, pos, varPopRex);
@@ -1692,6 +1695,7 @@ private static SqlNode expandRegrSzz(
}
private static SqlNode expandCovariance(
+ final SqlParserPos pos,
final SqlNode arg0Input,
final SqlNode arg1Input,
final @Nullable SqlNode dependent,
@@ -1705,8 +1709,7 @@ private static SqlNode expandCovariance(
// covar_samp(x1, x2) ==>
// (sum(x1 * x2) - sum(x1) * sum(x2) / count(x1, x2))
// / (count(x1, x2) - 1)
- final SqlParserPos pos = SqlParserPos.ZERO;
- final SqlLiteral nullLiteral = SqlLiteral.createNull(SqlParserPos.ZERO);
+ final SqlLiteral nullLiteral = SqlLiteral.createNull(pos);
final RelDataType highPrecision =
AvgVarianceConvertlet.highPrecision(cx, varType);
final RexNode arg0Rex = cx.convertExpression(arg0Input);
@@ -1751,7 +1754,7 @@ private static SqlNode expandCovariance(
} else {
final SqlNumericLiteral one = SqlLiteral.createExactNumeric("1", pos);
denominator =
- new SqlCase(SqlParserPos.ZERO, countCasted,
+ new SqlCase(pos, countCasted,
SqlNodeList.of(
SqlStdOperatorTable.EQUALS.createCall(pos, countCasted,
one)),
SqlNodeList.of(getCastedSqlNode(nullLiteral, highPrecision,
pos, null)),
@@ -2305,12 +2308,13 @@ private static class TimestampAddConvertlet implements
SqlRexConvertlet {
case 2:
if (call.getOperator() == SqlLibraryOperators.ADD_MONTHS) {
// Oracle-style 'ADD_MONTHS(date, integer months)'
- qualifier = new SqlIntervalQualifier(TimeUnit.MONTH, null,
SqlParserPos.ZERO);
+ qualifier =
+ new SqlIntervalQualifier(TimeUnit.MONTH, null,
call.getParserPosition());
op2 = handleFirstParameter(cx, rexBuilder, call);
op1 = handleSecondParameter(cx, rexBuilder, call);
} else if (call.getOperator() == SqlLibraryOperators.DATE_ADD_SPARK) {
// Spark-style 'DATE_ADD(date, integer days)'
- qualifier = new SqlIntervalQualifier(TimeUnit.DAY, null,
SqlParserPos.ZERO);
+ qualifier = new SqlIntervalQualifier(TimeUnit.DAY, null,
call.getParserPosition());
op2 = handleFirstParameter(cx, rexBuilder, call);
op1 = handleSecondParameter(cx, rexBuilder, call);
} else {
@@ -2405,7 +2409,7 @@ private static class TimestampSubConvertlet implements
SqlRexConvertlet {
final RexNode op2;
if (call.getOperator() == SqlLibraryOperators.DATE_SUB_SPARK) {
// Spark-style 'DATE_SUB(date, integer days)'
- qualifier = new SqlIntervalQualifier(TimeUnit.DAY, null,
SqlParserPos.ZERO);
+ qualifier = new SqlIntervalQualifier(TimeUnit.DAY, null,
call.getParserPosition());
op2 = handleFirstParameter(cx, rexBuilder, call);
op1 = handleSecondParameter(cx, rexBuilder, call);
} else {