xuefengze commented on code in PR #24384: URL: https://github.com/apache/doris/pull/24384#discussion_r1327890130
########## be/src/vec/functions/function_json.cpp: ########## @@ -1131,6 +1131,319 @@ class FunctionJsonUnquote : public IFunction { } }; +struct FunctionJsonInsert { + static constexpr auto name = "json_insert"; + static constexpr auto is_insert = true; Review Comment: I will do it. ########## be/src/vec/functions/function_json.cpp: ########## @@ -1131,6 +1131,319 @@ class FunctionJsonUnquote : public IFunction { } }; +struct FunctionJsonInsert { + static constexpr auto name = "json_insert"; + static constexpr auto is_insert = true; + static constexpr auto is_replace = false; +}; + +struct FunctionJsonReplace { + static constexpr auto name = "json_replace"; + static constexpr auto is_insert = false; + static constexpr auto is_replace = true; +}; +struct FunctionJsonSet { + static constexpr auto name = "json_set"; + static constexpr auto is_insert = true; + static constexpr auto is_replace = true; +}; + +template <typename Kind> +class FunctionJsonModifyImpl : public IFunction { +private: + // T = std::vector<std::string> + // TODO: update RE2 to support std::vector<std::string_view> + // if path is not a valid path expression or contains + // a * wildcard, return runtime error. + template <typename T> + Status get_parsed_paths_with_status(const T& path_exprs, std::vector<JsonPath>* parsed_paths) { + if (UNLIKELY(path_exprs.empty())) { + return Status::RuntimeError("json path empty function {}", get_name()); + } + + if (path_exprs[0] != "$") { + // keep same behaviour with get_parsed_paths(), + // '$[0]' is not invalid path, '$.[0]' is invalid + return Status::RuntimeError( + "Invalid JSON path expression. The error is around character position 1"); + } + parsed_paths->emplace_back("$", -1, true); + + for (int i = 1; i < path_exprs.size(); i++) { + std::string col; + std::string index; + if (UNLIKELY(!RE2::FullMatch(path_exprs[i], JSON_PATTERN, &col, &index))) { + return Status::RuntimeError( + "Invalid JSON path expression. The error is around character position {}", + i + 1); + } else { + int idx = -1; + if (!index.empty()) { + if (index == "*") { + return Status::RuntimeError( + "In this situation, path expressions may not contain the * token"); + } else { + idx = atoi(index.c_str()); + } + } + parsed_paths->emplace_back(col, idx, true); + } + } + return Status::OK(); + } + + Status get_parsed_path_columns(std::vector<std::vector<std::vector<JsonPath>>>& json_paths, + const std::vector<const ColumnString*>& data_columns, + size_t input_rows_count) { + for (auto col = 1; col + 1 < data_columns.size() - 1; col += 2) { + json_paths.emplace_back(std::vector<std::vector<JsonPath>>()); + for (auto row = 0; row < input_rows_count; row++) { + const auto path = data_columns[col]->get_data_at(row); + std::string_view path_string(path.data, path.size); + std::vector<JsonPath> parsed_paths; + +#ifdef USE_LIBCPP + std::string s(path_string); + auto tok = get_json_token(s); +#else + auto tok = get_json_token(path_string); +#endif + std::vector<std::string> paths(tok.begin(), tok.end()); + auto status = get_parsed_paths_with_status(paths, &parsed_paths); Review Comment: ok -- 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: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org