diff options
author | Eric Herman <eric@freesa.org> | 2021-07-02 08:20:37 +0200 |
---|---|---|
committer | Eric Herman <eric@freesa.org> | 2021-07-19 18:44:37 +0200 |
commit | 6681ee68d1c7321f8b770ed738e09486c74bf930 (patch) | |
tree | c6c14aeb6642755e9e9527368853a95d68f6c388 /sql | |
parent | 8c55a903a274145a2400989966bfd86f3ac10e4b (diff) | |
download | mariadb-git-bb-10.7-mdev23143.tar.gz |
MDEV-23143 Add JSON_EQUALS functionbb-10.7-mdev23143
This patch implements JSON_EQUALS SQL function. The function takes
advantage of the json_normalize functionality and does the following:
norm_a = json_normalize(a)
norm_b = json_normalize(b)
return strcmp(norm_a, norm_b)
Co-authored-by: Vicențiu Ciorbaru <vicentiu@mariadb.org>
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_create.cc | 24 | ||||
-rw-r--r-- | sql/item_jsonfunc.cc | 60 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 17 |
3 files changed, 101 insertions, 0 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc index 79f558ee844..e019ac6f8bb 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -915,6 +915,19 @@ protected: }; +class Create_func_json_equals : public Create_func_arg2 +{ +public: + virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); + + static Create_func_json_equals s_singleton; + +protected: + Create_func_json_equals() {} + virtual ~Create_func_json_equals() {} +}; + + class Create_func_json_exists : public Create_func_arg2 { public: @@ -3619,6 +3632,16 @@ Create_func_json_normalize::create_1_arg(THD *thd, Item *arg1) } +Create_func_json_equals Create_func_json_equals::s_singleton; + +Item* +Create_func_json_equals::create_2_arg(THD *thd, Item *arg1, Item *arg2) +{ + status_var_increment(thd->status_var.feature_json); + return new (thd->mem_root) Item_func_json_equals(thd, arg1, arg2); +} + + Create_func_json_exists Create_func_json_exists::s_singleton; Item* @@ -5574,6 +5597,7 @@ Native_func_registry func_array[] = { { STRING_WITH_LEN("JSON_CONTAINS_PATH") }, BUILDER(Create_func_json_contains_path)}, { { STRING_WITH_LEN("JSON_DEPTH") }, BUILDER(Create_func_json_depth)}, { { STRING_WITH_LEN("JSON_DETAILED") }, BUILDER(Create_func_json_detailed)}, + { { STRING_WITH_LEN("JSON_EQUALS") }, BUILDER(Create_func_json_equals)}, { { STRING_WITH_LEN("JSON_EXISTS") }, BUILDER(Create_func_json_exists)}, { { STRING_WITH_LEN("JSON_EXTRACT") }, BUILDER(Create_func_json_extract)}, { { STRING_WITH_LEN("JSON_INSERT") }, BUILDER(Create_func_json_insert)}, diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 32043b8f6a7..2fd729ba469 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -393,6 +393,66 @@ longlong Item_func_json_valid::val_int() } +bool Item_func_json_equals::fix_length_and_dec() +{ + if (Item_bool_func::fix_length_and_dec()) + return TRUE; + set_maybe_null(); + return FALSE; +} + + +longlong Item_func_json_equals::val_int() +{ + longlong result= 0; + + String a_tmp, b_tmp; + + String *a= args[0]->val_json(&a_tmp); + String *b= args[1]->val_json(&b_tmp); + + DYNAMIC_STRING a_res; + if (init_dynamic_string(&a_res, NULL, 0, 0)) + { + null_value= 1; + return 1; + } + + DYNAMIC_STRING b_res; + if (init_dynamic_string(&b_res, NULL, 0, 0)) + { + dynstr_free(&a_res); + null_value= 1; + return 1; + } + + if ((null_value= args[0]->null_value || args[1]->null_value)) + { + null_value= 1; + goto end; + } + + if (json_normalize(&a_res, a->c_ptr(), a->length(), a->charset())) + { + null_value= 1; + goto end; + } + + if (json_normalize(&b_res, b->c_ptr(), b->length(), b->charset())) + { + null_value= 1; + goto end; + } + + result= strcmp(a_res.str, b_res.str) ? 0 : 1; + +end: + dynstr_free(&b_res); + dynstr_free(&a_res); + return result; +} + + bool Item_func_json_exists::fix_length_and_dec() { if (Item_bool_func::fix_length_and_dec()) diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 04d06a0ebf7..518a98d95df 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -107,6 +107,23 @@ public: }; +class Item_func_json_equals: public Item_bool_func +{ +public: + Item_func_json_equals(THD *thd, Item *a, Item *b): + Item_bool_func(thd, a, b) {} + LEX_CSTRING func_name_cstring() const override + { + static LEX_CSTRING name= {STRING_WITH_LEN("json_equals") }; + return name; + } + bool fix_length_and_dec() override; + Item *get_copy(THD *thd) override + { return get_item_copy<Item_func_json_equals>(thd, this); } + longlong val_int() override; +}; + + class Item_func_json_exists: public Item_bool_func { protected: |