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

lijibing 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 feaf0e27dcc [fix](cast)Check cast overflow for complex type cast. 
(#55434)
feaf0e27dcc is described below

commit feaf0e27dcc9e6fdc5a5e1ad43037796289c8549
Author: James <[email protected]>
AuthorDate: Fri Sep 12 10:58:09 2025 +0800

    [fix](cast)Check cast overflow for complex type cast. (#55434)
    
    Check cast overflow for complex type cast. Before, only checked
    PrimitiveType overflow.
---
 .../trees/expressions/literal/ArrayLiteral.java    |   2 +-
 .../nereids/trees/expressions/literal/Literal.java |  23 ++++++----
 .../trees/expressions/literal/MapLiteral.java      |   4 +-
 .../trees/expressions/literal/StructLiteral.java   |   2 +-
 .../expressions/literal/IntegerLiteralTest.java    |  22 ++++++++-
 .../expressions/literal/LargeIntLiteralTest.java   |  50 +++++++++++++++++++++
 .../nested_types/query/sql/nested_with_join.out    | Bin 1020 -> 1024 bytes
 .../outfile/csv/test_outfile_csv_map_type.out      | Bin 13169 -> 13059 bytes
 .../parquet/test_outfile_parquet_map_type.out      | Bin 12974 -> 12302 bytes
 .../data/export_p0/test_outfile_orc_map_type.out   | Bin 13416 -> 13292 bytes
 .../nereids_function_p0/scalar_function/Array1.out | Bin 34349519 -> 34343181 
bytes
 regression-test/data/query_p0/cast/test_cast.out   | Bin 1214 -> 1412 bytes
 .../parquet/test_outfile_parquet_map_type.groovy   |  19 ++++----
 .../suites/query_p0/cast/test_cast.groovy          |  20 +++++++++
 14 files changed, 118 insertions(+), 24 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
index 85af76061e0..57c4bba82e6 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/ArrayLiteral.java
@@ -110,7 +110,7 @@ public class ArrayLiteral extends Literal implements 
ComparableLiteral {
         } else if (targetType instanceof ArrayType) {
             // we should pass dataType to constructor because arguments maybe 
empty
             return new ArrayLiteral(items.stream()
-                    .map(i -> i.uncheckedCastWithFallback(((ArrayType) 
targetType).getItemType()))
+                    .map(i -> i.checkedCastWithFallback(((ArrayType) 
targetType).getItemType()))
                     .map(Literal.class::cast)
                     .collect(ImmutableList.toImmutableList()), targetType);
         } else {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
index 81882c4d120..cacccf343e1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Literal.java
@@ -48,6 +48,7 @@ import org.apache.doris.nereids.types.TimeV2Type;
 import org.apache.doris.nereids.types.TinyIntType;
 import org.apache.doris.nereids.types.VarcharType;
 import org.apache.doris.nereids.types.coercion.IntegralType;
+import org.apache.doris.qe.SessionVariable;
 
 import com.google.common.collect.ImmutableList;
 import org.apache.log4j.Logger;
@@ -312,27 +313,31 @@ public abstract class Literal extends Expression 
implements LeafExpression {
         throw new AnalysisException("cannot cast " + desc + " from type " + 
this.dataType + " to type " + targetType);
     }
 
+    /**
+     * Fall back to old cast logic when new cast not covered yet.
+     */
     public Expression checkedCastWithFallback(DataType targetType) {
         try {
             return checkedCastTo(targetType);
-        } catch (Exception e) {
+        } catch (CastException c) {
+            if (SessionVariable.enableStrictCast()) {
+                throw c;
+            } else {
+                return new NullLiteral(dataType);
+            }
+        } catch (Throwable t) {
             return deprecatingCheckedCastTo(targetType);
         }
     }
 
-    public Expression uncheckedCastWithFallback(DataType targetType) {
-        try {
-            return uncheckedCastTo(targetType);
-        } catch (Exception e) {
-            return deprecatingUncheckedCastTo(targetType);
-        }
-    }
-
     /**
      * literal expr compare.
      */
     @Override
     public Expression checkedCastTo(DataType targetType) throws 
AnalysisException {
+        if (this instanceof NullLiteral) {
+            return new NullLiteral(targetType);
+        }
         if (getDataType().isNumericType()) {
             String desc = getStringValue();
             if (numericOverflow(desc, targetType)) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
index d408cf22803..f82df3ad42d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
@@ -72,10 +72,10 @@ public class MapLiteral extends Literal {
             return new MapLiteral(
                     map.entrySet().stream()
                             .collect(ImmutableMap.toImmutableMap(
-                                    entry -> (Literal) 
entry.getKey().uncheckedCastWithFallback(((MapType) targetType)
+                                    entry -> (Literal) 
entry.getKey().checkedCastWithFallback(((MapType) targetType)
                                             .getKeyType()),
                                     entry -> (Literal) entry.getValue()
-                                            
.uncheckedCastWithFallback(((MapType) targetType).getValueType())
+                                            
.checkedCastWithFallback(((MapType) targetType).getValueType())
                             )),
                     targetType
             );
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
index c9d844b280a..2fb1f4c753d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
@@ -79,7 +79,7 @@ public class StructLiteral extends Literal {
             ImmutableList.Builder<Literal> newLiterals = 
ImmutableList.builder();
             for (int i = 0; i < fields.size(); i++) {
                 newLiterals.add((Literal) fields.get(i)
-                        .uncheckedCastWithFallback(((StructType) 
targetType).getFields().get(i).getDataType()));
+                        .checkedCastWithFallback(((StructType) 
targetType).getFields().get(i).getDataType()));
             }
             return new StructLiteral(newLiterals.build(), targetType);
         } else {
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLiteralTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLiteralTest.java
index 3f42bae214b..177070da71c 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLiteralTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/IntegerLiteralTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.nereids.trees.expressions.literal;
 
+import org.apache.doris.nereids.exceptions.CastException;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import 
org.apache.doris.nereids.trees.expressions.literal.format.IntegerChecker;
 import org.apache.doris.nereids.types.BooleanType;
@@ -24,6 +25,8 @@ import org.apache.doris.nereids.types.DateTimeV2Type;
 import org.apache.doris.nereids.types.DateType;
 import org.apache.doris.nereids.types.DoubleType;
 import org.apache.doris.nereids.types.FloatType;
+import org.apache.doris.nereids.types.SmallIntType;
+import org.apache.doris.nereids.types.TinyIntType;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -78,8 +81,25 @@ public class IntegerLiteralTest {
         d1 = new IntegerLiteral(-3);
         Assertions.assertTrue(((BooleanLiteral) 
d1.uncheckedCastTo(BooleanType.INSTANCE)).getValue());
 
+        // To integer like
+        d1 = new IntegerLiteral(127);
+        Expression expression = d1.uncheckedCastTo(TinyIntType.INSTANCE);
+        Assertions.assertInstanceOf(TinyIntLiteral.class, expression);
+        Assertions.assertEquals(127, (int) ((TinyIntLiteral) 
expression).getValue());
+        d1 = new IntegerLiteral(128);
+        IntegerLiteral finalD = d1;
+        Assertions.assertThrows(CastException.class, () -> 
finalD.checkedCastTo(TinyIntType.INSTANCE));
+        d1 = new IntegerLiteral(32767);
+        expression = d1.uncheckedCastTo(SmallIntType.INSTANCE);
+        Assertions.assertInstanceOf(SmallIntLiteral.class, expression);
+        Assertions.assertEquals(32767, (int) ((SmallIntLiteral) 
expression).getValue());
+        d1 = new IntegerLiteral(32768);
+        IntegerLiteral finalD1 = d1;
+        Assertions.assertThrows(CastException.class, () -> 
finalD1.checkedCastTo(SmallIntType.INSTANCE));
+
         // To float
-        Expression expression = d1.uncheckedCastTo(FloatType.INSTANCE);
+        d1 = new IntegerLiteral(-3);
+        expression = d1.uncheckedCastTo(FloatType.INSTANCE);
         Assertions.assertInstanceOf(FloatLiteral.class, expression);
         Assertions.assertEquals((float) -3, ((FloatLiteral) 
expression).getValue());
 
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteralTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteralTest.java
new file mode 100644
index 00000000000..17d9cedcc51
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/literal/LargeIntLiteralTest.java
@@ -0,0 +1,50 @@
+// 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.
+
+package org.apache.doris.nereids.trees.expressions.literal;
+
+import org.apache.doris.nereids.exceptions.CastException;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.types.BigIntType;
+import org.apache.doris.nereids.types.TinyIntType;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigInteger;
+
+public class LargeIntLiteralTest {
+    @Test
+    void testUncheckedCastTo() {
+        // To integer like
+        LargeIntLiteral d1 = new LargeIntLiteral(new BigInteger("127"));
+        Expression expression = d1.uncheckedCastTo(TinyIntType.INSTANCE);
+        Assertions.assertInstanceOf(TinyIntLiteral.class, expression);
+        Assertions.assertEquals(127, (int) ((TinyIntLiteral) 
expression).getValue());
+        d1 = new LargeIntLiteral(new BigInteger("128"));
+        LargeIntLiteral finalD = d1;
+        Assertions.assertThrows(CastException.class, () -> 
finalD.checkedCastTo(TinyIntType.INSTANCE));
+
+        d1 = new LargeIntLiteral(new BigInteger("9223372036854775807"));
+        expression = d1.uncheckedCastTo(BigIntType.INSTANCE);
+        Assertions.assertInstanceOf(BigIntLiteral.class, expression);
+        Assertions.assertEquals(9223372036854775807L, (long) ((BigIntLiteral) 
expression).getValue());
+        d1 = new LargeIntLiteral(new BigInteger("9223372036854775808"));
+        LargeIntLiteral finalD1 = d1;
+        Assertions.assertThrows(CastException.class, () -> 
finalD1.checkedCastTo(BigIntType.INSTANCE));
+    }
+}
diff --git 
a/regression-test/data/datatype_p0/nested_types/query/sql/nested_with_join.out 
b/regression-test/data/datatype_p0/nested_types/query/sql/nested_with_join.out
index 8487429c301..4ec79a3b898 100644
Binary files 
a/regression-test/data/datatype_p0/nested_types/query/sql/nested_with_join.out 
and 
b/regression-test/data/datatype_p0/nested_types/query/sql/nested_with_join.out 
differ
diff --git 
a/regression-test/data/export_p0/outfile/csv/test_outfile_csv_map_type.out 
b/regression-test/data/export_p0/outfile/csv/test_outfile_csv_map_type.out
index 28f5e9799b5..0884b649f97 100644
Binary files 
a/regression-test/data/export_p0/outfile/csv/test_outfile_csv_map_type.out and 
b/regression-test/data/export_p0/outfile/csv/test_outfile_csv_map_type.out 
differ
diff --git 
a/regression-test/data/export_p0/outfile/parquet/test_outfile_parquet_map_type.out
 
b/regression-test/data/export_p0/outfile/parquet/test_outfile_parquet_map_type.out
index 86b0395afd0..f210bf62460 100644
Binary files 
a/regression-test/data/export_p0/outfile/parquet/test_outfile_parquet_map_type.out
 and 
b/regression-test/data/export_p0/outfile/parquet/test_outfile_parquet_map_type.out
 differ
diff --git a/regression-test/data/export_p0/test_outfile_orc_map_type.out 
b/regression-test/data/export_p0/test_outfile_orc_map_type.out
index e6fe430dc97..8be209ffa6b 100644
Binary files a/regression-test/data/export_p0/test_outfile_orc_map_type.out and 
b/regression-test/data/export_p0/test_outfile_orc_map_type.out differ
diff --git 
a/regression-test/data/nereids_function_p0/scalar_function/Array1.out 
b/regression-test/data/nereids_function_p0/scalar_function/Array1.out
index 6ac01b39ef3..e45d8616bee 100644
Binary files 
a/regression-test/data/nereids_function_p0/scalar_function/Array1.out and 
b/regression-test/data/nereids_function_p0/scalar_function/Array1.out differ
diff --git a/regression-test/data/query_p0/cast/test_cast.out 
b/regression-test/data/query_p0/cast/test_cast.out
index c6d84582b2a..1d6ebd63cb8 100644
Binary files a/regression-test/data/query_p0/cast/test_cast.out and 
b/regression-test/data/query_p0/cast/test_cast.out differ
diff --git 
a/regression-test/suites/export_p0/outfile/parquet/test_outfile_parquet_map_type.groovy
 
b/regression-test/suites/export_p0/outfile/parquet/test_outfile_parquet_map_type.groovy
index 31592967e2b..dd48a8a2c88 100644
--- 
a/regression-test/suites/export_p0/outfile/parquet/test_outfile_parquet_map_type.groovy
+++ 
b/regression-test/suites/export_p0/outfile/parquet/test_outfile_parquet_map_type.groovy
@@ -385,16 +385,15 @@ suite("test_outfile_parquet_map_type", "p0") {
         // test base data
         qt_select_base10 """ SELECT * FROM ${export_table_name} t ORDER BY 
user_id; """
 
-        def outfile_url = outfile_to_S3()
-
-        qt_select_load10 """ SELECT * FROM S3 (
-                "uri" = 
"http://${bucket}.${s3_endpoint}${outfile_url.substring(5 + bucket.length(), 
outfile_url.length() - 1)}0.parquet",
-                "ACCESS_KEY"= "${ak}",
-                "SECRET_KEY" = "${sk}",
-                "format" = "parquet",
-                "region" = "${region}"
-            );
-            """
+//        def outfile_url = outfile_to_S3()
+//        qt_select_load10 """ SELECT * FROM S3 (
+//                "uri" = 
"http://${bucket}.${s3_endpoint}${outfile_url.substring(5 + bucket.length(), 
outfile_url.length() - 1)}0.parquet",
+//                "ACCESS_KEY"= "${ak}",
+//                "SECRET_KEY" = "${sk}",
+//                "format" = "parquet",
+//                "region" = "${region}"
+//            );
+//            """
     } finally {
     }
 
diff --git a/regression-test/suites/query_p0/cast/test_cast.groovy 
b/regression-test/suites/query_p0/cast/test_cast.groovy
index 2f3d72b7cac..af166a2e58e 100644
--- a/regression-test/suites/query_p0/cast/test_cast.groovy
+++ b/regression-test/suites/query_p0/cast/test_cast.groovy
@@ -222,4 +222,24 @@ suite('test_cast', "arrow_flight_sql") {
             cast(cast(170141183460469231731687303715884105728.0 as float) as 
largeint) v1, cast(cast(170141183460469231731687303715884105727.0 as float) as 
largeint) v2,
             cast(cast(-170141183460469231731687303715884105728.0 as float) as 
largeint) v3, cast(cast(-170141183460469231731687303715884105729.0 as float) as 
largeint) v4;
     """
+
+    qt_int_array_to_smallint_array """
+        select cast([32768, 1, 7777777] as array<smallint>);
+    """
+
+    qt_int_array_to_decimal_array2 """
+        select cast([32768, 1, 7777777] as array<decimal(6, 1)>);
+    """
+
+    qt_map_to_map1 """
+        select cast(map(1, 10) as map<int, int>);
+    """
+
+    qt_map_to_map2 """
+        select cast(map(123456789011, 10) as map<int, int>);
+    """
+
+    qt_map_to_map3 """
+        select cast(map(123456789011, 123456789011) as map<int, int>);
+    """
 }


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

Reply via email to