From d326cb0c994a201d52cf6abdd2c3ea9b9801b226 Mon Sep 17 00:00:00 2001 From: amory Date: Wed, 30 Aug 2023 11:18:31 +0800 Subject: [PATCH] [fix](planner) array constructor do type coercion with decimal in wrong way (#23630) array creator with decimal type and integer type parameters should return array, but the legacy planner return array --- .../doris/analysis/FunctionCallExpr.java | 22 ++++++++++--------- gensrc/script/doris_builtins_functions.py | 4 ++-- .../test_array_functions_by_literal.groovy | 1 + 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index d361bf99b5f7ac..c4c7f967d93e52 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -1180,7 +1180,8 @@ private void analyzeArrayFunction(Analyzer analyzer) throws AnalysisException { || fnName.getFunction().equalsIgnoreCase("array_cum_sum") || fnName.getFunction().equalsIgnoreCase("array_intersect") || fnName.getFunction().equalsIgnoreCase("arrays_overlap") - || fnName.getFunction().equalsIgnoreCase("array_concat")) { + || fnName.getFunction().equalsIgnoreCase("array_concat") + || fnName.getFunction().equalsIgnoreCase("array")) { Type[] childTypes = collectChildReturnTypes(); Type compatibleType = childTypes[0]; for (int i = 1; i < childTypes.length; ++i) { @@ -1196,9 +1197,7 @@ private void analyzeArrayFunction(Analyzer analyzer) throws AnalysisException { for (int i = 0; i < childTypes.length; i++) { uncheckedCastChild(compatibleType, i); } - } - - if (fnName.getFunction().equalsIgnoreCase("array_exists")) { + } else if (fnName.getFunction().equalsIgnoreCase("array_exists")) { Type[] newArgTypes = new Type[1]; if (!(getChild(0) instanceof CastExpr)) { Expr castExpr = getChild(0).castTo(ArrayType.create(Type.BOOLEAN, true)); @@ -1213,13 +1212,14 @@ private void analyzeArrayFunction(Analyzer analyzer) throws AnalysisException { throw new AnalysisException(getFunctionNotFoundError(collectChildReturnTypes())); } fn.setReturnType(getChild(0).getType()); - } - - // make nested type with function param can be Compatible otherwise be will not deal with type - if (fnName.getFunction().equalsIgnoreCase("array_position") + } else if (fnName.getFunction().equalsIgnoreCase("array_position") || fnName.getFunction().equalsIgnoreCase("array_contains") || fnName.getFunction().equalsIgnoreCase("countequal")) { + // make nested type with function param can be Compatible otherwise be will not deal with type Type[] childTypes = collectChildReturnTypes(); + if (childTypes[0].isNull()) { + childTypes[0] = new ArrayType(Type.NULL); + } Type compatibleType = ((ArrayType) childTypes[0]).getItemType(); for (int i = 1; i < childTypes.length; ++i) { compatibleType = Type.getAssignmentCompatibleType(compatibleType, childTypes[i], true); @@ -1717,8 +1717,10 @@ && collectChildReturnTypes()[0].isDecimalV3()) { || (children.get(0).getType().isDecimalV2() && ((ArrayType) args[ix]).getItemType().isDecimalV2()))) { continue; - } else if ((fnName.getFunction().equalsIgnoreCase("array_distinct") || fnName.getFunction() - .equalsIgnoreCase("array_remove") || fnName.getFunction().equalsIgnoreCase("array_sort") + } else if ((fnName.getFunction().equalsIgnoreCase("array") + || fnName.getFunction().equalsIgnoreCase("array_distinct") + || fnName.getFunction().equalsIgnoreCase("array_remove") + || fnName.getFunction().equalsIgnoreCase("array_sort") || fnName.getFunction().equalsIgnoreCase("array_reverse_sort") || fnName.getFunction().equalsIgnoreCase("array_overlap") || fnName.getFunction().equalsIgnoreCase("array_union") diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index d707b95f1a65bd..b4a50f686666f7 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -103,12 +103,12 @@ [['array'], 'ARRAY', ['DATE', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DATETIMEV2', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DATEV2', '...'], 'ALWAYS_NOT_NULLABLE'], - [['array'], 'ARRAY', ['FLOAT', '...'], 'ALWAYS_NOT_NULLABLE'], - [['array'], 'ARRAY', ['DOUBLE', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DECIMALV2', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DECIMAL32', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DECIMAL64', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['DECIMAL128', '...'], 'ALWAYS_NOT_NULLABLE'], + [['array'], 'ARRAY', ['FLOAT', '...'], 'ALWAYS_NOT_NULLABLE'], + [['array'], 'ARRAY', ['DOUBLE', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['VARCHAR', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['STRING', '...'], 'ALWAYS_NOT_NULLABLE'], diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy index f2ac1da429083f..f35549019e5aac 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy @@ -17,6 +17,7 @@ suite("test_array_functions_by_literal") { // array_nested function + sql """ set enable_nereids_planner = false; """ qt_sql "select a from (select array(1, 1, 2, 2, 2, 2) as a) t" // array with decimal and other types