This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new f14519c1bf5 branch-4.1: [fix](variant) Preserve NestedGroup access 
paths through explode (#67022)
f14519c1bf5 is described below

commit f14519c1bf536ca81b8de4be7082f9c76702186c
Author: lihangyu <[email protected]>
AuthorDate: Mon Aug 24 13:50:35 2026 +0800

    branch-4.1: [fix](variant) Preserve NestedGroup access paths through 
explode (#67022)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #66575
    
    Problem Summary:
    
    This is a branch-4.1-specific regression. The Variant explode
    access-path logic introduced by #66575 conservatively preserves the
    whole input container. That fallback remains necessary for ordinary
    Variant columns because a generator may change the container kind, but
    it drops the exact leaf paths required by NestedGroup storage.
    
    This change keeps ordinary Variant behavior unchanged and propagates
    exact output suffixes only when Variant NestedGroup is enabled. It
    covers both unary and multi-argument explode.
    
    Red/green evidence:
    
    - Before the source fix, both new NestedGroup tests failed because the
    expected leaf paths were absent.
    - After the fix, `VariantPruningLogicTest` passed 14/14.
    - Related baseline `PruneNestedColumnTest` passed 39/39.
    
    ### Check List
    
    - Test
      - [x] Unit Test
      - [ ] Regression Test
    - Behavior changed
      - [ ] User-visible behavior changed
    
    ### Release note
    
    None
---
 .../rules/rewrite/AccessPathPlanCollector.java     | 18 ++++++++++++-----
 .../rules/rewrite/VariantPruningLogicTest.java     | 23 ++++++++++++++++++++++
 2 files changed, 36 insertions(+), 5 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java
index c2235a8d6ac..9f6b170a156 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/AccessPathPlanCollector.java
@@ -47,6 +47,7 @@ import 
org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation;
 import org.apache.doris.nereids.trees.plans.logical.LogicalUnion;
 import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanVisitor;
 import org.apache.doris.nereids.types.NestedColumnPrunable;
+import org.apache.doris.nereids.types.VariantType;
 
 import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Multimap;
@@ -92,7 +93,9 @@ public class AccessPathPlanCollector extends 
DefaultPlanVisitor<Void, StatementC
                     for (Expression child : function.children()) {
                         exprCollector.collect(child);
                     }
-                } else if (function.arity() == 1 && 
function.child(0).getDataType().isVariantType()) {
+                } else if (function.arity() == 1
+                        && function.child(0).getDataType() instanceof 
VariantType
+                        && !((VariantType) 
function.child(0).getDataType()).getEnableNestedGroup()) {
                     // A generator may change the Variant container kind, 
which the legacy path
                     // cannot encode. Preserve the whole input container so 
residual values stay visible.
                     exprCollector.collect(function.child(0));
@@ -103,9 +106,11 @@ public class AccessPathPlanCollector extends 
DefaultPlanVisitor<Void, StatementC
                             // $c$1.VALUES.b
                             CollectorContext argumentContext = new 
CollectorContext(context, false);
                             argumentContext.setType(accessPath.getType());
-                            argumentContext.getAccessPathBuilder()
-                                    .addSuffix(AccessPathInfo.ACCESS_ALL)
-                                    .addSuffix(path.subList(1, path.size()));
+                            if (!(function.child(0).getDataType() instanceof 
VariantType
+                                    && ((VariantType) 
function.child(0).getDataType()).getEnableNestedGroup())) {
+                                
argumentContext.getAccessPathBuilder().addSuffix(AccessPathInfo.ACCESS_ALL);
+                            }
+                            
argumentContext.getAccessPathBuilder().addSuffix(path.subList(1, path.size()));
                             function.child(0).accept(exprCollector, 
argumentContext);
                             continue;
                         } else if (path.size() >= 2) {
@@ -115,11 +120,14 @@ public class AccessPathPlanCollector extends 
DefaultPlanVisitor<Void, StatementC
                             int colIndex = 
Integer.parseInt(colName.substring(StructLiteral.COL_PREFIX.length())) - 1;
                             CollectorContext argumentContext = new 
CollectorContext(context, false);
                             argumentContext.setType(accessPath.getType());
-                            if 
(function.child(colIndex).getDataType().isVariantType()) {
+                            if (function.child(colIndex).getDataType() 
instanceof VariantType
+                                    && !((VariantType) 
function.child(colIndex).getDataType()).getEnableNestedGroup()) {
                                 // Every Variant argument determines the 
generated array shape, so
                                 // an output-field path must not narrow the 
input container.
                                 
exprCollector.collect(function.child(colIndex));
                                 continue;
+                            } else if (function.child(colIndex).getDataType() 
instanceof VariantType) {
+                                
argumentContext.getAccessPathBuilder().addSuffix(path.subList(2, path.size()));
                             } else {
                                 argumentContext.getAccessPathBuilder()
                                         .addSuffix(AccessPathInfo.ACCESS_ALL)
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
index bacd8c5d46b..65a61f8a0ff 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/VariantPruningLogicTest.java
@@ -50,6 +50,10 @@ public class VariantPruningLogicTest extends 
TestWithFeService {
                 + "  id int,\n"
                 + "  v variant\n"
                 + ") properties ('replication_num'='1')");
+        createTable("create table variant_ng_tbl(\n"
+                + "  id int,\n"
+                + "  v variant<properties(\"variant_enable_nested_group\" = 
\"true\")>\n"
+                + ") properties ('replication_num'='1')");
         
connectContext.getSessionVariable().setDisableNereidsRules(RuleType.PRUNE_EMPTY_PARTITION.name());
         connectContext.getSessionVariable().enableNereidsTimeout = false;
         connectContext.getSessionVariable().enablePruneNestedColumns = true;
@@ -205,6 +209,25 @@ public class VariantPruningLogicTest extends 
TestWithFeService {
         );
     }
 
+    @Test
+    public void testExplodeNestedGroupVariantAccessPaths() throws Exception {
+        assertAllAccessPathsContain(
+                "select x['x'] from variant_ng_tbl lateral view 
explode(v['arr']) tmp as x",
+                ImmutableList.of(path("v", "arr", "x")),
+                ImmutableList.of(path("v", "arr"))
+        );
+    }
+
+    @Test
+    public void testMultiArgumentExplodeNestedGroupVariantAccessPaths() throws 
Exception {
+        assertAllAccessPathsContain(
+                "select x1['x'], x2['y'] from variant_ng_tbl "
+                        + "lateral view explode(v['arr1'], v['arr2']) tmp as 
x1, x2",
+                ImmutableList.of(path("v", "arr1", "x"), path("v", "arr2", 
"y")),
+                ImmutableList.of(path("v", "arr1"), path("v", "arr2"))
+        );
+    }
+
     private Pair<PhysicalPlan, List<SlotDescriptor>> 
collectVariantSlots(String sql) throws Exception {
         NereidsPlanner planner = (NereidsPlanner) 
executeNereidsSql(sql).planner();
         List<SlotDescriptor> variantSlots = new ArrayList<>();


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

Reply via email to