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 be8b2c9abc3 branch-4.1: [fix](variant) Prefer sparse variant fields 
over root value #65660 (#65950)
be8b2c9abc3 is described below

commit be8b2c9abc3ab1a8c123170361771c4f2d855999
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Jul 24 10:43:18 2026 +0800

    branch-4.1: [fix](variant) Prefer sparse variant fields over root value 
#65660 (#65950)
    
    Cherry-picked from #65660
    
    ---------
    
    Co-authored-by: lihangyu <[email protected]>
---
 be/src/core/column/column_variant.cpp              |  5 ++
 be/test/core/column/column_variant_test.cpp        | 27 +++++++
 .../test_topn_lazy_materialize_sparse_variant.out  | 17 +++++
 ...est_topn_lazy_materialize_sparse_variant.groovy | 85 ++++++++++++++++++++++
 4 files changed, 134 insertions(+)

diff --git a/be/src/core/column/column_variant.cpp 
b/be/src/core/column/column_variant.cpp
index 694562ac553..7382c2cad4f 100644
--- a/be/src/core/column/column_variant.cpp
+++ b/be/src/core/column/column_variant.cpp
@@ -1830,6 +1830,11 @@ bool ColumnVariant::is_visible_root_value(size_t nrow) 
const {
         }
     }
 
+    const auto& sparse_offsets = serialized_sparse_column_offsets();
+    if (sparse_offsets[nrow - 1] != sparse_offsets[nrow]) {
+        return false;
+    }
+
     const auto& doc_value_column_map = assert_cast<const 
ColumnMap&>(*serialized_doc_value_column);
     // doc snapshot column is not empty
     if (doc_value_column_map.get_offsets()[nrow - 1] != 
doc_value_column_map.get_offsets()[nrow]) {
diff --git a/be/test/core/column/column_variant_test.cpp 
b/be/test/core/column/column_variant_test.cpp
index b01a5a28535..0ab96111075 100644
--- a/be/test/core/column/column_variant_test.cpp
+++ b/be/test/core/column/column_variant_test.cpp
@@ -1082,6 +1082,33 @@ TEST_F(ColumnVariantTest, test_insert_indices_from) {
     }
 }
 
+TEST_F(ColumnVariantTest, visible_root_does_not_hide_sparse_fields) {
+    auto source = ColumnVariant::create(0, false);
+    VariantMap mixed;
+    mixed.try_emplace(PathInData(), FieldWithDataType {.field = 
get_jsonb_field("array_int")});
+    mixed.try_emplace(PathInData("n"), FieldWithDataType {.field = 
VariantUtil::get_field("int")});
+    mixed.try_emplace(PathInData("word"),
+                      FieldWithDataType {.field = 
VariantUtil::get_field("string")});
+    source->try_insert(Field::create_field<TYPE_VARIANT>(std::move(mixed)));
+    source->finalize();
+
+    auto destination = ColumnVariant::create(1, false);
+    destination->try_insert(
+            VariantUtil::construct_variant_map({{"k", 
VariantUtil::get_field("int")}}));
+    destination->insert_range_from(*source, 0, 1);
+    destination->finalize();
+
+    
EXPECT_EQ(destination->get_subcolumns().get_root()->data.get_least_common_base_type_id(),
+              PrimitiveType::TYPE_JSONB);
+    const auto& sparse_offsets = 
destination->serialized_sparse_column_offsets();
+    EXPECT_LT(sparse_offsets[0], sparse_offsets[1]);
+
+    DataTypeSerDe::FormatOptions options;
+    std::string json;
+    destination->serialize_one_row_to_string(1, &json, options);
+    EXPECT_EQ(json, R"({"n":20,"word":"str"})");
+}
+
 TEST_F(ColumnVariantTest, is_variable_length) {
     EXPECT_TRUE(column_variant->is_variable_length());
 }
