diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h index 3ca13a270c620a..ef294d67d1f445 100644 --- a/be/src/vec/functions/function_string.h +++ b/be/src/vec/functions/function_string.h @@ -305,49 +305,31 @@ class FunctionStrcmp : public IFunction { size_t get_number_of_arguments() const override { return 2; } DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + if (arguments[0]->is_nullable() || arguments[1]->is_nullable()) { + return make_nullable(std::make_shared()); + } return std::make_shared(); } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) const override { - const auto& arg0_column = - assert_cast(*block.get_by_position(arguments[0]).column); - const auto& arg1_column = - assert_cast(*block.get_by_position(arguments[1]).column); + const auto& [arg0_column, arg0_const] = unpack_if_const(block.get_by_position(arguments[0]).column); + const auto& [arg1_column, arg1_const] = unpack_if_const(block.get_by_position(arguments[1]).column); auto result_column = ColumnInt16::create(input_rows_count); auto& result_data = result_column->get_data(); - auto null_column = ColumnUInt8::create(input_rows_count); - auto& null_map = null_column->get_data(); for (int row = 0; row < input_rows_count; row++) { - null_map[row] = false; - if (arg0_column.is_nullable() || arg1_column.is_nullable()) { - null_map[row] = true; - continue; - } - - auto arg0 = arg0_column.get_data_at(row).to_string(); - auto arg1 = arg1_column.get_data_at(row).to_string(); + auto arg0 = arg0_column->get_data_at(row); + auto arg1 = arg1_column->get_data_at(row); Int16* result_cell = &result_data[row]; - *result_cell = strcmp(arg0.c_str(), arg1.c_str()); + *result_cell = arg0.compare(arg1); } - block.replace_by_position( - result, ColumnNullable::create(std::move(result_column), std::move(null_column))); + block.replace_by_position(result, std::move(result_column)); return Status::OK(); } - - static int strcmp(const char* arg0, const char* arg1) { - int ret = std::strcmp(arg0, arg1); - if (ret < 0) { - return -1; - } else if (ret > 0) { - return 1; - } - return 0; - } }; struct SubstringUtilOld { diff --git a/be/test/vec/function/function_string_test.cpp b/be/test/vec/function/function_string_test.cpp index d8d1a57b8eb986..3b684987b91089 100644 --- a/be/test/vec/function/function_string_test.cpp +++ b/be/test/vec/function/function_string_test.cpp @@ -1187,4 +1187,24 @@ TEST(function_string_test, function_uuid_test) { } } +TEST(function_string_test, function_strcmp_test) { + std::string func_name = "strcmp"; + InputTypeSet input_types = {TypeIndex::String, TypeIndex::String}; + + DataSet data_set = {{{Null()}, Null()}, + {{std::string(""), std::string("")}, 0}, + {{std::string("test"), std::string("test")}, 0}, + {{std::string("test1"), std::string("test")}, 1}, + {{std::string("test"), std::string("test1")}, -1}, + {{Null(), std::string("test")}, Null()}, + {{std::string("test"), Null()}, Null()}, + {{VARCHAR(""), VARCHAR("")}, 0}, + {{VARCHAR("test"), VARCHAR("test")}, 0}, + {{VARCHAR("test1"), VARCHAR("test")}, 1}, + {{VARCHAR("test"), VARCHAR("test1")}, -1}, + {{Null(), VARCHAR("test")}, Null()}, + {{VARCHAR("test"), Null()}, Null()}}; + static_cast(check_function(func_name, input_types, data_set)); +} + } // namespace doris::vectorized diff --git a/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out b/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out index f2f00df695432b..e3ca494c632fb9 100644 Binary files a/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out and b/regression-test/data/query_p0/sql_functions/string_functions/test_string_function.out differ diff --git a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy index 89a8dccd9ad9d0..2f5b49aa22dc6a 100644 --- a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy +++ b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function.groovy @@ -285,20 +285,6 @@ suite("test_string_function", "arrow_flight_sql") { qt_sql "select substring_index(\"prefix_string\", \"_\", null);" qt_sql "select substring_index(\"prefix_string\", \"__\", -1);" - qt_sql_func_strcmp "select strcmp('test', 'test1');" - qt_sql_func_strcmp "select strcmp('test1', 'test');" - qt_sql_func_strcmp "select strcmp('test', 'test');" - qt_sql_func_strcmp "select strcmp('', '');" - qt_sql_func_strcmp "select strcmp(null, 'test');" - qt_sql_func_strcmp "select strcmp('test', null);" - qt_sql_func_strcmp "select strcmp(\"test\", \"test1\");" - qt_sql_func_strcmp "select strcmp(\"test1\", \"test\");" - qt_sql_func_strcmp "select strcmp(\"test\", \"test\");" - qt_sql_func_strcmp "select strcmp(\"\", \"\");" - qt_sql_func_strcmp "select strcmp(null, \"test\");" - qt_sql_func_strcmp "select strcmp(\"test\", null);" - qt_sql_func_strcmp "select strcmp(null, null);" - sql 'set enable_nereids_planner=true' sql 'set enable_fallback_to_original_planner=false'