[fix](nereids) don't build cte producer if the consumer is empty relation (#21317)

explain WITH cte_0 AS ( SELECT 1 AS a ) SELECT * from cte_0 t1 join cte_0 t2 on true WHERE false;
before:
```
+----------------------------+
| Explain String             |
+----------------------------+
| PLAN FRAGMENT 0            |
|   OUTPUT EXPRS:            |
|     a[#1]                  |
|     a[#2]                  |
|   PARTITION: UNPARTITIONED |
|                            |
|   VRESULT SINK             |
|                            |
|   1:VEMPTYSET              |
|                            |
| PLAN FRAGMENT 1            |
|   OUTPUT EXPRS:            |
|     a[#0]                  |
|   PARTITION: UNPARTITIONED |
|                            |
|   MultiCastDataSinks       |
|                            |
|   0:VUNION                 |
|      constant exprs:       |
|          1                 |
+----------------------------+
```
after:

```
+----------------------------+
| Explain String             |
+----------------------------+
| PLAN FRAGMENT 0            |
|   OUTPUT EXPRS:            |
|     a[#0]                  |
|     a[#1]                  |
|   PARTITION: UNPARTITIONED |
|                            |
|   VRESULT SINK             |
|                            |
|   0:VEMPTYSET              |
+----------------------------+
```
This commit is contained in:
starocean999
2023-07-07 18:12:28 +08:00
committed by GitHub
parent cad9e8849c
commit d39bca5ec7
2 changed files with 18 additions and 10 deletions

View File

@ -24,6 +24,7 @@ import org.apache.doris.nereids.trees.expressions.CTEId;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTE;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTEAnchor;
import org.apache.doris.nereids.trees.plans.logical.LogicalCTEProducer;
import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalSubQueryAlias;
import org.apache.doris.qe.ConnectContext;
@ -47,17 +48,19 @@ public class BuildCTEAnchorAndCTEProducer extends OneRewriteRuleFactory {
}
LogicalCTE logicalCTE = (LogicalCTE) p;
LogicalPlan child = (LogicalPlan) logicalCTE.child();
for (int i = logicalCTE.getAliasQueries().size() - 1; i >= 0; i--) {
LogicalSubQueryAlias s = (LogicalSubQueryAlias) logicalCTE.getAliasQueries().get(i);
CTEId id = logicalCTE.findCTEId(s.getAlias());
if (cascadesContext.cteReferencedCount(id)
<= ConnectContext.get().getSessionVariable().inlineCTEReferencedThreshold
|| !ConnectContext.get().getSessionVariable().getEnablePipelineEngine()) {
continue;
if (!(child instanceof LogicalEmptyRelation)) {
for (int i = logicalCTE.getAliasQueries().size() - 1; i >= 0; i--) {
LogicalSubQueryAlias s = (LogicalSubQueryAlias) logicalCTE.getAliasQueries().get(i);
CTEId id = logicalCTE.findCTEId(s.getAlias());
if (cascadesContext.cteReferencedCount(id)
<= ConnectContext.get().getSessionVariable().inlineCTEReferencedThreshold
|| !ConnectContext.get().getSessionVariable().getEnablePipelineEngine()) {
continue;
}
LogicalCTEProducer logicalCTEProducer = new LogicalCTEProducer(
rewrite((LogicalPlan) s.child(), cascadesContext), id);
child = new LogicalCTEAnchor(logicalCTEProducer, child, id);
}
LogicalCTEProducer logicalCTEProducer = new LogicalCTEProducer(
rewrite((LogicalPlan) s.child(), cascadesContext), id);
child = new LogicalCTEAnchor(logicalCTEProducer, child, id);
}
return child;
}

View File

@ -301,5 +301,10 @@ suite("cte") {
exception = "[cte1] cannot be used more than once"
}
explain {
sql("WITH cte_0 AS ( SELECT 1 AS a ) SELECT * from cte_0 t1 join cte_0 t2 on true WHERE false;")
notContains "MultiCastDataSinks"
}
}