englefly opened a new pull request, #69075:
URL: https://github.com/apache/doris/pull/69075

   
   ### What problem does this PR solve?
   
   Problem Summary:
   EliminateUnnecessaryProject removed a project only by comparing the exprIds 
of
   its output with the exprIds of its child:
   
       
project.getOutputExprIdBitSet().equals(project.getChildrenOutputExprIdBitSet())
   
   That equality does not mean the project is a pass-through. 
ConstantPropagation
   replaces a slot reference with a literal but keeps the exprId of the replaced
   slot (ConstantPropagation#visitLogicalAggregate:
   new Alias(expr.getExprId(), replacedExpr, expr.getName())), so such a project
   outputs the same exprIds as its child while its slots describe not nullable
   literals. RQG case 11000258898 reaches exactly this shape:
   
       BEFORE:
       LogicalResultSink[61] ( outputExprs=[2004-04-28#55, 2014-07-07#56] )
       +--LogicalLimit ( limit=1, offset=0, phase=GLOBAL )
          +--LogicalProject[260] ( projects=['2011-11-15 13:33:05.000' AS 
`2004-04-28`#55,
                                             '2011-11-15 13:33:05.000' AS 
`2014-07-07`#56] )
             +--LogicalIntersect ( qualifier=DISTINCT, outputs=[2004-04-28#55, 
2014-07-07#56], ... )
       AFTER:
       LogicalResultSink[61] ( outputExprs=[2004-04-28#55, 2014-07-07#56] )
       +--LogicalLimit ( limit=1, offset=0, phase=GLOBAL )
          +--LogicalIntersect ( qualifier=DISTINCT, outputs=[2004-04-28#55, 
2014-07-07#56], ... )
   
   The project is dropped because its output exprIds {55, 56} equal the child
   intersect's output exprIds {55, 56}, although the project's #55 is the not
   nullable literal cast('2011-11-15 13:33:05.000' as TEXT) while the 
intersect's
   #55 is nullable at schema level (its first branch reads the nullable column
   col_datetime_3__undef_signed). After the project is removed the upper plan
   reads the nullable slot again; those references had already been synced to 
the
   not nullable project slot during the rewrite, so the last AdjustNullable pass
   widens them and fe_debug=true reports
   "AdjustNullable convert slot 2004-04-28#55 from not-nullable to nullable".
   Dropping such a project also loses the data type carried by its slots.
   
   Fix:
   EliminateUnnecessaryProject only removes a project when every project item is
   a plain SlotReference of the child, i.e. a real pass-through. The reason why
   comparing exprIds is not enough is documented next to the check.
   
   ### Release note
   
   None
   
   ### Check List (For Author)
   
   - Test: Unit Test
       - 
EliminateUnnecessaryProjectTest#testKeepProjectThatReplacesSlotsWithLiterals
         builds such a project and fails before this change with
         "expected node type UNKNOWN but got LOGICAL_OLAP_SCAN".
       - EliminateUnnecessaryProjectTest, ColumnPruningTest, 
MergeProjectableTest,
         PushProjectIntoUnionTest, SetOperationOutputMappingTest,
         ConstantPropagationTest and SqlPlanSuiteTest rerun without new 
failures.
   - Behavior changed: Yes. A project that replaces output slots with literals 
is
     kept, so the not null and data type attributes of those slots survive.
   - Does this need documentation: No
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to