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