Skip to content

Commit

Permalink
MDEV-25875 JSON_TABLE: extract document fragment into JSON column.
Browse files Browse the repository at this point in the history
treat values insertedn into JSON column as JSON.
  • Loading branch information
Alexey Botchkov committed Jun 16, 2021
1 parent 71964c7 commit fe0dc6b
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 15 deletions.
17 changes: 17 additions & 0 deletions mysql-test/suite/json/r/json_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,23 @@ converted original
Warnings:
Warning 1264 Out of range value for column 'converted' at row 2
Warning 1366 Incorrect integer value: 'foo' for column ``.`(temporary)`.`converted` at row 3
select * from
json_table('[{"color": "blue", "price": { "high": 10, "low": 5}},
{"color": "white", "price": "pretty low"},
{"color": "yellow", "price": 256.20},
{"color": "red", "price": { "high": 20, "low": 8}}]',
'$[*]' columns(color varchar(100) path '$.color',
price json path '$.price'
)
) as T;
color price
blue { "high": 10, "low": 5}
white "pretty low"
yellow 256.20
red { "high": 20, "low": 8}
select * from json_table('{"foo": null}', '$' columns( jscol json path '$.foo')) as T;
jscol
null
#
# End of 10.6 tests
#
28 changes: 14 additions & 14 deletions mysql-test/suite/json/r/json_table_mysql.result
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ id jpath jsn_path jexst
2 2 2 0
3 33 {"x":33} 1
4 0 0 0
5 66 NULL 0
5 66 [1,2] 0
select * from
json_table(
'[{"a":"3"},{"a":2},{"b":1},{"a":0.33},{"a":"asd"}]',
Expand All @@ -55,11 +55,11 @@ jsn_path json path '$.a' default '{"x":33}' on empty,
jexst int exists path '$.b')
) as tt;
id jpath_i jpath_r jsn_path jexst
1 3 3 3 0
1 3 3 "3" 0
2 2 2 2 0
3 33 33.3 {"x":33} 1
4 0 0.33 0.33 0
5 0 0 asd 0
5 0 0 "asd" 0
Warnings:
Warning 1366 Incorrect integer value: 'asd' for column ``.`(temporary)`.`jpath_i` at row 5
Warning 1366 Incorrect double value: 'asd' for column ``.`(temporary)`.`jpath_r` at row 5
Expand All @@ -78,7 +78,7 @@ id jpath jsn_path jexst
2 2 2 0
3 33 {"x":33} 1
4 0 0 0
5 66 NULL 0
5 66 [1,2] 0
select * from
json_table(
'[{"a":"3"},{"a":2},{"b":1},{"a":0}]',
Expand All @@ -88,7 +88,7 @@ json_path json path '$.a',
jexst int exists path '$.b')
) as tt;
id jpath json_path jexst
1 3 3 0
1 3 "3" 0
2 2 2 0
3 NULL NULL 1
4 0 0 0
Expand Down Expand Up @@ -315,24 +315,24 @@ id1 jpath jexst id2 id3 jpath_3 id4 jpath_4
1 3 0 2 1 a1 NULL NULL
1 3 0 2 2 a2 NULL NULL
1 3 0 3 1 c NULL NULL
1 3 0 NULL NULL NULL 1 NULL
1 3 0 NULL NULL NULL 2 NULL
1 3 0 NULL NULL NULL 3 NULL
1 3 0 NULL NULL NULL 1 {"ll":["b1","b2","b3"]}
1 3 0 NULL NULL NULL 2 {"ll": ["a1","a2"]}
1 3 0 NULL NULL NULL 3 {"ll":["c"]}
2 2 0 1 1 1 NULL NULL
2 2 0 1 2 11 NULL NULL
2 2 0 1 3 111 NULL NULL
2 2 0 2 1 2 NULL NULL
2 2 0 NULL NULL NULL 1 NULL
2 2 0 NULL NULL NULL 2 NULL
2 2 0 NULL NULL NULL 1 {"ll":[1,11,111]}
2 2 0 NULL NULL NULL 2 {"ll":[2]}
3 NULL 1 1 1 zzz NULL NULL
3 NULL 1 NULL NULL NULL 1 NULL
3 NULL 1 NULL NULL NULL 1 {"ll":["zzz"]}
4 0 0 1 1 0.1 NULL NULL
4 0 0 1 2 0.01 NULL NULL
4 0 0 2 1 0.02 NULL NULL
4 0 0 2 2 0.002 NULL NULL
4 0 0 2 3 0.0002 NULL NULL
4 0 0 NULL NULL NULL 1 NULL
4 0 0 NULL NULL NULL 2 NULL
4 0 0 NULL NULL NULL 1 {"ll":[0.1,0.01]}
4 0 0 NULL NULL NULL 2 {"ll":[0.02,0.002,0.0002]}
ord should be 1,1,1,2, which tells that first two values of 'l' are
from the same object, and next two are from different objects
SELECT *
Expand Down Expand Up @@ -604,7 +604,7 @@ SELECT * FROM JSON_TABLE('{"a":"1"}',
o FOR ORDINALITY)) AS jt
WHERE o = 1;
jpath o
1 1
"1" 1
#
# Bug#25427982: ASSERTION `DERIVED' FAILED IN SQL/TABLE.H
#
Expand Down
16 changes: 16 additions & 0 deletions mysql-test/suite/json/t/json_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ from
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS2,
json_table(JS1.size, '$' columns (size INT PATH '$.size')) as JS3 where 1;


