cambyzju commented on code in PR #50151:
URL: https://github.com/apache/doris/pull/50151#discussion_r2053885099
##########
be/src/vec/functions/function_jsonb.cpp:
##########
@@ -1936,25 +2038,387 @@ class FunctionJsonSearch : public IFunction {
col_search->get_name());
}
if (search_is_const) {
- CheckNullFun search_null_check = always_not_null;
+ JsonSearchUtil::CheckNullFun search_null_check =
JsonSearchUtil::always_not_null;
if (col_search->is_null_at(0)) {
- search_null_check = always_null;
+ search_null_check = JsonSearchUtil::always_null;
}
- RETURN_IF_ERROR(execute_vector<true>(
+ RETURN_IF_ERROR(JsonSearchUtil::execute_vector<true>(
block, input_rows_count, json_null_check, get_json_fun,
one_null_check,
one_check, search_null_check, col_search_string, context,
result));
} else {
- CheckNullFun search_null_check = [col_search](size_t i) {
+ JsonSearchUtil::CheckNullFun search_null_check =
[col_search](size_t i) {
return col_search->is_null_at(i);
};
- RETURN_IF_ERROR(execute_vector<false>(
+ RETURN_IF_ERROR(JsonSearchUtil::execute_vector<false>(
block, input_rows_count, json_null_check, get_json_fun,
one_null_check,
one_check, search_null_check, col_search_string, context,
result));
}
return Status::OK();
}
};
+struct JsonSearchEscape {
+ static DataTypes get_variadic_argument_types() {
+ return {
+ std::make_shared<DataTypeString>(),
+ std::make_shared<DataTypeString>(),
+ std::make_shared<DataTypeString>(),
+ std::make_shared<DataTypeString>(),
+ };
+ }
+
+ static Status execute_impl(FunctionContext* context, Block& block,
+ const ColumnNumbers& arguments, uint32_t result,
+ size_t input_rows_count) {
+ if (arguments.size() != 4) {
+ return Status::InvalidArgument("wrong arguments for function
json_search");
+ }
+
+ JsonSearchUtil::CheckNullFun json_null_check =
JsonSearchUtil::always_not_null;
+ JsonSearchUtil::GetJsonStringRefFun get_json_fun;
+ ColumnPtr col_json;
+ bool json_is_const = false;
+ // prepare jsonb data column
+ std::tie(col_json, json_is_const) =
+ unpack_if_const(block.get_by_position(arguments[0]).column);
+ const auto* col_json_string =
check_and_get_column<ColumnString>(col_json.get());
+ if (const auto* nullable =
check_and_get_column<ColumnNullable>(col_json.get())) {
+ col_json_string =
+
check_and_get_column<ColumnString>(nullable->get_nested_column_ptr().get());
+ }
+
+ if (!col_json_string) {
+ return Status::RuntimeError("Illegal arg json {} should be
ColumnString",
+ col_json->get_name());
+ }
+ if (json_is_const) {
+ if (col_json->is_null_at(0)) {
+ json_null_check = JsonSearchUtil::always_null;
+ } else {
+ const auto& json_str = col_json_string->get_data_at(0);
+ get_json_fun = [json_str](size_t i) { return json_str; };
+ }
+ } else {
+ json_null_check = [col_json](size_t i) { return
col_json->is_null_at(i); };
+ get_json_fun = [col_json_string](size_t i) { return
col_json_string->get_data_at(i); };
+ }
+
+ JsonSearchUtil::CheckNullFun one_null_check =
JsonSearchUtil::always_not_null;
+ JsonSearchUtil::OneFun one_check = JsonSearchUtil::always_one;
+ ColumnPtr col_one;
+ bool one_is_const = false;
+ // prepare jsonb data column
+ std::tie(col_one, one_is_const) =
+ unpack_if_const(block.get_by_position(arguments[1]).column);
+ const auto* col_one_string =
check_and_get_column<ColumnString>(col_one.get());
+ if (const auto* nullable =
check_and_get_column<ColumnNullable>(col_one.get())) {
+ col_one_string =
check_and_get_column<ColumnString>(*nullable->get_nested_column_ptr());
+ }
+ if (!col_one_string) {
+ return Status::RuntimeError("Illegal arg one {} should be
ColumnString",
+ col_one->get_name());
+ }
+ if (one_is_const) {
+ if (col_one->is_null_at(0)) {
+ one_null_check = JsonSearchUtil::always_null;
+ } else {
+ const auto& one_or_all = col_one_string->get_data_at(0);
+ std::string one_or_all_str = one_or_all.to_string();
+ if (strcasecmp(one_or_all_str.c_str(), JsonSearchUtil::all) ==
0) {
+ one_check = JsonSearchUtil::always_all;
+ } else if (strcasecmp(one_or_all_str.c_str(),
JsonSearchUtil::one) == 0) {
+ // nothing
+ } else {
+ // an error occurs if the one_or_all argument is not 'one'
nor 'all'.
+ return Status::InvalidArgument(
+ "the one_or_all argument {} is not 'one' not
'all'", one_or_all_str);
+ }
+ }
+ } else {
+ one_null_check = [col_one](size_t i) { return
col_one->is_null_at(i); };
+ one_check = [col_one_string](size_t i, bool* is_one) {
+ const auto& one_or_all = col_one_string->get_data_at(i);
+ std::string one_or_all_str = one_or_all.to_string();
+ if (strcasecmp(one_or_all_str.c_str(), JsonSearchUtil::all) ==
0) {
+ *is_one = false;
+ } else if (strcasecmp(one_or_all_str.c_str(),
JsonSearchUtil::one) == 0) {
+ *is_one = true;
+ } else {
+ // an error occurs if the one_or_all argument is not 'one'
nor 'all'.
+ return Status::InvalidArgument(
+ "the one_or_all argument {} is not 'one' not
'all'", one_or_all_str);
+ }
+ return Status::OK();
+ };
+ }
+
+ JsonSearchUtil::CheckNullFun start_null_check =
JsonSearchUtil::always_null;
+ JsonSearchUtil::GetJsonStartFun get_start_path;
+
+ JsonSearchUtil::CheckNullFun escape_null_check =
JsonSearchUtil::always_null;
+ JsonSearchUtil::GetJsonEscapeFun get_escape_string;
+
+ ColumnPtr col_escape;
+ bool escape_is_const = false;
+
+ std::tie(col_escape, escape_is_const) =
+ unpack_if_const(block.get_by_position(arguments[3]).column);
+
+ const auto* col_escape_string =
check_and_get_column<ColumnString>(col_escape.get());
+ if (const auto* nullable =
check_and_get_column<ColumnNullable>(col_escape.get())) {
+ col_escape_string =
+
check_and_get_column<ColumnString>(*nullable->get_nested_column_ptr());
+ }
+ if (!col_escape_string) {
+ return Status::RuntimeError("Illegal arg pattern {} should be
ColumnString",
+ col_escape->get_name());
+ }
+ if (escape_is_const) {
+ if (col_escape->is_null_at(0)) {
+ escape_null_check = JsonSearchUtil::always_null;
+ }
+ } else {
+ escape_null_check = [col_escape](size_t i) { return
col_escape->is_null_at(i); };
+ get_escape_string = [col_escape_string](size_t i, char*
escape_char) {
+ auto escape_string =
col_escape_string->get_data_at(i).to_string();
+ if (escape_string.length() != 1) {
+ return Status::RuntimeError("Illegal arg pattern {} should
be char",
+ col_escape_string->get_name());
+ }
+ *escape_char = escape_string.at(0);
+ return Status::OK();
+ };
+ }
+
+ ColumnPtr col_search;
+ bool search_is_const = false;
+ std::tie(col_search, search_is_const) =
+ unpack_if_const(block.get_by_position(arguments[2]).column);
+
+ const auto* col_search_string =
check_and_get_column<ColumnString>(col_search.get());
+ if (const auto* nullable =
check_and_get_column<ColumnNullable>(col_search.get())) {
+ col_search_string =
+
check_and_get_column<ColumnString>(*nullable->get_nested_column_ptr());
+ }
+ if (!col_search_string) {
+ return Status::RuntimeError("Illegal arg pattern {} should be
ColumnString",
+ col_search->get_name());
+ }
+ if (search_is_const) {
+ JsonSearchUtil::CheckNullFun search_null_check =
JsonSearchUtil::always_not_null;
+ if (col_search->is_null_at(0)) {
+ search_null_check = JsonSearchUtil::always_null;
+ }
+ RETURN_IF_ERROR(JsonSearchUtil::execute_vector<true>(
+ block, input_rows_count, json_null_check, get_json_fun,
one_null_check,
+ one_check, search_null_check, col_search_string, context,
result,
+ start_null_check, get_start_path, escape_null_check,
get_escape_string));
+ } else {
+ JsonSearchUtil::CheckNullFun search_null_check =
[col_search](size_t i) {
+ return col_search->is_null_at(i);
+ };
+ RETURN_IF_ERROR(JsonSearchUtil::execute_vector<false>(
+ block, input_rows_count, json_null_check, get_json_fun,
one_null_check,
+ one_check, search_null_check, col_search_string, context,
result,
+ start_null_check, get_start_path, escape_null_check,
get_escape_string));
+ }
+ return Status::OK();
+ }
+};
+
+struct JsonSearchStartPath {
Review Comment:
please reuse codes in: `JsonSearchNormal JsonSearchEscape
JsonSearchStartPath`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]