feat: add json data type (#4619)

* feat: add json type and vector

* fix: allow to create and insert json data

* feat: udf to query json as string

* refactor: remove JsonbValue and JsonVector

* feat: show json value as strings

* chore: make ci happy

* test: adunit test and sqlness test

* refactor: use binary as grpc value of json

* fix: use non-preserve-order jsonb

* test: revert changed test

* refactor: change udf get_by_path to jq

* chore: make ci happy

* fix: distinguish binary and json in proto

* chore: delete udf for future pr

* refactor: remove Value(Json)

* chore: follow review comments

* test: some tests and checks

* test: fix unit tests

* chore: follow review comments

* chore: corresponding changes to proto

* fix: change grpc and pgsql server behavior alongside with sqlness/crud tests

* chore: follow review comments

* feat: udf of conversions between json and strings, used for grpc server

* refactor: rename to_string to json_to_string

* test: add more sqlness test for json

* chore: thanks for review :)

* Apply suggestions from code review

---------

Co-authored-by: Weny Xu <wenymedia@gmail.com>
This commit is contained in:
Yohan Wal
2024-09-09 11:41:36 +00:00
committed by GitHub
co-authored by Weny Xu
parent dc89944570
commit 04e7dd6fd5
30 changed files with 1076 additions and 61 deletions
@@ -0,0 +1,156 @@
CREATE TABLE jsons (j JSON, t timestamp time index);
Affected Rows: 0
--Insert valid json strings--
INSERT INTO jsons VALUES('[null]', 0),
('[true]', 1),
('[false]', 2),
('[0]', 3),
('["foo"]', 4),
('[]', 5),
('{}', 6),
('[0,1]', 7),
('{"foo":"bar"}', 8),
('{"a":null,"foo":"bar"}', 9),
('[-1]', 10),
('{"entities": {
"description": {
"urls": [
{
"url": "http://t.co/QMLJeFmfMT",
"expanded_url": "http://www.pixiv.net/member.php?id=4776",
"display_url": "pixiv.net/member.php?id=…",
"indices": [
58,
80
]
},
{
"url": "http://t.co/LU8T7vmU3h",
"expanded_url": "http://ask.fm/KATANA77",
"display_url": "ask.fm/KATANA77",
"indices": [
95,
117
]
}
]
}
}}', 11);
Affected Rows: 12
INSERT INTO jsons VALUES(to_json('[null]'), 12),
(to_json('[true]'), 13),
(to_json('[false]'), 14),
(to_json('[0]'), 15),
(to_json('["foo"]'), 16),
(to_json('[]'), 17),
(to_json('{}'), 18),
(to_json('[0,1]'), 19),
(to_json('{"foo":"bar"}'), 20),
(to_json('{"a":null,"foo":"bar"}'), 21),
(to_json('[-1]'), 22),
(to_json('[-2147483648]'), 23),
(to_json('{"entities": {
"description": {
"urls": [
{
"url": "http://t.co/QMLJeFmfMT",
"expanded_url": "http://www.pixiv.net/member.php?id=4776",
"display_url": "pixiv.net/member.php?id=…",
"indices": [
58,
80
]
},
{
"url": "http://t.co/LU8T7vmU3h",
"expanded_url": "http://ask.fm/KATANA77",
"display_url": "ask.fm/KATANA77",
"indices": [
95,
117
]
}
]
}
}}'), 24);
Affected Rows: 13
SELECT json_to_string(j), t FROM jsons;
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+
| json_to_string(jsons.j) | t |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+
| [null] | 1970-01-01T00:00:00 |
| [true] | 1970-01-01T00:00:00.001 |
| [false] | 1970-01-01T00:00:00.002 |
| [0] | 1970-01-01T00:00:00.003 |
| ["foo"] | 1970-01-01T00:00:00.004 |
| [] | 1970-01-01T00:00:00.005 |
| {} | 1970-01-01T00:00:00.006 |
| [0,1] | 1970-01-01T00:00:00.007 |
| {"foo":"bar"} | 1970-01-01T00:00:00.008 |
| {"a":null,"foo":"bar"} | 1970-01-01T00:00:00.009 |
| [-1] | 1970-01-01T00:00:00.010 |
| {"entities":{"description":{"urls":[{"display_url":"pixiv.net/member.php?id=…","expanded_url":"http://www.pixiv.net/member.php?id=4776","indices":[58,80],"url":"http://t.co/QMLJeFmfMT"},{"display_url":"ask.fm/KATANA77","expanded_url":"http://ask.fm/KATANA77","indices":[95,117],"url":"http://t.co/LU8T7vmU3h"}]}}} | 1970-01-01T00:00:00.011 |
| [null] | 1970-01-01T00:00:00.012 |
| [true] | 1970-01-01T00:00:00.013 |
| [false] | 1970-01-01T00:00:00.014 |
| [0] | 1970-01-01T00:00:00.015 |
| ["foo"] | 1970-01-01T00:00:00.016 |
| [] | 1970-01-01T00:00:00.017 |
| {} | 1970-01-01T00:00:00.018 |
| [0,1] | 1970-01-01T00:00:00.019 |
| {"foo":"bar"} | 1970-01-01T00:00:00.020 |
| {"a":null,"foo":"bar"} | 1970-01-01T00:00:00.021 |
| [-1] | 1970-01-01T00:00:00.022 |
| [-2147483648] | 1970-01-01T00:00:00.023 |
| {"entities":{"description":{"urls":[{"display_url":"pixiv.net/member.php?id=…","expanded_url":"http://www.pixiv.net/member.php?id=4776","indices":[58,80],"url":"http://t.co/QMLJeFmfMT"},{"display_url":"ask.fm/KATANA77","expanded_url":"http://ask.fm/KATANA77","indices":[95,117],"url":"http://t.co/LU8T7vmU3h"}]}}} | 1970-01-01T00:00:00.024 |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------+
--Insert invalid json strings--
DELETE FROM jsons;
Affected Rows: 25
INSERT INTO jsons VALUES(to_json('{"a":1, "b":2, "c":3'), 4);
Error: 3001(EngineExecuteQuery), DataFusion error: Invalid function args: Cannot convert the string to json, have: {"a":1, "b":2, "c":3
INSERT INTO jsons VALUES(to_json('Morning my friends, have a nice day :)'), 5);
Error: 3001(EngineExecuteQuery), DataFusion error: Invalid function args: Cannot convert the string to json, have: Morning my friends, have a nice day :)
SELECT json_to_string(j), t FROM jsons;
++
++
CREATE TABLE json_empty (j JSON, t timestamp time index);
Affected Rows: 0
INSERT INTO json_empty VALUES(NULL, 2);
Affected Rows: 1
SELECT json_to_string(j), t FROM json_empty;
+------------------------------+-------------------------+
| json_to_string(json_empty.j) | t |
+------------------------------+-------------------------+
| | 1970-01-01T00:00:00.002 |
+------------------------------+-------------------------+
drop table jsons;
Affected Rows: 0
drop table json_empty;
Affected Rows: 0
@@ -0,0 +1,96 @@
CREATE TABLE jsons (j JSON, t timestamp time index);
--Insert valid json strings--
INSERT INTO jsons VALUES('[null]', 0),
('[true]', 1),
('[false]', 2),
('[0]', 3),
('["foo"]', 4),
('[]', 5),
('{}', 6),
('[0,1]', 7),
('{"foo":"bar"}', 8),
('{"a":null,"foo":"bar"}', 9),
('[-1]', 10),
('{"entities": {
"description": {
"urls": [
{
"url": "http://t.co/QMLJeFmfMT",
"expanded_url": "http://www.pixiv.net/member.php?id=4776",
"display_url": "pixiv.net/member.php?id=…",
"indices": [
58,
80
]
},
{
"url": "http://t.co/LU8T7vmU3h",
"expanded_url": "http://ask.fm/KATANA77",
"display_url": "ask.fm/KATANA77",
"indices": [
95,
117
]
}
]
}
}}', 11);
INSERT INTO jsons VALUES(to_json('[null]'), 12),
(to_json('[true]'), 13),
(to_json('[false]'), 14),
(to_json('[0]'), 15),
(to_json('["foo"]'), 16),
(to_json('[]'), 17),
(to_json('{}'), 18),
(to_json('[0,1]'), 19),
(to_json('{"foo":"bar"}'), 20),
(to_json('{"a":null,"foo":"bar"}'), 21),
(to_json('[-1]'), 22),
(to_json('[-2147483648]'), 23),
(to_json('{"entities": {
"description": {
"urls": [
{
"url": "http://t.co/QMLJeFmfMT",
"expanded_url": "http://www.pixiv.net/member.php?id=4776",
"display_url": "pixiv.net/member.php?id=…",
"indices": [
58,
80
]
},
{
"url": "http://t.co/LU8T7vmU3h",
"expanded_url": "http://ask.fm/KATANA77",
"display_url": "ask.fm/KATANA77",
"indices": [
95,
117
]
}
]
}
}}'), 24);
SELECT json_to_string(j), t FROM jsons;
--Insert invalid json strings--
DELETE FROM jsons;
INSERT INTO jsons VALUES(to_json('{"a":1, "b":2, "c":3'), 4);
INSERT INTO jsons VALUES(to_json('Morning my friends, have a nice day :)'), 5);
SELECT json_to_string(j), t FROM jsons;
CREATE TABLE json_empty (j JSON, t timestamp time index);
INSERT INTO json_empty VALUES(NULL, 2);
SELECT json_to_string(j), t FROM json_empty;
drop table jsons;
drop table json_empty;