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]

Reply via email to