From ded698127ea862add64c73cc3c2e33ccc7e34be2 Mon Sep 17 00:00:00 2001 From: minghong Date: Mon, 13 Feb 2023 15:27:47 +0800 Subject: [PATCH] [fix](planner) fix bug for missing slot (#16601) In previous version, if the output slot of analyticExpr is not materialized, the analyticExpr is pruned. But there are some cases that it cannot be pruned. For example: SELECT count(*) FROM T1, (SELECT dd FROM ( SELECT 1.1 as cc, ROW_NUMBER() OVER() as dd FROM T2 ) V1 ORDER BY cc DESC limit 1 ) V2; analyticExpr(ROW_NUMBER() OVER() as dd) is not materialized, but we have to generate WindowGroup for it. tmp.dd is used by upper count(*), we have to generate data for tmp.dd In this fix, if an inline view only output one column(in this example, the 'dd'), we materialize this column. TODO: In order to prune 'ROW_NUMBER() OVER() as dd', we need to rethink the rule of choosing a column for count(*). (refer to SingleNodePlanner.materializeTableResultForCrossJoinOrCountStar) V2 can be transformed to SELECT cc FROM ( SELECT 1.1 as cc, ROW_NUMBER() OVER() as dd FROM T2 ) V1 ORDER BY cc DESC limit 1 ) V2; Except the byte size of cc and dd, we need to consider the cost to generate cc and dd. --- .../apache/doris/planner/SingleNodePlanner.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java index 1003991f46..2d5bc41d07 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java +++ b/fe/fe-core/src/main/java/org/apache/doris/planner/SingleNodePlanner.java @@ -1193,6 +1193,23 @@ public class SingleNodePlanner { // create left-deep sequence of binary hash joins; assign node ids as we go along TableRef tblRef = selectStmt.getTableRefs().get(0); materializeTableResultForCrossJoinOrCountStar(tblRef, analyzer); + if (selectStmt.getSelectList().getItems().size() == 1) { + final List slotIds = Lists.newArrayList(); + final List tupleIds = Lists.newArrayList(); + Expr resultExprSelected = selectStmt.getSelectList().getItems().get(0).getExpr(); + if (resultExprSelected != null && resultExprSelected instanceof SlotRef) { + resultExprSelected.getIds(tupleIds, slotIds); + for (SlotId id : slotIds) { + final SlotDescriptor slot = analyzer.getDescTbl().getSlotDesc(id); + slot.setIsMaterialized(true); + slot.materializeSrcExpr(); + } + for (TupleId id : tupleIds) { + final TupleDescriptor tuple = analyzer.getDescTbl().getTupleDesc(id); + tuple.setIsMaterialized(true); + } + } + } root = createTableRefNode(analyzer, tblRef, selectStmt); // to change the inner contains analytic function // selectStmt.seondSubstituteInlineViewExprs(analyzer.getChangeResSmap());