diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2017-08-08 10:35:26 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2017-08-08 10:35:26 +0400 |
commit | bb71d9abf26aa5a0f8bb703d4541e3c064eed003 (patch) | |
tree | bf38c69ddd9ae0dd09301584dd42a01361fa624e /sql/item_jsonfunc.cc | |
parent | 86e0a73eaa166f752d62b31e96925e29c4fe0c8c (diff) | |
download | mariadb-git-bb71d9abf26aa5a0f8bb703d4541e3c064eed003.tar.gz |
MDEV-12604 Comparison of JSON_EXTRACT result differs with Mysql.
Comparison fixed to take the actual type of JSON value into
account. Bug in escaping handling fixed.
Diffstat (limited to 'sql/item_jsonfunc.cc')
-rw-r--r-- | sql/item_jsonfunc.cc | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index c7639bc2513..3f001771e7c 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -587,24 +587,40 @@ void Item_func_json_unquote::fix_length_and_dec() } -String *Item_func_json_unquote::val_str(String *str) +String *Item_func_json_unquote::read_json(json_engine_t *je) { String *js= args[0]->val_json(&tmp_s); - json_engine_t je; - int c_len; if ((null_value= args[0]->null_value)) - return NULL; + return 0; - json_scan_start(&je, js->charset(),(const uchar *) js->ptr(), + json_scan_start(je, js->charset(),(const uchar *) js->ptr(), (const uchar *) js->ptr() + js->length()); - je.value_type= (enum json_value_types) -1; /* To report errors right. */ + je->value_type= (enum json_value_types) -1; /* To report errors right. */ - if (json_read_value(&je)) + if (json_read_value(je)) goto error; - if (je.value_type != JSON_VALUE_STRING) + return js; + +error: + if (je->value_type == JSON_VALUE_STRING) + report_json_error(js, je, 0); + return js; +} + + +String *Item_func_json_unquote::val_str(String *str) +{ + json_engine_t je; + int c_len; + String *js; + + if (!(js= read_json(&je))) + return NULL; + + if (je.s.error || je.value_type != JSON_VALUE_STRING) return js; str->length(0); @@ -621,13 +637,86 @@ String *Item_func_json_unquote::val_str(String *str) return str; error: - if (je.value_type == JSON_VALUE_STRING) - report_json_error(js, &je, 0); - /* We just return the argument's value in the case of error. */ + report_json_error(js, &je, 0); return js; } +double Item_func_json_unquote::val_real() +{ + json_engine_t je; + double d= 0.0; + String *js; + + if ((js= read_json(&je)) != NULL) + { + switch (je.value_type) + { + case JSON_VALUE_NUMBER: + { + char *end; + int err; + d= my_strntod(je.s.cs, (char *) je.value, je.value_len, &end, &err); + break; + } + case JSON_VALUE_TRUE: + d= 1.0; + break; + case JSON_VALUE_STRING: + { + char *end; + int err; + d= my_strntod(js->charset(), (char *) js->ptr(), js->length(), + &end, &err); + break; + } + default: + break; + }; + } + + return d; +} + + +longlong Item_func_json_unquote::val_int() +{ + json_engine_t je; + longlong i= 0; + String *js; + + if ((js= read_json(&je)) != NULL) + { + switch (je.value_type) + { + case JSON_VALUE_NUMBER: + { + char *end; + int err; + i= my_strntoll(je.s.cs, (char *) je.value, je.value_len, 10, + &end, &err); + break; + } + case JSON_VALUE_TRUE: + i= 1; + break; + case JSON_VALUE_STRING: + { + char *end; + int err; + i= my_strntoll(js->charset(), (char *) js->ptr(), js->length(), 10, + &end, &err); + break; + } + default: + break; + }; + } + + return i; +} + + static int alloc_tmp_paths(THD *thd, uint n_paths, json_path_with_flags **paths,String **tmp_paths) { |