This is an automated email from the ASF dual-hosted git repository.

yashmayya pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new ceee8c59aa Upgrade Calcite to 1.39.0 (#15263)
ceee8c59aa is described below

commit ceee8c59aad19468b754bef60f6afbe9595f4da6
Author: Yash Mayya <yash.ma...@gmail.com>
AuthorDate: Tue Apr 22 12:55:40 2025 +0100

    Upgrade Calcite to 1.39.0 (#15263)
---
 pinot-common/src/main/codegen/config.fmpp          |   3 +-
 pinot-common/src/main/codegen/default_config.fmpp  |   5 +-
 pinot-common/src/main/codegen/templates/Parser.jj  | 263 +++++++++++++--------
 .../tests/MultiStageEngineIntegrationTest.java     |  70 +-----
 .../integration/tests/SpoolIntegrationTest.java    |   9 +-
 .../rel/rules/PinotEvaluateLiteralRule.java        |  32 ++-
 .../pinot/calcite/rel/rules/PinotRuleUtils.java    |  13 +-
 .../rules/PinotWindowExchangeNodeInsertRule.java   |   2 +-
 .../planner/logical/PlanNodeToRelConverter.java    |   3 +-
 .../planner/logical/RelToPlanNodeConverter.java    |   7 +
 .../query/planner/logical/RexExpressionUtils.java  |  10 +-
 .../serde/RexExpressionToProtoExpression.java      |   2 +-
 .../org/apache/pinot/query/type/TypeSystem.java    |  22 +-
 .../PinotWindowExchangeNodeInsertRuleTest.java     |   8 +-
 .../apache/pinot/query/QueryCompilationTest.java   |   6 +
 .../src/test/resources/queries/AggregatePlans.json |  14 +-
 .../test/resources/queries/BasicQueryPlans.json    |   4 +-
 .../src/test/resources/queries/GroupByPlans.json   |  10 +-
 .../src/test/resources/queries/JoinPlans.json      |  37 +--
 .../resources/queries/LiteralEvaluationPlans.json  |   2 +-
 .../test/resources/queries/PinotHintablePlans.json |   6 +-
 .../resources/queries/WindowFunctionPlans.json     |  70 +++---
 pom.xml                                            |   2 +-
 23 files changed, 336 insertions(+), 264 deletions(-)

diff --git a/pinot-common/src/main/codegen/config.fmpp 
b/pinot-common/src/main/codegen/config.fmpp
index aebbab9397..fdc6edd260 100644
--- a/pinot-common/src/main/codegen/config.fmpp
+++ b/pinot-common/src/main/codegen/config.fmpp
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-# Copied from Calcite 1.37.0 babel and modified for Pinot syntax. Update this 
file when upgrading Calcite version.
+# Copied from Calcite 1.39.0 babel and modified for Pinot syntax. Update this 
file when upgrading Calcite version.
 
 data: {
   default: tdd("../default_config.fmpp")
@@ -35,6 +35,7 @@ data: {
     # List of additional classes and packages to import.
     # Example: "org.apache.calcite.sql.*", "java.util.List".
     imports: [
+      "org.apache.calcite.sql.babel.postgres.SqlSetOptions",
       "org.apache.pinot.sql.parsers.parser.*"
     ]
 
diff --git a/pinot-common/src/main/codegen/default_config.fmpp 
b/pinot-common/src/main/codegen/default_config.fmpp
index 31092dce92..cb69be203d 100644
--- a/pinot-common/src/main/codegen/default_config.fmpp
+++ b/pinot-common/src/main/codegen/default_config.fmpp
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-# Copied from Calcite 1.37.0 and modified for Pinot syntax. Update this file 
when upgrading Calcite version.
+# Copied from Calcite 1.39.0 and modified for Pinot syntax. Update this file 
when upgrading Calcite version.
 
 # Default data declarations for parsers.
 # Each of these may be overridden in a parser's config.fmpp file.
@@ -457,6 +457,9 @@ parser: {
   # Example: "< IDENTIFIER: (<LETTER>|<DIGIT>)+ >".
   customIdentifierToken: ""
 
+  # Method for parsing "SET [OR RESET]" calls.
+  setOptionParserMethod: "SqlSetOption"
+
   includePosixOperators: false
   includeCompoundIdentifier: true
   includeBraces: true
diff --git a/pinot-common/src/main/codegen/templates/Parser.jj 
b/pinot-common/src/main/codegen/templates/Parser.jj
index 965a87b21d..b8cd5d669f 100644
--- a/pinot-common/src/main/codegen/templates/Parser.jj
+++ b/pinot-common/src/main/codegen/templates/Parser.jj
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-// Copied from Calcite 1.37.0 and modified for Pinot syntax. Update this file 
when upgrading Calcite version.
+// Copied from Calcite 1.39.0 and modified for Pinot syntax. Update this file 
when upgrading Calcite version.
 // Modified parts are marked with "PINOT CUSTOMIZATION START/END".
 
 <@pp.dropOutputFile />
@@ -46,6 +46,7 @@ import org.apache.calcite.runtime.CalciteContextException;
 import org.apache.calcite.sql.JoinConditionType;
 import org.apache.calcite.sql.JoinType;
 import org.apache.calcite.sql.SqlAlter;
+import org.apache.calcite.sql.SqlAsofJoin;
 import org.apache.calcite.sql.SqlBasicTypeNameSpec;
 import org.apache.calcite.sql.SqlBinaryOperator;
 import org.apache.calcite.sql.SqlCall;
@@ -1150,7 +1151,7 @@ SqlNode SqlStmt() :
         LOOKAHEAD(2) stmt = ${method}
     |
 </#list>
-        stmt = SqlSetOption(Span.of(), null)
+        stmt = 
${parser.setOptionParserMethod!default.parser.setOptionParserMethod}(Span.of(), 
null)
     |
         stmt = SqlAlter()
     |
@@ -1750,10 +1751,10 @@ SqlNode SqlInsert() :
     (
         LOOKAHEAD(2)
         p = ParenthesizedCompoundIdentifierList() {
-            if (p.right.size() > 0) {
+            if (!p.right.isEmpty()) {
                 tableRef = extend(tableRef, p.right);
             }
-            if (p.left.size() > 0) {
+            if (!p.left.isEmpty()) {
                 columnList = p.left;
             } else {
                 columnList = null;
@@ -1825,14 +1826,14 @@ SqlNode SqlUpdate() :
     ( tableRef = TableHints(tableName) | { tableRef = tableName; } )
     [ tableRef = ExtendTable(tableRef) ]
     ( [ <AS> ] alias = SimpleIdentifier() | { alias = null; } )
-    <SET> id = SimpleIdentifier() {
+    <SET> id = CompoundIdentifier() {
         targetColumnList.add(id);
     }
     // TODO:  support DEFAULT also
     <EQ> AddExpression(sourceExpressionList, ExprContext.ACCEPT_SUB_QUERY)
     (
         <COMMA>
-        id = SimpleIdentifier() { targetColumnList.add(id); }
+        id = CompoundIdentifier() { targetColumnList.add(id); }
         <EQ> AddExpression(sourceExpressionList, ExprContext.ACCEPT_SUB_QUERY)
     )*
     ( where = Where() | { where = null; } )
@@ -1950,13 +1951,19 @@ SqlInsert WhenNotMatchedClause(SqlNode table) :
  */
 void AddSelectItem(List<SqlNode> list) :
 {
-    final SqlNode e;
+    SqlNode e;
     final SqlIdentifier id;
 }
 {
     e = SelectExpression()
     (
-        [ <AS> ]
+        [ <AS>
+            [ <MEASURE> {
+                    e = SqlInternalOperators.MEASURE.createCall(
+                        e.getParserPosition(), e);
+                }
+            ]
+        ]
         (
             id = SimpleIdentifier()
         |
@@ -1999,6 +2006,7 @@ SqlLiteral Natural() :
 SqlLiteral JoinType() :
 {
     JoinType joinType;
+    boolean asof = false;
 }
 {
     (
@@ -2011,7 +2019,9 @@ SqlLiteral JoinType() :
     |
         <INNER> <JOIN> { joinType = JoinType.INNER; }
     |
-        <LEFT> [ <OUTER> ] <JOIN> { joinType = JoinType.LEFT; }
+        <ASOF> <JOIN> { joinType = JoinType.ASOF; }
+    |
+        <LEFT> [ <OUTER> | <ASOF> { asof = true; } ] <JOIN> { joinType = asof 
? JoinType.LEFT_ASOF : JoinType.LEFT; }
     |
         <RIGHT> [ <OUTER> ] <JOIN> { joinType = JoinType.RIGHT; }
     |
@@ -2037,7 +2047,7 @@ SqlNode FromClause() :
     SqlLiteral joinType;
 }
 {
-    e = Join()
+    e = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
     (
         // Comma joins should only occur at top-level in the FROM clause.
         // Valid:
@@ -2046,39 +2056,36 @@ SqlNode FromClause() :
         // Not valid:
         //  * FROM a CROSS JOIN (b, c)
         LOOKAHEAD(1)
-        <COMMA> { joinType = JoinType.COMMA.symbol(getPos()); }
-        e2 = Join() {
-            e = new SqlJoin(joinType.getParserPosition(),
-                e,
-                SqlLiteral.createBoolean(false, joinType.getParserPosition()),
-                joinType,
-                e2,
-                JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
-                null);
-        }
+        e = JoinOrCommaTable(e)
     )*
     { return e; }
 }
 
-SqlNode Join() :
+SqlNode JoinOrCommaTable(SqlNode e) :
 {
-    SqlNode e;
+    SqlNode e2;
+    SqlLiteral joinType;
 }
 {
-    e = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
-    (
-        LOOKAHEAD(2)
-        e = JoinTable(e)
-    )*
-    {
-        return e;
+    LOOKAHEAD(2)
+    <COMMA> { joinType = JoinType.COMMA.symbol(getPos()); }
+    e2 = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN) {
+        return new SqlJoin(joinType.getParserPosition(),
+            e,
+            SqlLiteral.createBoolean(false, joinType.getParserPosition()),
+            joinType,
+            e2,
+            JoinConditionType.NONE.symbol(SqlParserPos.ZERO),
+            null);
     }
+|
+    e2 = JoinTable(e) { return e2; }
 }
 
 /** Matches "LEFT JOIN t ON ...", "RIGHT JOIN t USING ...", "JOIN t". */
 SqlNode JoinTable(SqlNode e) :
 {
-    SqlNode e2, condition;
+    SqlNode e2, condition, matchCondition = null;
     final SqlLiteral natural, joinType, on, using;
     SqlNodeList list;
 }
@@ -2095,13 +2102,32 @@ SqlNode JoinTable(SqlNode e) :
     //
     // We allow CROSS JOIN (joinType = CROSS_JOIN) to have a join condition,
     // even though that is not valid SQL; the validator will catch it.
-    LOOKAHEAD(3)
+    LOOKAHEAD(4)
     natural = Natural()
     joinType = JoinType()
     e2 = TableRef1(ExprContext.ACCEPT_QUERY_OR_JOIN)
     (
+        [ <MATCH_CONDITION> matchCondition = 
Expression(ExprContext.ACCEPT_SUB_QUERY) ]
         <ON> { on = JoinConditionType.ON.symbol(getPos()); }
         condition = Expression(ExprContext.ACCEPT_SUB_QUERY) {
+            JoinType type = joinType.getValueAs(JoinType.class);
+            if (matchCondition != null) {
+                if (type != JoinType.ASOF && type != JoinType.LEFT_ASOF) {
+                    throw SqlUtil.newContextException(getPos(), 
RESOURCE.matchConditionRequiresAsof());
+                }
+                return new SqlAsofJoin(joinType.getParserPosition(),
+                    e,
+                    natural,
+                    joinType,
+                    e2,
+                    on,
+                    condition,
+                    matchCondition);
+            } else {
+                if (type == JoinType.ASOF || type == JoinType.LEFT_ASOF) {
+                    throw SqlUtil.newContextException(getPos(), 
RESOURCE.asofRequiresMatchCondition());
+                }
+            }
             return new SqlJoin(joinType.getParserPosition(),
                 e,
                 natural,
@@ -2228,6 +2254,8 @@ SqlNode TableRef3(ExprContext exprContext, boolean 
lateral) :
         tableRef = addLateral(tableRef, lateral)
         [ tableRef = MatchRecognize(tableRef) ]
     |
+        LOOKAHEAD(2)
+        [ <LATERAL> ] // "LATERAL" is implicit with "UNNEST", so ignore
         <UNNEST> { s = span(); }
         args = ParenthesizedQueryOrCommaList(ExprContext.ACCEPT_SUB_QUERY)
         [
@@ -2742,6 +2770,7 @@ SqlWindow WindowSpecification() :
     final SqlNodeList orderList;
     final SqlLiteral isRows;
     final SqlNode lowerBound, upperBound;
+    final SqlLiteral exclude;
     final Span s, s1, s2;
     final SqlLiteral allowPartial;
 }
@@ -2774,9 +2803,11 @@ SqlWindow WindowSpecification() :
             lowerBound = WindowRange()
             { upperBound = null; }
         )
+        exclude = WindowExclusion()
     |
         {
             isRows = SqlLiteral.createBoolean(false, SqlParserPos.ZERO);
+            exclude = SqlWindow.createExcludeNoOthers(getPos());
             lowerBound = upperBound = null;
         }
     )
@@ -2793,7 +2824,7 @@ SqlWindow WindowSpecification() :
     <RPAREN>
     {
         return SqlWindow.create(null, id, partitionList, orderList,
-            isRows, lowerBound, upperBound, allowPartial, s.end(this));
+            isRows, lowerBound, upperBound, allowPartial, exclude, 
s.end(this));
     }
 }
 
@@ -2832,6 +2863,27 @@ SqlNode WindowRange() :
     )
 }
 
+/** Parses an exclusion clause for WINDOW FRAME. */
+SqlLiteral WindowExclusion() :
+{
+}
+{
+    (
+        <EXCLUDE>
+        (
+            <CURRENT> <ROW> { return 
SqlWindow.createExcludeCurrentRow(getPos()); }
+        |
+            <NO> <OTHERS> { return SqlWindow.createExcludeNoOthers(getPos()); }
+        |
+            <GROUP> { return SqlWindow.createExcludeGroup(getPos()); }
+        |
+            <TIES> { return SqlWindow.createExcludeTies(getPos()); }
+        )
+    |
+        { return SqlWindow.createExcludeNoOthers(SqlParserPos.ZERO); }
+    )
+}
+
 /** Parses a QUALIFY clause for SELECT. */
 SqlNode Qualify() :
 {
@@ -3786,8 +3838,12 @@ List<Object> Expression2(ExprContext exprContext) :
                 AddExpression2b(list, ExprContext.ACCEPT_SUB_QUERY)
             |
                 <LBRACKET>
-                itemOp = getItemOp()
-                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
+                ( <OFFSET> { itemOp = SqlLibraryOperators.OFFSET; } <LPAREN> { 
e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
+                | <ORDINAL> { itemOp = SqlLibraryOperators.ORDINAL; } <LPAREN> 
{ e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
+                | <SAFE_OFFSET> { itemOp = SqlLibraryOperators.SAFE_OFFSET; } 
<LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
+                | <SAFE_ORDINAL> { itemOp = SqlLibraryOperators.SAFE_ORDINAL; 
} <LPAREN> { e = Expression(ExprContext.ACCEPT_SUB_QUERY); } <RPAREN>
+                | { itemOp = SqlStdOperatorTable.ITEM; } e = 
Expression(ExprContext.ACCEPT_SUB_QUERY)
+                )
                 <RBRACKET> {
                     list.add(
                         new SqlParserUtil.ToTreeListItem(
@@ -3822,22 +3878,6 @@ List<Object> Expression2(ExprContext exprContext) :
     )
 }
 
-/** Returns the appropriate ITEM operator for indexing arrays. */
-SqlOperator getItemOp() :
-{
-}
-{
-    <OFFSET> { return SqlLibraryOperators.OFFSET; }
-|
-    <ORDINAL> { return SqlLibraryOperators.ORDINAL; }
-|
-    <SAFE_OFFSET> { return SqlLibraryOperators.SAFE_OFFSET; }
-|
-    <SAFE_ORDINAL> { return SqlLibraryOperators.SAFE_ORDINAL; }
-|
-    { return SqlStdOperatorTable.ITEM; }
-}
-
 /** Parses a comparison operator inside a SOME / ALL predicate. */
 SqlKind comp() :
 {
@@ -3956,7 +3996,7 @@ SqlNode Expression3(ExprContext exprContext) :
     {
         if (list1.size() == 1) {
             // interpret as single value or query
-            return list1.get(0);
+            return list1.get(0).clone(list1.getParserPosition());
         } else {
             // interpret as row constructor
             return SqlStdOperatorTable.ROW.createCall(span().end(list1),
@@ -4337,7 +4377,7 @@ SqlSetOption SqlSetOption(Span s, String scope) :
             }
         )
         {
-            return new SqlSetOption(s.end(val), scope, name, val);
+            return new SqlSetOption(s.end(val), scope, (SqlNode) name, val);
         }
     |
         <RESET> {
@@ -4352,7 +4392,7 @@ SqlSetOption SqlSetOption(Span s, String scope) :
             }
         )
         {
-            return new SqlSetOption(s.end(name), scope, name, null);
+            return new SqlSetOption(s.end(name), scope, (SqlNode) name, null);
         }
     )
 }
@@ -4376,8 +4416,7 @@ SqlAlter SqlAlter() :
         alterNode = ${method}(s, scope)
     |
 </#list>
-
-        alterNode = SqlSetOption(s, scope)
+        alterNode = 
${parser.setOptionParserMethod!default.parser.setOptionParserMethod}(s, scope)
     )
     {
         return alterNode;
@@ -4829,6 +4868,11 @@ SqlLiteral DateTimeLiteral() :
     <TIME> { s = span(); } p = SimpleStringLiteral() {
       return SqlLiteral.createUnknown("TIME", p, s.end(this));
     }
+|
+    LOOKAHEAD(2)
+    <UUID> { s = span(); } p = SimpleStringLiteral() {
+        return SqlLiteral.createUnknown("UUID", p, s.end(this));
+    }
 |
     LOOKAHEAD(2)
     <TIMESTAMP> { s = span(); } p = SimpleStringLiteral() {
@@ -4931,7 +4975,7 @@ SqlNode ArrayConstructor() :
         // by enumeration "ARRAY[e0, e1, ..., eN]"
         <LBRACKET> // TODO: do trigraph as well ??( ??)
         (
-            args = ExpressionCommaList(s, ExprContext.ACCEPT_NON_QUERY)
+            args = ExpressionCommaList(s, ExprContext.ACCEPT_SUB_QUERY)
         |
             { args = SqlNodeList.EMPTY; }
         )
@@ -5863,6 +5907,10 @@ SqlTypeNameSpec SqlTypeName1(Span s) :
         [ <PRECISION> ] { sqlTypeName = SqlTypeName.DOUBLE; }
     |
         <FLOAT> { s.add(this); sqlTypeName = SqlTypeName.FLOAT; }
+    |
+        <VARIANT> { s.add(this); sqlTypeName = SqlTypeName.VARIANT; }
+    |
+        <UUID> { s.add(this); sqlTypeName = SqlTypeName.UUID; }
     )
     {
         return new SqlBasicTypeNameSpec(sqlTypeName, s.end(this));
@@ -5896,8 +5944,8 @@ SqlTypeNameSpec SqlTypeName2(Span s) :
 SqlTypeNameSpec SqlTypeName3(Span s) :
 {
     final SqlTypeName sqlTypeName;
-    int precision = -1;
-    int scale = -1;
+    int precision = RelDataType.PRECISION_NOT_SPECIFIED;
+    int scale = RelDataType.SCALE_NOT_SPECIFIED;
 }
 {
     (
@@ -5910,7 +5958,7 @@ SqlTypeNameSpec SqlTypeName3(Span s) :
         precision = UnsignedIntLiteral()
         [
             <COMMA>
-            scale = UnsignedIntLiteral()
+            scale = IntLiteral()
         ]
         <RPAREN>
     ]
@@ -6284,10 +6332,17 @@ SqlNode BuiltinFunctionCall() :
                 }
             |
                 <COMMA> e = SimpleIdentifier() { args.add(e); }
-                <COMMA> e = SimpleIdentifier() { args.add(e); }
-                <RPAREN> {
-                    return SqlStdOperatorTable.CONVERT.createCall(s.end(this), 
args);
-                }
+                (
+                    <COMMA> e = SimpleIdentifier() { args.add(e); }
+                    <RPAREN> {
+                        SqlOperator op = 
SqlStdOperatorTable.getConvertFuncByConformance(this.conformance);
+                        return op.createCall(s.end(this), args);
+                    }
+                |
+                    <RPAREN> {
+                        return 
SqlLibraryOperators.CONVERT_ORACLE.createCall(s.end(this), args);
+                    }
+                )
             )
         |
             // MSSql CONVERT(type, val [,style])
@@ -6364,59 +6419,49 @@ SqlNode BuiltinFunctionCall() :
         <TRIM> {
             SqlLiteral flag = null;
             SqlNode trimChars = null;
+            SqlParserPos fromPos = SqlParserPos.ZERO;
             s = span();
         }
         <LPAREN>
-        [
-            LOOKAHEAD(2)
-            [
-                <BOTH> {
-                    s.add(this);
-                    flag = SqlTrimFunction.Flag.BOTH.symbol(getPos());
-                }
-            |
-                <TRAILING> {
-                    s.add(this);
-                    flag = SqlTrimFunction.Flag.TRAILING.symbol(getPos());
-                }
-            |
-                <LEADING> {
-                    s.add(this);
-                    flag = SqlTrimFunction.Flag.LEADING.symbol(getPos());
-                }
-            ]
-            [ trimChars = Expression(ExprContext.ACCEPT_SUB_QUERY) ]
+        (
             (
-                <FROM> {
-                    if (null == flag && null == trimChars) {
-                        throw SqlUtil.newContextException(getPos(),
-                            RESOURCE.illegalFromEmpty());
+                (
+                    <BOTH> {
+                        s.add(this);
+                        flag = SqlTrimFunction.Flag.BOTH.symbol(getPos());
                     }
-                }
-            |
-                <RPAREN> {
-                    // This is to handle the case of TRIM(x)
-                    // (FRG-191).
-                    if (flag == null) {
-                        flag = 
SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
+                |
+                    <TRAILING> {
+                        s.add(this);
+                        flag = SqlTrimFunction.Flag.TRAILING.symbol(getPos());
                     }
-                    args.add(flag);
-                    args.add(null); // no trim chars
-                    args.add(trimChars); // reinterpret trimChars as source
-                    return SqlStdOperatorTable.TRIM.createCall(s.end(this),
-                        args);
-                }
+                |
+                    <LEADING> {
+                        s.add(this);
+                        flag = SqlTrimFunction.Flag.LEADING.symbol(getPos());
+                    }
+                )
+                [ trimChars = Expression(ExprContext.ACCEPT_SUB_QUERY) ]
+                <FROM> { fromPos = getPos(); }
+                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
             )
-        ]
-        e = Expression(ExprContext.ACCEPT_SUB_QUERY) {
+            |
+            (
+                e = Expression(ExprContext.ACCEPT_SUB_QUERY)
+                [
+                    <FROM> { trimChars = e; fromPos = getPos(); }
+                    e = Expression(ExprContext.ACCEPT_SUB_QUERY)
+                ]
+            )
+        )
+        <RPAREN> {
             if (flag == null) {
                 flag = SqlTrimFunction.Flag.BOTH.symbol(SqlParserPos.ZERO);
             }
             args.add(flag);
+            // trimChars can be null
             args.add(trimChars);
             args.add(e);
-        }
-        <RPAREN> {
             return SqlStdOperatorTable.TRIM.createCall(s.end(this), args);
         }
     |
@@ -6712,7 +6757,7 @@ SqlNode JsonQueryWrapperBehavior() :
 
 SqlCall JsonQueryFunctionCall() :
 {
-    final SqlNode[] args = new SqlNode[5];
+    final SqlNode[] args = new SqlNode[6];
     SqlNode e;
     List<SqlNode> commonSyntax;
     final Span span;
@@ -6724,6 +6769,11 @@ SqlCall JsonQueryFunctionCall() :
         args[0] = commonSyntax.get(0);
         args[1] = commonSyntax.get(1);
     }
+    [
+        e = JsonReturningClause() {
+            args[5] = e;
+        }
+    ]
     [
         e = JsonQueryWrapperBehavior() <WRAPPER> {
             args[2] = e;
@@ -8057,6 +8107,7 @@ SqlPostfixOperator PostfixRowOperator() :
 |   < ARRAY_CONCAT_AGG: "ARRAY_CONCAT_AGG" >
 |   < ARRAY_MAX_CARDINALITY: "ARRAY_MAX_CARDINALITY" >
 |   < AS: "AS" >
+|   < ASOF: "ASOF" >
 |   < ASC: "ASC" >
 |   < ASENSITIVE: "ASENSITIVE" >
 |   < ASSERTION: "ASSERTION" >
@@ -8357,10 +8408,12 @@ SqlPostfixOperator PostfixRowOperator() :
 |   < MATCH: "MATCH" >
 |   < MATCHED: "MATCHED" >
 |   < MATCHES: "MATCHES" >
+|   < MATCH_CONDITION: "MATCH_CONDITION">
 |   < MATCH_NUMBER: "MATCH_NUMBER">
 |   < MATCH_RECOGNIZE: "MATCH_RECOGNIZE">
 |   < MAX: "MAX" >
 |   < MAXVALUE: "MAXVALUE" >
+|   < MEASURE: "MEASURE" >
 |   < MEASURES: "MEASURES" >
 |   < MEMBER: "MEMBER" >
 |   < MERGE: "MERGE" > { beforeTableName(); }
@@ -8717,6 +8770,7 @@ SqlPostfixOperator PostfixRowOperator() :
 |   < UTF8: "UTF8" >
 |   < UTF16: "UTF16" >
 |   < UTF32: "UTF32" >
+|   < UUID: "UUID" >
 |   < VALUE: "VALUE" >
 |   < VALUES: "VALUES" > { afterTableName(); }
 |   < VALUE_OF: "VALUE_OF" >
@@ -8724,6 +8778,7 @@ SqlPostfixOperator PostfixRowOperator() :
 |   < VAR_SAMP: "VAR_SAMP" >
 |   < VARBINARY: "VARBINARY" >
 |   < VARCHAR: "VARCHAR" >
+|   < VARIANT: "VARIANT" >
 |   < VARYING: "VARYING" >
 |   < VERSION: "VERSION" >
 |   < VERSIONING: "VERSIONING" >
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/MultiStageEngineIntegrationTest.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/MultiStageEngineIntegrationTest.java
index 4e04856619..80b76b1515 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/MultiStageEngineIntegrationTest.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/MultiStageEngineIntegrationTest.java
@@ -66,7 +66,6 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import static org.apache.pinot.common.function.scalar.StringFunctions.*;
-import static org.assertj.core.api.Assertions.*;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
@@ -1088,12 +1087,12 @@ public class MultiStageEngineIntegrationTest extends 
BaseClusterIntegrationTestS
   @Test
   public void testSearch()
       throws Exception {
-    String sqlQuery = "SELECT CASE WHEN ArrDelay > 50 OR ArrDelay < 10 THEN 10 
ELSE 0 END "
+    String sqlQuery = "SELECT CASE WHEN ArrDel15 > 50 OR ArrDel15 < 10 THEN 10 
ELSE 0 END "
         + "FROM mytable LIMIT 1000";
     JsonNode jsonNode = postQuery("Explain plan WITHOUT IMPLEMENTATION for " + 
sqlQuery);
     JsonNode plan = jsonNode.get("resultTable").get("rows").get(0).get(1);
 
-    Pattern pattern = Pattern.compile("SEARCH\\(\\$7, Sarg\\[\\(-∞\\.\\.10\\), 
\\(50\\.\\.\\+∞\\)]\\)");
+    Pattern pattern = Pattern.compile("Sarg\\[\\(-∞\\.\\.10\\), 
\\(50\\.\\.\\+∞\\)]");
     boolean matches = pattern.matcher(plan.asText()).find();
     Assert.assertTrue(matches, "Plan doesn't contain the expected SEARCH");
 
@@ -1114,10 +1113,10 @@ public class MultiStageEngineIntegrationTest extends 
BaseClusterIntegrationTestS
   @Test
   public void testBetween()
       throws Exception {
-    String sqlQuery = "SELECT COUNT(*) FROM mytable WHERE ArrDelay BETWEEN 10 
AND 50";
+    String sqlQuery = "SELECT COUNT(*) FROM mytable WHERE AirTime BETWEEN 10 
AND 50";
     JsonNode jsonNode = postQuery(sqlQuery);
     assertNoError(jsonNode);
-    
assertEquals(jsonNode.get("resultTable").get("rows").get(0).get(0).asInt(), 
18572);
+    
assertEquals(jsonNode.get("resultTable").get("rows").get(0).get(0).asInt(), 
17293);
 
     String explainQuery = "EXPLAIN PLAN FOR " + sqlQuery;
     jsonNode = postQuery(explainQuery);
@@ -1551,65 +1550,8 @@ public class MultiStageEngineIntegrationTest extends 
BaseClusterIntegrationTestS
 
   @Test
   public void testQueryCompileBrokerTimeout() throws Exception {
-    // See https://github.com/apache/pinot/issues/13617. This test can be 
updated / removed when that issue is closed
-    String query = "SET timeoutMs=100; SELECT Carrier\n"
-        + "FROM (\n"
-        + "         SELECT Carrier\n"
-        + "         FROM mytable\n"
-        + "         WHERE Carrier IN (\n"
-        + "             'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 
'a9',\n"
-        + "             'a10', 'a11', 'a12', 'a13', 'a14', 'a15', 'a16', 
'a17', 'a18', 'a19',\n"
-        + "             'a20', 'a21', 'a22', 'a23', 'a24', 'a25', 'a26', 
'a27', 'a28', 'a29',\n"
-        + "             'a30', 'a31', 'a32', 'a33', 'a34', 'a35', 'a36', 
'a37', 'a38', 'a39',\n"
-        + "             'a40', 'a41', 'a42', 'a43', 'a44', 'a45', 'a46', 
'a47', 'a48', 'a49',\n"
-        + "             'a50', 'a51', 'a52', 'a53', 'a54', 'a55', 'a56', 
'a57', 'a58', 'a59',\n"
-        + "             'a60', 'a61', 'a62', 'a63', 'a64', 'a65', 'a66', 
'a67', 'a68', 'a69',\n"
-        + "             'a70', 'a71', 'a72', 'a73', 'a74', 'a75', 'a76', 
'a77', 'a78', 'a79',\n"
-        + "             'a80', 'a81', 'a82', 'a83', 'a84', 'a85', 'a86', 
'a87', 'a88', 'a89',\n"
-        + "             'a90', 'a91', 'a92', 'a93', 'a94', 'a95', 'a96', 
'a97', 'a98', 'a99',\n"
-        + "             'a100', 'a101', 'a102', 'a103', 'a104', 'a105', 
'a106', 'a107', 'a108', 'a109',\n"
-        + "             'a110', 'a111', 'a112', 'a113', 'a114', 'a115', 
'a116', 'a117', 'a118', 'a119',\n"
-        + "             'a120', 'a121', 'a122', 'a123', 'a124', 'a125', 
'a126', 'a127', 'a128', 'a129',\n"
-        + "             'a130', 'a131', 'a132', 'a133', 'a134', 'a135', 
'a136', 'a137', 'a138', 'a139',\n"
-        + "             'a140', 'a141', 'a142', 'a143', 'a144', 'a145', 
'a146', 'a147', 'a148', 'a149',\n"
-        + "             'a150', 'a151', 'a152', 'a153', 'a154', 'a155', 
'a156', 'a157', 'a158', 'a159',\n"
-        + "             'a160', 'a161', 'a162', 'a163', 'a164', 'a165', 
'a166', 'a167', 'a168', 'a169',\n"
-        + "             'a170', 'a171', 'a172', 'a173', 'a174', 'a175', 
'a176', 'a177', 'a178', 'a179',\n"
-        + "             'a180', 'a181', 'a182', 'a183', 'a184', 'a185', 
'a186', 'a187', 'a188', 'a189',\n"
-        + "             'a190', 'a191', 'a192', 'a193', 'a194', 'a195', 
'a196', 'a197', 'a198', 'a199',\n"
-        + "             'a200', 'a201', 'a202', 'a203', 'a204', 'a205', 
'a206', 'a207', 'a208', 'a209',\n"
-        + "             'a210', 'a211', 'a212', 'a213', 'a214', 'a215', 
'a216', 'a217', 'a218', 'a219',\n"
-        + "             'a220', 'a221', 'a222', 'a223', 'a224', 'a225', 
'a226', 'a227', 'a228', 'a229',\n"
-        + "             'a230', 'a231', 'a232', 'a233', 'a234', 'a235', 
'a236', 'a237', 'a238', 'a239',\n"
-        + "             'a240', 'a241', 'a242', 'a243', 'a244', 'a245', 
'a246', 'a247', 'a248', 'a249',\n"
-        + "             'a250', 'a251', 'a252', 'a253', 'a254', 'a255', 
'a256', 'a257', 'a258', 'a259',\n"
-        + "             'a260', 'a261', 'a262', 'a263', 'a264', 'a265', 
'a266', 'a267', 'a268', 'a269',\n"
-        + "             'a270', 'a271', 'a272', 'a273', 'a274', 'a275', 
'a276', 'a277', 'a278', 'a279',\n"
-        + "             'a280', 'a281', 'a282', 'a283', 'a284', 'a285', 
'a286', 'a287', 'a288', 'a289',\n"
-        + "             'a290', 'a291', 'a292', 'a293', 'a294', 'a295', 
'a296', 'a297', 'a298', 'a299',\n"
-        + "             'a300', 'a301', 'a302', 'a303', 'a304', 'a305', 
'a306', 'a307', 'a308', 'a309',\n"
-        + "             'a310', 'a311', 'a312', 'a313', 'a314', 'a315', 
'a316', 'a317', 'a318', 'a319',\n"
-        + "             'a320', 'a321', 'a322', 'a323', 'a324', 'a325', 
'a326', 'a327', 'a328', 'a329',\n"
-        + "             'a330', 'a331', 'a332', 'a333', 'a334', 'a335', 
'a336', 'a337', 'a338', 'a339',\n"
-        + "             'a340', 'a341', 'a342', 'a343', 'a344', 'a345', 
'a346', 'a347', 'a348', 'a349',\n"
-        + "             'a350', 'a351', 'a352', 'a353', 'a354', 'a355', 
'a356', 'a357', 'a358', 'a359',\n"
-        + "             'a360', 'a361', 'a362', 'a363', 'a364', 'a365', 
'a366', 'a367', 'a368', 'a369',\n"
-        + "             'a370', 'a371', 'a372', 'a373', 'a374', 'a375', 
'a376', 'a377', 'a378', 'a379',\n"
-        + "             'a380', 'a381', 'a382', 'a383', 'a384', 'a385', 
'a386', 'a387', 'a388', 'a389',\n"
-        + "             'a390', 'a391', 'a392', 'a393', 'a394', 'a395', 
'a396', 'a397', 'a398', 'a399',\n"
-        + "             'a400', 'a401', 'a402', 'a403', 'a404', 'a405', 
'a406', 'a407', 'a408', 'a409',\n"
-        + "             'a410', 'a411', 'a412', 'a413', 'a414', 'a415', 
'a416', 'a417', 'a418', 'a419',\n"
-        + "             'a420', 'a421', 'a422', 'a423', 'a424', 'a425', 
'a426', 'a427', 'a428', 'a429',\n"
-        + "             'a430', 'a431', 'a432', 'a433', 'a434', 'a435', 
'a436', 'a437', 'a438', 'a439',\n"
-        + "             'a440', 'a441', 'a442', 'a443', 'a444', 'a445', 
'a446', 'a447', 'a448', 'a449',\n"
-        + "             'a450', 'a451', 'a452', 'a453', 'a454', 'a455', 
'a456', 'a457', 'a458', 'a459',\n"
-        + "             'a460', 'a461', 'a462', 'a463', 'a464', 'a465', 
'a466', 'a467', 'a468', 'a469',\n"
-        + "             'a470', 'a471', 'a472', 'a473', 'a474', 'a475', 
'a476', 'a477', 'a478', 'a479',\n"
-        + "             'a480', 'a481', 'a482', 'a483', 'a484', 'a485', 
'a486', 'a487', 'a488', 'a489',\n"
-        + "             'a490', 'a491', 'a492', 'a493', 'a494', 'a495', 
'a496', 'a497', 'a498', 'a499'\n"
-        + "         )\n"
-        + "     )\n"
-        + "GROUP BY Carrier;";
+    // The sleep function is called with a literal value so it should be 
evaluated during the query compile phase
+    String query = "SET timeoutMs=100; SELECT sleep(1000) FROM mytable";
 
     JsonNode result = postQuery(query);
     JsonNode exceptionsJson = result.get("exceptions");
diff --git 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/SpoolIntegrationTest.java
 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/SpoolIntegrationTest.java
index 1c37808401..cbdeef2a7e 100644
--- 
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/SpoolIntegrationTest.java
+++ 
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/SpoolIntegrationTest.java
@@ -129,12 +129,17 @@ public class SpoolIntegrationTest extends 
BaseClusterIntegrationTest
 
   /**
    * Test a complex with nested spools.
-   *
+   * <p>
    * Don't try to understand the query, just check that the spools are correct.
    * This query is an actual simplification of a query used in production.
    * It was the way we detected problems fixed in <a 
href="https://github.com/apache/pinot/pull/15135";>#15135</a>.
+   * <p>
+   * This test was disabled after upgrading Calcite to 1.39.0 which introduces 
an optimization that removes some of the
+   * "nested spools" that this test expects. We should consider replacing the 
query in this test with a different one
+   * that doesn't get optimized similarly. In the long term, we should allow 
providing hints that disable such
+   * optimizations that would prevent spooling.
    */
-  @Test
+  @Test(enabled = false)
   public void testNestedSpools()
       throws Exception {
     JsonNode jsonNode = postQuery("SET useSpools = true;\n"
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
index 7626a58ec0..cfa5fbfa3f 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotEvaluateLiteralRule.java
@@ -18,6 +18,7 @@
  */
 package org.apache.pinot.calcite.rel.rules;
 
+import com.google.common.base.Preconditions;
 import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.util.ArrayList;
@@ -176,6 +177,9 @@ public class PinotEvaluateLiteralRule {
       return rexCall;
     }
     RelDataType rexNodeType = rexCall.getType();
+    if (rexNodeType.getSqlTypeName() == SqlTypeName.DECIMAL) {
+      rexNodeType = convertDecimalType(rexNodeType, rexBuilder);
+    }
     Object resultValue;
     try {
       QueryFunctionInvoker invoker = new QueryFunctionInvoker(functionInfo);
@@ -212,8 +216,16 @@ public class PinotEvaluateLiteralRule {
     try {
       if (rexNodeType instanceof ArraySqlType) {
         List<Object> resultValues = new ArrayList<>();
-        for (Object value : (Object[]) resultValue) {
-          resultValues.add(convertResultValue(value, 
rexNodeType.getComponentType()));
+
+        // SQL FLOAT and DOUBLE literals are represented as Java double
+        if (resultValue instanceof double[]) {
+          for (double value: (double[]) resultValue) {
+            resultValues.add(convertResultValue(value, 
rexNodeType.getComponentType()));
+          }
+        } else {
+          for (Object value : (Object[]) resultValue) {
+            resultValues.add(convertResultValue(value, 
rexNodeType.getComponentType()));
+          }
         }
         return rexBuilder.makeLiteral(resultValues, rexNodeType, false);
       }
@@ -224,6 +236,11 @@ public class PinotEvaluateLiteralRule {
     }
   }
 
+  private static RelDataType convertDecimalType(RelDataType relDataType, 
RexBuilder rexBuilder) {
+    Preconditions.checkArgument(relDataType.getSqlTypeName() == 
SqlTypeName.DECIMAL);
+    return 
RelToPlanNodeConverter.convertToColumnDataType(relDataType).toType(rexBuilder.getTypeFactory());
+  }
+
   @Nullable
   private static Object getLiteralValue(RexLiteral rexLiteral) {
     Object value = rexLiteral.getValue();
@@ -258,13 +275,18 @@ public class PinotEvaluateLiteralRule {
         return TimestampUtils.toMillisSinceEpoch(resultValue.toString());
       }
     }
-    // Return BigDecimal for numbers
-    if (resultValue instanceof Integer || resultValue instanceof Long) {
+    // Use BigDecimal for INTEGER / BIGINT / DECIMAL literals
+    if (relDataType.getSqlTypeName() == SqlTypeName.INTEGER || 
relDataType.getSqlTypeName() == SqlTypeName.BIGINT) {
       return new BigDecimal(((Number) resultValue).longValue());
     }
-    if (resultValue instanceof Float || resultValue instanceof Double) {
+    if (relDataType.getSqlTypeName() == SqlTypeName.DECIMAL) {
       return new BigDecimal(resultValue.toString());
     }
+    // Use double for FLOAT / DOUBLE literals
+    if (relDataType.getSqlTypeName() == SqlTypeName.FLOAT || 
relDataType.getSqlTypeName() == SqlTypeName.DOUBLE
+        || relDataType.getSqlTypeName() == SqlTypeName.REAL) {
+      return ((Number) resultValue).doubleValue();
+    }
     // Return ByteString for byte[]
     if (resultValue instanceof byte[]) {
       return new ByteString((byte[]) resultValue);
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotRuleUtils.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotRuleUtils.java
index d134c8af90..cb1bae0827 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotRuleUtils.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotRuleUtils.java
@@ -46,10 +46,15 @@ public class PinotRuleUtils {
   public static final RelBuilderFactory PINOT_REL_FACTORY =
       RelBuilder.proto(Contexts.of(RelFactories.DEFAULT_STRUCT, 
PINOT_REL_CONFIG));
 
-  public static final SqlToRelConverter.Config PINOT_SQL_TO_REL_CONFIG =
-      
SqlToRelConverter.config().withHintStrategyTable(PinotHintStrategyTable.PINOT_HINT_STRATEGY_TABLE)
-          
.withTrimUnusedFields(true).withExpand(true).withInSubQueryThreshold(Integer.MAX_VALUE)
-          .withRelBuilderFactory(PINOT_REL_FACTORY);
+  public static final SqlToRelConverter.Config PINOT_SQL_TO_REL_CONFIG = 
SqlToRelConverter.config()
+      .withHintStrategyTable(PinotHintStrategyTable.PINOT_HINT_STRATEGY_TABLE)
+      .withTrimUnusedFields(true)
+      // TODO: expansion is deprecated in Calcite; we need to move to the 
default value of false here which will be the
+      //       only supported option in Calcite going forward. This will 
probably require some changes in the planner
+      //       rules in order to support things like scalar query filters.
+      .withExpand(true)
+      .withInSubQueryThreshold(Integer.MAX_VALUE)
+      .withRelBuilderFactory(PINOT_REL_FACTORY);
 
   public static RelNode unboxRel(RelNode rel) {
     if (rel instanceof HepRelVertex) {
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRule.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRule.java
index 6785774590..06df84ac50 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRule.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRule.java
@@ -207,7 +207,7 @@ public class PinotWindowExchangeNodeInsertRule extends 
RelOptRule {
     }
 
     return windowChanged ? new Window.Group(oldWindowGroup.keys, 
oldWindowGroup.isRows, lowerBound, upperBound,
-        oldWindowGroup.orderKeys, newAggCallWindow) : oldWindowGroup;
+        oldWindowGroup.exclude, oldWindowGroup.orderKeys, newAggCallWindow) : 
oldWindowGroup;
   }
 
   @Nullable
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/PlanNodeToRelConverter.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/PlanNodeToRelConverter.java
index bc6ba26884..f19e9c4e6a 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/PlanNodeToRelConverter.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/PlanNodeToRelConverter.java
@@ -42,6 +42,7 @@ import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexWindowBound;
 import org.apache.calcite.rex.RexWindowBounds;
+import org.apache.calcite.rex.RexWindowExclusion;
 import org.apache.calcite.sql.SqlAggFunction;
 import org.apache.calcite.tools.RelBuilder;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -330,7 +331,7 @@ public final class PlanNodeToRelConverter {
 
         Window.Group group =
             new Window.Group(keys, isRow, 
getWindowBound(node.getLowerBound()), getWindowBound(node.getUpperBound()),
-                orderKeys, aggCalls);
+                RexWindowExclusion.EXCLUDE_NO_OTHER, orderKeys, aggCalls);
 
         List<RexLiteral> constants =
             node.getConstants().stream().map(constant -> 
RexExpressionUtils.toRexLiteral(_builder, constant))
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
index 775bbe17cb..d42f903ab9 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RelToPlanNodeConverter.java
@@ -49,6 +49,7 @@ import org.apache.calcite.rel.type.RelRecordType;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexWindowExclusion;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.pinot.calcite.rel.hint.PinotHintOptions;
@@ -206,12 +207,18 @@ public final class RelToPlanNodeConverter {
         convertInputs(node.getInputs()), literalRows);
   }
 
+  /**
+   * TODO: Add support for exclude clauses ({@link 
org.apache.calcite.rex.RexWindowExclusion})
+   */
   private WindowNode convertLogicalWindow(LogicalWindow node) {
     // Only a single Window Group should exist per WindowNode.
     Preconditions.checkState(node.groups.size() == 1, "Only a single window 
group is allowed, got: %s",
         node.groups.size());
     Window.Group windowGroup = node.groups.get(0);
 
+    Preconditions.checkState(windowGroup.exclude == 
RexWindowExclusion.EXCLUDE_NO_OTHER,
+        "EXCLUDE clauses for window functions are not currently supported");
+
     int numAggregates = windowGroup.aggCalls.size();
     List<RexExpression.FunctionCall> aggCalls = new ArrayList<>(numAggregates);
     for (int i = 0; i < numAggregates; i++) {
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
index 2cc63c6a01..afef239ff9 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/logical/RexExpressionUtils.java
@@ -115,11 +115,13 @@ public class RexExpressionUtils {
       }
       case FLOAT: {
         assert value != null;
-        return rexBuilder.makeApproxLiteral(BigDecimal.valueOf((float) value));
+        return rexBuilder.makeApproxLiteral((double) value,
+            rexBuilder.getTypeFactory().createSqlType(SqlTypeName.REAL));
       }
       case DOUBLE: {
         assert value != null;
-        return rexBuilder.makeApproxLiteral(BigDecimal.valueOf((double) 
value));
+        return rexBuilder.makeApproxLiteral((double) value,
+            rexBuilder.getTypeFactory().createSqlType(SqlTypeName.DOUBLE));
       }
       case BIG_DECIMAL: {
         assert value != null;
@@ -244,10 +246,10 @@ public class RexExpressionUtils {
         value = ((BigDecimal) value).longValue();
         break;
       case FLOAT:
-        value = ((BigDecimal) value).floatValue();
+        value = ((Double) value).floatValue();
         break;
       case DOUBLE:
-        value = ((BigDecimal) value).doubleValue();
+        value = ((Number) value).doubleValue();
         break;
       case BIG_DECIMAL:
         break;
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/serde/RexExpressionToProtoExpression.java
 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/serde/RexExpressionToProtoExpression.java
index 2053de0cc1..072256fe01 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/serde/RexExpressionToProtoExpression.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/planner/serde/RexExpressionToProtoExpression.java
@@ -92,7 +92,7 @@ public class RexExpressionToProtoExpression {
           literalBuilder.setFloat((Float) value);
           break;
         case DOUBLE:
-          literalBuilder.setDouble((Double) value);
+          literalBuilder.setDouble(((Number) value).doubleValue());
           break;
         case BIG_DECIMAL:
           
literalBuilder.setBytes(ByteString.copyFrom(BigDecimalUtils.serialize((BigDecimal)
 value)));
diff --git 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/type/TypeSystem.java 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/type/TypeSystem.java
index 5268e91edf..b40f913c4e 100644
--- 
a/pinot-query-planner/src/main/java/org/apache/pinot/query/type/TypeSystem.java
+++ 
b/pinot-query-planner/src/main/java/org/apache/pinot/query/type/TypeSystem.java
@@ -32,7 +32,7 @@ public class TypeSystem extends RelDataTypeSystemImpl {
   public static final TypeSystem INSTANCE = new TypeSystem();
 
   private static final int MAX_DECIMAL_SCALE = 1000;
-  private static final int MAX_DECIMAL_PRECISION = 1000;
+  private static final int MAX_DECIMAL_PRECISION = 2000;
 
   /**
    * Default precision for derived arithmetic decimal 
types(plus/multiply/divide/mod). We won't allow the return
@@ -62,16 +62,36 @@ public class TypeSystem extends RelDataTypeSystemImpl {
     return true;
   }
 
+  @Override
+  public int getMaxScale(SqlTypeName typeName) {
+    return typeName == SqlTypeName.DECIMAL ? MAX_DECIMAL_SCALE : 
super.getMaxScale(typeName);
+  }
+
   @Override
   public int getMaxNumericScale() {
     return MAX_DECIMAL_SCALE;
   }
 
+  @Override
+  public int getDefaultScale(SqlTypeName typeName) {
+    return typeName == SqlTypeName.DECIMAL ? MAX_DECIMAL_SCALE : 
super.getDefaultScale(typeName);
+  }
+
+  @Override
+  public int getMaxPrecision(SqlTypeName typeName) {
+    return typeName == SqlTypeName.DECIMAL ? MAX_DECIMAL_PRECISION : 
super.getMaxPrecision(typeName);
+  }
+
   @Override
   public int getMaxNumericPrecision() {
     return MAX_DECIMAL_PRECISION;
   }
 
+  @Override
+  public int getDefaultPrecision(SqlTypeName typeName) {
+    return typeName == SqlTypeName.DECIMAL ? MAX_DECIMAL_PRECISION : 
super.getDefaultPrecision(typeName);
+  }
+
   @Override
   public RelDataType deriveAvgAggType(RelDataTypeFactory typeFactory, 
RelDataType argumentType) {
     assert SqlTypeUtil.isNumeric(argumentType);
diff --git 
a/pinot-query-planner/src/test/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRuleTest.java
 
b/pinot-query-planner/src/test/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRuleTest.java
index cf8a5f33ce..0c2f86b634 100644
--- 
a/pinot-query-planner/src/test/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRuleTest.java
+++ 
b/pinot-query-planner/src/test/java/org/apache/pinot/calcite/rel/rules/PinotWindowExchangeNodeInsertRuleTest.java
@@ -34,6 +34,7 @@ import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexWindowBounds;
+import org.apache.calcite.rex.RexWindowExclusion;
 import org.apache.calcite.sql.fun.SqlSumAggFunction;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -99,9 +100,10 @@ public class PinotWindowExchangeNodeInsertRuleTest {
 
     List<Window.Group> groups = Collections.singletonList(
         new Window.Group(ImmutableBitSet.of(List.of(1)), true, 
RexWindowBounds.preceding(lowerBoundInputRef),
-            RexWindowBounds.following(upperBoundInputRef), 
RelCollations.of(2), List.of(
-            new Window.RexWinAggCall(new SqlSumAggFunction(intType), intType, 
List.of(windowFunctionInputRef), 0, false,
-                false))));
+            RexWindowBounds.following(upperBoundInputRef), 
RexWindowExclusion.EXCLUDE_NO_OTHER, RelCollations.of(2),
+            List.of(
+                new Window.RexWinAggCall(new SqlSumAggFunction(intType), 
intType, List.of(windowFunctionInputRef), 0,
+                    false, false))));
 
     List<RexLiteral> literals = List.of(REX_BUILDER.makeLiteral(5, intType), 
REX_BUILDER.makeLiteral(10, intType));
     LogicalWindow originalWindow = 
LogicalWindow.create(RelTraitSet.createEmpty(), _input, literals, intType, 
groups);
diff --git 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/QueryCompilationTest.java
 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/QueryCompilationTest.java
index a02032b7a8..a955727711 100644
--- 
a/pinot-query-planner/src/test/java/org/apache/pinot/query/QueryCompilationTest.java
+++ 
b/pinot-query-planner/src/test/java/org/apache/pinot/query/QueryCompilationTest.java
@@ -484,6 +484,12 @@ public class QueryCompilationTest extends 
QueryEnvironmentTestBase {
             + "CURRENT ROW) FROM a";
     e = expectThrows(RuntimeException.class, () -> 
_queryEnvironment.planQuery(ntileQueryWithNoArg));
     assertTrue(e.getMessage().contains("expecting 1 argument"));
+
+    String excludeCurrentRowQuery =
+        "SELECT col1, col2, SUM(col3) OVER (PARTITION BY col1 ORDER BY col2 
ROWS BETWEEN UNBOUNDED PRECEDING AND "
+            + "CURRENT ROW EXCLUDE CURRENT ROW) FROM a";
+    e = expectThrows(RuntimeException.class, () -> 
_queryEnvironment.planQuery(excludeCurrentRowQuery));
+    assertTrue(e.getMessage().contains("EXCLUDE clauses for window functions 
are not currently supported"));
   }
 
   @Test
diff --git a/pinot-query-planner/src/test/resources/queries/AggregatePlans.json 
b/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
index 25ee2878be..1fd3b3cd33 100644
--- a/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
+++ b/pinot-query-planner/src/test/resources/queries/AggregatePlans.json
@@ -6,16 +6,16 @@
         "sql": "EXPLAIN PLAN FOR SELECT AVG(a.col4) as avg FROM a WHERE a.col3 
>= (SELECT AVG(a.col4) FROM a)",
         "output": [
           "Execution Plan",
-          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(1000, 0), 
$0), $1)):DECIMAL(1000, 0)])",
+          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(2000, 
1000), $0), $1)):DECIMAL(2000, 1000)])",
           "\n  PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT($1)], aggType=[FINAL])",
           "\n    PinotLogicalExchange(distribution=[hash])",
-          "\n      PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($1)], 
agg#1=[COUNT()], aggType=[LEAF])",
-          "\n        LogicalJoin(condition=[>=($0, $2)], joinType=[inner])",
+          "\n      PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT()], aggType=[LEAF])",
+          "\n        LogicalJoin(condition=[>=($1, $2)], joinType=[inner])",
           "\n          PinotLogicalExchange(distribution=[random])",
-          "\n            LogicalProject(col3=[$2], col4=[$3])",
+          "\n            LogicalProject(col4=[$3], 
EXPR$0=[CAST($2):DECIMAL(2000, 1000) NOT NULL])",
           "\n              PinotLogicalTableScan(table=[[default, a]])",
           "\n          PinotLogicalExchange(distribution=[broadcast])",
-          "\n            LogicalProject(EXPR$0=[CAST(/(CASE(=($1, 0), 
null:DECIMAL(1000, 0), $0), $1)):DECIMAL(1000, 0)])",
+          "\n            LogicalProject(EXPR$0=[CAST(/(CASE(=($1, 0), 
null:DECIMAL(2000, 1000), $0), $1)):DECIMAL(2000, 1000)])",
           "\n              PinotLogicalAggregate(group=[{}], 
agg#0=[$SUM0($0)], agg#1=[COUNT($1)], aggType=[FINAL])",
           "\n                PinotLogicalExchange(distribution=[hash])",
           "\n                  PinotLogicalAggregate(group=[{}], 
agg#0=[$SUM0($3)], agg#1=[COUNT()], aggType=[LEAF])",
@@ -28,7 +28,7 @@
         "sql": "EXPLAIN PLAN FOR SELECT AVG(a.col4) as avg FROM a WHERE a.col3 
>= 0 AND a.col2 = 'pink floyd'",
         "output": [
           "Execution Plan",
-          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(1000, 0), 
$0), $1)):DECIMAL(1000, 0)])",
+          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(2000, 
1000), $0), $1)):DECIMAL(2000, 1000)])",
           "\n  PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT($1)], aggType=[FINAL])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($3)], 
agg#1=[COUNT()], aggType=[LEAF])",
@@ -42,7 +42,7 @@
         "sql": "EXPLAIN PLAN FOR SELECT AVG(a.col4) as avg, SUM(a.col4) as 
sum, MAX(a.col4) as max FROM a WHERE a.col3 >= 0 AND a.col2 = 'pink floyd'",
         "output": [
           "Execution Plan",
-          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(1000, 0), 
$0), $1)):DECIMAL(1000, 0)], sum=[CASE(=($1, 0), null:DECIMAL(1000, 0), $0)], 
max=[$2])",
+          "\nLogicalProject(avg=[CAST(/(CASE(=($1, 0), null:DECIMAL(2000, 
1000), $0), $1)):DECIMAL(2000, 1000)], sum=[CASE(=($1, 0), null:DECIMAL(2000, 
1000), $0)], max=[$2])",
           "\n  PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT($1)], agg#2=[MAX($2)], aggType=[FINAL])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($3)], 
agg#1=[COUNT()], agg#2=[MAX($3)], aggType=[LEAF])",
diff --git 
a/pinot-query-planner/src/test/resources/queries/BasicQueryPlans.json 
b/pinot-query-planner/src/test/resources/queries/BasicQueryPlans.json
index b11e0bbfd7..aa6be1cbfa 100644
--- a/pinot-query-planner/src/test/resources/queries/BasicQueryPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/BasicQueryPlans.json
@@ -87,11 +87,11 @@
         "sql": "EXPLAIN PLAN FOR SELECT SUM(CASE WHEN col3 > 10 THEN 1 WHEN 
col3 > 20 THEN 2 WHEN col3 > 30 THEN 3 WHEN col3 > 40 THEN 4 WHEN col3 > 50 
THEN '5' ELSE 0 END) FROM a",
         "output": [
           "Execution Plan",
-          "\nLogicalProject(EXPR$0=[CASE(=($1, 0), null:DECIMAL(1000, 500), 
$0)])",
+          "\nLogicalProject(EXPR$0=[CASE(=($1, 0), null:DECIMAL(2000, 1000), 
$0)])",
           "\n  PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT($1)], aggType=[FINAL])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      PinotLogicalAggregate(group=[{}], agg#0=[$SUM0($0)], 
agg#1=[COUNT()], aggType=[LEAF])",
-          "\n        LogicalProject($f0=[CAST(CASE(>($2, 10), 
_UTF-8'1':VARCHAR CHARACTER SET \"UTF-8\", >($2, 20), _UTF-8'2':VARCHAR 
CHARACTER SET \"UTF-8\", >($2, 30), _UTF-8'3':VARCHAR CHARACTER SET \"UTF-8\", 
>($2, 40), _UTF-8'4':VARCHAR CHARACTER SET \"UTF-8\", >($2, 50), 
_UTF-8'5':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'0':VARCHAR CHARACTER SET 
\"UTF-8\")):DECIMAL(1000, 500) NOT NULL])",
+          "\n        LogicalProject($f0=[CAST(CASE(>($2, 10), 
_UTF-8'1':VARCHAR CHARACTER SET \"UTF-8\", >($2, 20), _UTF-8'2':VARCHAR 
CHARACTER SET \"UTF-8\", >($2, 30), _UTF-8'3':VARCHAR CHARACTER SET \"UTF-8\", 
>($2, 40), _UTF-8'4':VARCHAR CHARACTER SET \"UTF-8\", >($2, 50), 
_UTF-8'5':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'0':VARCHAR CHARACTER SET 
\"UTF-8\")):DECIMAL(2000, 1000) NOT NULL])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
diff --git a/pinot-query-planner/src/test/resources/queries/GroupByPlans.json 
b/pinot-query-planner/src/test/resources/queries/GroupByPlans.json
index 41fe4192be..064a686d6c 100644
--- a/pinot-query-planner/src/test/resources/queries/GroupByPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/GroupByPlans.json
@@ -73,7 +73,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(col1=[$0], EXPR$1=[$1], EXPR$2=[$2])",
-          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5))])",
+          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[COUNT($1)], 
agg#1=[$SUM0($2)], agg#2=[MAX($3)], agg#3=[MIN($4)], aggType=[FINAL])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
           "\n        PinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($2)], agg#2=[MAX($2)], agg#3=[MIN($2)], aggType=[LEAF])",
@@ -88,7 +88,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(value1=[$0], count=[$1], SUM=[$2])",
-          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5))])",
+          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[COUNT($1)], 
agg#1=[$SUM0($2)], agg#2=[MAX($3)], agg#3=[MIN($4)], aggType=[FINAL])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
           "\n        PinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($2)], agg#2=[MAX($2)], agg#3=[MIN($2)], aggType=[LEAF])",
@@ -195,7 +195,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(col1=[$0], EXPR$1=[$1], EXPR$2=[$2])",
-          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5))])",
+          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($1)], agg#2=[MAX($1)], agg#3=[MIN($1)], aggType=[DIRECT])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
           "\n        LogicalProject(col1=[$0], col3=[$2])",
@@ -210,7 +210,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(col1=[$0], EXPR$1=[$1])",
-          "\n  LogicalFilter(condition=[AND(>=($2, 0), <($3, 20), <=($1, 10), 
=(/(CAST($1):DOUBLE NOT NULL, $4), 5))])",
+          "\n  LogicalFilter(condition=[AND(>=($2, 0), <($3, 20), <=($1, 10), 
=(/(CAST($1):DOUBLE NOT NULL, $4), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[$SUM0($1)], 
agg#1=[MAX($1)], agg#2=[MIN($1)], agg#3=[COUNT()], aggType=[DIRECT])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
           "\n        LogicalProject(col1=[$0], col3=[$2])",
@@ -225,7 +225,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(value1=[$0], count=[$1], SUM=[$2])",
-          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5))])",
+          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($3, 0), <($4, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($1)], agg#2=[MAX($1)], agg#3=[MIN($1)], aggType=[DIRECT])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
           "\n        LogicalProject(col1=[$0], col3=[$2])",
diff --git a/pinot-query-planner/src/test/resources/queries/JoinPlans.json 
b/pinot-query-planner/src/test/resources/queries/JoinPlans.json
index 279ae6d7cb..c9ccb17b3a 100644
--- a/pinot-query-planner/src/test/resources/queries/JoinPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/JoinPlans.json
@@ -193,11 +193,11 @@
           "\n  LogicalJoin(condition=[=($0, $1)], joinType=[inner])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0])",
-          "\n        LogicalFilter(condition=[SEARCH($1, Sarg[_UTF-8'bar', 
_UTF-8'foo']:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[_UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'foo':VARCHAR CHARACTER 
SET \"UTF-8\"]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col2=[$1])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'alice':VARCHAR(7) CHARACTER SET \"UTF-8\"), 
(_UTF-8'alice':VARCHAR(7) CHARACTER SET \"UTF-8\".._UTF-8'charlie':VARCHAR(7) 
CHARACTER SET \"UTF-8\"), (_UTF-8'charlie':VARCHAR(7) CHARACTER SET 
\"UTF-8\"..+∞)]:VARCHAR(7) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'alice':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'alice':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'charlie':VARCHAR 
CHARACTER SET \"UTF-8\"), (_UTF-8'charlie':VARCHAR CHARACTER SET 
\"UTF-8\"..+∞)]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, b]])",
           "\n"
         ]
@@ -211,11 +211,11 @@
           "\n  LogicalJoin(condition=[=($0, $1)], joinType=[inner])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0])",
-          "\n        LogicalFilter(condition=[SEARCH($1, Sarg[_UTF-8'bar', 
_UTF-8'foo']:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[_UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'foo':VARCHAR CHARACTER 
SET \"UTF-8\"]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col2=[$1])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'alice':VARCHAR(7) CHARACTER SET \"UTF-8\"), 
(_UTF-8'alice':VARCHAR(7) CHARACTER SET \"UTF-8\".._UTF-8'charlie':VARCHAR(7) 
CHARACTER SET \"UTF-8\"), (_UTF-8'charlie':VARCHAR(7) CHARACTER SET 
\"UTF-8\"..+∞)]:VARCHAR(7) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'alice':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'alice':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'charlie':VARCHAR 
CHARACTER SET \"UTF-8\"), (_UTF-8'charlie':VARCHAR CHARACTER SET 
\"UTF-8\"..+∞)]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, b]])",
           "\n"
         ]
@@ -408,7 +408,7 @@
           "\n      LogicalProject(col1=[$0], col2=[$1], col4=[$3])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0, 1]])",
-          "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[*(0.5:DECIMAL(2, 1), $2)])",
+          "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[CAST(*(0.5:DECIMAL(2, 1), $2)):DECIMAL(2000, 1000)])",
           "\n        PinotLogicalAggregate(group=[{0, 1}], agg#0=[$SUM0($2)], 
aggType=[FINAL])",
           "\n          PinotLogicalExchange(distribution=[hash[0, 1]])",
           "\n            PinotLogicalAggregate(group=[{0, 1}], 
agg#0=[$SUM0($2)], aggType=[LEAF])",
@@ -427,11 +427,12 @@
           "\n      LogicalProject(col1=[$0], col2=[$1], col4=[$3])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0, 1]])",
-          "\n      PinotLogicalAggregate(group=[{0, 1}], agg#0=[$SUM0($2)], 
aggType=[FINAL])",
-          "\n        PinotLogicalExchange(distribution=[hash[0, 1]])",
-          "\n          PinotLogicalAggregate(group=[{0, 1}], 
agg#0=[$SUM0($2)], aggType=[LEAF])",
-          "\n            LogicalProject(col1=[$0], col2=[$1], 
$f0=[*(0.5:DECIMAL(2, 1), $2)])",
-          "\n              PinotLogicalTableScan(table=[[default, b]])",
+          "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[CAST($2):DECIMAL(2000, 1000)])",
+          "\n        PinotLogicalAggregate(group=[{0, 1}], agg#0=[$SUM0($2)], 
aggType=[FINAL])",
+          "\n          PinotLogicalExchange(distribution=[hash[0, 1]])",
+          "\n            PinotLogicalAggregate(group=[{0, 1}], 
agg#0=[$SUM0($2)], aggType=[LEAF])",
+          "\n              LogicalProject(col1=[$0], col2=[$1], 
$f0=[*(0.5:DECIMAL(2, 1), $2)])",
+          "\n                PinotLogicalTableScan(table=[[default, b]])",
           "\n"
         ]
       },
@@ -446,7 +447,7 @@
           "\n      LogicalProject(col1=[$0], col2=[$1], col4=[$3])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0, 1]])",
-          "\n      LogicalProject(col1=[$0], col2=[$1], EXPR$0=[CAST(/($2, 
$3)):DECIMAL(12, 1) NOT NULL])",
+          "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[CAST(CAST(/($2, $3)):DECIMAL(12, 1) NOT NULL):DECIMAL(2000, 1000)])",
           "\n        PinotLogicalAggregate(group=[{0, 1}], agg#0=[$SUM0($2)], 
agg#1=[COUNT($3)], aggType=[FINAL])",
           "\n          PinotLogicalExchange(distribution=[hash[0, 1]])",
           "\n            PinotLogicalAggregate(group=[{0, 1}], 
agg#0=[$SUM0($2)], agg#1=[COUNT()], aggType=[LEAF])",
@@ -463,7 +464,7 @@
           "\nLogicalProject(col1=[$0])",
           "\n  LogicalJoin(condition=[AND(=($0, $3), =($1, $4), >($2, $5))], 
joinType=[inner])",
           "\n    PinotLogicalExchange(distribution=[hash[0, 1]])",
-          "\n      LogicalProject(col1=[$0], col2=[$1], col4=[$3])",
+          "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[CAST($3):DOUBLE NOT NULL])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[hash[0, 1]])",
           "\n      LogicalProject(col1=[$0], col2=[$1], 
EXPR$0=[*(0.5:DECIMAL(2, 1), /(CAST($2):DOUBLE NOT NULL, $3))])",
@@ -522,7 +523,7 @@
           "\n      PinotLogicalTableScan(table=[[default, a]])",
           "\n      PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n        LogicalProject(col1=[$0])",
-          "\n          LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\")])",
+          "\n          LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\")])",
           "\n            PinotLogicalTableScan(table=[[default, a]])",
           "\n    PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n      LogicalProject(col1=[$0])",
@@ -550,7 +551,7 @@
           "\n              PinotLogicalTableScan(table=[[default, a]])",
           "\n            PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n              LogicalProject(col1=[$0])",
-          "\n                LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\")])",
+          "\n                LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\")])",
           "\n                  PinotLogicalTableScan(table=[[default, a]])",
           "\n        PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n          LogicalProject(col3=[$2])",
@@ -576,7 +577,7 @@
           "\n                  PinotLogicalTableScan(table=[[default, a]])",
           "\n                PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n                  LogicalProject(col1=[$0])",
-          "\n                    LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\")])",
+          "\n                    LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\")])",
           "\n                      PinotLogicalTableScan(table=[[default, 
a]])",
           "\n            PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n              LogicalProject(col3=[$2])",
@@ -596,11 +597,11 @@
           "\n      PinotLogicalTableScan(table=[[default, b]])",
           "\n    PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n      LogicalProject(col1=[$0])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n  PinotLogicalExchange(distribution=[broadcast], 
relExchangeType=[PIPELINE_BREAKER])",
           "\n    LogicalProject(col3=[$2])",
-          "\n      LogicalFilter(condition=[SEARCH($1, Sarg[(-∞.._UTF-8'bar'), 
(_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET 
\"UTF-8\")])",
+          "\n      LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\")])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -628,7 +629,7 @@
           "\n                              LogicalJoin(condition=[=($1, $2)], 
joinType=[left])",
           "\n                                
PinotLogicalExchange(distribution=[hash[1]])",
           "\n                                  LogicalProject(col3=[$2], 
col30=[$2])",
-          "\n                                    
LogicalFilter(condition=[AND(=($0, _UTF-8'foo'), =($1, _UTF-8'xylo'), =($3, 
12), NOT($4))])",
+          "\n                                    
LogicalFilter(condition=[AND(=($0, _UTF-8'foo'), =($1, _UTF-8'xylo'), =($3, 
12.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 [...]
           "\n                                      
PinotLogicalTableScan(table=[[default, a]])",
           "\n                                
PinotLogicalExchange(distribution=[hash[0]])",
           "\n                                  LogicalProject(col3=[$0], 
$f1=[$1])",
diff --git 
a/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json 
b/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
index 3f9e73e0f6..5389c9cada 100644
--- a/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/LiteralEvaluationPlans.json
@@ -155,7 +155,7 @@
         "sql": "EXPLAIN PLAN FOR SELECT 
CAST('12345678901234567890123456789.1234567890123456789' AS DECIMAL) FROM a",
         "output": [
           "Execution Plan",
-          
"\nLogicalProject(EXPR$0=[12345678901234567890123456789.1234567890123456789:DECIMAL(1000,
 0)])",
+          
"\nLogicalProject(EXPR$0=[12345678901234567890123456789.123456789012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 [...]
           "\n  PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
diff --git 
a/pinot-query-planner/src/test/resources/queries/PinotHintablePlans.json 
b/pinot-query-planner/src/test/resources/queries/PinotHintablePlans.json
index 2839c212d4..41d5693735 100644
--- a/pinot-query-planner/src/test/resources/queries/PinotHintablePlans.json
+++ b/pinot-query-planner/src/test/resources/queries/PinotHintablePlans.json
@@ -152,10 +152,10 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(col2=[$0], EXPR$1=[$1], EXPR$2=[$2], EXPR$3=[$3])",
-          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($4, 0), <($5, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5))])",
+          "\n  LogicalFilter(condition=[AND(>($1, 10), >=($4, 0), <($5, 20), 
<=($2, 10), =(/(CAST($2):DOUBLE NOT NULL, $1), 5.0E0))])",
           "\n    PinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($1)], agg#2=[$SUM0($2)], agg#3=[MAX($1)], agg#4=[MIN($1)], 
aggType=[DIRECT])",
           "\n      PinotLogicalExchange(distribution=[hash[0]])",
-          "\n        LogicalProject(col2=[$1], col3=[$2], 
$f2=[CAST($0):DECIMAL(1000, 500) NOT NULL])",
+          "\n        LogicalProject(col2=[$1], col3=[$2], 
$f2=[CAST($0):DECIMAL(2000, 1000) NOT NULL])",
           "\n          LogicalFilter(condition=[AND(>=($2, 0), =($1, 
_UTF-8'a'))])",
           "\n            PinotLogicalTableScan(table=[[default, a]])",
           "\n"
@@ -167,7 +167,7 @@
         "output": [
           "Execution Plan",
           "\nPinotLogicalAggregate(group=[{0}], agg#0=[COUNT()], 
agg#1=[$SUM0($1)], agg#2=[$SUM0($2)], aggType=[DIRECT])",
-          "\n  LogicalProject(col2=[$1], col3=[$2], 
$f2=[CAST($0):DECIMAL(1000, 500) NOT NULL])",
+          "\n  LogicalProject(col2=[$1], col3=[$2], 
$f2=[CAST($0):DECIMAL(2000, 1000) NOT NULL])",
           "\n    LogicalFilter(condition=[AND(>=($2, 0), =($1, _UTF-8'a'))])",
           "\n      PinotLogicalTableScan(table=[[default, a]])",
           "\n"
diff --git 
a/pinot-query-planner/src/test/resources/queries/WindowFunctionPlans.json 
b/pinot-query-planner/src/test/resources/queries/WindowFunctionPlans.json
index 8eec5a5065..f1f6da0973 100644
--- a/pinot-query-planner/src/test/resources/queries/WindowFunctionPlans.json
+++ b/pinot-query-planner/src/test/resources/queries/WindowFunctionPlans.json
@@ -218,7 +218,7 @@
           "\n  LogicalWindow(window#0=[window(aggs [MIN($0)])])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      LogicalProject(col3=[$2], $1=[CONCAT($0, _UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[SEARCH($0, Sarg[_UTF-8'bar', 
_UTF-8'foo']:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($0, 
Sarg[_UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'foo':VARCHAR CHARACTER 
SET \"UTF-8\"]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -457,7 +457,7 @@
           "\n  LogicalWindow(window#0=[window(aggs [MIN($0), MAX($0)])])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      LogicalProject(col3=[$2], $1=[LENGTH(CONCAT($0, _UTF-8' ', 
$1))])",
-          "\n        LogicalFilter(condition=[SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -472,7 +472,7 @@
           "\n  LogicalWindow(window#0=[window(rows between UNBOUNDED PRECEDING 
and CURRENT ROW aggs [ROW_NUMBER()])])",
           "\n    PinotLogicalExchange(distribution=[hash])",
           "\n      LogicalProject($0=[LENGTH(CONCAT($0, _UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -762,7 +762,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} aggs [SUM($1), 
COUNT($1)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col2=[$1], col3=[$2], $2=[CONCAT($0, 
_UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1099,7 +1099,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} aggs [SUM($1), 
COUNT($1), COUNT($0)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col3=[$2])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1113,7 +1113,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} aggs [MIN($1), 
MAX($1)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col3=[$2], $2=[REVERSE(CONCAT($0, 
_UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1605,7 +1605,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] aggs [SUM($1), 
COUNT($1)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col2=[$1], col3=[$2], $2=[CONCAT($0, 
_UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1619,7 +1619,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] rows between 
UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col2=[$1], $1=[CONCAT($0, _UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1633,7 +1633,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] aggs [RANK()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col2=[$1], $1=[CONCAT($0, _UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1922,7 +1922,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] aggs [SUM($1), 
COUNT($1), COUNT($0)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col3=[$2])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1936,7 +1936,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] aggs [MIN($1), 
MAX($1)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col3=[$2], $2=[REVERSE(CONCAT($0, 
_UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -1950,7 +1950,7 @@
           "\n  LogicalWindow(window#0=[window(order by [0] aggs [RANK(), 
DENSE_RANK()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], $1=[REVERSE(CONCAT($0, _UTF-8' ', 
$1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2270,7 +2270,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[SUM($1), COUNT($1)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col2=[$1], col3=[$2], $2=[CONCAT($0, 
_UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2284,7 +2284,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[RANK()])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col2=[$1], $1=[CONCAT($0, _UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2571,7 +2571,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[SUM($1), COUNT($1), COUNT($0)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col3=[$2])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2584,7 +2584,7 @@
           "\nLogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[RANK(), DENSE_RANK()])])",
           "\n  PinotLogicalExchange(distribution=[hash[0]])",
           "\n    LogicalProject(col1=[$0])",
-          "\n      LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n      LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2598,7 +2598,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[MIN($1), MAX($1)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col3=[$2], $2=[REVERSE(CONCAT($0, 
_UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2612,7 +2612,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [0] aggs 
[DENSE_RANK(), MAX($1)])])",
           "\n    PinotLogicalExchange(distribution=[hash[0]])",
           "\n      LogicalProject(col1=[$0], col3=[$2], $2=[REVERSE(CONCAT($0, 
_UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2956,7 +2956,7 @@
           "\n  LogicalWindow(window#0=[window(partition {1} order by [0] aggs 
[SUM($2), COUNT($2)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[1]], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], col3=[$2], 
$3=[CONCAT($0, _UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2970,7 +2970,7 @@
           "\n  LogicalWindow(window#0=[window(partition {1} order by [0] rows 
between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[1]], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], $2=[CONCAT($0, 
_UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -2984,7 +2984,7 @@
           "\n  LogicalWindow(window#0=[window(partition {1} order by [0] aggs 
[RANK()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[1]], 
collation=[[0]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], $2=[CONCAT($0, 
_UTF-8'-', $1)])",
-          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'foo'), (_UTF-8'foo'..+∞)]:CHAR(3) 
CHARACTER SET \"UTF-8\"), >=($2, 42))])",
+          "\n        LogicalFilter(condition=[OR(SEARCH($0, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR CHARACTER SET 
\"UTF-8\"), >=($2, 42))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3233,7 +3233,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [1] aggs 
[SUM($2), COUNT($2), COUNT($0)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], col3=[$2])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3247,7 +3247,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [1] rows 
between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3261,7 +3261,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [1] aggs 
[RANK(), DENSE_RANK()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1])",
-          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR(9) CHARACTER SET \"UTF-8\", 
_UTF-8'vader':VARCHAR(9) CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR(9) 
CHARACTER SET \"UTF-8\"]:VARCHAR(9) CHARACTER SET \"UTF-8\"))])",
+          "\n        LogicalFilter(condition=[AND(>($2, 42), SEARCH($0, 
Sarg[_UTF-8'chewbacca':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'vader':VARCHAR 
CHARACTER SET \"UTF-8\", _UTF-8'yoda':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR 
CHARACTER SET \"UTF-8\"))])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3275,7 +3275,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [1] aggs 
[MIN($2), MAX($2)])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], col3=[$2], 
$3=[REVERSE(CONCAT($0, _UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3289,7 +3289,7 @@
           "\n  LogicalWindow(window#0=[window(partition {0} order by [1] aggs 
[DENSE_RANK(), RANK()])])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], $2=[REVERSE(CONCAT($0, 
_UTF-8' ', $1))])",
-          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar'), (_UTF-8'bar'.._UTF-8'baz'), (_UTF-8'baz'.._UTF-8'foo'), 
(_UTF-8'foo'..+∞)]:CHAR(3) CHARACTER SET \"UTF-8\")])",
+          "\n        LogicalFilter(condition=[SEARCH($1, 
Sarg[(-∞.._UTF-8'bar':VARCHAR CHARACTER SET \"UTF-8\"), (_UTF-8'bar':VARCHAR 
CHARACTER SET \"UTF-8\".._UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\"), 
(_UTF-8'baz':VARCHAR CHARACTER SET \"UTF-8\".._UTF-8'foo':VARCHAR CHARACTER SET 
\"UTF-8\"), (_UTF-8'foo':VARCHAR CHARACTER SET \"UTF-8\"..+∞)]:VARCHAR 
CHARACTER SET \"UTF-8\")])",
           "\n          PinotLogicalTableScan(table=[[default, a]])",
           "\n"
         ]
@@ -3473,7 +3473,7 @@
           "\n                  PinotLogicalTableScan(table=[[default, a]])",
           "\n            PinotLogicalExchange(distribution=[hash[0]])",
           "\n              LogicalProject(col2=[$1])",
-          "\n                LogicalFilter(condition=[SEARCH($0, 
Sarg[_UTF-8'brandon sanderson':VARCHAR(17) CHARACTER SET \"UTF-8\", 
_UTF-8'douglas adams':VARCHAR(17) CHARACTER SET \"UTF-8\"]:VARCHAR(17) 
CHARACTER SET \"UTF-8\")])",
+          "\n                LogicalFilter(condition=[SEARCH($0, 
Sarg[_UTF-8'brandon sanderson':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'douglas 
adams':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n                  PinotLogicalTableScan(table=[[default, b]])",
           "\n"
         ]
@@ -3495,7 +3495,7 @@
           "\n                  PinotLogicalTableScan(table=[[default, a]])",
           "\n            PinotLogicalExchange(distribution=[hash[0]])",
           "\n              LogicalProject(col2=[$1])",
-          "\n                LogicalFilter(condition=[SEARCH($0, 
Sarg[_UTF-8'brandon sanderson':VARCHAR(17) CHARACTER SET \"UTF-8\", 
_UTF-8'douglas adams':VARCHAR(17) CHARACTER SET \"UTF-8\"]:VARCHAR(17) 
CHARACTER SET \"UTF-8\")])",
+          "\n                LogicalFilter(condition=[SEARCH($0, 
Sarg[_UTF-8'brandon sanderson':VARCHAR CHARACTER SET \"UTF-8\", _UTF-8'douglas 
adams':VARCHAR CHARACTER SET \"UTF-8\"]:VARCHAR CHARACTER SET \"UTF-8\")])",
           "\n                  PinotLogicalTableScan(table=[[default, b]])",
           "\n"
         ]
@@ -3519,7 +3519,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject($0=[$3])",
-          "\n  LogicalWindow(window#0=[window(partition {0} order by [2] aggs 
[LEAD($1, 2)])])",
+          "\n  LogicalWindow(window#0=[window(partition {0} order by [2] aggs 
[LEAD($1, 2)])], constants=[[2]])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[2]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col2=[$1], col3=[$2])",
           "\n        PinotLogicalTableScan(table=[[default, a]])",
@@ -3532,7 +3532,7 @@
         "output": [
           "Execution Plan",
           "\nLogicalProject(EXPR$0=[/(CAST(CASE(>($2, 0), $3, 
null:BIGINT)):DOUBLE, $2)])",
-          "\n  LogicalWindow(window#0=[window(partition {0} order by [1] rows 
between 5 PRECEDING and 10 FOLLOWING aggs [COUNT($1), $SUM0($1)])])",
+          "\n  LogicalWindow(window#0=[window(partition {0} order by [1] rows 
between 5 PRECEDING and 10 FOLLOWING aggs [COUNT($1), SUM($1)])], 
constants=[[5, 10]])",
           "\n    PinotLogicalSortExchange(distribution=[hash[0]], 
collation=[[1]], isSortOnSender=[false], isSortOnReceiver=[true])",
           "\n      LogicalProject(col1=[$0], col3=[$2])",
           "\n        LogicalFilter(condition=[>=($2, 0)])",
@@ -3676,7 +3676,7 @@
       {
         "description": "Apache Calcite failures with ROW_NUMBER() window 
functions - even default frame cannot be specified",
         "sql": "EXPLAIN PLAN FOR SELECT ROW_NUMBER() OVER(PARTITION BY a.col1 
ORDER BY a.col2 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM a",
-        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER or PERCENTILE_CONT/DISC functions.*"
+        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER, PERCENTILE_CONT/DISC or LAG/LEAD functions.*"
       },
       {
         "description": "Apache Calcite failures with ROW_NUMBER() window 
functions - default frame for ROW_NUMBER is different from aggregation window 
functions, resulting in multiple window groups",
@@ -3686,12 +3686,12 @@
       {
         "description": "Apache Calcite failures with ROW_NUMBER() window 
functions - custom frames not allowed",
         "sql": "EXPLAIN PLAN FOR SELECT ROW_NUMBER() OVER(PARTITION BY a.col1 
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM a",
-        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER or PERCENTILE_CONT/DISC functions.*"
+        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER, PERCENTILE_CONT/DISC or LAG/LEAD functions.*"
       },
       {
         "description": "Apache Calcite failures with ROW_NUMBER() window 
functions - custom frames not allowed",
         "sql": "EXPLAIN PLAN FOR SELECT ROW_NUMBER() OVER(PARTITION BY a.col1 
ROWS 2 PRECEDING) FROM a",
-        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER or PERCENTILE_CONT/DISC functions.*"
+        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER, PERCENTILE_CONT/DISC or LAG/LEAD functions.*"
       },
       {
         "description": "Apache Calcite failures with ROW_NUMBER() window 
functions - passing argument to ROW_NUMBER() should fail",
@@ -3731,12 +3731,12 @@
       {
         "description": "Apache Calcite failures with RANK() window functions - 
cannot take default frame specification, even though same as actual frame if no 
frame specified",
         "sql": "EXPLAIN PLAN FOR SELECT RANK() OVER(ORDER BY a.col1 RANGE 
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM a",
-        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER or PERCENTILE_CONT/DISC functions.*"
+        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER, PERCENTILE_CONT/DISC or LAG/LEAD functions.*"
       },
       {
         "description": "Apache Calcite failures with DENSE_RANK() window 
functions - cannot take default frame specification, even though same as actual 
frame if no frame specified",
         "sql": "EXPLAIN PLAN FOR SELECT DENSE_RANK() OVER(ORDER BY a.col1 
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM a",
-        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER or PERCENTILE_CONT/DISC functions.*"
+        "expectedException": ".*ROW/RANGE not allowed with RANK, DENSE_RANK, 
ROW_NUMBER, PERCENTILE_CONT/DISC or LAG/LEAD functions.*"
       }
     ]
   }
diff --git a/pom.xml b/pom.xml
index 29a05f4621..2b99e37aa5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -154,7 +154,7 @@
     <jsonpath.version>2.9.0</jsonpath.version>
     <jsonsmart.version>2.5.2</jsonsmart.version>
     <quartz.version>2.5.0</quartz.version>
-    <calcite.version>1.37.0</calcite.version>
+    <calcite.version>1.39.0</calcite.version>
     <immutables.version>2.10.1</immutables.version>
     <lucene.version>9.12.0</lucene.version>
     <reflections.version>0.10.2</reflections.version>


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to