From 25616ef6905a64a7e5dddb5f1286418a9e9a16c4 Mon Sep 17 00:00:00 2001 From: seawinde Date: Mon, 3 Nov 2025 11:45:04 +0800 Subject: [PATCH] [fix](mtmv) Fix mv rewrite fail when mv contains group sets and filter above scan (#57343) ### What problem does this PR solve? Related PR: #36056 Problem Summary: if mv is defined as following CREATE MATERIALIZED VIEW mv_11 BUILD IMMEDIATE REFRESH COMPLETE ON MANUAL DISTRIBUTED BY RANDOM BUCKETS 2 PROPERTIES ('replication_num' = '1') AS select o_orderstatus, o_orderdate, o_orderpriority, sum(o_totalprice) as sum_total, max(o_totalprice) as max_total, min(o_totalprice) as min_total, count(*) as count_all, bitmap_union(to_bitmap(case when o_shippriority > 1 and o_orderkey IN (1, 3) then o_custkey else null end)) as bitmap_union_basic from orders where o_custkey > 1 group by o_orderstatus, o_orderdate, o_orderpriority; there is filter `where o_custkey > 1` in mv, if query is as following, should be rewritten successfully but fail, because the filter `o_custkey > 1` is lost compare and could not compensate the filter, the pr fixed this. select o_orderstatus, o_orderpriority, grouping_id(o_orderstatus, o_orderpriority), grouping_id(o_orderstatus), grouping(o_orderstatus), sum(o_totalprice), max(o_totalprice), min(o_totalprice), count(*), count(distinct case when o_shippriority > 1 and o_orderkey IN (1, 3) then o_custkey else null end) from orders where o_custkey > 1 group by ROLLUP (o_orderstatus, o_orderpriority); --- .../rules/exploration/mv/StructInfo.java | 15 ++------ .../mv/grouping_sets/grouping_sets.out | 10 +++++ .../mv/grouping_sets/grouping_sets.groovy | 37 +++++++++++++++++++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/StructInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/StructInfo.java index fedd2ece30b783..7b8b976295d1c9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/StructInfo.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/mv/StructInfo.java @@ -83,7 +83,6 @@ public class StructInfo { public static final ScanPlanPatternChecker SCAN_PLAN_PATTERN_CHECKER = new ScanPlanPatternChecker(); // struct info splitter public static final PlanSplitter PLAN_SPLITTER = new PlanSplitter(); - private static final RelationCollector RELATION_COLLECTOR = new RelationCollector(); private static final PredicateCollector PREDICATE_COLLECTOR = new PredicateCollector(); // source data private final Plan originalPlan; @@ -453,23 +452,15 @@ public String toString() { return "StructInfo{ originalPlanId = " + originalPlanId + ", relations = " + relations + '}'; } - private static class RelationCollector extends DefaultPlanVisitor> { - @Override - public Void visit(Plan plan, List collectedRelations) { - if (plan instanceof CatalogRelation) { - collectedRelations.add((CatalogRelation) plan); - } - return super.visit(plan, collectedRelations); - } - } - private static class PredicateCollector extends DefaultPlanVisitor> { @Override public Void visit(Plan plan, Set predicates) { // Just collect the filter in top plan, if meet other node except project and filter, return if (!(plan instanceof LogicalProject) && !(plan instanceof LogicalFilter) - && !(plan instanceof LogicalAggregate)) { + && !(plan instanceof LogicalAggregate) + && !(plan instanceof LogicalSort) + && !(plan instanceof LogicalRepeat)) { return null; } if (plan instanceof LogicalFilter) { diff --git a/regression-test/data/nereids_rules_p0/mv/grouping_sets/grouping_sets.out b/regression-test/data/nereids_rules_p0/mv/grouping_sets/grouping_sets.out index b6e7a2759840e4..16e370a993d38d 100644 --- a/regression-test/data/nereids_rules_p0/mv/grouping_sets/grouping_sets.out +++ b/regression-test/data/nereids_rules_p0/mv/grouping_sets/grouping_sets.out @@ -163,6 +163,16 @@ o \N 1 0 0 178.10 56.20 1.20 8 0 o a 0 0 0 77.50 33.50 9.50 5 0 o c 0 0 0 100.60 56.20 1.20 3 0 +-- !query10_1_before -- +\N \N 3 1 1 100.60 56.20 1.20 3 0 +o \N 1 0 0 100.60 56.20 1.20 3 0 +o c 0 0 0 100.60 56.20 1.20 3 0 + +-- !query10_1_after -- +\N \N 3 1 1 100.60 56.20 1.20 3 0 +o \N 1 0 0 100.60 56.20 1.20 3 0 +o c 0 0 0 100.60 56.20 1.20 3 0 + -- !query11_0_before -- \N \N \N 43.20 43.20 43.20 1 0 3 \N \N 43.20 43.20 43.20 1 0 diff --git a/regression-test/suites/nereids_rules_p0/mv/grouping_sets/grouping_sets.groovy b/regression-test/suites/nereids_rules_p0/mv/grouping_sets/grouping_sets.groovy index 595693d5ff602a..8f1608f7ca2697 100644 --- a/regression-test/suites/nereids_rules_p0/mv/grouping_sets/grouping_sets.groovy +++ b/regression-test/suites/nereids_rules_p0/mv/grouping_sets/grouping_sets.groovy @@ -474,6 +474,43 @@ suite("materialized_view_grouping_sets") { order_qt_query10_0_after "${query10_0}" sql """ DROP MATERIALIZED VIEW IF EXISTS mv10_0""" + + // single table rollup with grouping scalar function and filter + def mv10_1 = + """ + select o_orderstatus, o_orderdate, o_orderpriority, + sum(o_totalprice) as sum_total, + max(o_totalprice) as max_total, + min(o_totalprice) as min_total, + count(*) as count_all, + bitmap_union(to_bitmap(case when o_shippriority > 1 and o_orderkey IN (1, 3) then o_custkey else null end)) as bitmap_union_basic + from orders + where o_custkey > 1 + group by + o_orderstatus, o_orderdate, o_orderpriority; + """ + def query10_1 = + """ + select o_orderstatus, o_orderpriority, + grouping_id(o_orderstatus, o_orderpriority), + grouping_id(o_orderstatus), + grouping(o_orderstatus), + sum(o_totalprice), + max(o_totalprice), + min(o_totalprice), + count(*), + count(distinct case when o_shippriority > 1 and o_orderkey IN (1, 3) then o_custkey else null end) + from orders + where o_custkey > 1 + group by + ROLLUP (o_orderstatus, o_orderpriority); + """ + order_qt_query10_1_before "${query10_1}" + async_mv_rewrite_success(db, mv10_1, query10_1, "mv10_1") + order_qt_query10_1_after "${query10_1}" + sql """ DROP MATERIALIZED VIEW IF EXISTS mv10_1""" + + // multi table rollup without grouping scalar function def mv11_0 = """