Commit d26b9f67 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-11470 JSON_KEYS accepts arguments in invalid format.

        Now JSON functions return warnings if arguments are invalid.
parent 1b7a794b
...@@ -102,6 +102,7 @@ typedef struct st_json_path_t ...@@ -102,6 +102,7 @@ typedef struct st_json_path_t
json_path_step_t *last_step; /* Points to the last step. */ json_path_step_t *last_step; /* Points to the last step. */
int mode_strict; /* TRUE if the path specified as 'strict' */ int mode_strict; /* TRUE if the path specified as 'strict' */
enum json_path_step_types types_used; /* The '|' of all step's 'type'-s */
} json_path_t; } json_path_t;
......
...@@ -92,7 +92,9 @@ select json_contains('[1]', '[1]', '$', '$[0]'); ...@@ -92,7 +92,9 @@ select json_contains('[1]', '[1]', '$', '$[0]');
ERROR 42000: Incorrect parameter count in the call to native function 'json_contains' ERROR 42000: Incorrect parameter count in the call to native function 'json_contains'
select json_contains('', '', '$'); select json_contains('', '', '$');
json_contains('', '', '$') json_contains('', '', '$')
0 NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_contains'
select json_contains('null', 'null', '$'); select json_contains('null', 'null', '$');
json_contains('null', 'null', '$') json_contains('null', 'null', '$')
1 1
...@@ -276,6 +278,8 @@ ERROR 42000: Incorrect parameter count in the call to native function 'json_merg ...@@ -276,6 +278,8 @@ ERROR 42000: Incorrect parameter count in the call to native function 'json_merg
select json_merge('string', 123); select json_merge('string', 123);
json_merge('string', 123) json_merge('string', 123)
NULL NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_merge' at position 1
select json_merge('"string"', 123); select json_merge('"string"', 123);
json_merge('"string"', 123) json_merge('"string"', 123)
["string", 123] ["string", 123]
...@@ -294,6 +298,8 @@ NULL ...@@ -294,6 +298,8 @@ NULL
select json_merge('a','b'); select json_merge('a','b');
json_merge('a','b') json_merge('a','b')
NULL NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_merge' at position 1
select json_merge('{"a":"b"}','{"c":"d"}'); select json_merge('{"a":"b"}','{"c":"d"}');
json_merge('{"a":"b"}','{"c":"d"}') json_merge('{"a":"b"}','{"c":"d"}')
{"a":"b", "c":"d"} {"a":"b", "c":"d"}
...@@ -321,6 +327,11 @@ json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a") ...@@ -321,6 +327,11 @@ json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a")
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b"); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b");
json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b") json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b")
NULL NULL
select json_keys('foo');
json_keys('foo')
NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
select json_search(@j, 'one', 'abc'); select json_search(@j, 'one', 'abc');
json_search(@j, 'one', 'abc') json_search(@j, 'one', 'abc')
...@@ -385,6 +396,8 @@ json_depth('[[[1,2,3],"s"], {}, []]') ...@@ -385,6 +396,8 @@ json_depth('[[[1,2,3],"s"], {}, []]')
select json_length(''); select json_length('');
json_length('') json_length('')
NULL NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_length'
select json_length('{}'); select json_length('{}');
json_length('{}') json_length('{}')
0 0
......
...@@ -129,6 +129,7 @@ select json_type('123.12'); ...@@ -129,6 +129,7 @@ select json_type('123.12');
select json_keys('{"a":{"c":1, "d":2}, "b":2}'); select json_keys('{"a":{"c":1, "d":2}, "b":2}');
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a"); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a");
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b"); select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b");
select json_keys('foo');
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]'; SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
select json_search(@j, 'one', 'abc'); select json_search(@j, 'one', 'abc');
......
...@@ -113,12 +113,131 @@ static int st_append_escaped(String *s, const String *a) ...@@ -113,12 +113,131 @@ static int st_append_escaped(String *s, const String *a)
} }
#define report_json_error(js, je, n_param) \
report_json_error_ex(js, je, func_name(), n_param, \
Sql_condition::WARN_LEVEL_WARN)
static void report_json_error_ex(String *js, json_engine_t *je,
const char *fname, int n_param,
Sql_condition::enum_warning_level lv)
{
THD *thd= current_thd;
int position= (const char *) je->s.c_str - js->ptr();
uint code;
n_param++;
switch (je->s.error)
{
case JE_BAD_CHR:
code= ER_JSON_BAD_CHR;
break;
case JE_NOT_JSON_CHR:
code= ER_JSON_NOT_JSON_CHR;
break;
case JE_EOS:
code= ER_JSON_EOS;
break;
case JE_SYN:
case JE_STRING_CONST:
code= ER_JSON_SYNTAX;
break;
case JE_ESCAPING:
code= ER_JSON_ESCAPING;
break;
case JE_DEPTH:
code= ER_JSON_DEPTH;
push_warning_printf(thd, lv, code, ER_THD(thd, code), JSON_DEPTH_LIMIT,
n_param, fname, position);
return;
default:
return;
}
push_warning_printf(thd, lv, code, ER_THD(thd, code),
n_param, fname, position);
}
#define NO_WILDCARD_ALLOWED 1
#define SHOULD_END_WITH_ARRAY 2
#define report_path_error(js, je, n_param) \
report_path_error_ex(js, je, func_name(), n_param,\
Sql_condition::WARN_LEVEL_WARN)
static void report_path_error_ex(String *ps, json_path_t *p,
const char *fname, int n_param,
Sql_condition::enum_warning_level lv)
{
THD *thd= current_thd;
int position= (const char *) p->s.c_str - ps->ptr() + 1;
uint code;
n_param++;
switch (p->s.error)
{
case JE_BAD_CHR:
case JE_NOT_JSON_CHR:
case JE_SYN:
code= ER_JSON_PATH_SYNTAX;
break;
case JE_EOS:
code= ER_JSON_PATH_EOS;
break;
case JE_DEPTH:
code= ER_JSON_PATH_DEPTH;
push_warning_printf(thd, lv, code, ER_THD(thd, code),
JSON_DEPTH_LIMIT, n_param, fname, position);
return;
case NO_WILDCARD_ALLOWED:
code= ER_JSON_PATH_NO_WILDCARD;
break;
default:
return;
}
push_warning_printf(thd, lv, code, ER_THD(thd, code),
n_param, fname, position);
}
/*
Checks if the path has '.*' '[*]' or '**' constructions
and sets the NO_WILDCARD_ALLOWED error if the case.
*/
static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
const uchar *str, const uchar *end)
{
if (!json_path_setup(p, i_cs, str, end))
{
if ((p->types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0)
return 0;
p->s.error= NO_WILDCARD_ALLOWED;
}
return 1;
}
longlong Item_func_json_valid::val_int() longlong Item_func_json_valid::val_int()
{ {
String *js= args[0]->val_str(&tmp_value); String *js= args[0]->val_str(&tmp_value);
json_engine_t je; json_engine_t je;
if ((null_value= args[0]->null_value) || js == NULL) if ((null_value= args[0]->null_value))
return 0; return 0;
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(), json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
...@@ -339,6 +458,8 @@ String *Item_func_json_unquote::val_str(String *str) ...@@ -339,6 +458,8 @@ String *Item_func_json_unquote::val_str(String *str)
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()); (const uchar *) js->ptr() + js->length());
je.value_type= (enum json_value_types) -1; /* To report errors right. */
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto error;
...@@ -359,6 +480,8 @@ String *Item_func_json_unquote::val_str(String *str) ...@@ -359,6 +480,8 @@ String *Item_func_json_unquote::val_str(String *str)
return str; return str;
error: 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. */ /* We just return the argument's value in the case of error. */
return js; return js;
} }
...@@ -449,12 +572,12 @@ String *Item_func_json_extract::val_str(String *str) ...@@ -449,12 +572,12 @@ String *Item_func_json_extract::val_str(String *str)
if (s_p && if (s_p &&
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(), json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; goto return_null;
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto error; goto return_null;
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()); (const uchar *) js->ptr() + js->length());
...@@ -513,8 +636,7 @@ String *Item_func_json_extract::val_str(String *str) ...@@ -513,8 +636,7 @@ String *Item_func_json_extract::val_str(String *str)
if (first_value == NULL) if (first_value == NULL)
{ {
/* Nothing was found. */ /* Nothing was found. */
null_value= 1; goto return_null;
return 0;
} }
if (multiple_values_found ? if (multiple_values_found ?
...@@ -525,6 +647,8 @@ String *Item_func_json_extract::val_str(String *str) ...@@ -525,6 +647,8 @@ String *Item_func_json_extract::val_str(String *str)
return str; return str;
error: error:
report_json_error(js, &je, 0);
return_null:
/* TODO: launch error messages. */ /* TODO: launch error messages. */
null_value= 1; null_value= 1;
return 0; return 0;
...@@ -778,24 +902,35 @@ longlong Item_func_json_contains::val_int() ...@@ -778,24 +902,35 @@ longlong Item_func_json_contains::val_int()
{ {
String *s_p= args[2]->val_str(&tmp_path); String *s_p= args[2]->val_str(&tmp_path);
if (s_p && if (s_p &&
json_path_setup(&path.p,s_p->charset(),(const uchar *) s_p->ptr(), path_setup_nwc(&path.p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->end())) (const uchar *) s_p->end()))
goto error; {
report_path_error(s_p, &path.p, 2);
goto return_null;
}
path.parsed= path.constant; path.parsed= path.constant;
} }
if (args[2]->null_value) if (args[2]->null_value)
goto error; goto return_null;
path.cur_step= path.p.steps; path.cur_step= path.p.steps;
if (json_find_path(&je, &path.p, &path.cur_step, array_counters)) if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
{
if (je.s.error)
{
ve.s.error= 0;
goto error; goto error;
} }
return FALSE;
}
}
json_scan_start(&ve, val->charset(),(const uchar *) val->ptr(), json_scan_start(&ve, val->charset(),(const uchar *) val->ptr(),
(const uchar *) val->end()); (const uchar *) val->end());
if (json_read_value(&je) || json_read_value(&ve)) if (json_read_value(&je) || json_read_value(&ve))
return FALSE; goto error;
result= check_contains(&je, &ve); result= check_contains(&je, &ve);
if (je.s.error || ve.s.error) if (je.s.error || ve.s.error)
...@@ -804,6 +939,11 @@ longlong Item_func_json_contains::val_int() ...@@ -804,6 +939,11 @@ longlong Item_func_json_contains::val_int()
return result; return result;
error: error:
if (je.s.error)
report_json_error(js, &je, 0);
if (ve.s.error)
report_json_error(val, &ve, 1);
return_null:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -837,7 +977,7 @@ void Item_func_json_contains_path::cleanup() ...@@ -837,7 +977,7 @@ void Item_func_json_contains_path::cleanup()
} }
static int parse_one_or_all(Item *ooa_arg, static int parse_one_or_all(const Item_func *f, Item *ooa_arg,
bool *ooa_parsed, bool ooa_constant, bool *mode_one) bool *ooa_parsed, bool ooa_constant, bool *mode_one)
{ {
if (!*ooa_parsed) if (!*ooa_parsed)
...@@ -846,13 +986,21 @@ static int parse_one_or_all(Item *ooa_arg, ...@@ -846,13 +986,21 @@ static int parse_one_or_all(Item *ooa_arg,
String *res, tmp(buff, sizeof(buff), &my_charset_bin); String *res, tmp(buff, sizeof(buff), &my_charset_bin);
if ((res= ooa_arg->val_str(&tmp)) == NULL) if ((res= ooa_arg->val_str(&tmp)) == NULL)
return TRUE; return TRUE;
*mode_one=eq_ascii_string(res->charset(), "one", *mode_one=eq_ascii_string(res->charset(), "one",
res->ptr(), res->length()); res->ptr(), res->length());
if (!*mode_one) if (!*mode_one)
{ {
if (!eq_ascii_string(res->charset(), "all", res->ptr(), res->length())) if (!eq_ascii_string(res->charset(), "all", res->ptr(), res->length()))
{
THD *thd= current_thd;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_JSON_ONE_OR_ALL, ER_THD(thd, ER_JSON_ONE_OR_ALL),
f->func_name());
*mode_one= TRUE;
return TRUE; return TRUE;
} }
}
*ooa_parsed= ooa_constant; *ooa_parsed= ooa_constant;
} }
return FALSE; return FALSE;
...@@ -869,8 +1017,8 @@ longlong Item_func_json_contains_path::val_int() ...@@ -869,8 +1017,8 @@ longlong Item_func_json_contains_path::val_int()
if ((null_value= args[0]->null_value)) if ((null_value= args[0]->null_value))
return 0; return 0;
if (parse_one_or_all(args[1], &ooa_parsed, ooa_constant, &mode_one)) if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
goto error; goto return_null;
result= !mode_one; result= !mode_one;
for (n_arg=2; n_arg < arg_count; n_arg++) for (n_arg=2; n_arg < arg_count; n_arg++)
...@@ -881,14 +1029,17 @@ longlong Item_func_json_contains_path::val_int() ...@@ -881,14 +1029,17 @@ longlong Item_func_json_contains_path::val_int()
{ {
String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-2)); String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-2));
if (s_p && if (s_p &&
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(), path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; {
report_path_error(s_p, &c_path->p, n_arg-2);
goto return_null;
}
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto error; goto return_null;
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()); (const uchar *) js->ptr() + js->length());
...@@ -898,7 +1049,7 @@ longlong Item_func_json_contains_path::val_int() ...@@ -898,7 +1049,7 @@ longlong Item_func_json_contains_path::val_int()
{ {
/* Path wasn't found. */ /* Path wasn't found. */
if (je.s.error) if (je.s.error)
goto error; goto js_error;
if (!mode_one) if (!mode_one)
{ {
...@@ -916,7 +1067,9 @@ longlong Item_func_json_contains_path::val_int() ...@@ -916,7 +1067,9 @@ longlong Item_func_json_contains_path::val_int()
return result; return result;
error: js_error:
report_json_error(js, &je, 0);
return_null:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1014,7 +1167,7 @@ String *Item_func_json_array::val_str(String *str) ...@@ -1014,7 +1167,7 @@ String *Item_func_json_array::val_str(String *str)
str->length(0); str->length(0);
if (str->append("[", 1) || if (str->append("[", 1) ||
((arg_count > 0) && append_json_value(str, args[0],&tmp_val))) ((arg_count > 0) && append_json_value(str, args[0], &tmp_val)))
goto err_return; goto err_return;
for (n_arg=1; n_arg < arg_count; n_arg++) for (n_arg=1; n_arg < arg_count; n_arg++)
...@@ -1074,16 +1227,16 @@ String *Item_func_json_array_append::val_str(String *str) ...@@ -1074,16 +1227,16 @@ String *Item_func_json_array_append::val_str(String *str)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths+n_path); String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p && if (s_p &&
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(), path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; {
report_path_error(s_p, &c_path->p, n_arg);
goto return_null;
}
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
{ goto return_null;
null_value= 1;
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()); (const uchar *) js->ptr() + js->length());
...@@ -1093,33 +1246,33 @@ String *Item_func_json_array_append::val_str(String *str) ...@@ -1093,33 +1246,33 @@ String *Item_func_json_array_append::val_str(String *str)
if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
{ {
if (je.s.error) if (je.s.error)
goto error; goto js_error;
null_value= 1;
return 0; goto return_null;
} }
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
str->length(0); str->length(0);
str->set_charset(js->charset()); str->set_charset(js->charset());
if (str->reserve(js->length() + 8, 1024)) if (str->reserve(js->length() + 8, 1024))
goto error; /* Out of memory. */ goto return_null; /* Out of memory. */
if (je.value_type == JSON_VALUE_ARRAY) if (je.value_type == JSON_VALUE_ARRAY)
{ {
if (json_skip_level(&je)) if (json_skip_level(&je))
goto error; goto js_error;
ar_end= je.s.c_str - je.sav_c_len; ar_end= je.s.c_str - je.sav_c_len;
str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr()); str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr()); str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
str->append(", ", 2); str->append(", ", 2);
if (append_json_value(str, args[n_arg+1], &tmp_val)) if (append_json_value(str, args[n_arg+1], &tmp_val))
goto error; /* Out of memory. */ goto return_null; /* Out of memory. */
if (str->reserve(str_rest_len, 1024)) if (str->reserve(str_rest_len, 1024))
goto error; /* Out of memory. */ goto return_null; /* Out of memory. */
str->q_append((const char *) ar_end, str_rest_len); str->q_append((const char *) ar_end, str_rest_len);
} }
else else
...@@ -1133,7 +1286,7 @@ String *Item_func_json_array_append::val_str(String *str) ...@@ -1133,7 +1286,7 @@ String *Item_func_json_array_append::val_str(String *str)
if (je.value_type == JSON_VALUE_OBJECT) if (je.value_type == JSON_VALUE_OBJECT)
{ {
if (json_skip_level(&je)) if (json_skip_level(&je))
goto error; goto js_error;
c_to= je.s.c_str; c_to= je.s.c_str;
} }
else else
...@@ -1146,7 +1299,7 @@ String *Item_func_json_array_append::val_str(String *str) ...@@ -1146,7 +1299,7 @@ String *Item_func_json_array_append::val_str(String *str)
str->append("]", 1) || str->append("]", 1) ||
str->append((const char *) je.s.c_str, str->append((const char *) je.s.c_str,
js->end() - (const char *) je.s.c_str)) js->end() - (const char *) je.s.c_str))
goto error; goto return_null; /* Out of memory. */
} }
{ {
/* Swap str and js. */ /* Swap str and js. */
...@@ -1165,7 +1318,10 @@ String *Item_func_json_array_append::val_str(String *str) ...@@ -1165,7 +1318,10 @@ String *Item_func_json_array_append::val_str(String *str)
return js; return js;
error: js_error:
report_json_error(js, &je, 0);
return_null:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1193,16 +1349,23 @@ String *Item_func_json_array_insert::val_str(String *str) ...@@ -1193,16 +1349,23 @@ String *Item_func_json_array_insert::val_str(String *str)
{ {
String *s_p= args[n_arg]->val_str(tmp_paths+n_path); String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p && if (s_p &&
(json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(), (path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()) || (const uchar *) s_p->ptr() + s_p->length()) ||
c_path->p.last_step - 1 < c_path->p.steps || c_path->p.last_step - 1 < c_path->p.steps ||
c_path->p.last_step->type != JSON_PATH_ARRAY)) c_path->p.last_step->type != JSON_PATH_ARRAY))
goto error; {
if (c_path->p.s.error == 0)
c_path->p.s.error= SHOULD_END_WITH_ARRAY;
report_path_error(s_p, &c_path->p, n_arg);
goto return_null;
}
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
c_path->p.last_step--; c_path->p.last_step--;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto null_return; goto return_null;
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()); (const uchar *) js->ptr() + js->length());
...@@ -1212,19 +1375,19 @@ String *Item_func_json_array_insert::val_str(String *str) ...@@ -1212,19 +1375,19 @@ String *Item_func_json_array_insert::val_str(String *str)
if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
{ {
if (je.s.error) if (je.s.error)
goto error; goto js_error;
/* Can't find the array to insert. */ /* Can't find the array to insert. */
goto null_return; continue;
} }
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
if (je.value_type != JSON_VALUE_ARRAY) if (je.value_type != JSON_VALUE_ARRAY)
{ {
/* Must be an array. */ /* Must be an array. */
goto null_return; continue;
} }
item_pos= 0; item_pos= 0;
...@@ -1253,6 +1416,9 @@ String *Item_func_json_array_insert::val_str(String *str) ...@@ -1253,6 +1416,9 @@ String *Item_func_json_array_insert::val_str(String *str)
} }
} }
if (je.s.error)
goto js_error;
str->length(0); str->length(0);
str->set_charset(js->charset()); str->set_charset(js->charset());
if (!item_pos) if (!item_pos)
...@@ -1264,7 +1430,7 @@ String *Item_func_json_array_insert::val_str(String *str) ...@@ -1264,7 +1430,7 @@ String *Item_func_json_array_insert::val_str(String *str)
append_json_value(str, args[n_arg+1], &tmp_val) || append_json_value(str, args[n_arg+1], &tmp_val) ||
(je.state != JST_ARRAY_END && str->append(",", 1)) || (je.state != JST_ARRAY_END && str->append(",", 1)) ||
append_simple(str, item_pos, js->end() - item_pos)) append_simple(str, item_pos, js->end() - item_pos))
goto error; /* Out of memory. */ goto return_null; /* Out of memory. */
{ {
/* Swap str and js. */ /* Swap str and js. */
...@@ -1283,8 +1449,9 @@ String *Item_func_json_array_insert::val_str(String *str) ...@@ -1283,8 +1449,9 @@ String *Item_func_json_array_insert::val_str(String *str)
return js; return js;
null_return: js_error:
error: report_json_error(js, &je, 0);
return_null:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1327,17 +1494,17 @@ String *Item_func_json_merge::val_str(String *str) ...@@ -1327,17 +1494,17 @@ String *Item_func_json_merge::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
json_engine_t je1, je2; json_engine_t je1, je2;
String *js1= args[0]->val_str(&tmp_js1); String *js1= args[0]->val_str(&tmp_js1), *js2;
uint n_arg; uint n_arg;
if (args[0]->null_value) if (args[0]->null_value)
goto error_return; goto null_return;
for (n_arg=1; n_arg < arg_count; n_arg++) for (n_arg=1; n_arg < arg_count; n_arg++)
{ {
String *js2= args[n_arg]->val_str(&tmp_js2); js2= args[n_arg]->val_str(&tmp_js2);
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
goto error_return; goto null_return;
json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(), json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
(const uchar *) js1->ptr() + js1->length()); (const uchar *) js1->ptr() + js1->length());
...@@ -1394,6 +1561,11 @@ String *Item_func_json_merge::val_str(String *str) ...@@ -1394,6 +1561,11 @@ String *Item_func_json_merge::val_str(String *str)
return js1; return js1;
error_return: error_return:
if (je1.s.error)
report_json_error(js1, &je1, 0);
if (je2.s.error)
report_json_error(js2, &je2, n_arg);
null_return:
null_value= 1; null_value= 1;
return NULL; return NULL;
} }
...@@ -1418,13 +1590,12 @@ longlong Item_func_json_length::val_int() ...@@ -1418,13 +1590,12 @@ longlong Item_func_json_length::val_int()
length++; length++;
} while (json_scan_next(&je) == 0); } while (json_scan_next(&je) == 0);
if (je.s.error) if (!je.s.error)
{ return length - 1;
report_json_error(js, &je, 0);
null_value= 1; null_value= 1;
return 0; return 0;
}
return length - 1;
} }
...@@ -1470,13 +1641,12 @@ longlong Item_func_json_depth::val_int() ...@@ -1470,13 +1641,12 @@ longlong Item_func_json_depth::val_int()
} }
} while (json_scan_next(&je) == 0); } while (json_scan_next(&je) == 0);
if (je.s.error) if (!je.s.error)
{ return depth;
report_json_error(js, &je, 0);
null_value= 1; null_value= 1;
return 0; return 0;
}
return depth;
} }
...@@ -1530,6 +1700,7 @@ String *Item_func_json_type::val_str(String *str) ...@@ -1530,6 +1700,7 @@ String *Item_func_json_type::val_str(String *str)
return str; return str;
error: error:
report_json_error(js, &je, 0);
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1580,10 +1751,13 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1580,10 +1751,13 @@ String *Item_func_json_insert::val_str(String *str)
String *s_p= args[n_arg]->val_str(tmp_paths+n_path); String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p) if (s_p)
{ {
if (json_path_setup(&c_path->p,s_p->charset(), if (path_setup_nwc(&c_path->p,s_p->charset(),
(const uchar *) s_p->ptr(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; {
report_path_error(s_p, &c_path->p, n_arg);
goto return_null;
}
/* We search to the last step. */ /* We search to the last step. */
c_path->p.last_step--; c_path->p.last_step--;
...@@ -1591,10 +1765,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1591,10 +1765,7 @@ String *Item_func_json_insert::val_str(String *str)
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
{ goto return_null;
null_value= 1;
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()); (const uchar *) js->ptr() + js->length());
...@@ -1605,11 +1776,11 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1605,11 +1776,11 @@ String *Item_func_json_insert::val_str(String *str)
json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
{ {
if (je.s.error) if (je.s.error)
goto error; goto js_error;
} }
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
lp= c_path->p.last_step+1; lp= c_path->p.last_step+1;
if (lp->type & JSON_PATH_ARRAY) if (lp->type & JSON_PATH_ARRAY)
...@@ -1626,12 +1797,12 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1626,12 +1797,12 @@ String *Item_func_json_insert::val_str(String *str)
/* Wrap the value as an array. */ /* Wrap the value as an array. */
if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) || if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) ||
str->append("[", 1)) str->append("[", 1))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
if (je.value_type == JSON_VALUE_OBJECT) if (je.value_type == JSON_VALUE_OBJECT)
{ {
if (json_skip_level(&je)) if (json_skip_level(&je))
goto error; goto js_error;
} }
if (append_simple(str, v_from, je.s.c_str - v_from) || if (append_simple(str, v_from, je.s.c_str - v_from) ||
...@@ -1639,7 +1810,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1639,7 +1810,7 @@ String *Item_func_json_insert::val_str(String *str)
append_json_value(str, args[n_arg+1], &tmp_val) || append_json_value(str, args[n_arg+1], &tmp_val) ||
str->append("]", 1) || str->append("]", 1) ||
append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str)) append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
goto continue_point; goto continue_point;
} }
...@@ -1653,7 +1824,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1653,7 +1824,7 @@ String *Item_func_json_insert::val_str(String *str)
goto v_found; goto v_found;
n_item++; n_item++;
if (json_skip_array_item(&je)) if (json_skip_array_item(&je))
goto error; goto js_error;
break; break;
default: default:
break; break;
...@@ -1661,7 +1832,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1661,7 +1832,7 @@ String *Item_func_json_insert::val_str(String *str)
} }
if (je.s.error) if (je.s.error)
goto error; goto js_error;
if (!mode_insert) if (!mode_insert)
continue; continue;
...@@ -1672,7 +1843,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1672,7 +1843,7 @@ String *Item_func_json_insert::val_str(String *str)
str->append(", ", 2) || str->append(", ", 2) ||
append_json_value(str, args[n_arg+1], &tmp_val) || append_json_value(str, args[n_arg+1], &tmp_val) ||
append_simple(str, v_to, js->end() - v_to)) append_simple(str, v_to, js->end() - v_to))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
} }
else /*JSON_PATH_KEY*/ else /*JSON_PATH_KEY*/
{ {
...@@ -1688,7 +1859,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1688,7 +1859,7 @@ String *Item_func_json_insert::val_str(String *str)
if (json_key_matches(&je, &key_name)) if (json_key_matches(&je, &key_name))
goto v_found; goto v_found;
if (json_skip_key(&je)) if (json_skip_key(&je))
goto error; goto js_error;
break; break;
default: default:
break; break;
...@@ -1696,7 +1867,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1696,7 +1867,7 @@ String *Item_func_json_insert::val_str(String *str)
} }
if (je.s.error) if (je.s.error)
goto error; goto js_error;
if (!mode_insert) if (!mode_insert)
continue; continue;
...@@ -1709,7 +1880,7 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1709,7 +1880,7 @@ String *Item_func_json_insert::val_str(String *str)
str->append("\":", 2) || str->append("\":", 2) ||
append_json_value(str, args[n_arg+1], &tmp_val) || append_json_value(str, args[n_arg+1], &tmp_val) ||
append_simple(str, v_to, js->end() - v_to)) append_simple(str, v_to, js->end() - v_to))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
} }
goto continue_point; goto continue_point;
...@@ -1720,20 +1891,20 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1720,20 +1891,20 @@ String *Item_func_json_insert::val_str(String *str)
continue; continue;
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
v_to= (const char *) je.value_begin; v_to= (const char *) je.value_begin;
str->length(0); str->length(0);
if (!json_value_scalar(&je)) if (!json_value_scalar(&je))
{ {
if (json_skip_level(&je)) if (json_skip_level(&je))
goto error; goto js_error;
} }
if (append_simple(str, js->ptr(), v_to - js->ptr()) || if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
append_json_value(str, args[n_arg+1], &tmp_val) || append_json_value(str, args[n_arg+1], &tmp_val) ||
append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str)) append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
continue_point: continue_point:
{ {
/* Swap str and js. */ /* Swap str and js. */
...@@ -1752,7 +1923,9 @@ String *Item_func_json_insert::val_str(String *str) ...@@ -1752,7 +1923,9 @@ String *Item_func_json_insert::val_str(String *str)
return js; return js;
error: js_error:
report_json_error(js, &je, 0);
return_null:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1795,10 +1968,13 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1795,10 +1968,13 @@ String *Item_func_json_remove::val_str(String *str)
String *s_p= args[n_arg]->val_str(tmp_paths+n_path); String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
if (s_p) if (s_p)
{ {
if (json_path_setup(&c_path->p,s_p->charset(), if (path_setup_nwc(&c_path->p,s_p->charset(),
(const uchar *) s_p->ptr(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; {
report_path_error(s_p, &c_path->p, n_arg);
goto null_return;
}
/* We search to the last step. */ /* We search to the last step. */
c_path->p.last_step--; c_path->p.last_step--;
...@@ -1808,10 +1984,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1808,10 +1984,7 @@ String *Item_func_json_remove::val_str(String *str)
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
{ goto null_return;
null_value= 1;
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()); (const uchar *) js->ptr() + js->length());
...@@ -1821,11 +1994,11 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1821,11 +1994,11 @@ String *Item_func_json_remove::val_str(String *str)
if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
{ {
if (je.s.error) if (je.s.error)
goto error; goto js_error;
} }
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
lp= c_path->p.last_step+1; lp= c_path->p.last_step+1;
if (lp->type & JSON_PATH_ARRAY) if (lp->type & JSON_PATH_ARRAY)
...@@ -1846,7 +2019,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1846,7 +2019,7 @@ String *Item_func_json_remove::val_str(String *str)
} }
n_item++; n_item++;
if (json_skip_array_item(&je)) if (json_skip_array_item(&je))
goto error; goto js_error;
break; break;
default: default:
break; break;
...@@ -1854,7 +2027,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1854,7 +2027,7 @@ String *Item_func_json_remove::val_str(String *str)
} }
if (je.s.error) if (je.s.error)
goto error; goto js_error;
continue; continue;
} }
...@@ -1875,7 +2048,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1875,7 +2048,7 @@ String *Item_func_json_remove::val_str(String *str)
goto v_found; goto v_found;
if (json_skip_key(&je)) if (json_skip_key(&je))
goto error; goto js_error;
rem_start= (const char *) je.s.c_str; rem_start= (const char *) je.s.c_str;
n_item++; n_item++;
...@@ -1886,7 +2059,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1886,7 +2059,7 @@ String *Item_func_json_remove::val_str(String *str)
} }
if (je.s.error) if (je.s.error)
goto error; goto js_error;
continue; continue;
} }
...@@ -1894,7 +2067,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1894,7 +2067,7 @@ String *Item_func_json_remove::val_str(String *str)
v_found: v_found:
if (json_skip_key(&je) || json_scan_next(&je)) if (json_skip_key(&je) || json_scan_next(&je))
goto error; goto js_error;
rem_end= (je.state == JST_VALUE && n_item == 0) ? rem_end= (je.state == JST_VALUE && n_item == 0) ?
(const char *) je.s.c_str : (const char *) (je.s.c_str - je.sav_c_len); (const char *) je.s.c_str : (const char *) (je.s.c_str - je.sav_c_len);
...@@ -1903,7 +2076,7 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1903,7 +2076,7 @@ String *Item_func_json_remove::val_str(String *str)
if (append_simple(str, js->ptr(), rem_start - js->ptr()) || if (append_simple(str, js->ptr(), rem_start - js->ptr()) ||
append_simple(str, rem_end, js->end() - rem_end)) append_simple(str, rem_end, js->end() - rem_end))
goto error; /* Out of memory. */ goto js_error; /* Out of memory. */
{ {
/* Swap str and js. */ /* Swap str and js. */
...@@ -1922,8 +2095,9 @@ String *Item_func_json_remove::val_str(String *str) ...@@ -1922,8 +2095,9 @@ String *Item_func_json_remove::val_str(String *str)
return js; return js;
js_error:
report_json_error(js, &je, 0);
null_return: null_return:
error:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -1958,9 +2132,12 @@ String *Item_func_json_keys::val_str(String *str) ...@@ -1958,9 +2132,12 @@ String *Item_func_json_keys::val_str(String *str)
{ {
String *s_p= args[1]->val_str(&tmp_path); String *s_p= args[1]->val_str(&tmp_path);
if (s_p && if (s_p &&
json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(), path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto err_return; {
report_path_error(s_p, &path.p, 1);
goto null_return;
}
path.parsed= path.constant; path.parsed= path.constant;
} }
...@@ -2024,8 +2201,9 @@ String *Item_func_json_keys::val_str(String *str) ...@@ -2024,8 +2201,9 @@ String *Item_func_json_keys::val_str(String *str)
null_value= 0; null_value= 0;
return str; return str;
null_return:
err_return: err_return:
report_json_error(js, &je, 0);
null_return:
null_value= 1; null_value= 1;
return 0; return 0;
} }
...@@ -2173,10 +2351,7 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2173,10 +2351,7 @@ String *Item_func_json_search::val_str(String *str)
if (args[0]->null_value || args[2]->null_value) if (args[0]->null_value || args[2]->null_value)
goto null_return; goto null_return;
if (parse_one_or_all(args[1], &ooa_parsed, ooa_constant, &mode_one)) if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
goto error;
if (args[1]->null_value)
goto null_return; goto null_return;
n_path_found= 0; n_path_found= 0;
...@@ -2192,7 +2367,10 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2192,7 +2367,10 @@ String *Item_func_json_search::val_str(String *str)
if (s_p && if (s_p &&
json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(), json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length())) (const uchar *) s_p->ptr() + s_p->length()))
goto error; {
report_path_error(s_p, &c_path->p, n_arg);
goto null_return;
}
c_path->parsed= c_path->constant; c_path->parsed= c_path->constant;
} }
if (args[n_arg]->null_value) if (args[n_arg]->null_value)
...@@ -2215,12 +2393,12 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2215,12 +2393,12 @@ String *Item_func_json_search::val_str(String *str)
while (json_read_keyname_chr(&je) == 0) while (json_read_keyname_chr(&je) == 0)
p.last_step->key_end= je.s.c_str; p.last_step->key_end= je.s.c_str;
if (je.s.error) if (je.s.error)
goto error; goto js_error;
/* Now we have je.state == JST_VALUE, so let's handle it. */ /* Now we have je.state == JST_VALUE, so let's handle it. */
case JST_VALUE: case JST_VALUE:
if (json_read_value(&je)) if (json_read_value(&je))
goto error; goto js_error;
if (json_value_scalar(&je)) if (json_value_scalar(&je))
{ {
if ((arg_count < 5 || path_ok(paths, n_arg - 4, &p)) && if ((arg_count < 5 || path_ok(paths, n_arg - 4, &p)) &&
...@@ -2238,10 +2416,10 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2238,10 +2416,10 @@ String *Item_func_json_search::val_str(String *str)
{ {
if (str->append("[", 1) || if (str->append("[", 1) ||
append_json_path(str, &sav_path)) append_json_path(str, &sav_path))
goto error; goto js_error;
} }
if (str->append(", ", 2) || append_json_path(str, &p)) if (str->append(", ", 2) || append_json_path(str, &p))
goto error; goto js_error;
} }
if (mode_one) if (mode_one)
...@@ -2270,7 +2448,7 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2270,7 +2448,7 @@ String *Item_func_json_search::val_str(String *str)
} while (json_scan_next(&je) == 0); } while (json_scan_next(&je) == 0);
if (je.s.error) if (je.s.error)
goto error; goto js_error;
end: end:
if (n_path_found == 0) if (n_path_found == 0)
...@@ -2278,20 +2456,21 @@ String *Item_func_json_search::val_str(String *str) ...@@ -2278,20 +2456,21 @@ String *Item_func_json_search::val_str(String *str)
if (n_path_found == 1) if (n_path_found == 1)
{ {
if (append_json_path(str, &sav_path)) if (append_json_path(str, &sav_path))
goto error; goto js_error;
} }
else else
{ {
if (str->append("]", 1)) if (str->append("]", 1))
goto error; goto js_error;
} }
null_value= 0; null_value= 0;
return str; return str;
js_error:
report_json_error(js, &je, 0);
null_return: null_return:
error:
/* TODO: launch error messages. */ /* TODO: launch error messages. */
null_value= 1; null_value= 1;
return 0; return 0;
......
...@@ -7414,3 +7414,27 @@ ER_BINLOG_NON_SUPPORTED_BULK ...@@ -7414,3 +7414,27 @@ ER_BINLOG_NON_SUPPORTED_BULK
eng "Only row based replication supported for bulk operations" eng "Only row based replication supported for bulk operations"
ER_BINLOG_UNCOMPRESS_ERROR ER_BINLOG_UNCOMPRESS_ERROR
eng "Uncompress the compressed binlog failed" eng "Uncompress the compressed binlog failed"
ER_JSON_BAD_CHR
eng "Broken JSON string in argument %d to function '%s' at position %d"
ER_JSON_NOT_JSON_CHR
eng "Character disallowd in JSON in argument %d to function '%s' at position %d"
ER_JSON_EOS
eng "Unexpected end of JSON text in argument %d to function '%s'"
ER_JSON_SYNTAX
eng "Syntax error in JSON text in argument %d to function '%s' at position %d"
ER_JSON_ESCAPING
eng "Incorrect escaping in JSON text in argument %d to function '%s' at position %d"
ER_JSON_DEPTH
eng "Limit of %d on JSON nested strucures depth is reached in argument %d to function '%s' at position %d"
ER_JSON_PATH_EOS
eng "Unexpected end of JSON path in argument %d to function '%s'"
ER_JSON_PATH_SYNTAX
eng "Syntax error in JSON path in argument %d to function '%s' at position %d"
ER_JSON_PATH_DEPTH
eng "Limit of %d on JSON path depth is reached in argument %d to function '%s' at position %d"
ER_JSON_PATH_NO_WILDCARD
eng "Wildcards in JSON path not allowed in argument %d to function '%s'"
ER_JSON_PATH_ARRAY
eng "JSON path should end with an array identifier in argument %d to function '%s'"
ER_JSON_ONE_OR_ALL
eng "Argument 2 to function '%s' must be "one" or "all"."
...@@ -392,12 +392,12 @@ static int v_string(json_engine_t *j) ...@@ -392,12 +392,12 @@ static int v_string(json_engine_t *j)
static int read_strn(json_engine_t *j) static int read_strn(json_engine_t *j)
{ {
j->value= j->s.c_str; j->value= j->s.c_str;
j->value_type= JSON_VALUE_STRING;
if (skip_str_constant(j)) if (skip_str_constant(j))
return 1; return 1;
j->state= *j->stack_p; j->state= *j->stack_p;
j->value_type= JSON_VALUE_STRING;
j->value_len= (j->s.c_str - j->value) - 1; j->value_len= (j->s.c_str - j->value) - 1;
return 0; return 0;
} }
...@@ -556,9 +556,9 @@ static int skip_string_verbatim(json_string_t *s, const char *str) ...@@ -556,9 +556,9 @@ static int skip_string_verbatim(json_string_t *s, const char *str)
s->c_str+= c_len; s->c_str+= c_len;
continue; continue;
} }
return JE_SYN; return s->error= JE_SYN;
} }
return json_eos(s) ? JE_EOS : JE_BAD_CHR; return s->error= json_eos(s) ? JE_EOS : JE_BAD_CHR;
} }
return 0; return 0;
...@@ -1078,6 +1078,7 @@ int json_path_setup(json_path_t *p, ...@@ -1078,6 +1078,7 @@ int json_path_setup(json_path_t *p,
p->steps[0].type= JSON_PATH_ARRAY_WILD; p->steps[0].type= JSON_PATH_ARRAY_WILD;
p->last_step= p->steps; p->last_step= p->steps;
p->mode_strict= FALSE; p->mode_strict= FALSE;
p->types_used= JSON_PATH_KEY_NULL;
do do
{ {
...@@ -1109,6 +1110,7 @@ int json_path_setup(json_path_t *p, ...@@ -1109,6 +1110,7 @@ int json_path_setup(json_path_t *p,
if (p->last_step->type & JSON_PATH_DOUBLE_WILD) if (p->last_step->type & JSON_PATH_DOUBLE_WILD)
return p->s.error= JE_SYN; return p->s.error= JE_SYN;
p->last_step->type|= JSON_PATH_WILD; p->last_step->type|= JSON_PATH_WILD;
p->types_used|= JSON_PATH_WILD;
continue; continue;
case PS_INT: case PS_INT:
p->last_step->n_item*= 10; p->last_step->n_item*= 10;
...@@ -1122,7 +1124,7 @@ int json_path_setup(json_path_t *p, ...@@ -1122,7 +1124,7 @@ int json_path_setup(json_path_t *p,
p->last_step++; p->last_step++;
if (p->last_step - p->steps >= JSON_DEPTH_LIMIT) if (p->last_step - p->steps >= JSON_DEPTH_LIMIT)
return p->s.error= JE_DEPTH; return p->s.error= JE_DEPTH;
p->last_step->type= JSON_PATH_KEY | double_wildcard; p->types_used|= p->last_step->type= JSON_PATH_KEY | double_wildcard;
double_wildcard= JSON_PATH_KEY_NULL; double_wildcard= JSON_PATH_KEY_NULL;
p->last_step->key= p->s.c_str; p->last_step->key= p->s.c_str;
continue; continue;
...@@ -1134,7 +1136,7 @@ int json_path_setup(json_path_t *p, ...@@ -1134,7 +1136,7 @@ int json_path_setup(json_path_t *p,
p->last_step++; p->last_step++;
if (p->last_step - p->steps >= JSON_DEPTH_LIMIT) if (p->last_step - p->steps >= JSON_DEPTH_LIMIT)
return p->s.error= JE_DEPTH; return p->s.error= JE_DEPTH;
p->last_step->type= JSON_PATH_ARRAY | double_wildcard; p->types_used|= p->last_step->type= JSON_PATH_ARRAY | double_wildcard;
double_wildcard= JSON_PATH_KEY_NULL; double_wildcard= JSON_PATH_KEY_NULL;
p->last_step->n_item= 0; p->last_step->n_item= 0;
continue; continue;
......
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