[fix](mtmv) Fix exception when create materialized view with cte (#33988)
Fix exception when create materialized view with cte, after this fix, can create materialized view with following
```
CREATE MATERIALIZED VIEW mv_with_cte
BUILD IMMEDIATE REFRESH AUTO ON MANUAL
DISTRIBUTED BY RANDOM BUCKETS 2
PROPERTIES ('replication_num' = '1')
AS
with `test_with` AS (
select l_partkey, l_suppkey
from lineitem
union
select
ps_partkey, ps_suppkey
from
partsupp)
select * from test_with;
```
this is brought from https://github.com/apache/doris/pull/28144
This commit is contained in:
@ -41,10 +41,12 @@ import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.algebra.Sink;
|
||||
import org.apache.doris.nereids.trees.plans.commands.insert.InsertOverwriteTableCommand;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalCTE;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalCatalogRelation;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSink;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
|
||||
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
|
||||
import org.apache.doris.nereids.util.ExpressionUtils;
|
||||
import org.apache.doris.nereids.util.RelationUtil;
|
||||
@ -197,11 +199,21 @@ public class UpdateMvByPartitionCommand extends InsertOverwriteTableCommand {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add predicates on base table when mv can partition update
|
||||
* Add predicates on base table when mv can partition update, Also support plan that contain cte and view
|
||||
*/
|
||||
public static class PredicateAdder extends DefaultPlanRewriter<Map<TableIf, Set<Expression>>> {
|
||||
|
||||
// record view and cte name parts, these should be ignored and visit it's actual plan
|
||||
public Set<List<String>> virtualRelationNamePartSet = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Plan visitUnboundRelation(UnboundRelation unboundRelation, Map<TableIf, Set<Expression>> predicates) {
|
||||
if (predicates.isEmpty()) {
|
||||
return unboundRelation;
|
||||
}
|
||||
if (virtualRelationNamePartSet.contains(unboundRelation.getNameParts())) {
|
||||
return unboundRelation;
|
||||
}
|
||||
List<String> tableQualifier = RelationUtil.getQualifierName(ConnectContext.get(),
|
||||
unboundRelation.getNameParts());
|
||||
TableIf table = RelationUtil.getTable(tableQualifier, Env.getCurrentEnv());
|
||||
@ -212,9 +224,34 @@ public class UpdateMvByPartitionCommand extends InsertOverwriteTableCommand {
|
||||
return unboundRelation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan visitLogicalCTE(LogicalCTE<? extends Plan> cte, Map<TableIf, Set<Expression>> predicates) {
|
||||
if (predicates.isEmpty()) {
|
||||
return cte;
|
||||
}
|
||||
for (LogicalSubQueryAlias<Plan> subQueryAlias : cte.getAliasQueries()) {
|
||||
this.virtualRelationNamePartSet.add(subQueryAlias.getQualifier());
|
||||
subQueryAlias.children().forEach(subQuery -> subQuery.accept(this, predicates));
|
||||
}
|
||||
return super.visitLogicalCTE(cte, predicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan visitLogicalSubQueryAlias(LogicalSubQueryAlias<? extends Plan> subQueryAlias,
|
||||
Map<TableIf, Set<Expression>> predicates) {
|
||||
if (predicates.isEmpty()) {
|
||||
return subQueryAlias;
|
||||
}
|
||||
this.virtualRelationNamePartSet.add(subQueryAlias.getQualifier());
|
||||
return super.visitLogicalSubQueryAlias(subQueryAlias, predicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plan visitLogicalCatalogRelation(LogicalCatalogRelation catalogRelation,
|
||||
Map<TableIf, Set<Expression>> predicates) {
|
||||
if (predicates.isEmpty()) {
|
||||
return catalogRelation;
|
||||
}
|
||||
TableIf table = catalogRelation.getTable();
|
||||
if (predicates.containsKey(table)) {
|
||||
return new LogicalFilter<>(ImmutableSet.of(ExpressionUtils.or(predicates.get(table))),
|
||||
|
||||
@ -63,3 +63,9 @@ zhangsang 200
|
||||
-- !desc_mv --
|
||||
field_1 VARCHAR(16) No false \N NONE
|
||||
|
||||
-- !query_mv_with_cte --
|
||||
2 3
|
||||
2 4
|
||||
3 3
|
||||
4 3
|
||||
|
||||
|
||||
@ -625,6 +625,30 @@ suite("test_build_mtmv") {
|
||||
(5, 2, 3, 6, 7.5, 8.5, 9.5, 10.5, 'k', 'o', '2023-12-12', '2023-12-12', '2023-12-13', 'c', 'd', 'xxxxxxxxx');
|
||||
"""
|
||||
|
||||
sql """
|
||||
drop table if exists partsupp
|
||||
"""
|
||||
|
||||
sql """
|
||||
CREATE TABLE IF NOT EXISTS partsupp (
|
||||
ps_partkey INTEGER NOT NULL,
|
||||
ps_suppkey INTEGER NOT NULL,
|
||||
ps_availqty INTEGER NOT NULL,
|
||||
ps_supplycost DECIMALV3(15,2) NOT NULL,
|
||||
ps_comment VARCHAR(199) NOT NULL
|
||||
)
|
||||
DUPLICATE KEY(ps_partkey, ps_suppkey)
|
||||
DISTRIBUTED BY HASH(ps_partkey) BUCKETS 3
|
||||
PROPERTIES (
|
||||
"replication_num" = "1"
|
||||
)"""
|
||||
|
||||
sql """
|
||||
insert into partsupp values
|
||||
(2, 3, 9, 10.01, 'supply1'),
|
||||
(2, 3, 10, 11.01, 'supply2');
|
||||
"""
|
||||
|
||||
sql """DROP MATERIALIZED VIEW IF EXISTS test_varchar_literal_mv;"""
|
||||
sql """
|
||||
CREATE MATERIALIZED VIEW test_varchar_literal_mv
|
||||
@ -635,4 +659,24 @@ suite("test_build_mtmv") {
|
||||
select case when l_orderkey > 1 then "一二三四" else "五六七八" end as field_1 from lineitem;
|
||||
"""
|
||||
qt_desc_mv """desc test_varchar_literal_mv;"""
|
||||
|
||||
sql """DROP MATERIALIZED VIEW IF EXISTS mv_with_cte;"""
|
||||
sql """
|
||||
CREATE MATERIALIZED VIEW mv_with_cte
|
||||
BUILD IMMEDIATE REFRESH AUTO ON MANUAL
|
||||
DISTRIBUTED BY RANDOM BUCKETS 2
|
||||
PROPERTIES ('replication_num' = '1')
|
||||
AS
|
||||
with `test_with` AS (
|
||||
select l_partkey, l_suppkey
|
||||
from lineitem
|
||||
union
|
||||
select
|
||||
ps_partkey, ps_suppkey
|
||||
from
|
||||
partsupp)
|
||||
select * from test_with;
|
||||
"""
|
||||
waitingMTMVTaskFinished(getJobName("regression_test_mtmv_p0", "mv_with_cte"))
|
||||
order_qt_query_mv_with_cte """select * from mv_with_cte;"""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user