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 e03594db0ec [fix](fe) Let INSERT write UUID values into connector 
Variant columns (#68935)
e03594db0ec is described below

commit e03594db0ec93b51c9987cabbcb221b8baf8d13e
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Tue Oct 13 14:56:22 2026 +0800

    [fix](fe) Let INSERT write UUID values into connector Variant columns 
(#68935)
    
    ### What problem does this PR solve?
    
    Issue Number: None
    
    Related PR: #68919, #67627, #68320
    
    Problem Summary:
    
    **In short.** On master, an INSERT that writes a UUID value into the
    VARIANT column of a connector table, such as a Paimon `VARIANT` column,
    fails in analysis with `can not cast from origin type UUID to target
    type=variant<...>`, and so does an `ARRAY<UUID>` value. This PR lets the
    analyzer accept both. It is not a branch-4.x port (branch-4.x has no
    UUID type); the gap came up in the review of #68919, which ports
    branch-4.x write tests.
    
    **Background.** A connector sink writes a VARIANT column through the
    Variant V2 compute carrier: the sink casts the value to
    `ConnectorComputeVariantType`, and `CheckCast` admits the source type
    only when `VariantType.isSupportedComputeV2CastSource` accepts it. That
    predicate (#68320) lists the scalar types the carrier can hold. The UUID
    type (#67627) was merged the same day, and the BE carrier takes it
    (`is_supported_variant_typed_identity` and the V2 CAST's
    `is_supported_scalar_source` both include `TYPE_UUID`), but the FE
    predicate does not: `UuidType` extends `PrimitiveType`, not
    `CharacterType`, so none of the predicate's type families match it. An
    internal VARIANT column accepts the same value through the strict cast
    whitelist.
    
    **The problem, and what it cost.**
    
    | Statement on a Paimon table `t (id INT, v VARIANT)` | master | with
    this PR |
    |---|---|---|
    | `INSERT INTO t SELECT 1, CAST('6ba7b810-9dad-11d1-80b4-00c04fd430c8'
    AS UUID)` | `can not cast from origin type UUID to target
    type=variant<...>`, with `enable_strict_cast` on or off | written; reads
    back as `6ba7b810-9dad-11d1-80b4-00c04fd430c8`, `variant_type` `uuid` |
    | `INSERT INTO t SELECT 2,
    ARRAY(CAST('6ba7b811-9dad-11d1-80b4-00c04fd430c8' AS UUID), NULL)` |
    `can not cast from origin type ARRAY<UUID> ...`, either mode | written;
    reads back as `["6ba7b811-9dad-11d1-80b4-00c04fd430c8",null]` |
    | `INSERT INTO t SELECT 3,
    CAST(CAST('6ba7b810-9dad-11d1-80b4-00c04fd430c8' AS UUID) AS VARIANT)` |
    written | written (unchanged) |
    
    So a UUID could reach a connector VARIANT column only through an
    explicit `CAST(... AS VARIANT)`, which an INSERT into an internal table
    does not need.
    
    **How this PR fixes it.** `isSupportedComputeV2CastSource` accepts
    `UuidType`; the existing array recursion covers UUID array elements. The
    predicate now admits the same scalar types as the BE carrier; TIME,
    VARBINARY and 256-bit decimals stay rejected on both sides.
    
    **Results.** On a local cluster with a file-system Paimon catalog, both
    failing statements above succeed in both cast modes. The rows read back
    the same through Doris and through the Paimon API
    (`"6ba7b810-9dad-11d1-80b4-00c04fd430c8"` and
    `["6ba7b811-9dad-11d1-80b4-00c04fd430c8",null]`), and match the row
    written with the explicit cast.
---
 .../org/apache/doris/nereids/types/VariantType.java |  3 ++-
 .../rules/expression/check/CheckCastTest.java       | 16 ++++++++++++++++
 .../paimon/write/test_paimon_write_variant.out      |  7 ++++++-
 .../paimon/write/test_paimon_write_variant.groovy   | 21 +++++++++++++++++++++
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantType.java
index 04a2e8fc372..3e4d2103405 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/VariantType.java
@@ -311,7 +311,8 @@ public class VariantType extends PrimitiveType {
                 || dataType.isDecimalV2Type()
                 || dataType.isDateLikeType()
                 || dataType.isStringLikeType()
-                || dataType.isIPType();
+                || dataType.isIPType()
+                || dataType.isUuidType();
     }
 
 }
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/check/CheckCastTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/check/CheckCastTest.java
index 35abe7a662d..fe500079b91 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/check/CheckCastTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/check/CheckCastTest.java
@@ -50,6 +50,7 @@ import org.apache.doris.nereids.types.TimeStampNsType;
 import org.apache.doris.nereids.types.TimeStampTzType;
 import org.apache.doris.nereids.types.TimeV2Type;
 import org.apache.doris.nereids.types.TinyIntType;
+import org.apache.doris.nereids.types.UuidType;
 import org.apache.doris.nereids.types.VarBinaryType;
 import org.apache.doris.nereids.types.VarcharType;
 import org.apache.doris.nereids.types.VariantType;
@@ -1247,6 +1248,21 @@ public class CheckCastTest {
         Assertions.assertFalse(CheckCast.check(IPv6Type.INSTANCE, 
QuantileStateType.INSTANCE, false));
     }
 
+    @Test
+    public void testCastFromUuidToVariant() {
+        // A connector Variant column (e.g. a Paimon VARIANT) takes a UUID the 
way an internal VARIANT
+        // column does: the V2 compute carrier holds UUID values, also as 
array elements.
+        for (boolean strictMode : new boolean[] {true, false}) {
+            Assertions.assertTrue(CheckCast.check(UuidType.INSTANCE, 
VariantType.INSTANCE, strictMode));
+            Assertions.assertTrue(CheckCast.check(
+                    UuidType.INSTANCE, ConnectorComputeVariantType.INSTANCE, 
strictMode));
+            Assertions.assertTrue(CheckCast.check(
+                    ArrayType.of(UuidType.INSTANCE), 
ConnectorComputeVariantType.INSTANCE, strictMode));
+            
Assertions.assertTrue(CheckCast.check(ArrayType.of(UuidType.INSTANCE),
+                    ArrayType.of(ConnectorComputeVariantType.INSTANCE), 
strictMode));
+        }
+    }
+
     @Test
     public void testCastFromChar() {
         // Strict mode
diff --git 
a/regression-test/data/external_table_p0/paimon/write/test_paimon_write_variant.out
 
b/regression-test/data/external_table_p0/paimon/write/test_paimon_write_variant.out
index c5a8e265379..7b2eab071d9 100644
--- 
a/regression-test/data/external_table_p0/paimon/write/test_paimon_write_variant.out
+++ 
b/regression-test/data/external_table_p0/paimon/write/test_paimon_write_variant.out
@@ -3,6 +3,10 @@
 20     1       row-one
 21     row-two 2
 
+-- !variant_uuid --
+30     6ba7b810-9dad-11d1-80b4-00c04fd430c8    
["6ba7b811-9dad-11d1-80b4-00c04fd430c8",null]   uuid    uuid
+31     6ba7b812-9dad-11d1-80b4-00c04fd430c8    
["6ba7b813-9dad-11d1-80b4-00c04fd430c8"]        uuid    uuid
+
 -- !variant_object --
 doris  Hangzhou        1       true    {}      []      δΈ­ζ–‡πŸ˜€     2
 
@@ -23,4 +27,5 @@ doris Hangzhou        1       true    {}      []      δΈ­ζ–‡πŸ˜€     
2
 45056  large-string
 
 -- !variant_row_count --
-15
+17
+
diff --git 
a/regression-test/suites/external_table_p0/paimon/write/test_paimon_write_variant.groovy
 
b/regression-test/suites/external_table_p0/paimon/write/test_paimon_write_variant.groovy
index 6cd559bb467..666f0970445 100644
--- 
a/regression-test/suites/external_table_p0/paimon/write/test_paimon_write_variant.groovy
+++ 
b/regression-test/suites/external_table_p0/paimon/write/test_paimon_write_variant.groovy
@@ -103,6 +103,27 @@ suite("test_paimon_write_variant", 
"p0,external,paimon,nonConcurrent") {
             ORDER BY id
         """
 
+        // A UUID reaches a Variant column without an explicit cast, as a 
scalar and as array
+        // elements, in both cast modes, and reads back as the UUID it holds.
+        sql """
+            INSERT INTO t_variant_basic VALUES
+                (30, CAST('6ba7b810-9dad-11d1-80b4-00c04fd430c8' AS UUID),
+                     ARRAY(CAST('6ba7b811-9dad-11d1-80b4-00c04fd430c8' AS 
UUID), NULL))
+        """
+        sql """SET enable_strict_cast = true"""
+        sql """
+            INSERT INTO t_variant_basic
+            SELECT 31, CAST('6ba7b812-9dad-11d1-80b4-00c04fd430c8' AS UUID),
+                   ARRAY(CAST('6ba7b813-9dad-11d1-80b4-00c04fd430c8' AS UUID))
+        """
+        sql """SET enable_strict_cast = false"""
+        order_qt_variant_uuid """
+            SELECT id, payload, secondary, variant_type(payload), 
variant_type(secondary[1])
+            FROM t_variant_basic
+            WHERE id IN (30, 31)
+            ORDER BY id
+        """
+
         order_qt_variant_object """
             SELECT
                 CAST(payload['object']['name'] AS STRING),


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

Reply via email to