From 3f0e9d96d6d3cb0ab84acedd47a0728804c7e0b6 Mon Sep 17 00:00:00 2001 From: Seaven Date: Tue, 14 May 2024 19:41:55 +0800 Subject: [PATCH] [Enhancement] to_json return null when unsupported Signed-off-by: Seaven --- be/src/exprs/cast_expr.h | 2 +- be/src/exprs/cast_expr_json.cpp | 38 +++++++++++++++++++++++-------- be/src/exprs/function_context.cpp | 4 ++++ be/src/exprs/function_context.h | 2 ++ be/src/exprs/json_functions.cpp | 2 +- test/sql/test_json/R/to_json | 10 +++++++- test/sql/test_json/T/to_json | 5 +++- 7 files changed, 49 insertions(+), 14 deletions(-) diff --git a/be/src/exprs/cast_expr.h b/be/src/exprs/cast_expr.h index aee2abab14adf..304d1b5c37cce 100644 --- a/be/src/exprs/cast_expr.h +++ b/be/src/exprs/cast_expr.h @@ -193,7 +193,7 @@ struct CastToString { } }; -StatusOr cast_nested_to_json(const ColumnPtr& column); +StatusOr cast_nested_to_json(const ColumnPtr& column, bool allow_throw_exception); // cast column[idx] to coresponding json type. StatusOr cast_type_to_json_str(const ColumnPtr& column, int idx); diff --git a/be/src/exprs/cast_expr_json.cpp b/be/src/exprs/cast_expr_json.cpp index 65f9f69287fef..463d03aa3c900 100644 --- a/be/src/exprs/cast_expr_json.cpp +++ b/be/src/exprs/cast_expr_json.cpp @@ -134,7 +134,7 @@ class CastColumnItemVisitor final : public ColumnVisitorAdapterhas_null()) { - return Status::NotSupported("key of Map should not be nullable"); + return Status::NotSupported("key of Map should not be null"); } if (key_col->is_nullable()) { key_col = ColumnHelper::as_column(key_col)->data_column(); @@ -216,20 +216,38 @@ class CastColumnItemVisitor final : public ColumnVisitorAdapter cast_nested_to_json(const ColumnPtr& column) { +StatusOr cast_nested_to_json(const ColumnPtr& column, bool allow_throw_exception) { ColumnBuilder column_builder(column->size()); vpack::Builder json_builder; - for (int row = 0; row < column->size(); row++) { - if (column->is_null(row)) { - column_builder.append_null(); - continue; + if (allow_throw_exception) { + for (int row = 0; row < column->size(); row++) { + if (column->is_null(row)) { + column_builder.append_null(); + continue; + } + json_builder.clear(); + RETURN_IF_ERROR(CastColumnItemVisitor::cast_datum_to_json(column, row, "", &json_builder)); + JsonValue json(json_builder.slice()); + column_builder.append(std::move(json)); } - json_builder.clear(); - RETURN_IF_ERROR(CastColumnItemVisitor::cast_datum_to_json(column, row, "", &json_builder)); + } else { + for (int row = 0; row < column->size(); row++) { + if (column->is_null(row)) { + column_builder.append_null(); + continue; + } + json_builder.clear(); + auto st = CastColumnItemVisitor::cast_datum_to_json(column, row, "", &json_builder); + if (!st.ok()) { + column_builder.append_null(); + continue; + } - JsonValue json(json_builder.slice()); - column_builder.append(std::move(json)); + JsonValue json(json_builder.slice()); + column_builder.append(std::move(json)); + } } + return column_builder.build(false); } diff --git a/be/src/exprs/function_context.cpp b/be/src/exprs/function_context.cpp index 37a77f05d21e1..f20c0d7c5d8d1 100644 --- a/be/src/exprs/function_context.cpp +++ b/be/src/exprs/function_context.cpp @@ -169,6 +169,10 @@ bool FunctionContext::error_if_overflow() const { return _state != nullptr && _state->error_if_overflow(); } +bool FunctionContext::allow_throw_exception() const { + return _state != nullptr && _state->query_options().allow_throw_exception; +} + void FunctionContext::set_function_state(FunctionStateScope scope, void* ptr) { switch (scope) { case THREAD_LOCAL: diff --git a/be/src/exprs/function_context.h b/be/src/exprs/function_context.h index 773fb0390ce42..063fbcc910a7b 100644 --- a/be/src/exprs/function_context.h +++ b/be/src/exprs/function_context.h @@ -174,6 +174,8 @@ class FunctionContext { bool error_if_overflow() const; + bool allow_throw_exception() const; + std::unique_ptr& get_ngram_state() { return _ngramState; } private: diff --git a/be/src/exprs/json_functions.cpp b/be/src/exprs/json_functions.cpp index 5e7cad9029fae..ca5813bdc6301 100644 --- a/be/src/exprs/json_functions.cpp +++ b/be/src/exprs/json_functions.cpp @@ -1085,7 +1085,7 @@ StatusOr JsonFunctions::_json_keys_without_path(FunctionContext* cont StatusOr JsonFunctions::to_json(FunctionContext* context, const Columns& columns) { RETURN_IF_COLUMNS_ONLY_NULL(columns); - return cast_nested_to_json(columns[0]); + return cast_nested_to_json(columns[0], context->allow_throw_exception()); } } // namespace starrocks diff --git a/test/sql/test_json/R/to_json b/test/sql/test_json/R/to_json index c88e9d3815b12..1adbe6653b052 100644 --- a/test/sql/test_json/R/to_json +++ b/test/sql/test_json/R/to_json @@ -33,4 +33,12 @@ SELECT to_json(row(1, 1)); SELECT to_json(NULL); -- result: None --- !result \ No newline at end of file +-- !result +select /*+SET_VAR(sql_mode='ONLY_FULL_GROUP_BY,ALLOW_THROW_EXCEPTION')*/ to_json(map{null:null}); +-- result: +E: (1064, 'key of Map should not be null') +-- !result +select /*+SET_VAR(sql_mode='ONLY_FULL_GROUP_BY')*/ to_json(map{null:null}); +-- result: +None +-- !result diff --git a/test/sql/test_json/T/to_json b/test/sql/test_json/T/to_json index 17ac15da4a3ce..b7062f50b309e 100644 --- a/test/sql/test_json/T/to_json +++ b/test/sql/test_json/T/to_json @@ -16,4 +16,7 @@ INSERT INTO t0 VALUES (2, row(1, 1)); select to_json(c1) from t0 order by c0; SELECT to_json(row(1, 1)); -SELECT to_json(NULL); \ No newline at end of file +SELECT to_json(NULL); + +select /*+SET_VAR(sql_mode='ONLY_FULL_GROUP_BY,ALLOW_THROW_EXCEPTION')*/ to_json(map{null:null}); +select /*+SET_VAR(sql_mode='ONLY_FULL_GROUP_BY')*/ to_json(map{null:null});