diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2018-06-18 23:00:34 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2018-06-18 23:00:34 +0400 |
commit | 5ba6cee01255186ea77a69f122d3a15c07f44f6d (patch) | |
tree | f5d22de417e0711b945a98176cbb05ba45b6cc36 /sql/item_jsonfunc.cc | |
parent | eb77f8cf8de44ecaa7155afa7f55ece73b2b0497 (diff) | |
download | mariadb-git-5ba6cee01255186ea77a69f122d3a15c07f44f6d.tar.gz |
MDEV-16209 JSON_EXTRACT in query crashes server.
The optimizer can create various item's over the original one,
so we can't count on the exact item's type inside the comparison.
Diffstat (limited to 'sql/item_jsonfunc.cc')
-rw-r--r-- | sql/item_jsonfunc.cc | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index c8cda66580c..8103aa906ff 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -3229,34 +3229,44 @@ String *Item_func_json_format::val_json(String *str) int Arg_comparator::compare_json_str_basic(Item *j, Item *s) { - String *res1,*res2; - json_value_types type; - char *value; - int value_len, c_len; - Item_func_json_extract *e= (Item_func_json_extract *) j; - - if ((res1= e->read_json(&value1, &type, &value, &value_len))) - { - if ((res2= s->val_str(&value2))) - { - if (type == JSON_VALUE_STRING) - { - if (value1.realloc_with_extra_if_needed(value_len) || - (c_len= json_unescape(value1.charset(), (uchar *) value, - (uchar *) value+value_len, - &my_charset_utf8_general_ci, - (uchar *) value1.ptr(), - (uchar *) (value1.ptr() + value_len))) < 0) - goto error; - value1.length(c_len); - res1= &value1; - } + String *js,*str; + int c_len; + json_engine_t je; - if (set_null) - owner->null_value= 0; - return sortcmp(res1, res2, compare_collation()); - } + if ((js= j->val_str(&value1))) + { + json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), + (const uchar *) js->ptr()+js->length()); + if (json_read_value(&je)) + goto error; + if (je.value_type == JSON_VALUE_STRING) + { + if (value2.realloc_with_extra_if_needed(je.value_len) || + (c_len= json_unescape(js->charset(), je.value, + je.value + je.value_len, + &my_charset_utf8_general_ci, + (uchar *) value2.ptr(), + (uchar *) (value2.ptr() + je.value_len))) < 0) + goto error; + + value2.length(c_len); + js= &value2; + str= &value1; + } + else + { + str= &value2; + } + + + if ((str= s->val_str(str))) + { + if (set_null) + owner->null_value= 0; + return sortcmp(js, str, compare_collation()); + } } + error: if (set_null) owner->null_value= 1; |