Commit 5ba6cee0 authored by Alexey Botchkov's avatar Alexey Botchkov

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.
parent eb77f8cf
......@@ -742,3 +742,8 @@ json_extract('{"test":8.437e-5}','$.test')
select json_value('{"b":true}','$.b')=1;
json_value('{"b":true}','$.b')=1
1
CREATE TABLE t1 (c VARCHAR(8));
INSERT INTO t1 VALUES ('foo'),('bar');
SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*'));
c
DROP TABLE t1;
......@@ -404,4 +404,12 @@ select json_extract('{"test":8.437e-5}','$.test');
#
select json_value('{"b":true}','$.b')=1;
#
# MDEV-16209 JSON_EXTRACT in query crashes server.
#
CREATE TABLE t1 (c VARCHAR(8));
INSERT INTO t1 VALUES ('foo'),('bar');
SELECT * FROM t1 WHERE c IN (JSON_EXTRACT('{"a":"b"}', '$.*'));
DROP TABLE t1;
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment