diff --git a/be/src/vec/functions/functions_multi_string_position.cpp b/be/src/vec/functions/functions_multi_string_position.cpp index 904fbb2e23..4498147c67 100644 --- a/be/src/vec/functions/functions_multi_string_position.cpp +++ b/be/src/vec/functions/functions_multi_string_position.cpp @@ -80,26 +80,22 @@ public: Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) const override { auto haystack_column = block.get_by_position(arguments[0]).column; - auto haystack_ptr = haystack_column; - auto needles_column = block.get_by_position(arguments[1]).column; - auto needles_ptr = needles_column; bool haystack_nullable = false; bool needles_nullable = false; if (haystack_column->is_nullable()) { - haystack_ptr = check_and_get_column(haystack_column.get()) - ->get_nested_column_ptr(); haystack_nullable = true; } if (needles_column->is_nullable()) { - needles_ptr = check_and_get_column(needles_column.get()) - ->get_nested_column_ptr(); needles_nullable = true; } + auto haystack_ptr = remove_nullable(haystack_column); + auto needles_ptr = remove_nullable(needles_column); + const ColumnString* col_haystack_vector = check_and_get_column(&*haystack_ptr); const ColumnConst* col_haystack_const = @@ -110,6 +106,11 @@ public: const ColumnConst* col_needles_const = check_and_get_column_const(needles_ptr.get()); + if (!col_needles_const && !col_needles_vector) + return Status::InvalidArgument( + "function '{}' encountered unsupported needles column, found {}", name, + needles_column->get_name()); + if (col_haystack_const && col_needles_vector) { return Status::InvalidArgument( "function '{}' doesn't support search with non-constant needles " diff --git a/be/src/vec/functions/functions_multi_string_search.cpp b/be/src/vec/functions/functions_multi_string_search.cpp index 72c0eeed87..f7a1b8d7a9 100644 --- a/be/src/vec/functions/functions_multi_string_search.cpp +++ b/be/src/vec/functions/functions_multi_string_search.cpp @@ -78,26 +78,22 @@ public: Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) const override { auto haystack_column = block.get_by_position(arguments[0]).column; - auto haystack_ptr = haystack_column; - auto needles_column = block.get_by_position(arguments[1]).column; - auto needles_ptr = needles_column; bool haystack_nullable = false; bool needles_nullable = false; if (haystack_column->is_nullable()) { - haystack_ptr = check_and_get_column(haystack_column.get()) - ->get_nested_column_ptr(); haystack_nullable = true; } if (needles_column->is_nullable()) { - needles_ptr = check_and_get_column(needles_column.get()) - ->get_nested_column_ptr(); needles_nullable = true; } + auto haystack_ptr = remove_nullable(haystack_column); + auto needles_ptr = remove_nullable(needles_column); + const ColumnString* col_haystack_vector = check_and_get_column(&*haystack_ptr); const ColumnConst* col_haystack_const = @@ -108,6 +104,11 @@ public: const ColumnConst* col_needles_const = check_and_get_column_const(needles_ptr.get()); + if (!col_needles_const && !col_needles_vector) + return Status::InvalidArgument( + "function '{}' encountered unsupported needles column, found {}", name, + needles_column->get_name()); + if (col_haystack_const && col_needles_vector) return Status::InvalidArgument( "function '{}' doesn't support search with non-constant needles " 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 9907b497bb..1460adaf04 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 @@ -84,6 +84,9 @@ public class FunctionCallExpr extends Expr { String.CASE_INSENSITIVE_ORDER) .add("round").add("round_bankers").add("ceil").add("floor") .add("truncate").add("dround").add("dceil").add("dfloor").build(); + public static final ImmutableSet STRING_SEARCH_FUNCTION_SET = new ImmutableSortedSet.Builder( + String.CASE_INSENSITIVE_ORDER) + .add("multi_search_all_positions").add("multi_match_any").build(); private final AtomicBoolean addOnce = new AtomicBoolean(false); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java index babd697680..b69d52b2c1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java @@ -495,6 +495,12 @@ public class FunctionSet { return false; } } + if (FunctionCallExpr.STRING_SEARCH_FUNCTION_SET.contains(desc.functionName())) { + if (descArgTypes[1].isStringType() && candicateArgTypes[1].isArrayType()) { + // The needles arg of search functions should not be allowed to cast from string. + return false; + } + } // If set `roundPreciseDecimalV2Value`, only use decimalv3 as target type to execute round function if (ConnectContext.get() != null && ConnectContext.get().getSessionVariable().roundPreciseDecimalV2Value diff --git a/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_position.groovy b/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_position.groovy index f6a8aa110e..1c82fc7c6e 100644 --- a/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_position.groovy +++ b/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_position.groovy @@ -54,4 +54,28 @@ suite("test_multi_string_position") { qt_select3 "select multi_search_all_positions('mpswgtljbbrmivkcglamemayfn', ['', 'm', 'saejhpnfgfq', 'rzanrkdssmmkanqjpfi', 'oputeneprgoowg', 'mp', '', '', 'wgtljbbrmivkcglamemay', 'cbpthtrgrmgfypizi', 'tl', 'tlj', 'xuhs', 'brmivkcglamemayfn', '', 'gtljb'])" qt_select4 "select multi_search_all_positions('arbphzbbecypbzsqsljurtddve', ['arbphzb', 'mnrboimjfijnti', 'cikcrd', 'becypbz', 'z', 'uocmqgnczhdcrvtqrnaxdxjjlhakoszuwc', 'bbe', '', 'bp', 'yhltnexlpdijkdzt', 'jkwjmrckvgmccmmrolqvy', 'vdxmicjmfbtsbqqmqcgtnrvdgaucsgspwg', 'witlfqwvhmmyjrnrzttrikhhsrd', 'pbzsqsljurt'])" qt_select5 "select multi_search_all_positions('aizovxqpzcbbxuhwtiaaqhdqjdei', ['qpzcbbxuhw', 'jugrpglqbm', 'dspwhzpyjohhtizegrnswhjfpdz', 'pzcbbxuh', 'vayzeszlycke', 'i', 'gvrontcpqavsjxtjwzgwxugiyhkhmhq', 'gyzmeroxztgaurmrqwtmsxcqnxaezuoapatvu', 'xqpzc', 'mjiswsvlvlpqrhhptqq', 'iz', 'hmzjxxfjsvcvdpqwtrdrp', 'zovxqpzcbbxuhwtia', 'ai'])" + + try { + sql "select multi_search_all_positions(content, 'hello') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_search_all_positions")) + } + + try { + sql "select multi_search_all_positions(content, 'hello, !, world, Hello, World') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_search_all_positions")) + } + + try { + sql "select multi_search_all_positions(content, '[hello]') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_search_all_positions")) + } + + try { + sql "select multi_search_all_positions(content, '[hello, !, world, Hello, World]') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_search_all_positions")) + } } diff --git a/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_search.groovy b/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_search.groovy index 111fcaf717..55a9f6894f 100644 --- a/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_search.groovy +++ b/regression-test/suites/query_p0/sql_functions/search_functions/test_multi_string_search.groovy @@ -71,4 +71,28 @@ suite("test_multi_string_search", "arrow_flight_sql") { qt_select "select multi_match_any('ldrzgttlqaphekkkdukgngl', ['gttlqaphekkkdukgn', 'ekkkd', 'gttlqaphe', 'qaphek', 'h', 'kdu', 'he', 'phek', '', 'drzgttlqaphekkkd'])" qt_select "select multi_match_any('ololo', ['ololo', 'ololo', 'ololo'])" qt_select "select multi_match_any('khljxzxlpcrxpkrfybbfk', ['k'])" -} \ No newline at end of file + + try { + sql "select multi_match_any(content, 'hello') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_match_any")) + } + + try { + sql "select multi_match_any(content, 'hello, !, world, Hello, World') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_match_any")) + } + + try { + sql "select multi_match_any(content, '[hello]') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_match_any")) + } + + try { + sql "select multi_match_any(content, '[hello, !, world, Hello, World]') from ${table_name} order by col1" + } catch (Exception ex) { + assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: multi_match_any")) + } +}