create table t1 (json varchar(100) character set utf8);
insert into t1 values ('{"value":"АБВ"}');
create table tj1 as
Expand Down Expand Up @@ -814,6 +815,21 @@ select * from json_table('{"a":"foo", "b":1, "c":1000}', '$.*' columns(converted

select * from json_table('{"a":"foo", "b":1, "c":1000}', '$.*' columns(converted tinyint path '$', original text path '$')) as jt order by original;

#
# MDEV-25875 SON_TABLE: extract document fragment into JSON column.
#

select * from
json_table('[{"color": "blue", "price": { "high": 10, "low": 5}},
{"color": "white", "price": "pretty low"},
{"color": "yellow", "price": 256.20},
{"color": "red", "price": { "high": 20, "low": 8}}]',
'$[*]' columns(color varchar(100) path '$.color',
price json path '$.price'
)
) as T;

select * from json_table('{"foo": null}', '$' columns( jscol json path '$.foo')) as T;
--echo #
--echo # End of 10.6 tests
--echo #
37 changes: 36 additions & 1 deletion sql/json_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "sql_priv.h"
#include "sql_class.h" /* TMP_TABLE_PARAM */
#include "table.h"
#include "sql_type_json.h"
#include "item_jsonfunc.h"
#include "json_table.h"
#include "sql_show.h"
Expand Down Expand Up @@ -377,6 +378,30 @@ static void store_json_in_field(Field *f, const json_engine_t *je)
}


/*
Store the current JSON element pointed by je into field f, as a separate
JSON document.
*/

static int store_value_as_json_doc(Field *f, json_engine_t *je)
{
const uchar *from= je->value_begin;
const uchar *to;

if (json_value_scalar(je))
to= je->value_end;
else
{
int error;
if ((error= json_skip_level(je)))
return error;
to= je->s.c_str;
}
f->store((const char *) from, (uint32) (to - from), je->s.cs);
return 0;
}


bool Json_table_nested_path::check_error(const char *str)
{
if (m_engine.s.error)
Expand Down Expand Up @@ -541,7 +566,12 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
}
else
{
if (!(error= !json_value_scalar(&je)))
if (jc->m_format_json)
{
if (!(error= store_value_as_json_doc(*f, &je)))
error= er_handler.errors;
}
else if (!(error= !json_value_scalar(&je)))
{
store_json_in_field(*f, &je);
error= er_handler.errors;
Expand Down Expand Up @@ -868,6 +898,11 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path)
anctual content. Not sure though if we should.
*/
m_path.s.c_str= (const uchar *) path.str;

if (ctype == PATH)
m_format_json=
MY_TEST(m_field->type_handler() == &type_handler_json_longtext);

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions sql/json_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class Json_table_column : public Sql_alloc
};

enum_type m_column_type;
bool m_format_json;
json_path_t m_path;
On_response m_on_error;
On_response m_on_empty;
Expand Down

0 comments on commit fe0dc6b

Please sign in to comment.