mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -648,3 +648,18 @@ NULL
|
||||
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' );
|
||||
JSON_EXTRACT( '{"foo":"bar"}', '$[*]' )
|
||||
NULL
|
||||
select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value';
|
||||
JSON_EXTRACT('{"name":"value"}', '$.name') = 'value'
|
||||
1
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true;
|
||||
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true
|
||||
1
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
|
||||
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false
|
||||
0
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
|
||||
JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1
|
||||
1
|
||||
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
|
||||
JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"')
|
||||
"\u00f6"
|
||||
|
@ -302,3 +302,13 @@ DROP TABLE t1;
|
||||
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*].*' );
|
||||
SELECT JSON_EXTRACT( '{"foo":"bar"}', '$[*]' );
|
||||
|
||||
#
|
||||
# MDEV-12604 Comparison of JSON_EXTRACT result differs with Mysql.
|
||||
#
|
||||
|
||||
select JSON_EXTRACT('{"name":"value"}', '$.name') = 'value';
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = true;
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = false;
|
||||
select JSON_EXTRACT('{\"asdf\":true}', "$.\"asdf\"") = 1;
|
||||
select JSON_EXTRACT('{\"input1\":\"\\u00f6\"}', '$.\"input1\"');
|
||||
|
||||
|
@ -670,6 +670,15 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
|
||||
&Arg_comparator::compare_datetime;
|
||||
}
|
||||
|
||||
if ((*a)->is_json_type() ^ (*b)->is_json_type())
|
||||
{
|
||||
Item **j_item= (*a)->is_json_type() ? a : b;
|
||||
Item *uf= new(thd->mem_root) Item_func_json_unquote(thd, *j_item);
|
||||
if (!uf || uf->fix_fields(thd, &uf))
|
||||
return 1;
|
||||
*j_item= uf;
|
||||
}
|
||||
|
||||
a= cache_converted_constant(thd, a, &a_cache, m_compare_type);
|
||||
b= cache_converted_constant(thd, b, &b_cache, m_compare_type);
|
||||
return set_compare_func(owner_arg, m_compare_type);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -127,12 +127,14 @@ class Item_func_json_unquote: public Item_str_func
|
||||
{
|
||||
protected:
|
||||
String tmp_s;
|
||||
|
||||
String *read_json(json_engine_t *je);
|
||||
public:
|
||||
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {}
|
||||
const char *func_name() const { return "json_unquote"; }
|
||||
void fix_length_and_dec();
|
||||
String *val_str(String *);
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_json_unquote>(thd, mem_root, this); }
|
||||
};
|
||||
|
@ -253,7 +253,7 @@ static int read_4_hexdigits(json_string_t *s, uchar *dest)
|
||||
if ((c_len= json_next_char(s)) <= 0)
|
||||
return s->error= json_eos(s) ? JE_EOS : JE_BAD_CHR;
|
||||
|
||||
if (s->c_next >= 128 || (t= json_instr_chr_map[s->c_next]) >= S_F)
|
||||
if (s->c_next >= 128 || (t= json_instr_chr_map[s->c_next]) > S_F)
|
||||
return s->error= JE_SYN;
|
||||
|
||||
s->c_str+= c_len;
|
||||
|
Reference in New Issue
Block a user