From 8e3d28b93a9cf812aa79b99e18140dd98523de42 Mon Sep 17 00:00:00 2001 From: koarz <66543806+koarz@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:11:57 +0800 Subject: [PATCH] [Feature] Support Array Type compare function for nereids planner (#31701) Support Array Type compare function for nereids planner --- .../apache/doris/analysis/ArrayLiteral.java | 9 +- .../expressions/ComparisonPredicate.java | 2 +- .../doris/nereids/util/TypeCoercionUtils.java | 3 + .../data/nereids_syntax_p0/array_compare.out | 68 +++++++++++++++ .../nereids_syntax_p0/array_compare.groovy | 83 +++++++++++++++++++ .../test_array_functions_with_where.groovy | 6 -- 6 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 regression-test/data/nereids_syntax_p0/array_compare.out create mode 100644 regression-test/suites/nereids_syntax_p0/array_compare.groovy diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java index 770d826dd0..422a9ef332 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ArrayLiteral.java @@ -99,7 +99,14 @@ public class ArrayLiteral extends LiteralExpr { @Override public int compareLiteral(LiteralExpr expr) { - return 0; + int size = Math.min(expr.getChildren().size(), this.children.size()); + for (int i = 0; i < size; i++) { + if (((LiteralExpr) (this.getChild(i))).compareTo((LiteralExpr) (expr.getChild(i))) != 0) { + return ((LiteralExpr) (this.getChild(i))).compareTo((LiteralExpr) (expr.getChild(i))); + } + } + return this.children.size() > expr.getChildren().size() ? 1 : + (this.children.size() == expr.getChildren().size() ? 0 : -1); } @Override diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java index a22852ca31..c9d10bde36 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/ComparisonPredicate.java @@ -62,7 +62,7 @@ public abstract class ComparisonPredicate extends BinaryOperator { @Override public void checkLegalityBeforeTypeCoercion() { children().forEach(c -> { - if (c.getDataType().isComplexType()) { + if (c.getDataType().isComplexType() && !c.getDataType().isArrayType()) { throw new AnalysisException("comparison predicate could not contains complex type: " + this.toSql()); } }); diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java index 758bb03a04..4ec437055a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/util/TypeCoercionUtils.java @@ -1635,6 +1635,9 @@ public class TypeCoercionUtils { } private static boolean supportCompare(DataType dataType) { + if (dataType.isArrayType()) { + return true; + } if (!(dataType instanceof PrimitiveType)) { return false; } diff --git a/regression-test/data/nereids_syntax_p0/array_compare.out b/regression-test/data/nereids_syntax_p0/array_compare.out new file mode 100644 index 0000000000..2b89118aa7 --- /dev/null +++ b/regression-test/data/nereids_syntax_p0/array_compare.out @@ -0,0 +1,68 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !select_default -- +1 [1, 2, 3] +2 [4, 5, 6] +3 [] +4 [1, 2, 3, 4] +5 \N + +-- !array_compare_1 -- +1 [1, 2, 3] + +-- !array_compare_2 -- +3 [] + +-- !array_compare_3 -- +1 [1, 2, 3] +2 [4, 5, 6] +3 [] + +-- !array_compare_4 -- +2 [4, 5, 6] +4 [1, 2, 3, 4] + +-- !array_compare_5 -- +1 [1, 2, 3] +3 [] + +-- !array_compare_6 -- +1 [1, 2, 3] + +-- !array_compare_7 -- +1 [1, 2, 3] +2 [4, 5, 6] +3 [] + +-- !array_compare_8 -- +2 [4, 5, 6] +4 [1, 2, 3, 4] + +-- !array_compare_9 -- +1 [1, 2, 3] +3 [] +4 [1, 2, 3, 4] + +-- !sql -- +false + +-- !sql -- +true + +-- !sql -- +true + +-- !sql -- +true + +-- !sql -- +false + +-- !sql -- +true + +-- !sql -- +false + +-- !sql -- +false + diff --git a/regression-test/suites/nereids_syntax_p0/array_compare.groovy b/regression-test/suites/nereids_syntax_p0/array_compare.groovy new file mode 100644 index 0000000000..30457c83d9 --- /dev/null +++ b/regression-test/suites/nereids_syntax_p0/array_compare.groovy @@ -0,0 +1,83 @@ +// 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("array_compare") { + def tableName = "test_array" + + sql """ DROP TABLE IF EXISTS ${tableName} """ + sql """ + CREATE TABLE IF NOT EXISTS ${tableName} ( + `id` INT NULL, + `c_array` ARRAY NULL + ) DISTRIBUTED BY HASH(id) PROPERTIES("replication_num" = "1"); + """ + + sql """ INSERT INTO ${tableName} (`id`,`c_array`) VALUES + (1, [1, 2, 3]), + (2, [4, 5, 6]), + (3, []), + (4, [1, 2, 3, 4]), + (5, NULL) + """ + try { + qt_select_default """ SELECT * FROM ${tableName} t ORDER BY id; """ + + sql """ set enable_nereids_planner = true;""" + sql """ set enable_fallback_to_original_planner=false;""" + order_qt_array_compare_1 """ + SELECT * FROM ${tableName} where c_array = [1, 2, 3]; + """ + order_qt_array_compare_2 """ + SELECT * FROM ${tableName} where c_array = []; + """ + order_qt_array_compare_3 """ + SELECT * FROM ${tableName} where c_array != [1, 2, 3, 4]; + """ + order_qt_array_compare_4 """ + SELECT * FROM ${tableName} where c_array > [1, 2, 3]; + """ + order_qt_array_compare_5 """ + SELECT * FROM ${tableName} where c_array < [1, 2, 3, 4]; + """ + order_qt_array_compare_6 """ + SELECT * FROM ${tableName} where c_array = ['1', '2', '3']; + """ + order_qt_array_compare_7 """ + SELECT * FROM ${tableName} where c_array != ["1", "2", "3", "4"]; + """ + order_qt_array_compare_8 """ + SELECT * FROM ${tableName} where c_array > [1.0, 2.0, 3.0]; + """ + order_qt_array_compare_9 """ + SELECT * FROM ${tableName} where c_array < [1.00001, 2.00001, 3.00001, 4.00001]; + """ + } finally { + try_sql("DROP TABLE IF EXISTS ${tableName}") + } + + qt_sql """select [1, 2] = ["1, 2"];""" + qt_sql """select [1, 2, 3] = ['1', '2', '3'];""" + qt_sql """select [1, 2, 3] = ["1", "2", "3"];""" + qt_sql """select [1, 2, 3] = [1.0, 2.0, 3.0];""" + qt_sql """select [1, 2, 3] = [1.000000000000000001, 2.000000000000000001, 3.000000000000000001];""" + + qt_sql """select [1, 2, 3] > ['1', '2'];""" + qt_sql """select [1, 2, 3] < ["1", "2", "3"];""" + qt_sql """select [1, 2, 3] != [1.0, 2.0, 3.0];""" + +} diff --git a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy index 94f2e6c0b5..724fb8047f 100644 --- a/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy +++ b/regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_with_where.groovy @@ -48,12 +48,6 @@ suite("test_array_functions_with_where") { qt_select "SELECT k1, array(k1, 'abc') FROM ${tableName} WHERE k1 is not null ORDER BY k1, size(k2)" qt_select "SELECT k1, array(null, k1) FROM ${tableName} WHERE k1 is not null ORDER BY k1, size(k2)" - test { - sql "select k1, size(k2) FROM ${tableName} WHERE k2 = []" - // check exception message contains - exception "errCode" - } - tableName = "tbl_test_array_functions_with_where2" sql """DROP TABLE IF EXISTS ${tableName}""" sql """