[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))),
|
||||
|
||||
Reference in New Issue
Block a user