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

xuyang 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 0a450d96a5 [Fix] fix `cast(array<not_null> as array<>)` causes be core 
dump (#11649)
0a450d96a5 is described below

commit 0a450d96a529b6a746f94aa98f44f1e1f00423ef
Author: xy720 <22125576+xy...@users.noreply.github.com>
AuthorDate: Wed Aug 24 22:51:30 2022 +0800

    [Fix] fix `cast(array<not_null> as array<>)` causes be core dump (#11649)
---
 .../java/org/apache/doris/analysis/CastExpr.java   | 36 +++++++++-------
 .../array_functions/test_cast_array_function.out   | 24 +++++++++++
 .../test_cast_array_function.groovy                | 49 ++++++++++++++++++++++
 .../test_cast_array_functions_by_literal.groovy    | 46 +-------------------
 4 files changed, 95 insertions(+), 60 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
index 7950c04db4..cca5e50d52 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
@@ -20,6 +20,7 @@
 
 package org.apache.doris.analysis;
 
+import org.apache.doris.catalog.ArrayType;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.Function;
 import org.apache.doris.catalog.FunctionSet;
@@ -29,7 +30,6 @@ import org.apache.doris.catalog.ScalarType;
 import org.apache.doris.catalog.Type;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.Pair;
-import org.apache.doris.common.util.VectorizedUtil;
 import org.apache.doris.qe.ConnectContext;
 import org.apache.doris.thrift.TExpr;
 import org.apache.doris.thrift.TExprNode;
@@ -270,15 +270,28 @@ public class CastExpr extends Expr {
 
         // this cast may result in loss of precision, but the user requested it
         if (childType.matchesType(type)) {
-            // For types which has precision and scale, we also need to check 
quality between precisions and scales
-            if (!PrimitiveType.typeWithPrecision.contains(
-                    type.getPrimitiveType()) || ((((ScalarType) 
type).decimalPrecision()
-                    == ((ScalarType) childType).decimalPrecision()) && 
(((ScalarType) type).decimalScale()
-                    == ((ScalarType) childType).decimalScale()))) {
+            if 
(PrimitiveType.typeWithPrecision.contains(type.getPrimitiveType())) {
+                // For types which has precision and scale, we also need to 
check quality between precisions and scales
+                if ((((ScalarType) type).decimalPrecision()
+                        == ((ScalarType) childType).decimalPrecision()) && 
(((ScalarType) type).decimalScale()
+                        == ((ScalarType) childType).decimalScale())) {
+                    noOp = true;
+                }
+            } else if (type.isArrayType()) {
+                // For types array, we also need to check contains null for 
case like
+                // cast(array<not_null(int)> as array<int>)
+                if (((ArrayType) type).getContainsNull() == ((ArrayType) 
childType).getContainsNull()) {
+                    noOp = true;
+                }
+            } else {
                 noOp = true;
-                return;
             }
         }
+
+        if (noOp) {
+            return;
+        }
+
         // select stmt will make BE coredump when its castExpr is like 
cast(int as array<>),
         // it is necessary to check if it is castable before creating fn.
         // char type will fail in canCastTo, so for compatibility, only the 
cast of array type is checked here.
@@ -301,17 +314,10 @@ public class CastExpr extends Expr {
                         searchDesc, Function.CompareMode.IS_IDENTICAL);
             }
         } else if (type.isArrayType()) {
-            if (VectorizedUtil.isVectorized()) {
-                // Vec engine don't need a scala cast function, but we still 
create one to pass the check.
-                fn = ScalarFunction.createBuiltin("CAST", type,  
Lists.newArrayList(), false,
-                    "", null, null, true);
-            } else if (childType.isVarchar()) {
-                // only support varchar cast to array for origin exec engine.
-                fn = ScalarFunction.createBuiltin(getFnName(Type.ARRAY),
+            fn = ScalarFunction.createBuiltin(getFnName(Type.ARRAY),
                     type, Function.NullableMode.ALWAYS_NULLABLE,
                     Lists.newArrayList(Type.VARCHAR), false,
                     "doris::CastFunctions::cast_to_array_val", null, null, 
true);
-            }
         }
 
         if (fn == null) {
diff --git 
a/regression-test/data/query_p0/sql_functions/array_functions/test_cast_array_function.out
 
b/regression-test/data/query_p0/sql_functions/array_functions/test_cast_array_function.out
new file mode 100644
index 0000000000..7c3874ea69
--- /dev/null
+++ 
b/regression-test/data/query_p0/sql_functions/array_functions/test_cast_array_function.out
@@ -0,0 +1,24 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select --
+1      [1, 2, 3]       ['a', 'b', '']
+2      [4]     ['1', '2', '3']
+3      [10000] ['2022-08-10', '2022-08-11']
+4      []      []
+
+-- !select --
+1      ['1', '2', '3'] [NULL, NULL, NULL]
+2      ['4']   [1, 2, 3]
+3      ['10000']       [NULL, NULL]
+4      []      []
+
+-- !select --
+1      [1.3, 2.14]     [1.3, 2.14]
+2      [5]     [5]
+3      [1]     [1]
+4      \N      \N
+
+-- !select --
+1      [1, 2, 3]       [NULL, NULL, NULL]
+2      [4]     [NULL, NULL, NULL]
+3      [16]    [2022-08-10, 2022-08-11]
+4      []      []
diff --git 
a/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_function.groovy
 
b/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_function.groovy
new file mode 100644
index 0000000000..94b8a9ea1b
--- /dev/null
+++ 
b/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_function.groovy
@@ -0,0 +1,49 @@
+// 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_cast_array_function", "query") {
+    def tableName = "tbl_test_cast_array_function"
+    // open enable_array_type
+    sql "ADMIN SET FRONTEND CONFIG ('enable_array_type' = 'true')"
+    // array functions only supported in vectorized engine
+    sql """ set enable_vectorized_engine = true """
+
+    sql """DROP TABLE IF EXISTS ${tableName}"""
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+              `k1` int(11) NULL COMMENT "",
+              `k2` ARRAY<int(11)> NOT NULL COMMENT "",
+              `k3` ARRAY<VARCHAR(20)> NULL COMMENT "",
+              `k4` ARRAY<decimal(27,9)> NULL COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`k1`)
+            DISTRIBUTED BY HASH(`k1`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "storage_format" = "V2"
+            )
+        """
+    sql """ INSERT INTO ${tableName} VALUES(1, [1, 2, 3], ["a", "b", ""], 
[1.3, 2.14]) """
+    sql """ INSERT INTO ${tableName} VALUES(2, [4], ["1", "2", "3"], [5]) """
+    sql """ INSERT INTO ${tableName} VALUES(3, [10000], ["2022-08-10", 
"2022-08-11"], [1]) """
+    sql """ INSERT INTO ${tableName} VALUES(4, [], [], NULL) """
+    
+    qt_select "SELECT k1, cast(k2 as array<int>), cast(k3 as 
array<varchar>)FROM ${tableName} ORDER BY k1"
+    qt_select "SELECT k1, cast(k2 as array<varchar>), cast(k3 as array<int>) 
FROM ${tableName} ORDER BY k1"
+    qt_select "SELECT k1, cast(k4 as array<float>), cast(k4 as array<double>) 
FROM ${tableName} ORDER BY k1"
+    qt_select "SELECT k1, cast(k2 as array<tinyint>), cast(k3 as array<date>) 
FROM ${tableName} ORDER BY k1"
+}
diff --git 
a/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_functions_by_literal.groovy
 
b/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_functions_by_literal.groovy
index cc00a56b76..349560a5aa 100644
--- 
a/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_functions_by_literal.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/array_functions/test_cast_array_functions_by_literal.groovy
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-suite("test_cast_array_functions") {
+suite("test_cast_array_functions_by_literal") {
     // open enable_array_type
     sql "ADMIN SET FRONTEND CONFIG ('enable_array_type' = 'true')"
     // array functions only supported in vectorized engine
@@ -190,48 +190,4 @@ suite("test_cast_array_functions") {
         // check exception message contains
         exception "errCode = 2,"
     }
-
-    //  ========== cast array to array ===========
-    test {
-        sql "select cast(['x'] as array<int>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast([0] as array<int>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast(['1'] as array<tinyint>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast(['100'] as array<smallint>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast([999.999] as array<double>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast([1] as array<char>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-
-    test {
-        sql "select cast([1] as array<varchar>)"
-        // check exception message contains
-        exception "errCode = 2,"
-    }
-    
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to