This is an automated email from the ASF dual-hosted git repository.
eldenmoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new f4b06fd895c [fix](variant) fix array subscript on pruned variant
subpath (#63891)
f4b06fd895c is described below
commit f4b06fd895cce3f15ed8b151d1d9473ca9fb14be
Author: lihangyu <[email protected]>
AuthorDate: Mon Jun 1 22:13:24 2026 +0800
[fix](variant) fix array subscript on pruned variant subpath (#63891)
### What problem does this PR solve?
Fix variant subpath pruning for projections where the top-level
expression is an array subscript or `element_at` over a variant subpath.
The planner could leave the outer subscript on the original variant
access chain after pruning, which made valid 1-based array subscripts
return `NULL`.
The original array-of-objects repro depends on nested-group variant
semantics, so the regression in this PR uses a plain `VARIANT` array
leaf without nested group. Since that query result is already correct on
current master, the regression asserts the verbose plan instead: the
scan uses `subColPath=[items, type]` and the final array subscript is
applied to the pruned variant slot.
### Check List
- [x] Added regression test
- [x] Added FE planner unit test
### Tests
- `./run-regression-test.sh --run --conf tmp/regression-conf.auto.groovy
-d variant_p0 -s test_variant_array_subscript`
- `./run-fe-ut.sh --run
org.apache.doris.nereids.rules.rewrite.VariantPruningLogicTest` passed
earlier on the same FE code; rerun after this regression-only amend was
blocked by system pid/thread exhaustion before test execution.
---
.../rules/rewrite/VariantSubPathPruning.java | 3 +-
.../rules/rewrite/VariantPruningLogicTest.java | 18 ++++++++
.../variant_p0/test_variant_array_subscript.groovy | 54 ++++++++++++++++++++++
3 files changed, 74 insertions(+), 1 deletion(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java
index df0eebc8d38..5b081ce2c24 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/VariantSubPathPruning.java
@@ -386,7 +386,8 @@ public class VariantSubPathPruning implements
CustomRewriter {
.withChildren(context.elementAtToSlotMap.get(child));
} else {
addOthers = false;
- newProjection = projection;
+ newProjection = (NamedExpression) projection
+
.withChildren(ExpressionUtils.replace(child, context.elementAtToSlotMap));
// try push element_at on this slot
if (extractSlotToSubPathPair((ElementAt) child) ==
null) {
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 480c98b76e2..5268569e0b8 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
@@ -72,6 +72,24 @@ public class VariantPruningLogicTest extends
TestWithFeService {
);
}
+ @Test
+ public void testVariantArraySubscriptUsesPrunedSubPath() throws Exception {
+ String sql = "select cast(v['items']['type'] as array<string>)[1] from
variant_tbl";
+ String explain = getSQLPlanOrErrorMsg(sql, true);
+ Assertions.assertTrue(explain.contains("final projections:
element_at(CAST(v AS array<text>), 1)"),
+ explain);
+ Assertions.assertTrue(explain.contains("subColPath=[items, type]"),
+ explain);
+
Assertions.assertFalse(explain.contains("element_at(CAST(element_at(element_at("),
+ explain);
+ assertVariantSubColumnSlots(
+ sql,
+ ImmutableList.of(
+ ImmutableList.of("items", "type")
+ )
+ );
+ }
+
@Test
public void testVariantOrPredicatePaths() throws Exception {
assertPredicateAccessPathsEqual(
diff --git
a/regression-test/suites/variant_p0/test_variant_array_subscript.groovy
b/regression-test/suites/variant_p0/test_variant_array_subscript.groovy
new file mode 100644
index 00000000000..c038e5aefaf
--- /dev/null
+++ b/regression-test/suites/variant_p0/test_variant_array_subscript.groovy
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+suite("test_variant_array_subscript", "p0") {
+ sql "set enable_nereids_planner = true"
+ sql "set enable_fallback_to_original_planner = false"
+ sql "set default_variant_enable_nested_group = false"
+ sql "set default_variant_max_subcolumns_count = 100"
+
+ sql "DROP TABLE IF EXISTS test_variant_array_subscript"
+ sql """
+ CREATE TABLE test_variant_array_subscript (
+ id BIGINT,
+ v VARIANT
+ ) ENGINE=OLAP
+ DUPLICATE KEY(id)
+ DISTRIBUTED BY HASH(id) BUCKETS 1
+ PROPERTIES (
+ "replication_allocation" = "tag.location.default: 1",
+ "disable_auto_compaction" = "true"
+ )
+ """
+
+ sql """
+ INSERT INTO test_variant_array_subscript VALUES
+ (1, '{"items":{"type":["e2e_QC","platform_QC"]}}')
+ """
+ sql "sync"
+
+ explain {
+ verbose true
+ sql """
+ SELECT CAST(v['items']['type'] AS ARRAY<STRING>)[1]
+ FROM test_variant_array_subscript
+ """
+ contains "subColPath=[items, type]"
+ contains "element_at(CAST(v"
+ notContains "element_at(CAST(element_at(element_at("
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]