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]