Skip to content
Permalink
Browse files
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.
  • Loading branch information
Alexey Botchkov committed Jun 18, 2018
1 parent eb77f8c commit 5ba6cee
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
@@ -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;

0 comments on commit 5ba6cee

Please sign in to comment.