From dd82d0f71ad6348f9153ab64be6bd01f48415085 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:37:56 +0800 Subject: [PATCH] [BugFix] MV rewrite may generate wrong plans if query only contains constant call operators (backport #50757) (#50777) Signed-off-by: shuming.li Co-authored-by: shuming.li --- .../materialization/EquationRewriter.java | 9 +++- .../planner/MaterializedViewManualTest.java | 42 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/materialization/EquationRewriter.java b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/materialization/EquationRewriter.java index 5e6df3bb3e847..62a2610f1dfd0 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/materialization/EquationRewriter.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/optimizer/rule/transformation/materialization/EquationRewriter.java @@ -148,7 +148,14 @@ public ScalarOperator visitCall(CallOperator call, Void context) { return rewritten; } } - + // If count(1)/sum(1) cannot be rewritten by mv's defined equivalents, return null directly, + // otherwise it may cause a wrong plan. + // mv : SELECT 1, count(distinct k1) from tbl1; + // query : SELECT count(1) from tbl1; + // MV should not rewrite the query. + if (call.isAggregate() && call.isConstant()) { + return null; + } return super.visitCall(call, context); } diff --git a/fe/fe-core/src/test/java/com/starrocks/planner/MaterializedViewManualTest.java b/fe/fe-core/src/test/java/com/starrocks/planner/MaterializedViewManualTest.java index ad315f01dd655..14986e02c6667 100644 --- a/fe/fe-core/src/test/java/com/starrocks/planner/MaterializedViewManualTest.java +++ b/fe/fe-core/src/test/java/com/starrocks/planner/MaterializedViewManualTest.java @@ -356,4 +356,46 @@ public void testRewriteWithCaseWhen() { } }); } + + @Test + public void testWrongMVRewrite() throws Exception { + starRocksAssert.withTable("CREATE TABLE `tbl1` (\n" + + " `k1` date,\n" + + " `k2` decimal64(18, 2),\n" + + " `k3` varchar(255),\n" + + " `v1` varchar(255)\n" + + ") ENGINE=OLAP \n" + + "DUPLICATE KEY(`k1`, `k2`, `k3`)\n" + + "DISTRIBUTED BY RANDOM\n" + + "PROPERTIES (\n" + + "\"replication_num\" = \"1\"\n" + + ");"); + { + starRocksAssert.withMaterializedView("CREATE MATERIALIZED VIEW `mv1` \n" + + "DISTRIBUTED BY RANDOM\n" + + "REFRESH ASYNC\n" + + "PROPERTIES (\n" + + "\"replication_num\" = \"1\"\n" + + ")\n" + + "AS SELECT 1, count(distinct k1) from tbl1"); + sql("select count(distinct k1) from tbl1").contains("mv1"); + sql("select count(1) from tbl1").notContain("mv1"); + sql("select count(*) from tbl1").notContain("mv1"); + starRocksAssert.dropMaterializedView("mv1"); + } + { + starRocksAssert.withMaterializedView("CREATE MATERIALIZED VIEW `mv1` \n" + + "DISTRIBUTED BY RANDOM\n" + + "REFRESH ASYNC\n" + + "PROPERTIES (\n" + + "\"replication_num\" = \"1\"\n" + + ")\n" + + "AS SELECT 1, count(1) from tbl1"); + sql("select count(distinct k1) from tbl1").notContain("mv1"); + sql("select count(1) from tbl1").contains("mv1"); + sql("select count(*) from tbl1").contains("mv1"); + starRocksAssert.dropMaterializedView("mv1"); + } + starRocksAssert.dropTable("tbl1"); + } }