This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch branch-2.1 in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push: new c12137a8d6f [branch-2.1][fix](expr) Enhance SQL Expression Handling by Introducing printSqlInParens to CompoundPredicate (#39082) c12137a8d6f is described below commit c12137a8d6ff9faf72a4c885134fb698393e2ea3 Author: zy-kkk <zhongy...@gmail.com> AuthorDate: Wed Aug 14 21:14:58 2024 +0800 [branch-2.1][fix](expr) Enhance SQL Expression Handling by Introducing printSqlInParens to CompoundPredicate (#39082) pick #39064 --- .../apache/doris/analysis/CompoundPredicate.java | 2 + .../doris/datasource/jdbc/source/JdbcScanNode.java | 34 +--------- .../doris/analysis/CancelExportStmtTest.java | 4 +- .../apache/doris/analysis/CancelLoadStmtTest.java | 4 +- .../org/apache/doris/analysis/SelectStmtTest.java | 28 ++++----- .../doris/analysis/ShowBuildIndexStmtTest.java | 8 +-- .../org/apache/doris/analysis/SqlModeTest.java | 2 +- .../org/apache/doris/planner/QueryPlanTest.java | 23 ++++--- .../java/org/apache/doris/policy/PolicyTest.java | 10 +-- .../org/apache/doris/qe/OlapQueryCacheTest.java | 40 ++++++------ .../ExtractCommonFactorsRuleFunctionTest.java | 6 +- .../get_assignment_compatible_type.out | 2 +- .../jdbc/test_clickhouse_jdbc_catalog.groovy | 2 +- .../explain/test_compoundpredicate_explain.groovy | 72 ++++++++++++++++++++++ 14 files changed, 139 insertions(+), 98 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java index 78e28da6ed9..8e6b0b31573 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CompoundPredicate.java @@ -61,11 +61,13 @@ public class CompoundPredicate extends Predicate { if (e2 != null) { children.add(e2); } + printSqlInParens = true; } protected CompoundPredicate(CompoundPredicate other) { super(other); op = other.op; + printSqlInParens = true; } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/source/JdbcScanNode.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/source/JdbcScanNode.java index a85dd4aaafb..ba7e684820c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/source/JdbcScanNode.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/source/JdbcScanNode.java @@ -20,8 +20,6 @@ package org.apache.doris.datasource.jdbc.source; import org.apache.doris.analysis.Analyzer; import org.apache.doris.analysis.BinaryPredicate; import org.apache.doris.analysis.BoolLiteral; -import org.apache.doris.analysis.CompoundPredicate; -import org.apache.doris.analysis.CompoundPredicate.Operator; import org.apache.doris.analysis.DateLiteral; import org.apache.doris.analysis.Expr; import org.apache.doris.analysis.ExprSubstitutionMap; @@ -321,36 +319,6 @@ public class JdbcScanNode extends ExternalScanNode { } public static String conjunctExprToString(TOdbcTableType tableType, Expr expr, TableIf tbl) { - if (expr instanceof CompoundPredicate) { - StringBuilder result = new StringBuilder(); - CompoundPredicate compoundPredicate = (CompoundPredicate) expr; - - // If the operator is 'NOT', prepend 'NOT' to the start of the string - if (compoundPredicate.getOp() == Operator.NOT) { - result.append("NOT "); - } - - // Iterate through all children of the CompoundPredicate - for (Expr child : compoundPredicate.getChildren()) { - // Recursively call conjunctExprToString for each child and append to the result - result.append(conjunctExprToString(tableType, child, tbl)); - - // If the operator is not 'NOT', append the operator after each child expression - if (!(compoundPredicate.getOp() == Operator.NOT)) { - result.append(" ").append(compoundPredicate.getOp().toString()).append(" "); - } - } - - // For operators other than 'NOT', remove the extra appended operator at the end - // This is necessary for operators like 'AND' or 'OR' that appear between child expressions - if (!(compoundPredicate.getOp() == Operator.NOT)) { - result.setLength(result.length() - compoundPredicate.getOp().toString().length() - 2); - } - - // Return the processed string trimmed of any extra spaces - return result.toString().trim(); - } - if (expr.contains(DateLiteral.class) && expr instanceof BinaryPredicate) { ArrayList<Expr> children = expr.getChildren(); String filter = children.get(0).toExternalSql(TableType.JDBC_EXTERNAL_TABLE, tbl); @@ -367,7 +335,7 @@ public class JdbcScanNode extends ExternalScanNode { return filter; } - // only for old planner + // Only for old planner if (expr.contains(BoolLiteral.class) && "1".equals(expr.getStringValue()) && expr.getChildren().isEmpty()) { return "1 = 1"; } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java index 8808597ac3e..2d188230d8b 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelExportStmtTest.java @@ -93,7 +93,7 @@ public class CancelExportStmtTest extends TestWithFeService { stmt = new CancelExportStmt(null, compoundAndPredicate); stmt.analyze(analyzer); Assertions.assertEquals( - "CANCEL EXPORT FROM testDb WHERE (`label` = 'doris_test_label') AND (`state` = 'PENDING')", + "CANCEL EXPORT FROM testDb WHERE ((`label` = 'doris_test_label') AND (`state` = 'PENDING'))", stmt.toString()); CompoundPredicate compoundOrPredicate = new CompoundPredicate(Operator.OR, labelBinaryPredicate, @@ -101,7 +101,7 @@ public class CancelExportStmtTest extends TestWithFeService { stmt = new CancelExportStmt(null, compoundOrPredicate); stmt.analyze(analyzer); Assertions.assertEquals( - "CANCEL EXPORT FROM testDb WHERE (`label` = 'doris_test_label') OR (`state` = 'PENDING')", + "CANCEL EXPORT FROM testDb WHERE ((`label` = 'doris_test_label') OR (`state` = 'PENDING'))", stmt.toString()); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelLoadStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelLoadStmtTest.java index f51ac74c342..6e8bea509f6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelLoadStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CancelLoadStmtTest.java @@ -94,7 +94,7 @@ public class CancelLoadStmtTest extends TestWithFeService { stmt = new CancelLoadStmt(null, compoundAndPredicate); stmt.analyze(analyzer); Assertions.assertEquals( - "CANCEL LOAD FROM testDb WHERE (`label` = 'doris_test_label') AND (`state` = 'LOADING')", + "CANCEL LOAD FROM testDb WHERE ((`label` = 'doris_test_label') AND (`state` = 'LOADING'))", stmt.toString()); CompoundPredicate compoundOrPredicate = new CompoundPredicate(Operator.OR, labelBinaryPredicate, @@ -102,7 +102,7 @@ public class CancelLoadStmtTest extends TestWithFeService { stmt = new CancelLoadStmt(null, compoundOrPredicate); stmt.analyze(analyzer); Assertions.assertEquals( - "CANCEL LOAD FROM testDb WHERE (`label` = 'doris_test_label') OR (`state` = 'LOADING')", + "CANCEL LOAD FROM testDb WHERE ((`label` = 'doris_test_label') OR (`state` = 'LOADING'))", stmt.toString()); // test match diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java index cc01f66a9c9..fe342841f25 100755 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/SelectStmtTest.java @@ -301,9 +301,9 @@ public class SelectStmtTest { String commonExpr2 = "`t3`.`k3` = `t1`.`k3`"; String commonExpr3 = "`t1`.`k1` = `t5`.`k1`"; String commonExpr4 = "t5`.`k2` = 'United States'"; - String betweenExpanded1 = "(CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) >= 100) AND (CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) <= 150)"; - String betweenExpanded2 = "(CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) >= 50) AND (CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) <= 100)"; - String betweenExpanded3 = "(`t1`.`k4` >= 50) AND (`t1`.`k4` <= 250)"; + String betweenExpanded1 = "(CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) >= 100)) AND (CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) <= 150))"; + String betweenExpanded2 = "(CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) >= 50)) AND (CAST(CAST(`t1`.`k4` AS decimalv3(12,2)) AS int) <= 100))"; + String betweenExpanded3 = "(`t1`.`k4` >= 50)) AND (`t1`.`k4` <= 250)"; String rewrittenSql = stmt.toSql(); Assert.assertTrue(rewrittenSql.contains(commonExpr1)); @@ -347,17 +347,17 @@ public class SelectStmtTest { SelectStmt stmt2 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql2, ctx); stmt2.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter()); String fragment3 = - "((((`t1`.`k4` >= 50) AND (`t1`.`k4` <= 300)) AND `t2`.`k2` IN ('United States', 'United States1') " + "(((((`t1`.`k4` >= 50) AND (`t1`.`k4` <= 300)) AND `t2`.`k2` IN ('United States', 'United States1')) " + "AND `t2`.`k3` IN ('CO', 'IL', 'MN', 'OH', 'MT', 'NM', 'TX', 'MO', 'MI')) " - + "AND (`t1`.`k1` = `t2`.`k3`) AND (`t2`.`k2` = 'United States') " - + "AND `t2`.`k3` IN ('CO', 'IL', 'MN') AND (`t1`.`k4` >= 100) AND (`t1`.`k4` <= 200) " + + "AND (((((((`t1`.`k1` = `t2`.`k3`) AND (`t2`.`k2` = 'United States')) " + + "AND `t2`.`k3` IN ('CO', 'IL', 'MN')) AND (`t1`.`k4` >= 100)) AND (`t1`.`k4` <= 200)) " + "OR " - + "(`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States1') " - + "AND `t2`.`k3` IN ('OH', 'MT', 'NM') AND (`t1`.`k4` >= 150) AND (`t1`.`k4` <= 300) " + + "(((((`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States1')) " + + "AND `t2`.`k3` IN ('OH', 'MT', 'NM')) AND (`t1`.`k4` >= 150)) AND (`t1`.`k4` <= 300))) " + "OR " - + "(`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States') " - + "AND `t2`.`k3` IN ('TX', 'MO', 'MI') " - + "AND (`t1`.`k4` >= 50) AND (`t1`.`k4` <= 250))"; + + "(((((`t1`.`k1` = `t2`.`k1`) AND (`t2`.`k2` = 'United States')) " + + "AND `t2`.`k3` IN ('TX', 'MO', 'MI')) " + + "AND (`t1`.`k4` >= 50)) AND (`t1`.`k4` <= 250))))"; Assert.assertTrue(stmt2.toSql().contains(fragment3)); String sql3 = "select\n" @@ -417,7 +417,7 @@ public class SelectStmtTest { SelectStmt stmt7 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql7, ctx); stmt7.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter()); Assert.assertTrue(stmt7.toSql() - .contains("`t2`.`k1` IS NOT NULL OR `t1`.`k1` IS NOT NULL AND `t1`.`k2` IS NOT NULL")); + .contains("`t2`.`k1` IS NOT NULL OR (`t1`.`k1` IS NOT NULL AND `t1`.`k2` IS NOT NULL)")); String sql8 = "select\n" + " avg(t1.k4)\n" @@ -429,13 +429,13 @@ public class SelectStmtTest { SelectStmt stmt8 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql8, ctx); stmt8.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter()); Assert.assertTrue(stmt8.toSql() - .contains("`t2`.`k1` IS NOT NULL AND `t1`.`k1` IS NOT NULL AND `t1`.`k1` IS NOT NULL")); + .contains("(`t2`.`k1` IS NOT NULL AND `t1`.`k1` IS NOT NULL) AND `t1`.`k1` IS NOT NULL")); String sql9 = "select * from db1.tbl1 where (k1='shutdown' and k4<1) or (k1='switchOff' and k4>=1)"; SelectStmt stmt9 = (SelectStmt) UtFrameUtils.parseAndAnalyzeStmt(sql9, ctx); stmt9.rewriteExprs(new Analyzer(ctx.getEnv(), ctx).getExprRewriter()); Assert.assertTrue( - stmt9.toSql().contains("(`k1` = 'shutdown') AND (`k4` < 1) OR (`k1` = 'switchOff') AND (`k4` >= 1)")); + stmt9.toSql().contains("((`k1` = 'shutdown') AND (`k4` < 1)) OR ((`k1` = 'switchOff') AND (`k4` >= 1))")); } @Test diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowBuildIndexStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowBuildIndexStmtTest.java index 61ea17c374b..b4c48af64a8 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowBuildIndexStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/ShowBuildIndexStmtTest.java @@ -98,14 +98,14 @@ public class ShowBuildIndexStmtTest { List<OrderByElement> orderBy = Arrays.asList( new OrderByElement(new SlotRef(tableName, "TableName"), false, false)); ShowBuildIndexStmt stmt1 = new ShowBuildIndexStmt(null, where, orderBy, new LimitElement(1, 100)); - Assertions.assertEquals(stmt1.toSql(), "SHOW BUILD INDEX WHERE (`a`.`b`.`c`.`createtime` > '%.b.%') " - + "AND (`a`.`b`.`c`.`tablename` = '%.b.%') ORDER BY `a`.`b`.`c`.`TableName` DESC NULLS LAST " + Assertions.assertEquals(stmt1.toSql(), "SHOW BUILD INDEX WHERE ((`a`.`b`.`c`.`createtime` > '%.b.%') " + + "AND (`a`.`b`.`c`.`tablename` = '%.b.%')) ORDER BY `a`.`b`.`c`.`TableName` DESC NULLS LAST " + "LIMIT 1, 100"); stmt1.analyze(analyzer); Assertions.assertEquals(stmt1.toSql(), "SHOW BUILD INDEX FROM `testDb` WHERE " - + "(`a`.`b`.`c`.`createtime` > CAST('%.b.%' AS datetimev2(0))) " - + "AND (`a`.`b`.`c`.`tablename` = '%.b.%') " + + "((`a`.`b`.`c`.`createtime` > CAST('%.b.%' AS datetimev2(0))) " + + "AND (`a`.`b`.`c`.`tablename` = '%.b.%')) " + "ORDER BY `a`.`b`.`c`.`TableName` DESC NULLS LAST LIMIT 1, 100"); Assertions.assertEquals(stmt1.getFilterMap().size(), 2); diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/SqlModeTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/SqlModeTest.java index c27743a951a..fe3c1b44f6e 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/SqlModeTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/SqlModeTest.java @@ -80,7 +80,7 @@ public class SqlModeTest { if (!(expr instanceof CompoundPredicate)) { Assert.fail(); } - Assert.assertEquals("'a' OR 'b' OR 'c'", expr.toSql()); + Assert.assertEquals("(('a' OR 'b') OR 'c')", expr.toSql()); } @Test diff --git a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java index 2aff60804f4..a6ef320a2b8 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/planner/QueryPlanTest.java @@ -2234,15 +2234,15 @@ public class QueryPlanTest extends TestWithFeService { sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2) and query_time in (3, 4)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) AND `query_time` IN (3, 4)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` IN (1, 2) AND `query_time` IN (3, 4))\n")); sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2 or scan_bytes = 2) and scan_bytes in (2, 3)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) OR (`scan_bytes` = 2) AND `scan_bytes` IN (2, 3)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: ((`query_time` IN (1, 2) OR (`scan_bytes` = 2)) AND `scan_bytes` IN (2, 3))\n")); sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2) and (scan_bytes = 2 or scan_bytes = 3)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) AND `scan_bytes` IN (2, 3)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` IN (1, 2) AND `scan_bytes` IN (2, 3))\n")); sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where query_time = 1 or query_time = 2 or query_time = 3 or query_time = 1"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); @@ -2255,22 +2255,22 @@ public class QueryPlanTest extends TestWithFeService { connectContext.getSessionVariable().setRewriteOrToInPredicateThreshold(100); sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where query_time = 1 or query_time = 2 or query_time in (3, 4)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` = 1) OR (`query_time` = 2) OR `query_time` IN (3, 4)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: (((`query_time` = 1) OR (`query_time` = 2)) OR `query_time` IN (3, 4))\n")); connectContext.getSessionVariable().setRewriteOrToInPredicateThreshold(2); sql = "SELECT /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2) and query_time in (3, 4)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) AND `query_time` IN (3, 4)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` IN (1, 2) AND `query_time` IN (3, 4))\n")); //test we can handle `!=` and `not in` sql = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2 or query_time!= 3 or query_time not in (5, 6))"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) OR (`query_time` != 3) OR `query_time` NOT IN (5, 6)\n")); + Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` IN (1, 2) OR ((`query_time` != 3) OR `query_time` NOT IN (5, 6)))\n")); //test we can handle merge 2 or more columns sql = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2 or scan_rows = 3 or scan_rows = 4)"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); - Assert.assertTrue(explainString.contains("PREDICATES: `query_time` IN (1, 2) OR `scan_rows` IN (3, 4)")); + Assert.assertTrue(explainString.contains("PREDICATES: (`query_time` IN (1, 2) OR `scan_rows` IN (3, 4))")); //merge in-pred or in-pred sql = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (query_time = 1 or query_time = 2 or query_time = 3 or query_time = 4)"; @@ -2285,16 +2285,15 @@ public class QueryPlanTest extends TestWithFeService { + " or (db not in ('x', 'y')) "; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); Assert.assertTrue(explainString.contains( - "PREDICATES: (`query_id` = `client_ip`) " - + "AND (`stmt_id` IN (1, 2, 3) OR (`user` = 'abc') AND `state` IN ('a', 'b', 'c', 'd')) " - + "OR (`db` NOT IN ('x', 'y'))\n")); + "PREDICATES: (((`query_id` = `client_ip`) AND (`stmt_id` IN (1, 2, 3) OR ((`user` = 'abc') " + + "AND `state` IN ('a', 'b', 'c', 'd')))) OR (`db` NOT IN ('x', 'y')))\n")); //ExtractCommonFactorsRule may generate more expr, test the rewriteOrToIn applied on generated exprs sql = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from test1 where (stmt_id=1 and state='a') or (stmt_id=2 and state='b')"; explainString = UtFrameUtils.getSQLPlanOrErrorMsg(connectContext, "EXPLAIN " + sql); Assert.assertTrue(explainString.contains( - "PREDICATES: `state` IN ('a', 'b') AND `stmt_id` IN (1, 2) AND" - + " (`stmt_id` = 1) AND (`state` = 'a') OR (`stmt_id` = 2) AND (`state` = 'b')\n" + "PREDICATES: ((`state` IN ('a', 'b') AND `stmt_id` IN (1, 2)) AND (((`stmt_id` = 1) AND " + + "(`state` = 'a')) OR ((`stmt_id` = 2) AND (`state` = 'b'))))\n" )); } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java index 8d6a2a48ae3..aa04c14bbe9 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/policy/PolicyTest.java @@ -270,7 +270,7 @@ public class PolicyTest extends TestWithFeService { createPolicy("CREATE ROW POLICY test_row_policy4 ON test.table1 AS PERMISSIVE TO test_policy USING (k2 = 1)"); String queryStr = "EXPLAIN select /*+ SET_VAR(enable_nereids_planner=false) */ * from test.table1"; String explainString = getSQLPlanOrErrorMsg(queryStr); - Assertions.assertTrue(explainString.contains("(`k1` = 1) AND (`k2` = 1) AND (`k2` = 2) OR (`k2` = 1)")); + Assertions.assertTrue(explainString.contains("(((`k1` = 1) AND (`k2` = 1)) AND ((`k2` = 2) OR (`k2` = 1)))")); dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1"); dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1"); dropPolicy("DROP ROW POLICY test_row_policy3 ON test.table1"); @@ -318,13 +318,13 @@ public class PolicyTest extends TestWithFeService { createPolicy("CREATE ROW POLICY test_row_policy1 ON test.table1 AS RESTRICTIVE TO test_policy USING (k1 = 1)"); createPolicy("CREATE ROW POLICY test_row_policy2 ON test.table1 AS RESTRICTIVE TO test_policy USING (k2 = 1)"); String joinSql = "select * from table1 join table2 on table1.k1=table2.k1"; - Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: (k1 = 1) AND (k2 = 1)")); + Assertions.assertTrue(getSQLPlanOrErrorMsg(joinSql).contains("PREDICATES: ((k1 = 1) AND (k2 = 1))")); String unionSql = "select * from table1 union select * from table2"; - Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: (k1 = 1) AND (k2 = 1)")); + Assertions.assertTrue(getSQLPlanOrErrorMsg(unionSql).contains("PREDICATES: ((k1 = 1) AND (k2 = 1))")); String subQuerySql = "select * from table2 where k1 in (select k1 from table1)"; - Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: (k1 = 1) AND (k2 = 1)")); + Assertions.assertTrue(getSQLPlanOrErrorMsg(subQuerySql).contains("PREDICATES: ((k1 = 1) AND (k2 = 1))")); String aliasSql = "select * from table1 t1 join table2 t2 on t1.k1=t2.k1"; - Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: (k1 = 1) AND (k2 = 1)")); + Assertions.assertTrue(getSQLPlanOrErrorMsg(aliasSql).contains("PREDICATES: ((k1 = 1) AND (k2 = 1))")); dropPolicy("DROP ROW POLICY test_row_policy1 ON test.table1"); dropPolicy("DROP ROW POLICY test_row_policy2 ON test.table1"); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java b/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java index 18dee386c8c..270d5a3152a 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/qe/OlapQueryCacheTest.java @@ -673,7 +673,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); - Assert.assertEquals(sql, "(`date` >= 20200114) AND (`date` <= 20200115)"); + Assert.assertEquals(sql, "((`date` >= 20200114) AND (`date` <= 20200115))"); } catch (Exception e) { LOG.warn("ex={}", e); Assert.fail(e.getMessage()); @@ -715,7 +715,7 @@ public class OlapQueryCacheTest { hitRange = range.buildDiskPartitionRange(newRangeList); cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); - Assert.assertEquals(sql, "(`eventdate` >= '2020-01-14') AND (`eventdate` <= '2020-01-15')"); + Assert.assertEquals(sql, "((`eventdate` >= '2020-01-14') AND (`eventdate` <= '2020-01-15'))"); } catch (Exception e) { LOG.warn("ex={}", e); Assert.fail(e.getMessage()); @@ -858,7 +858,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); - Assert.assertEquals(sql, "(`eventdate` >= '2020-01-13') AND (`eventdate` <= '2020-01-15')"); + Assert.assertEquals(sql, "((`eventdate` >= '2020-01-13') AND (`eventdate` <= '2020-01-15'))"); List<PartitionRange.PartitionSingle> updateRangeList = range.buildUpdatePartitionRange(); Assert.assertEquals(updateRangeList.size(), 2); @@ -906,7 +906,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); LOG.warn("MultiPredicate={}", sql); - Assert.assertEquals(sql, "(`eventdate` > '2020-01-13') AND (`eventdate` < '2020-01-16') AND (`eventid` = 1)"); + Assert.assertEquals(sql, "(((`eventdate` > '2020-01-13') AND (`eventdate` < '2020-01-16')) AND (`eventid` = 1))"); } catch (Exception e) { LOG.warn("multi ex={}", e); Assert.fail(e.getMessage()); @@ -949,8 +949,8 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); LOG.warn("Join rewrite={}", sql); - Assert.assertEquals(sql, "(`appevent`.`eventdate` >= '2020-01-14')" - + " AND (`appevent`.`eventdate` <= '2020-01-15') AND (`eventid` = 1)"); + Assert.assertEquals(sql, "(((`appevent`.`eventdate` >= '2020-01-14')" + + " AND (`appevent`.`eventdate` <= '2020-01-15')) AND (`eventid` = 1))"); } catch (Exception e) { LOG.warn("Join ex={}", e); Assert.fail(e.getMessage()); @@ -1000,8 +1000,8 @@ public class OlapQueryCacheTest { Assert.assertEquals(sql, "SELECT `eventdate` AS `eventdate`, sum(`pv`) AS `sum(``pv``)` " + "FROM (SELECT `eventdate`, count(`userid`) `pv` " - + "FROM `testDb`.`appevent` WHERE (`eventdate` > '2020-01-13') " - + "AND (`eventdate` < '2020-01-16') AND (`eventid` = 1) GROUP BY `eventdate`) tbl " + + "FROM `testDb`.`appevent` WHERE (((`eventdate` > '2020-01-13') " + + "AND (`eventdate` < '2020-01-16')) AND (`eventid` = 1)) GROUP BY `eventdate`) tbl " + "GROUP BY `eventdate`"); } catch (Exception e) { LOG.warn("sub ex={}", e); @@ -1053,8 +1053,8 @@ public class OlapQueryCacheTest { SqlCache sqlCache = (SqlCache) ca.getCache(); String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT `eventdate` AS `eventdate`, count(`userid`) " - + "AS `count(``userid``)` FROM `testDb`.`appevent` WHERE (`eventdate` >= '2020-01-12') " - + "AND (`eventdate` <= '2020-01-14') GROUP BY `eventdate`|"); + + "AS `count(``userid``)` FROM `testDb`.`appevent` WHERE ((`eventdate` >= '2020-01-12') " + + "AND (`eventdate` <= '2020-01-14')) GROUP BY `eventdate`|"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1092,8 +1092,8 @@ public class OlapQueryCacheTest { Assert.assertEquals(cacheKey, "SELECT `testDb`.`view1`.`eventdate` AS `eventdate`, " + "`testDb`.`view1`.`__count_1` AS `__count_1` FROM `testDb`.`view1`|" + "SELECT `eventdate` AS `eventdate`, count(`userid`) AS `__count_1` FROM " - + "`testDb`.`appevent` WHERE (`eventdate` >= '2020-01-12') AND " - + "(`eventdate` <= '2020-01-14') GROUP BY `eventdate`"); + + "`testDb`.`appevent` WHERE ((`eventdate` >= '2020-01-12') AND " + + "(`eventdate` <= '2020-01-14')) GROUP BY `eventdate`"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1111,7 +1111,7 @@ public class OlapQueryCacheTest { String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT * from testDb.view1|SELECT `eventdate` AS `eventdate`, " + "count(`userid`) AS `__count_1` FROM `testDb`.`appevent` " - + "WHERE (`eventdate` >= '2020-01-12') AND (`eventdate` <= '2020-01-14') GROUP BY `eventdate`"); + + "WHERE ((`eventdate` >= '2020-01-12') AND (`eventdate` <= '2020-01-14')) GROUP BY `eventdate`"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1137,7 +1137,7 @@ public class OlapQueryCacheTest { Assert.assertEquals(cacheKey, "SELECT `origin`.`eventdate` AS `eventdate`, " + "`origin`.`userid` AS `userid` FROM (SELECT `view2`.`eventdate` `eventdate`, " + "`view2`.`userid` `userid` FROM `testDb`.`view2` view2 " - + "WHERE (`view2`.`eventdate` >= '2020-01-12') AND (`view2`.`eventdate` <= '2020-01-14')) origin|" + + "WHERE ((`view2`.`eventdate` >= '2020-01-12') AND (`view2`.`eventdate` <= '2020-01-14'))) origin|" + "SELECT `eventdate` AS `eventdate`, `userid` AS `userid` FROM `testDb`.`appevent`"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1189,8 +1189,8 @@ public class OlapQueryCacheTest { Assert.assertEquals(cache.getSqlWithViewStmt(), "SELECT `testDb`.`view3`.`eventdate` " + "AS `eventdate`, `testDb`.`view3`.`__count_1` AS `__count_1` " + "FROM `testDb`.`view3`|SELECT `eventdate` AS `eventdate`, count(`userid`) " - + "AS `__count_1` FROM `testDb`.`appevent` WHERE (`eventdate` >= '2020-01-12') " - + "AND (`eventdate` <= '2020-01-15') GROUP BY `eventdate`"); + + "AS `__count_1` FROM `testDb`.`appevent` WHERE ((`eventdate` >= '2020-01-12') " + + "AND (`eventdate` <= '2020-01-15')) GROUP BY `eventdate`"); } catch (Exception e) { LOG.warn("ex={}", e); Assert.fail(e.getMessage()); @@ -1245,7 +1245,7 @@ public class OlapQueryCacheTest { Assert.assertEquals(cacheKey, "SELECT `testDb`.`view4`.`eventdate` AS `eventdate`, " + "`testDb`.`view4`.`__count_1` AS `__count_1` FROM `testDb`.`view4`|" + "SELECT `eventdate` AS `eventdate`, count(`userid`) AS `__count_1` FROM `testDb`.`view2` " - + "WHERE (`eventdate` >= '2020-01-12') AND (`eventdate` <= '2020-01-14') GROUP BY `eventdate`|" + + "WHERE ((`eventdate` >= '2020-01-12') AND (`eventdate` <= '2020-01-14')) GROUP BY `eventdate`|" + "SELECT `eventdate` AS `eventdate`, `userid` AS `userid` FROM `testDb`.`appevent`"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1263,8 +1263,8 @@ public class OlapQueryCacheTest { SqlCache sqlCache = (SqlCache) ca.getCache(); String cacheKey = sqlCache.getSqlWithViewStmt(); Assert.assertEquals(cacheKey, "SELECT * from testDb.view4|SELECT `eventdate` AS `eventdate`, " - + "count(`userid`) AS `__count_1` FROM `testDb`.`view2` WHERE (`eventdate` >= '2020-01-12') " - + "AND (`eventdate` <= '2020-01-14') GROUP BY `eventdate`|SELECT `eventdate` AS `eventdate`, " + + "count(`userid`) AS `__count_1` FROM `testDb`.`view2` WHERE ((`eventdate` >= '2020-01-12') " + + "AND (`eventdate` <= '2020-01-14')) GROUP BY `eventdate`|SELECT `eventdate` AS `eventdate`, " + "`userid` AS `userid` FROM `testDb`.`appevent`"); Assert.assertEquals(selectedPartitionIds.size(), sqlCache.getSumOfPartitionNum()); } @@ -1328,7 +1328,7 @@ public class OlapQueryCacheTest { cache.rewriteSelectStmt(newRangeList); sql = ca.getRewriteStmt().getWhereClause().toSql(); - Assert.assertEquals(sql, "(`date` >= 20200114) AND (`date` <= 20200115)"); + Assert.assertEquals(sql, "((`date` >= 20200114) AND (`date` <= 20200115))"); } catch (Exception e) { LOG.warn("ex={}", e); Assert.fail(e.getMessage()); diff --git a/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java b/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java index d7841313d71..915dce122d8 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/rewrite/ExtractCommonFactorsRuleFunctionTest.java @@ -100,7 +100,7 @@ public class ExtractCommonFactorsRuleFunctionTest { public void testWideCommonFactorsWithOrPredicate() throws Exception { String query = "select /*+ SET_VAR(enable_nereids_planner=false) */ * from tb1 where tb1.k1 > 1000 or tb1.k1 < 200 or tb1.k1 = 300"; String planString = dorisAssert.query(query).explainQuery(); - Assert.assertTrue(planString.contains("(`tb1`.`k1` = 300) OR (`tb1`.`k1` > 1000) OR (`tb1`.`k1` < 200)")); + Assert.assertTrue(planString.contains("((`tb1`.`k1` = 300) OR ((`tb1`.`k1` > 1000) OR (`tb1`.`k1` < 200)))")); } @Test @@ -259,8 +259,8 @@ public class ExtractCommonFactorsRuleFunctionTest { Assert.assertTrue(planString.contains("`l_partkey` = `p_partkey`")); Assert.assertTrue(planString.contains("`l_shipmode` IN ('AIR', 'AIR REG')")); Assert.assertTrue(planString.contains("`l_shipinstruct` = 'DELIVER IN PERSON'")); - Assert.assertTrue(planString.contains("(`l_quantity` >= 9.00) AND (`l_quantity` <= 19.00) " - + "OR (`l_quantity` >= 20.00) AND (`l_quantity` <= 36.00)")); + Assert.assertTrue(planString.contains("(((`l_quantity` >= 9.00) AND (`l_quantity` <= 19.00)) " + + "OR ((`l_quantity` >= 20.00) AND (`l_quantity` <= 36.00)))")); Assert.assertTrue(planString.contains("`p_size` >= 1")); Assert.assertTrue(planString.contains("`p_brand` IN ('Brand#11', 'Brand#21', 'Brand#32')")); Assert.assertTrue(planString.contains("`p_size` <= 15")); diff --git a/regression-test/data/datatype_p0/scalar_types/get_assignment_compatible_type.out b/regression-test/data/datatype_p0/scalar_types/get_assignment_compatible_type.out index 1875bb02659..030a9b1286c 100644 --- a/regression-test/data/datatype_p0/scalar_types/get_assignment_compatible_type.out +++ b/regression-test/data/datatype_p0/scalar_types/get_assignment_compatible_type.out @@ -1,6 +1,6 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !test_sql -- -test_decimal_boolean_view CREATE VIEW `test_decimal_boolean_view` AS SELECT `id` AS `id`, `c1` AS `c1`, `c2` AS `c2` FROM `regression_test_datatype_p0_scalar_types`.`test_decimal_boolean` WHERE (0.0 = CAST(`c1` AS decimalv3(2,1))) AND (CAST(`c2` AS decimalv3(6,1)) = 1.0); utf8mb4 utf8mb4_0900_bin +test_decimal_boolean_view CREATE VIEW `test_decimal_boolean_view` AS SELECT `id` AS `id`, `c1` AS `c1`, `c2` AS `c2` FROM `regression_test_datatype_p0_scalar_types`.`test_decimal_boolean` WHERE ((0.0 = CAST(`c1` AS decimalv3(2,1))) AND (CAST(`c2` AS decimalv3(6,1)) = 1.0)); utf8mb4 utf8mb4_0900_bin -- !test_union -- 0.0 diff --git a/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy b/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy index e83cf6a38f2..f92663660af 100644 --- a/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy +++ b/regression-test/suites/external_table_p0/jdbc/test_clickhouse_jdbc_catalog.groovy @@ -84,7 +84,7 @@ suite("test_clickhouse_jdbc_catalog", "p0,external,clickhouse,external_docker,ex contains """QUERY: SELECT "id", "ts" FROM "doris_test"."ts" WHERE ((FROM_UNIXTIME("ts", '%Y%m%d') >= '2022-01-01'))""" } explain { - sql("select * from ts where nvl(ts,null) >= '2022-01-01';") + sql("select * from ts where nvl(ts,null) >= '1';") contains """QUERY: SELECT "id", "ts" FROM "doris_test"."ts""" } order_qt_func_push2 """select * from ts where ts <= unix_timestamp(from_unixtime(ts,'yyyyMMdd'));""" diff --git a/regression-test/suites/query_p0/explain/test_compoundpredicate_explain.groovy b/regression-test/suites/query_p0/explain/test_compoundpredicate_explain.groovy new file mode 100644 index 00000000000..fccdd1b2e2f --- /dev/null +++ b/regression-test/suites/query_p0/explain/test_compoundpredicate_explain.groovy @@ -0,0 +1,72 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_compoundpredicate_explain") { + sql "drop table if exists test_compoundpredicate_explain" + sql """create table test_compoundpredicate_explain + (k1 int, k2 int) + distributed by hash(k1) buckets 3 properties('replication_num' = '1');""" + + sql """INSERT INTO test_compoundpredicate_explain (k1, k2) VALUES (500, 450), (1100, 400), (300, 600), (700, 650), (800, 800), (1500, 300);""" + + def testQueries = [ + "select * from test_compoundpredicate_explain where k1 > 500 and k2 < 700 or k1 < 3000", + "select * from test_compoundpredicate_explain where k1 > 500 or k2 < 700 and k1 < 3000", + "select * from test_compoundpredicate_explain where not (k1 > 500 and k2 < 700) or k1 < 3000", + "select * from test_compoundpredicate_explain where k1 > 500 and (k2 < 700 or k1 < 3000)", + "select * from test_compoundpredicate_explain where not (k1 > 500 or k2 < 700) and k1 < 3000", + "select * from test_compoundpredicate_explain where (k1 > 500 and not k2 < 700) or k1 < 3000", + "select * from test_compoundpredicate_explain where (k1 > 500 and k2 < 700) and (k1 < 3000 or k2 > 400)", + "select * from test_compoundpredicate_explain where not (k1 > 500 or (k2 < 700 and k1 < 3000))", + "select * from test_compoundpredicate_explain where k1 > 500 or not (k2 < 700 and k1 < 3000)", + "select * from test_compoundpredicate_explain where k1 < 1000 and (k2 < 700 or k1 > 500) and not (k2 > 300)", + "select * from test_compoundpredicate_explain where not ((k1 > 500 and k2 < 700) or k1 < 3000)", + "select * from test_compoundpredicate_explain where k1 > 500 and not (k2 < 700 or k1 < 3000)", + "select * from test_compoundpredicate_explain where (k1 > 500 or k2 < 700) and (k1 < 3000 and k2 > 200)", + "select * from test_compoundpredicate_explain where (k1 > 500 and k2 < 700) or not (k1 < 3000 and k2 > 200)" + ] + + testQueries.each { query -> + def explainResult1 = sql "explain all plan ${query}" + def explainResult2 = sql "explain ${query}" + + def predicates2Line = explainResult2.find { line -> + line[0].toString().trim().startsWith("PREDICATES:") + } + + if (predicates2Line != null) { + def predicates2 = predicates2Line[0].split("PREDICATES:").last().trim() + + predicates2 = predicates2?.replaceAll(/\[\#(\d+)\]/) { match, group1 -> "#" + group1 } + + def isMatch = explainResult1.any { line -> + line.toString().contains(predicates2) + } + + log.info("Testing query: " + query) + log.info("Standardized Predicates from PREDICATES: " + predicates2) + log.info("Match found in OPTIMIZED PLAN: " + isMatch) + + assert isMatch : "Predicates are not equal for query: ${query}" + } else { + logger.error("PREDICATES: not found in explain result for query: ${query}") + assert false : "PREDICATES: not found in explain result" + } + } + + sql "drop table if exists test_compoundpredicate_explain" +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org