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

morningman 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 a7ee5ab2d68 [test](paimon) Cover Variant reads of a deduplicate 
primary-key Paimon table (#69227)
a7ee5ab2d68 is described below

commit a7ee5ab2d68bad37f2de6d4888be494ab07fafca
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Mon Oct 19 11:02:36 2026 +0100

    [test](paimon) Cover Variant reads of a deduplicate primary-key Paimon 
table (#69227)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #66466, #68242
    
    Problem Summary:
    
    **In short.** Ports the primary-key Variant coverage of branch-4.1
    #66466 to master: a Paimon deduplicate table whose second snapshot
    updates two keys, and three blocks of `test_paimon_catalog_variant` that
    read it through JNI. The rest of #66466 and the WAL fix #68242 are not
    ported, because master handles those cases another way; see below.
    
    **Background.** #66466 did three things on branch-4.x:
    
    1. In BE, a generic gate in `TableReader::validate_file_mapping` rejects
    a physical Variant read from any file format but Parquet. #68242 then
    exempted WAL, which stores Doris blocks and supports Variant, because
    the gate broke group commit WAL replay.
    2. In FE, `PaimonScanNode` rejects a query that projects a Variant
    column while Variant V2 is disabled.
    3. In the tests, `run13.sql` gets `variant_primary_key_smoke`, and
    `test_paimon_catalog_variant` reads it.
    
    **The problem, and what it cost.** Every Variant table master's
    `test_paimon_catalog_variant` reads is append-only, so the regression
    does not check that a Paimon merge read keeps only the latest row of
    each key while it materializes Variant values.
    
    **How this PR fixes it.**
    
    - `run13.sql` creates `variant_primary_key_smoke` as on branch-4.x: a
    deduplicate primary-key table in Parquet, written in two snapshots. The
    second updates ids 1 and 2 and inserts id 4; id 3 holds a root array.
    - The JNI section of `test_paimon_catalog_variant` gets the three
    branch-4.x blocks: the whole Variant value, Variant paths cast to
    scalars, and a predicate on a Variant path. All three expect the latest
    value of ids 1 and 2.
    
    The other parts of #66466 and #68242 do not apply to master:
    
    | Branch-4.x change | Master |
    |---|---|
    | FE rejects a Variant projection while Variant V2 is disabled | #66858
    made Variant V2 the default and removed the switch, so there is nothing
    to check |
    | BE rejects a physical Variant read from any format but Parquet | Would
    reject the native Variant reads of the ADBC reader (#68883). Master
    keeps the Iceberg-specific gate in `IcebergTableReader`, admits Arrow
    Variant reads in `FileScannerV2` only for ADBC, and plans a Paimon split
    that projects a Variant natively only when every file is Parquet or an
    ORC file whose schema predates the Variant column. Paimon 1.4.2 cannot
    create an ORC table with a VARIANT column (`Unsupported type: VARIANT`)
    |
    | WAL is exempted from that gate | WAL is not gated on master |
    
    **Results.** On a local cluster against the Iceberg docker environment,
    Spark reads `variant_primary_key_smoke` as four rows, with the
    second-snapshot values for ids 1 and 2. Doris returns the same rows in
    the three new blocks, and every other result block of the suite is
    unchanged.
    
    Co-authored-by: zhangstar333 <[email protected]>
---
 .../create_preinstalled_scripts/paimon/run13.sql   | 26 ++++++++++++++++++++++
 .../paimon/test_paimon_catalog_variant.out         | 16 +++++++++++++
 .../paimon/test_paimon_catalog_variant.groovy      | 26 +++++++++++++++++++++-
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git 
a/docker/thirdparties/docker-compose/iceberg/scripts/create_preinstalled_scripts/paimon/run13.sql
 
b/docker/thirdparties/docker-compose/iceberg/scripts/create_preinstalled_scripts/paimon/run13.sql
index ec071966382..49ff2d2369d 100644
--- 
a/docker/thirdparties/docker-compose/iceberg/scripts/create_preinstalled_scripts/paimon/run13.sql
+++ 
b/docker/thirdparties/docker-compose/iceberg/scripts/create_preinstalled_scripts/paimon/run13.sql
@@ -70,3 +70,29 @@ alter table variant_mixed_su unset tblproperties (
 );
 insert into variant_mixed_su values
     (2, date '2026-07-01', 
parse_json('{"name":"bob","age":30,"layout":"unshredded"}'));
+
+-- Keep a primary-key table separate from variant_smoke so the regression 
covers both Paimon
+-- append-only reads and deduplicate merge reads with Variant payloads.
+drop table if exists variant_primary_key_smoke;
+create table variant_primary_key_smoke (
+    id BIGINT,
+    payload VARIANT
+) using paimon
+tblproperties (
+    'primary-key' = 'id',
+    'bucket' = '1',
+    'merge-engine' = 'deduplicate',
+    'file.format' = 'parquet'
+);
+
+insert into variant_primary_key_smoke values
+    (1, 
parse_json('{"name":"alice","version":1,"active":false,"profile":{"city":"beijing"}}')),
+    (2, parse_json('{"name":"bob","version":1,"tags":["old"]}')),
+    (3, parse_json('[10,"original"]'));
+
+-- A second snapshot updates two existing keys and inserts a new key. Doris 
should expose only the
+-- latest logical row for ids 1 and 2.
+insert into variant_primary_key_smoke values
+    (1, 
parse_json('{"name":"alice-updated","version":2,"active":true,"profile":{"city":"hangzhou"}}')),
+    (2, parse_json('{"name":"bob","version":2,"tags":["new","primary-key"]}')),
+    (4, parse_json('{"name":"carol","version":1,"active":true}'));
diff --git 
a/regression-test/data/external_table_p0/paimon/test_paimon_catalog_variant.out 
b/regression-test/data/external_table_p0/paimon/test_paimon_catalog_variant.out
index 256a115c8d2..d1e70d1b963 100644
--- 
a/regression-test/data/external_table_p0/paimon/test_paimon_catalog_variant.out
+++ 
b/regression-test/data/external_table_p0/paimon/test_paimon_catalog_variant.out
@@ -24,6 +24,22 @@ payload      variant<PROPERTIES 
("variant_max_subcolumns_count" = "0","variant_enable
 -- !subpath_predicate --
 2      bob
 
+-- !primary_key_full_variant --
+1      
{"active":true,"name":"alice-updated","profile":{"city":"hangzhou"},"version":2}
+2      {"name":"bob","tags":["new","primary-key"],"version":2}
+3      [10,"original"]
+4      {"active":true,"name":"carol","version":1}
+
+-- !primary_key_deduplicate --
+1      alice-updated   2       true
+2      bob     2       \N
+3      \N      \N      \N
+4      carol   1       true
+
+-- !primary_key_subpath_predicate --
+1      alice-updated
+2      bob
+
 -- !jni_shredded_projection --
 2      bob     30
 
diff --git 
a/regression-test/suites/external_table_p0/paimon/test_paimon_catalog_variant.groovy
 
b/regression-test/suites/external_table_p0/paimon/test_paimon_catalog_variant.groovy
index f8364971e8f..8aa1933acc7 100644
--- 
a/regression-test/suites/external_table_p0/paimon/test_paimon_catalog_variant.groovy
+++ 
b/regression-test/suites/external_table_p0/paimon/test_paimon_catalog_variant.groovy
@@ -106,8 +106,32 @@ suite("test_paimon_catalog_variant", 
"p0,external,doris,external_docker,external
             order by id
         """
 
+        // variant_smoke is append-only. This table has duplicate primary-key 
writes, so the scan
+        // must preserve Paimon's deduplicate semantics while materializing 
Variant values.
+        order_qt_primary_key_full_variant """
+            select id, payload
+            from variant_primary_key_smoke
+            order by id
+        """
+
+        order_qt_primary_key_deduplicate """
+            select id,
+                   cast(payload['name'] as string),
+                   cast(payload['version'] as int),
+                   cast(payload['active'] as boolean)
+            from variant_primary_key_smoke
+            order by id
+        """
+
+        order_qt_primary_key_subpath_predicate """
+            select id, cast(payload['name'] as string)
+            from variant_primary_key_smoke
+            where cast(payload['version'] as int) = 2
+            order by id
+        """
+
         // Exercise Paimon's metadata-marked read type against a physically 
shredded file. The
-        // variant_smoke cases above read unshredded files.
+        // unshredded and primary-key cases above cover Paimon's raw-value and 
merge fallbacks.
         order_qt_jni_shredded_projection """
             select id,
                    cast(payload['name'] as string),


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

Reply via email to