github-actions[bot] commented on code in PR #69414:
URL: https://github.com/apache/doris/pull/69414#discussion_r4348130457


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java:
##########
@@ -263,17 +264,18 @@ public Plan visitLogicalUnion(LogicalUnion union, Context 
context) {
                     
constExprs.get(j).add(union.getConstantExprsList().get(j).get(i));
                 }
                 outputs.add(union.getOutputs().get(i));
-                // if not variant, no need to process
-                if (!union.getOutput().get(i).getDataType().isVariantType()) {
+                // Whole-column reads have no sub-path requests, including in 
constant-only unions.
+                if (!originalSlot.getDataType().isVariantType()
+                        || 
!context.slotToSubPathsMap.containsKey(originalSlot)) {
                     continue;
                 }
+                Set<List<String>> requestedSubPaths = 
context.slotToSubPathsMap.get(originalSlot);
                 // put new slots generated by sub path push down
                 Map<List<String>, List<SlotReference>> subPathSlots = 
Maps.newHashMap();
                 for (int j = 0; j < regularChildrenOutputs.size(); j++) {
                     List<SlotReference> regularChildOutput = 
union.getRegularChildOutput(j);
                     Expression output = regularChildOutput.get(i);
-                    if (!context.slotToSlotsMap.containsKey(output)
-                            || 
!context.slotToSubPathsMap.containsKey(outputs.get(i))) {
+                    if (!context.slotToSlotsMap.containsKey(output)) {

Review Comment:
   [P2] Handle branches without path slots before expanding later outputs
   
   A later VARIANT output can now enter expansion even when a branch cannot 
supply a path slot. For example, consumers of a twice-referenced CTE can retain 
this reduced plan:
   
   ```text
   Project(A['x'], B['x'])
     UnionAll(outputs=[A,B], mappings=[[a1,e],[a2,b2]])
       Project(a1,e)
         Generate(explode_variant_array(arr) AS e)
           OlapScan(a1,arr)
       OlapScan(a2,b2)
   ```
   
   `visitLogicalGenerate` does not register subpath slots for `e`, and a 
forwarding project cannot create them. Expansion of `A` succeeds, but expansion 
of `B` skips child 0 here; child 1 then supplies `b2['x']` and throws `cannot 
find sub path for child 1` because no entry was initialized by child 0. 
Reversing the branches instead leaves a short list indexed when appending child 
slots. Before this patch, `outputs.get(1)` referred to the inserted `A['x']` 
slot, so `B` was left unexpanded and the upper `B['x']` remained valid: this is 
a newly exposed failure for later columns, even though the analogous 
first-column limitation predates the PR.
   
   Please synthesize missing branch expressions, or retain evaluation above 
UNION for that output/path when a branch cannot supply it, and add a regression 
with an earlier expandable VARIANT and a later exploded/scan VARIANT pair.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java:
##########
@@ -294,7 +296,7 @@ public Plan visitLogicalUnion(LogicalUnion union, Context 
context) {
                         // because context only record sub path generated by 
parent
                         List<String> parentPaths = entry.getKey()
                                 .subList(subPathByChildren.size(), 
entry.getKey().size());
-                        if 
(!context.slotToSubPathsMap.get(outputs.get(i)).contains(parentPaths)) {
+                        if (!requestedSubPaths.contains(parentPaths)) {

Review Comment:
   [P2] Preserve one evaluation of volatile constant UNION values
   
   The corrected lookup also activates later outputs whose constant-row 
expression is volatile. Consider this reduced producer of a twice-referenced 
CTE:
   
   ```text
   UnionAll(outputs=[A,B], regular mappings=[[a,b]])
     OlapScan(a,b)
     constant row: [parse_to_variant('{"x":1}'), F]
   F = parse_to_variant(concat('{"x":"', uuid(), '"}'))
   ```
   
   When consumers request `A['x']`, whole `B`, and `B['x']`, expansion of `B` 
now retains `F` and appends `ElementAt(F,'x')` as a separate constant field. 
The UNION source executes those fields in separate expression contexts, so `B` 
contains one UUID while its separately returned `B['x']` contains another. This 
breaks same-row value consistency and can change predicate results. Before this 
patch, the inserted `A['x']` occupied `outputs.get(1)`, so later `B` was left 
unexpanded and its path was read from its single materialized value.
   
   `MergeOneRowRelationIntoUnion` allows this row because `uuid()` initially 
occurs only once. Volatile-expression extraction runs before this new 
duplication and has no UNION handler; physical common-expression optimization 
only handles projects, so neither restores sharing for these constant fields. 
Please materialize a volatile value once before deriving paths, or retain its 
path evaluation above UNION, and add a mixed-input regression checking that a 
whole object's field agrees with its separately requested path.



-- 
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