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 {

Reply via email to