From d3b48a4ce99c20b8c976d55986446825f9e2b25d Mon Sep 17 00:00:00 2001 From: morrySnow <101034200+morrySnow@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:11:44 +0800 Subject: [PATCH] [fix](Nereids) producer to consumer should be multimap in cte (#39850) because consumer could refer multi times for one producer' slot, so producer to consumer slot map should be multimap --- .../apache/doris/nereids/CascadesContext.java | 19 +++++-- .../doris/nereids/StatementContext.java | 5 +- .../translator/PhysicalPlanTranslator.java | 7 +-- .../nereids/rules/rewrite/AdjustNullable.java | 15 +++-- .../nereids/rules/rewrite/OrExpansion.java | 8 +-- .../rules/rewrite/VariantSubPathPruning.java | 4 +- .../trees/copier/LogicalPlanDeepCopier.java | 4 +- .../plans/logical/LogicalCTEConsumer.java | 57 +++++++++---------- .../plans/physical/PhysicalCTEConsumer.java | 20 +++---- .../test_cte_with_duplicate_consumer.groovy | 25 ++++++++ 10 files changed, 100 insertions(+), 64 deletions(-) create mode 100644 regression-test/suites/nereids_p0/cte/test_cte_with_duplicate_consumer.groovy diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/CascadesContext.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/CascadesContext.java index 306da4d0c50235..9be4b89e57c968 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/CascadesContext.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/CascadesContext.java @@ -71,6 +71,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -618,8 +619,8 @@ public Map> getConsumerIdToFilters() { return this.statementContext.getConsumerIdToFilters(); } - public void addCTEConsumerGroup(CTEId cteId, Group g, Map producerSlotToConsumerSlot) { - List, Group>> consumerGroups = + public void addCTEConsumerGroup(CTEId cteId, Group g, Multimap producerSlotToConsumerSlot) { + List, Group>> consumerGroups = this.statementContext.getCteIdToConsumerGroup().computeIfAbsent(cteId, k -> new ArrayList<>()); consumerGroups.add(Pair.of(producerSlotToConsumerSlot, g)); } @@ -628,12 +629,18 @@ public void addCTEConsumerGroup(CTEId cteId, Group g, Map producerSl * Update CTE consumer group as producer's stats update */ public void updateConsumerStats(CTEId cteId, Statistics statistics) { - List, Group>> consumerGroups = this.statementContext.getCteIdToConsumerGroup().get(cteId); - for (Pair, Group> p : consumerGroups) { - Map producerSlotToConsumerSlot = p.first; + List, Group>> consumerGroups + = this.statementContext.getCteIdToConsumerGroup().get(cteId); + for (Pair, Group> p : consumerGroups) { + Multimap producerSlotToConsumerSlot = p.first; Statistics updatedConsumerStats = new StatisticsBuilder(statistics).build(); for (Entry entry : statistics.columnStatistics().entrySet()) { - updatedConsumerStats.addColumnStats(producerSlotToConsumerSlot.get(entry.getKey()), entry.getValue()); + if (!(entry.getKey() instanceof Slot)) { + continue; + } + for (Slot consumer : producerSlotToConsumerSlot.get((Slot) entry.getKey())) { + updatedConsumerStats.addColumnStats(consumer, entry.getValue()); + } } p.value().setStatistics(updatedConsumerStats); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java index d23a6cb960cca9..65cfeeceab6386 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/StatementContext.java @@ -54,6 +54,7 @@ import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -115,7 +116,7 @@ public class StatementContext implements Closeable { private final Map> cteIdToOutputIds = new HashMap<>(); private final Map> consumerIdToFilters = new HashMap<>(); // Used to update consumer's stats - private final Map, Group>>> cteIdToConsumerGroup = new HashMap<>(); + private final Map, Group>>> cteIdToConsumerGroup = new HashMap<>(); private final Map rewrittenCteProducer = new HashMap<>(); private final Map rewrittenCteConsumer = new HashMap<>(); private final Set viewDdlSqlSet = Sets.newHashSet(); @@ -357,7 +358,7 @@ public Map getIdToPlaceholderRealExpr() { return idToPlaceholderRealExpr; } - public Map, Group>>> getCteIdToConsumerGroup() { + public Map, Group>>> getCteIdToConsumerGroup() { return cteIdToConsumerGroup; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java index 55d99e6b50fc7d..1201bc6e32cc72 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/glue/translator/PhysicalPlanTranslator.java @@ -1205,12 +1205,9 @@ public PlanFragment visitPhysicalCTEConsumer(PhysicalCTEConsumer cteConsumer, for (Slot producerSlot : cteProducer.getOutput()) { SlotRef slotRef = context.findSlotRef(producerSlot.getExprId()); tupleDescriptor = slotRef.getDesc().getParent(); - Slot consumerSlot = cteConsumer.getProducerToConsumerSlotMap().get(producerSlot); - // consumerSlot could be null if we prune partial consumers' columns - if (consumerSlot == null) { - continue; + for (Slot consumerSlot : cteConsumer.getProducerToConsumerSlotMap().get(producerSlot)) { + context.addExprIdSlotRefPair(consumerSlot.getExprId(), slotRef); } - context.addExprIdSlotRefPair(consumerSlot.getExprId(), slotRef); } CTEScanNode cteScanNode = new CTEScanNode(tupleDescriptor); context.getRuntimeTranslator().ifPresent(runtimeFilterTranslator -> diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java index e387218c47c5d1..808288b8fe3cab 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AdjustNullable.java @@ -51,8 +51,10 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import java.util.LinkedHashMap; import java.util.List; @@ -261,14 +263,15 @@ public Plan visitLogicalPartitionTopN(LogicalPartitionTopN parti @Override public Plan visitLogicalCTEConsumer(LogicalCTEConsumer cteConsumer, Map replaceMap) { Map consumerToProducerOutputMap = new LinkedHashMap<>(); - Map producerToConsumerOutputMap = new LinkedHashMap<>(); + Multimap producerToConsumerOutputMap = LinkedHashMultimap.create(); for (Slot producerOutputSlot : cteConsumer.getConsumerToProducerOutputMap().values()) { Slot newProducerOutputSlot = updateExpression(producerOutputSlot, replaceMap); - Slot newConsumerOutputSlot = cteConsumer.getProducerToConsumerOutputMap().get(producerOutputSlot) - .withNullable(newProducerOutputSlot.nullable()); - producerToConsumerOutputMap.put(newProducerOutputSlot, newConsumerOutputSlot); - consumerToProducerOutputMap.put(newConsumerOutputSlot, newProducerOutputSlot); - replaceMap.put(newConsumerOutputSlot.getExprId(), newConsumerOutputSlot); + for (Slot consumerOutputSlot : cteConsumer.getProducerToConsumerOutputMap().get(producerOutputSlot)) { + Slot newConsumerOutputSlot = consumerOutputSlot.withNullable(newProducerOutputSlot.nullable()); + producerToConsumerOutputMap.put(newProducerOutputSlot, newConsumerOutputSlot); + consumerToProducerOutputMap.put(newConsumerOutputSlot, newProducerOutputSlot); + replaceMap.put(newConsumerOutputSlot.getExprId(), newConsumerOutputSlot); + } } return cteConsumer.withTwoMaps(consumerToProducerOutputMap, producerToConsumerOutputMap); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/OrExpansion.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/OrExpansion.java index a04cce4d78462b..378ee0f67aef20 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/OrExpansion.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/OrExpansion.java @@ -206,11 +206,11 @@ public Plan visitLogicalJoin(LogicalJoin join, O private Map constructReplaceMap(LogicalCTEConsumer leftConsumer, Map leftCloneToLeft, LogicalCTEConsumer rightConsumer, Map rightCloneToRight) { Map replaced = new HashMap<>(); - for (Entry entry : leftConsumer.getProducerToConsumerOutputMap().entrySet()) { - replaced.put(leftCloneToLeft.get(entry.getKey()), entry.getValue()); + for (Entry entry : leftConsumer.getConsumerToProducerOutputMap().entrySet()) { + replaced.put(leftCloneToLeft.get(entry.getValue()), entry.getKey()); } - for (Entry entry : rightConsumer.getProducerToConsumerOutputMap().entrySet()) { - replaced.put(rightCloneToRight.get(entry.getKey()), entry.getValue()); + for (Entry entry : rightConsumer.getConsumerToProducerOutputMap().entrySet()) { + replaced.put(rightCloneToRight.get(entry.getValue()), entry.getKey()); } return replaced; } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java index 111493837a0cdd..414dac1c95d0aa 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java @@ -59,8 +59,10 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import java.util.Collections; @@ -394,7 +396,7 @@ public Plan visitLogicalCTEConsumer(LogicalCTEConsumer cteConsumer, Context cont return cteConsumer; } Map consumerToProducerOutputMap = Maps.newHashMap(); - Map producerToConsumerOutputMap = Maps.newHashMap(); + Multimap producerToConsumerOutputMap = LinkedHashMultimap.create(); Map, SlotReference>> oriSlotToSubPathToSlot = Maps.newHashMap(); for (Map.Entry consumerToProducer : cteConsumer.getConsumerToProducerOutputMap().entrySet()) { Slot consumer = consumerToProducer.getKey(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java index 277f5ae345a6f8..7b7c95dd811d79 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/copier/LogicalPlanDeepCopier.java @@ -63,6 +63,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; import java.util.LinkedHashMap; import java.util.List; @@ -397,7 +399,7 @@ public Plan visitLogicalCTEConsumer(LogicalCTEConsumer cteConsumer, DeepCopierCo return context.getRelationReplaceMap().get(cteConsumer.getRelationId()); } Map consumerToProducerOutputMap = new LinkedHashMap<>(); - Map producerToConsumerOutputMap = new LinkedHashMap<>(); + Multimap producerToConsumerOutputMap = LinkedHashMultimap.create(); for (Slot consumerOutput : cteConsumer.getOutput()) { Slot newOutput = (Slot) ExpressionDeepCopier.INSTANCE.deepCopy(consumerOutput, context); consumerToProducerOutputMap.put(newOutput, cteConsumer.getProducerSlot(consumerOutput)); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCTEConsumer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCTEConsumer.java index cd73c96d02e192..415fdddf80b449 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCTEConsumer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/logical/LogicalCTEConsumer.java @@ -33,6 +33,10 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; import java.util.LinkedHashMap; import java.util.List; @@ -50,20 +54,15 @@ public class LogicalCTEConsumer extends LogicalRelation implements BlockFuncDeps private final String name; private final CTEId cteId; private final Map consumerToProducerOutputMap; - private final Map producerToConsumerOutputMap; + private final Multimap producerToConsumerOutputMap; /** * Logical CTE consumer. */ public LogicalCTEConsumer(RelationId relationId, CTEId cteId, String name, - Map consumerToProducerOutputMap, Map producerToConsumerOutputMap) { - super(relationId, PlanType.LOGICAL_CTE_CONSUMER, Optional.empty(), Optional.empty()); - this.cteId = Objects.requireNonNull(cteId, "cteId should not null"); - this.name = Objects.requireNonNull(name, "name should not null"); - this.consumerToProducerOutputMap = Objects.requireNonNull(consumerToProducerOutputMap, - "consumerToProducerOutputMap should not null"); - this.producerToConsumerOutputMap = Objects.requireNonNull(producerToConsumerOutputMap, - "producerToConsumerOutputMap should not null"); + Map consumerToProducerOutputMap, Multimap producerToConsumerOutputMap) { + this(relationId, cteId, name, consumerToProducerOutputMap, producerToConsumerOutputMap, + Optional.empty(), Optional.empty()); } /** @@ -73,24 +72,31 @@ public LogicalCTEConsumer(RelationId relationId, CTEId cteId, String name, Logic super(relationId, PlanType.LOGICAL_CTE_CONSUMER, Optional.empty(), Optional.empty()); this.cteId = Objects.requireNonNull(cteId, "cteId should not null"); this.name = Objects.requireNonNull(name, "name should not null"); - this.consumerToProducerOutputMap = new LinkedHashMap<>(); - this.producerToConsumerOutputMap = new LinkedHashMap<>(); - initOutputMaps(producerPlan); + ImmutableMap.Builder cToPBuilder = ImmutableMap.builder(); + ImmutableMultimap.Builder pToCBuilder = ImmutableMultimap.builder(); + List producerOutput = producerPlan.getOutput(); + for (Slot producerOutputSlot : producerOutput) { + Slot consumerSlot = generateConsumerSlot(this.name, producerOutputSlot); + cToPBuilder.put(consumerSlot, producerOutputSlot); + pToCBuilder.put(producerOutputSlot, consumerSlot); + } + consumerToProducerOutputMap = cToPBuilder.build(); + producerToConsumerOutputMap = pToCBuilder.build(); } /** * Logical CTE consumer. */ public LogicalCTEConsumer(RelationId relationId, CTEId cteId, String name, - Map consumerToProducerOutputMap, Map producerToConsumerOutputMap, + Map consumerToProducerOutputMap, Multimap producerToConsumerOutputMap, Optional groupExpression, Optional logicalProperties) { super(relationId, PlanType.LOGICAL_CTE_CONSUMER, groupExpression, logicalProperties); this.cteId = Objects.requireNonNull(cteId, "cteId should not null"); this.name = Objects.requireNonNull(name, "name should not null"); - this.consumerToProducerOutputMap = Objects.requireNonNull(consumerToProducerOutputMap, - "consumerToProducerOutputMap should not null"); - this.producerToConsumerOutputMap = Objects.requireNonNull(producerToConsumerOutputMap, - "producerToConsumerOutputMap should not null"); + this.consumerToProducerOutputMap = ImmutableMap.copyOf(Objects.requireNonNull(consumerToProducerOutputMap, + "consumerToProducerOutputMap should not null")); + this.producerToConsumerOutputMap = ImmutableMultimap.copyOf(Objects.requireNonNull(producerToConsumerOutputMap, + "producerToConsumerOutputMap should not null")); } /** @@ -107,20 +113,11 @@ public static SlotReference generateConsumerSlot(String cteName, Slot producerOu slotRef != null ? Optional.of(slotRef.getInternalName()) : Optional.empty()); } - private void initOutputMaps(LogicalPlan childPlan) { - List producerOutput = childPlan.getOutput(); - for (Slot producerOutputSlot : producerOutput) { - Slot consumerSlot = generateConsumerSlot(this.name, producerOutputSlot); - producerToConsumerOutputMap.put(producerOutputSlot, consumerSlot); - consumerToProducerOutputMap.put(consumerSlot, producerOutputSlot); - } - } - public Map getConsumerToProducerOutputMap() { return consumerToProducerOutputMap; } - public Map getProducerToConsumerOutputMap() { + public Multimap getProducerToConsumerOutputMap() { return producerToConsumerOutputMap; } @@ -129,7 +126,8 @@ public R accept(PlanVisitor visitor, C context) { return visitor.visitLogicalCTEConsumer(this, context); } - public Plan withTwoMaps(Map consumerToProducerOutputMap, Map producerToConsumerOutputMap) { + public Plan withTwoMaps(Map consumerToProducerOutputMap, + Multimap producerToConsumerOutputMap) { return new LogicalCTEConsumer(relationId, cteId, name, consumerToProducerOutputMap, producerToConsumerOutputMap); } @@ -162,7 +160,8 @@ public List computeOutput() { @Override public Plan pruneOutputs(List prunedOutputs) { Map consumerToProducerOutputMap = new LinkedHashMap<>(this.consumerToProducerOutputMap.size()); - Map producerToConsumerOutputMap = new LinkedHashMap<>(this.consumerToProducerOutputMap.size()); + Multimap producerToConsumerOutputMap = LinkedHashMultimap.create( + this.consumerToProducerOutputMap.size(), this.consumerToProducerOutputMap.size()); for (Entry consumerToProducerSlot : this.consumerToProducerOutputMap.entrySet()) { if (prunedOutputs.contains(consumerToProducerSlot.getKey())) { consumerToProducerOutputMap.put(consumerToProducerSlot.getKey(), consumerToProducerSlot.getValue()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalCTEConsumer.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalCTEConsumer.java index 9139e3142b1f57..385c411e7217de 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalCTEConsumer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalCTEConsumer.java @@ -31,6 +31,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Multimap; import java.util.List; import java.util.Map; @@ -43,14 +45,14 @@ public class PhysicalCTEConsumer extends PhysicalRelation { private final CTEId cteId; - private final Map producerToConsumerSlotMap; + private final Multimap producerToConsumerSlotMap; private final Map consumerToProducerSlotMap; /** * Constructor */ public PhysicalCTEConsumer(RelationId relationId, CTEId cteId, Map consumerToProducerSlotMap, - Map producerToConsumerSlotMap, LogicalProperties logicalProperties) { + Multimap producerToConsumerSlotMap, LogicalProperties logicalProperties) { this(relationId, cteId, consumerToProducerSlotMap, producerToConsumerSlotMap, Optional.empty(), logicalProperties); } @@ -59,7 +61,7 @@ public PhysicalCTEConsumer(RelationId relationId, CTEId cteId, Map c * Constructor */ public PhysicalCTEConsumer(RelationId relationId, CTEId cteId, - Map consumerToProducerSlotMap, Map producerToConsumerSlotMap, + Map consumerToProducerSlotMap, Multimap producerToConsumerSlotMap, Optional groupExpression, LogicalProperties logicalProperties) { this(relationId, cteId, consumerToProducerSlotMap, producerToConsumerSlotMap, groupExpression, logicalProperties, null, null); @@ -69,14 +71,14 @@ public PhysicalCTEConsumer(RelationId relationId, CTEId cteId, * Constructor */ public PhysicalCTEConsumer(RelationId relationId, CTEId cteId, Map consumerToProducerSlotMap, - Map producerToConsumerSlotMap, Optional groupExpression, + Multimap producerToConsumerSlotMap, Optional groupExpression, LogicalProperties logicalProperties, PhysicalProperties physicalProperties, Statistics statistics) { super(relationId, PlanType.PHYSICAL_CTE_CONSUMER, groupExpression, logicalProperties, physicalProperties, statistics); this.cteId = cteId; this.consumerToProducerSlotMap = ImmutableMap.copyOf(Objects.requireNonNull( consumerToProducerSlotMap, "consumerToProducerSlotMap should not null")); - this.producerToConsumerSlotMap = ImmutableMap.copyOf(Objects.requireNonNull( + this.producerToConsumerSlotMap = ImmutableMultimap.copyOf(Objects.requireNonNull( producerToConsumerSlotMap, "consumerToProducerSlotMap should not null")); } @@ -84,7 +86,7 @@ public CTEId getCteId() { return cteId; } - public Map getProducerToConsumerSlotMap() { + public Multimap getProducerToConsumerSlotMap() { return producerToConsumerSlotMap; } @@ -99,8 +101,7 @@ public Slot getProducerSlot(Slot consumerSlot) { public String toString() { StringBuilder builder = new StringBuilder(); if (!getAppliedRuntimeFilters().isEmpty()) { - getAppliedRuntimeFilters() - .stream().forEach(rf -> builder.append(" RF").append(rf.getId().asInt())); + getAppliedRuntimeFilters().forEach(rf -> builder.append(" RF").append(rf.getId().asInt())); } return Utils.toSqlString("PhysicalCTEConsumer[" + id.asInt() + "]", "stats", getStats(), "cteId", cteId, "RFs", builder, "map", consumerToProducerSlotMap); @@ -141,8 +142,7 @@ public String shapeInfo() { "cteId", cteId)); if (!getAppliedRuntimeFilters().isEmpty()) { shapeBuilder.append(" apply RFs:"); - getAppliedRuntimeFilters() - .stream().forEach(rf -> shapeBuilder.append(" RF").append(rf.getId().asInt())); + getAppliedRuntimeFilters().forEach(rf -> shapeBuilder.append(" RF").append(rf.getId().asInt())); } return shapeBuilder.toString(); } diff --git a/regression-test/suites/nereids_p0/cte/test_cte_with_duplicate_consumer.groovy b/regression-test/suites/nereids_p0/cte/test_cte_with_duplicate_consumer.groovy new file mode 100644 index 00000000000000..4064efcfc6e2e9 --- /dev/null +++ b/regression-test/suites/nereids_p0/cte/test_cte_with_duplicate_consumer.groovy @@ -0,0 +1,25 @@ +// 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_cte_with_duplicate_consumer") { + test { + sql """ + WITH cte1(col1) AS (SELECT 1), cte2(col2_1, col2_2) AS (SELECT col1, col1 FROM cte1) SELECT * FROM cte2 + """ + + result([[1, 1]]) + } +}