mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge 10.2 into bb-10.2-ext
This commit is contained in:
@ -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)
|
||||
{
|
||||
@ -1397,6 +1486,8 @@ void Item_func_json_array::fix_length_and_dec()
|
||||
ulonglong char_length= 2;
|
||||
uint n_arg;
|
||||
|
||||
result_limit= 0;
|
||||
|
||||
if (arg_count == 0)
|
||||
{
|
||||
collation.set(&my_charset_utf8_general_ci);
|
||||
@ -1413,7 +1504,6 @@ void Item_func_json_array::fix_length_and_dec()
|
||||
|
||||
fix_char_length_ulonglong(char_length);
|
||||
tmp_val.set_charset(collation.collation);
|
||||
result_limit= 0;
|
||||
}
|
||||
|
||||
|
||||
@ -2692,6 +2782,41 @@ void Item_func_json_keys::fix_length_and_dec()
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
That function is for Item_func_json_keys::val_str exclusively.
|
||||
It utilizes the fact the resulting string is in specific format:
|
||||
["key1", "key2"...]
|
||||
*/
|
||||
static int check_key_in_list(String *res,
|
||||
const uchar *key, int key_len)
|
||||
{
|
||||
const uchar *c= (const uchar *) res->ptr() + 2; /* beginning '["' */
|
||||
const uchar *end= (const uchar *) res->end() - 1; /* ending '"' */
|
||||
|
||||
while (c < end)
|
||||
{
|
||||
int n_char;
|
||||
for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++)
|
||||
{
|
||||
if (c[n_char] != key[n_char])
|
||||
break;
|
||||
}
|
||||
if (c[n_char] == '"')
|
||||
{
|
||||
if (n_char == key_len)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (c[n_char] != '"')
|
||||
n_char++;
|
||||
}
|
||||
c+= n_char + 4; /* skip ', "' */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_json_keys::val_str(String *str)
|
||||
{
|
||||
json_engine_t je;
|
||||
@ -2748,6 +2873,7 @@ skip_search:
|
||||
while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
|
||||
{
|
||||
const uchar *key_start, *key_end;
|
||||
int key_len;
|
||||
|
||||
switch (je.state)
|
||||
{
|
||||
@ -2757,13 +2883,19 @@ skip_search:
|
||||
{
|
||||
key_end= je.s.c_str;
|
||||
} while (json_read_keyname_chr(&je) == 0);
|
||||
if (je.s.error ||
|
||||
(n_keys > 0 && str->append(", ", 2)) ||
|
||||
if (je.s.error)
|
||||
goto err_return;
|
||||
key_len= key_end - key_start;
|
||||
|
||||
if (!check_key_in_list(str, key_start, key_len))
|
||||
{
|
||||
if ((n_keys > 0 && str->append(", ", 2)) ||
|
||||
str->append("\"", 1) ||
|
||||
append_simple(str, key_start, key_end - key_start) ||
|
||||
append_simple(str, key_start, key_len) ||
|
||||
str->append("\"", 1))
|
||||
goto err_return;
|
||||
n_keys++;
|
||||
n_keys++;
|
||||
}
|
||||
break;
|
||||
case JST_OBJ_START:
|
||||
case JST_ARRAY_START:
|
||||
|
Reference in New Issue
Block a user