[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.
This commit is contained in:
minghong
2023-02-13 15:27:47 +08:00
committed by GitHub
parent 77be0d13c3
commit ded698127e

View File

@ -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<SlotId> slotIds = Lists.newArrayList();
final List<TupleId> 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());