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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]