mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-11439 No data type JSON, but CAST(something AS JSON) pretends to
work. json_detailed() fixed
This commit is contained in:
@@ -567,3 +567,25 @@ json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}')
|
|||||||
select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ;
|
select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ;
|
||||||
json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}')
|
json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}')
|
||||||
{"a": {"u": 12, "x": ["b", "c"], "r": [1, 2]}}
|
{"a": {"u": 12, "x": ["b", "c"], "r": [1, 2]}}
|
||||||
|
select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}')
|
||||||
|
{"a":1,"b":[1,2,3],"c":{"aa":"v1","bb":"v2"}}
|
||||||
|
select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}')
|
||||||
|
{"a": 1, "b": [1, 2, 3], "c": {"aa": "v1", "bb": "v2"}}
|
||||||
|
select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}')
|
||||||
|
{
|
||||||
|
"a": 1,
|
||||||
|
"b":
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"c":
|
||||||
|
{
|
||||||
|
"aa": "v1",
|
||||||
|
"bb": "v2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -234,3 +234,7 @@ select json_merge('{"a":"b"}', '{"a":"c"}') ;
|
|||||||
select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') ;
|
select json_merge('{"a":{"x":"b"}}', '{"a":"c"}') ;
|
||||||
select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') ;
|
select json_merge('{"a":{"u":12, "x":"b"}}', '{"a":{"x":"c"}}') ;
|
||||||
select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ;
|
select json_merge('{"a":{"u":12, "x":"b", "r":1}}', '{"a":{"x":"c", "r":2}}') ;
|
||||||
|
|
||||||
|
select json_compact('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
select json_loose('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
select json_detailed('{"a":1, "b":[1,2,3], "c":{"aa":"v1", "bb": "v2"}}');
|
||||||
|
@@ -1788,10 +1788,10 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Create_func_json_detailed : public Create_func_arg2
|
class Create_func_json_detailed: public Create_native_func
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
|
virtual Item *create_native(THD *thd, LEX_STRING name, List<Item> *item_list);
|
||||||
|
|
||||||
static Create_func_json_detailed s_singleton;
|
static Create_func_json_detailed s_singleton;
|
||||||
|
|
||||||
@@ -1801,7 +1801,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Create_func_json_type : public Create_func_arg1
|
class Create_func_json_type : public Create_func_arg1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -5046,9 +5045,25 @@ Create_func_json_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
|||||||
Create_func_json_detailed Create_func_json_detailed::s_singleton;
|
Create_func_json_detailed Create_func_json_detailed::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
Create_func_json_detailed::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
Create_func_json_detailed::create_native(THD *thd, LEX_STRING name,
|
||||||
|
List<Item> *item_list)
|
||||||
{
|
{
|
||||||
return new (thd->mem_root) Item_func_json_format(thd, arg1, arg2);
|
Item *func= NULL;
|
||||||
|
int arg_count= 0;
|
||||||
|
|
||||||
|
if (item_list != NULL)
|
||||||
|
arg_count= item_list->elements;
|
||||||
|
|
||||||
|
if (arg_count < 1 || arg_count > 2 /* json_doc, [path]...*/)
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
func= new (thd->mem_root) Item_func_json_format(thd, *item_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
return func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -113,8 +113,24 @@ static int st_append_escaped(String *s, const String *a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const int TAB_SIZE_LIMIT= 8;
|
||||||
|
static const char tab_arr[TAB_SIZE_LIMIT+1]= " ";
|
||||||
|
|
||||||
|
static int append_tab(String *js, int depth, int tab_size)
|
||||||
|
{
|
||||||
|
if (js->append("\n", 1))
|
||||||
|
return 1;
|
||||||
|
for (int i=0; i<depth; i++)
|
||||||
|
{
|
||||||
|
if (js->append(tab_arr, tab_size))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int json_nice(json_engine_t *je, String *nice_js,
|
static int json_nice(json_engine_t *je, String *nice_js,
|
||||||
Item_func_json_format::formats mode)
|
Item_func_json_format::formats mode, int tab_size=4)
|
||||||
{
|
{
|
||||||
int depth= 0;
|
int depth= 0;
|
||||||
const char *comma, *colon;
|
const char *comma, *colon;
|
||||||
@@ -122,19 +138,24 @@ static int json_nice(json_engine_t *je, String *nice_js,
|
|||||||
int first_value= 1;
|
int first_value= 1;
|
||||||
|
|
||||||
DBUG_ASSERT(je->s.cs == nice_js->charset());
|
DBUG_ASSERT(je->s.cs == nice_js->charset());
|
||||||
|
DBUG_ASSERT(mode != Item_func_json_format::DETAILED ||
|
||||||
|
(tab_size >= 0 && tab_size <= TAB_SIZE_LIMIT));
|
||||||
|
|
||||||
|
comma= ", ";
|
||||||
|
colon= "\": ";
|
||||||
if (mode == Item_func_json_format::LOOSE)
|
if (mode == Item_func_json_format::LOOSE)
|
||||||
{
|
{
|
||||||
comma= ", ";
|
|
||||||
comma_len= 2;
|
comma_len= 2;
|
||||||
colon= "\": ";
|
colon_len= 3;
|
||||||
|
}
|
||||||
|
else if (mode == Item_func_json_format::DETAILED)
|
||||||
|
{
|
||||||
|
comma_len= 1;
|
||||||
colon_len= 3;
|
colon_len= 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
comma= ",";
|
|
||||||
comma_len= 1;
|
comma_len= 1;
|
||||||
colon= "\":";
|
|
||||||
colon_len= 2;
|
colon_len= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,6 +179,10 @@ static int json_nice(json_engine_t *je, String *nice_js,
|
|||||||
if (!first_value)
|
if (!first_value)
|
||||||
nice_js->append(comma, comma_len);
|
nice_js->append(comma, comma_len);
|
||||||
|
|
||||||
|
if (mode == Item_func_json_format::DETAILED &&
|
||||||
|
append_tab(nice_js, depth, tab_size))
|
||||||
|
goto error;
|
||||||
|
|
||||||
nice_js->append("\"", 1);
|
nice_js->append("\"", 1);
|
||||||
append_simple(nice_js, key_start, key_end - key_start);
|
append_simple(nice_js, key_start, key_end - key_start);
|
||||||
nice_js->append(colon, colon_len);
|
nice_js->append(colon, colon_len);
|
||||||
@@ -170,6 +195,11 @@ static int json_nice(json_engine_t *je, String *nice_js,
|
|||||||
if (!first_value)
|
if (!first_value)
|
||||||
nice_js->append(comma, comma_len);
|
nice_js->append(comma, comma_len);
|
||||||
|
|
||||||
|
if (mode == Item_func_json_format::DETAILED &&
|
||||||
|
depth > 0 &&
|
||||||
|
append_tab(nice_js, depth, tab_size))
|
||||||
|
goto error;
|
||||||
|
|
||||||
handle_value:
|
handle_value:
|
||||||
if (json_read_value(je))
|
if (json_read_value(je))
|
||||||
goto error;
|
goto error;
|
||||||
@@ -183,6 +213,10 @@ handle_value:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (mode == Item_func_json_format::DETAILED &&
|
||||||
|
depth > 0 &&
|
||||||
|
append_tab(nice_js, depth, tab_size))
|
||||||
|
goto error;
|
||||||
nice_js->append((je->value_type == JSON_VALUE_OBJECT) ? "{" : "[", 1);
|
nice_js->append((je->value_type == JSON_VALUE_OBJECT) ? "{" : "[", 1);
|
||||||
first_value= 1;
|
first_value= 1;
|
||||||
depth++;
|
depth++;
|
||||||
@@ -193,6 +227,9 @@ handle_value:
|
|||||||
case JST_OBJ_END:
|
case JST_OBJ_END:
|
||||||
case JST_ARRAY_END:
|
case JST_ARRAY_END:
|
||||||
depth--;
|
depth--;
|
||||||
|
if (mode == Item_func_json_format::DETAILED &&
|
||||||
|
append_tab(nice_js, depth, tab_size))
|
||||||
|
goto error;
|
||||||
nice_js->append((je->state == JST_OBJ_END) ? "}": "]", 1);
|
nice_js->append((je->state == JST_OBJ_END) ? "}": "]", 1);
|
||||||
first_value= 0;
|
first_value= 0;
|
||||||
break;
|
break;
|
||||||
@@ -2941,15 +2978,35 @@ String *Item_func_json_format::val_str(String *str)
|
|||||||
{
|
{
|
||||||
String *js= args[0]->val_str(&tmp_js);
|
String *js= args[0]->val_str(&tmp_js);
|
||||||
json_engine_t je;
|
json_engine_t je;
|
||||||
|
int tab_size;
|
||||||
|
|
||||||
if ((null_value= args[0]->null_value))
|
if ((null_value= args[0]->null_value))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (fmt == DETAILED)
|
||||||
|
{
|
||||||
|
tab_size= 4;
|
||||||
|
if (arg_count > 1)
|
||||||
|
{
|
||||||
|
tab_size= args[1]->val_int();
|
||||||
|
if (args[1]->null_value)
|
||||||
|
{
|
||||||
|
null_value= 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tab_size < 0)
|
||||||
|
tab_size= 0;
|
||||||
|
else if (tab_size > TAB_SIZE_LIMIT)
|
||||||
|
tab_size= TAB_SIZE_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
||||||
str->length(0);
|
str->length(0);
|
||||||
str->set_charset(js->charset());
|
str->set_charset(js->charset());
|
||||||
if (json_nice(&je, str, fmt))
|
if (json_nice(&je, str, fmt, tab_size))
|
||||||
{
|
{
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
report_json_error(js, &je, 0);
|
report_json_error(js, &je, 0);
|
||||||
|
@@ -443,8 +443,9 @@ protected:
|
|||||||
public:
|
public:
|
||||||
Item_func_json_format(THD *thd, Item *js, formats format):
|
Item_func_json_format(THD *thd, Item *js, formats format):
|
||||||
Item_str_func(thd, js), fmt(format) {}
|
Item_str_func(thd, js), fmt(format) {}
|
||||||
Item_func_json_format(THD *thd, Item *js, Item *tabsize):
|
Item_func_json_format(THD *thd, List<Item> &list):
|
||||||
Item_str_func(thd, js, tabsize), fmt(DETAILED) {}
|
Item_str_func(thd, list), fmt(DETAILED) {}
|
||||||
|
|
||||||
const char *func_name() const;
|
const char *func_name() const;
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
|
Reference in New Issue
Block a user