diff --git 
a/regression-test/data/variant_p0/test_topn_lazy_materialize_sparse_variant.out 
b/regression-test/data/variant_p0/test_topn_lazy_materialize_sparse_variant.out
new file mode 100644
index 00000000000..505edfbb546
--- /dev/null
+++ 
b/regression-test/data/variant_p0/test_topn_lazy_materialize_sparse_variant.out
@@ -0,0 +1,17 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !topn_lazy_sparse_variant --
+0      1       {}      {}
+1      -1      {}      [1,2,3]
+3      42      {"k":1} {}
+4      -9223372036854775808    [1,2,3] {"k":1}
+6      1       [1,2,3] {}
+7      0       [1,2,3] [1,2,3]
+9      \N      {}      []
+10     1       {}      {"n":7,"word":"hot"}
+12     1       {"word":"hot","n":7}    \N
+13     5777142737451291289     {}      {"n":7,"word":"hot"}
+15     -1      [1,2,3] []
+16     -906638365906932436     {"word":"hot","n":7}    {"k":1}
+18     -9223372036854775808    {"word":"hot","n":7}    {"n":7,"word":"hot"}
+19     -9223372036854775808    {"word":"hot","n":7}    [1,2,3]
+
diff --git 
a/regression-test/suites/variant_p0/test_topn_lazy_materialize_sparse_variant.groovy
 
b/regression-test/suites/variant_p0/test_topn_lazy_materialize_sparse_variant.groovy
new file mode 100644
index 00000000000..041c704feaa
--- /dev/null
+++ 
b/regression-test/suites/variant_p0/test_topn_lazy_materialize_sparse_variant.groovy
@@ -0,0 +1,85 @@
+// 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_topn_lazy_materialize_sparse_variant", "p0") {
+    sql "set default_variant_enable_doc_mode = false"
+    sql "set default_variant_max_subcolumns_count = 1"
+    sql "set default_variant_sparse_hash_shard_count = 2"
+    sql "set use_v3_storage_format = true"
+    sql "set enable_file_cache = true"
+    sql "set topn_lazy_materialization_threshold = 1024"
+
+    sql "DROP TABLE IF EXISTS test_topn_lazy_materialize_sparse_variant"
+    sql """
+        CREATE TABLE test_topn_lazy_materialize_sparse_variant (
+            pk INT,
+            col_bigint BIGINT NULL,
+            col_json JSON NOT NULL,
+            col_variant VARIANT NULL
+        ) ENGINE = OLAP
+        DUPLICATE KEY(pk)
+        PARTITION BY RANGE(pk) (
+            PARTITION p0 VALUES LESS THAN ('4'),
+            PARTITION p1 VALUES LESS THAN ('64'),
+            PARTITION p2 VALUES LESS THAN ('256'),
+            PARTITION pmax VALUES LESS THAN ('2147483647')
+        )
+        DISTRIBUTED BY HASH(pk) BUCKETS 4
+        PROPERTIES (
+            "replication_num" = "1",
+            "disable_auto_compaction" = "true",
+            "storage_format" = "V3"
+        )
+    """
+
+    sql """
+        INSERT INTO test_topn_lazy_materialize_sparse_variant VALUES
+            (19, -9223372036854775808, '{"word":"hot","n":7}', '[1,2,3]'),
+            (18, -9223372036854775808, '{"word":"hot","n":7}', 
'{"word":"hot","n":7}'),
+            (17, -1, '{"k":1}', '{}'),
+            (16, -906638365906932436, '{"word":"hot","n":7}', '{"k":1}'),
+            (15, -1, '[1,2,3]', '{}'),
+            (14, -9223372036854775808, '{"word":"hot","n":7}', '[1,2,3]'),
+            (13, 5777142737451291289, '{}', '{"word":"hot","n":7}'),
+            (12, 1, '{"word":"hot","n":7}', NULL),
+            (11, 42, '[1,2,3]', NULL),
+            (10, 1, '{}', '{"word":"hot","n":7}'),
+            (9, NULL, '{}', '{}'),
+            (8, NULL, '{"k":1}', '{"k":1}'),
+            (7, 0, '[1,2,3]', '[1,2,3]'),
+            (6, 1, '[1,2,3]', '{}'),
+            (5, -3610716764638269764, '{"k":1}', '[1,2,3]'),
+            (4, -9223372036854775808, '[1,2,3]', '{"k":1}'),
+            (3, 42, '{"k":1}', '{}'),
+            (2, -9223372036854775808, '{}', '{}'),
+            (1, -1, '{}', '[1,2,3]'),
+            (0, 1, '{}', '{}')
+    """
+
+    def topnQuery = """
+        SELECT pk, col_bigint, col_json, col_variant
+        FROM test_topn_lazy_materialize_sparse_variant
+        WHERE ABS(pk % 3) IN (0, 1, 3)
+        ORDER BY pk ASC
+        LIMIT 128
+    """
+    explain {
+        sql topnQuery
+        contains("MaterializeNode")
+    }
+    qt_topn_lazy_sparse_variant topnQuery
+}


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

Reply via email to