1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-10-31 18:30:33 +03:00

MDEV-32854: Make JSON_DEPTH_LIMIT unlimited

This patch is the columnstore-part of the task. Columnstore wanted to have
previous 32 depth, so this patch aims at keeping the compatibility.
This commit is contained in:
Rucha Deodhar
2025-05-22 15:42:12 +05:30
committed by Leonid Fedorov
parent 9a2ebebaf9
commit 9fe37d5919
50 changed files with 1047 additions and 952 deletions

View File

@@ -354,25 +354,25 @@ void FunctionColumn::unserialize(messageqcpp::ByteStream& b)
fFunctor = fDynamicFunctor = new Func_json_contains(); fFunctor = fDynamicFunctor = new Func_json_contains();
if (dynamic_cast<Func_json_array_append*>(fFunctor)) if (dynamic_cast<Func_json_array_append*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_array_append(); fFunctor = fDynamicFunctor = new Func_json_array_append(fFunctionParms);
if (dynamic_cast<Func_json_array_insert*>(fFunctor)) if (dynamic_cast<Func_json_array_insert*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_array_insert(); fFunctor = fDynamicFunctor = new Func_json_array_insert(fFunctionParms);
if (auto f = dynamic_cast<Func_json_insert*>(fFunctor)) if (auto f = dynamic_cast<Func_json_insert*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_insert(f->getMode()); fFunctor = fDynamicFunctor = new Func_json_insert(fFunctionParms, f->getMode());
if (dynamic_cast<Func_json_remove*>(fFunctor)) if (dynamic_cast<Func_json_remove*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_remove(); fFunctor = fDynamicFunctor = new Func_json_remove(fFunctionParms);
if (dynamic_cast<Func_json_contains_path*>(fFunctor)) if (dynamic_cast<Func_json_contains_path*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_contains_path(); fFunctor = fDynamicFunctor = new Func_json_contains_path(fFunctionParms);
if (dynamic_cast<Func_json_search*>(fFunctor)) if (dynamic_cast<Func_json_search*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_search(); fFunctor = fDynamicFunctor = new Func_json_search(fFunctionParms);
if (dynamic_cast<Func_json_extract*>(fFunctor)) if (dynamic_cast<Func_json_extract*>(fFunctor))
fFunctor = fDynamicFunctor = new Func_json_extract(); fFunctor = fDynamicFunctor = new Func_json_extract(fFunctionParms);
} }
bool FunctionColumn::operator==(const FunctionColumn& t) const bool FunctionColumn::operator==(const FunctionColumn& t) const

View File

@@ -5,35 +5,16 @@ USE json_array_append_db;
# Test of JSON_ARRAY_APPEND function. # Test of JSON_ARRAY_APPEND function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2);
t1 INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2);
VALUES INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1');
('[1,2,3]', '$[0]', 2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE);
('[1,2,3]', '$[0]', 1.2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false);
('[1,2,3]', '$[0]', 'key1'), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL);
('[1,2,3]', '$[0]', TRUE), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4);
('[1,2,3]', '$[0]', false), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape');
('[1,2,3]', '$[0]', NULL), INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.b', 4);
( INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.c', 'grape');
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.b',
4
),
(
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.c',
'grape'
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.b',
4
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.c',
'grape'
);
SELECT SELECT
a AS arrary, a AS arrary,
p AS path, p AS path,
@@ -54,10 +35,7 @@ arrary path value result
{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]} $.c grape {"a": "foo", "b": [1, 2, 3], "c": ["apple", "pear", "grape"]} {"a": "foo", "b": [1,2,3], "c": ["apple","pear"]} $.c grape {"a": "foo", "b": [1, 2, 3], "c": ["apple", "pear", "grape"]}
# NULL args # NULL args
CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('[1,2,3]');
t2
VALUES
('[1,2,3]');
SELECT SELECT
JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)),
JSON_ARRAY_APPEND(a, '$', NULL) JSON_ARRAY_APPEND(a, '$', NULL)
@@ -66,10 +44,7 @@ t2;
JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_APPEND(a, '$', NULL) JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_APPEND(a, '$', NULL)
NULL [1, 2, 3, null] NULL [1, 2, 3, null]
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$.b');
t2
VALUES
('$.b');
SELECT SELECT
JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)), JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)),
JSON_ARRAY_APPEND('[1,2,3]', a, NULL) JSON_ARRAY_APPEND('[1,2,3]', a, NULL)
@@ -78,10 +53,7 @@ t2;
JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)) JSON_ARRAY_APPEND('[1,2,3]', a, NULL) JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)) JSON_ARRAY_APPEND('[1,2,3]', a, NULL)
NULL NULL NULL NULL
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$**[0]');
t2
VALUES
('$**[0]');
error ER_INVALID_JSON_PATH_WILDCARD error ER_INVALID_JSON_PATH_WILDCARD
SELECT SELECT
JSON_ARRAY_APPEND(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6) JSON_ARRAY_APPEND(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6)

View File

@@ -5,35 +5,16 @@ USE json_array_insert_db;
# Test of JSON_ARRAY_INSERT function. # Test of JSON_ARRAY_INSERT function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2);
t1 INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2);
VALUES INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1');
('[1,2,3]', '$[0]', 2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE);
('[1,2,3]', '$[0]', 1.2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false);
('[1,2,3]', '$[0]', 'key1'), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL);
('[1,2,3]', '$[0]', TRUE), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4);
('[1,2,3]', '$[0]', false), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape');
('[1,2,3]', '$[0]', NULL), INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.b', 4);
( INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.c', 'grape');
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.b',
4
),
(
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.c',
'grape'
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.b',
4
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.c',
'grape'
);
SELECT SELECT
a AS arrary, a AS arrary,
p AS path, p AS path,
@@ -54,10 +35,7 @@ arrary path value result
{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]} $.c grape NULL {"a": "foo", "b": [1,2,3], "c": ["apple","pear"]} $.c grape NULL
# NULL args # NULL args
CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('[1,2,3]');
t2
VALUES
('[1,2,3]');
SELECT SELECT
JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)),
JSON_ARRAY_INSERT(a, '$', NULL) JSON_ARRAY_INSERT(a, '$', NULL)
@@ -66,10 +44,7 @@ t2;
JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_INSERT(a, '$', NULL) JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_INSERT(a, '$', NULL)
NULL NULL NULL NULL
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$.b');
t2
VALUES
('$.b');
SELECT SELECT
JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)), JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)),
JSON_ARRAY_INSERT('[1,2,3]', a, NULL) JSON_ARRAY_INSERT('[1,2,3]', a, NULL)
@@ -78,10 +53,7 @@ t2;
JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)) JSON_ARRAY_INSERT('[1,2,3]', a, NULL) JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)) JSON_ARRAY_INSERT('[1,2,3]', a, NULL)
NULL NULL NULL NULL
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$**[0]');
t2
VALUES
('$**[0]');
error ER_INVALID_JSON_PATH_WILDCARD error ER_INVALID_JSON_PATH_WILDCARD
SELECT SELECT
JSON_ARRAY_INSERT(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6) JSON_ARRAY_INSERT(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6)

View File

@@ -5,16 +5,13 @@ USE json_contains_db;
# Test of JSON_CONTAINS function. # Test of JSON_CONTAINS function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore; CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t1 VALUES ('{"k1":123, "k2":345}', '123', '$.k1');
t1 INSERT INTO t1 VALUES ('', '', '$');
VALUES INSERT INTO t1 VALUES ('null', 'null', '$');
('{"k1":123, "k2":345}', '123', '$.k1'), INSERT INTO t1 VALUES ('"10"', '"10"', '$');
('', '', '$'), INSERT INTO t1 VALUES ('"10"', '10', '$');
('null', 'null', '$'), INSERT INTO t1 VALUES ('10.1', '10', '$');
('"10"', '"10"', '$'), INSERT INTO t1 VALUES ('10.0', '10', '$');
('"10"', '10', '$'),
('10.1', '10', '$'),
('10.0', '10', '$');
SELECT SELECT
j AS json, j AS json,
v AS value, v AS value,
@@ -31,28 +28,22 @@ null null $ 1
10.1 10 $ 0 10.1 10 $ 0
10.0 10 $ 1 10.0 10 $ 1
CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore; CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t2 VALUES ('"you"', '"you"');
t2 INSERT INTO t2 VALUES ('"youth"', '"you"');
VALUES INSERT INTO t2 VALUES ('[1]', '1');
('"you"', '"you"'), INSERT INTO t2 VALUES ('[2, 1]', '1');
('"youth"', '"you"'), INSERT INTO t2 VALUES ('[2, [2, 3], 1]', '1');
('[1]', '1'), INSERT INTO t2 VALUES ('[4, [2, 3], 1]', '2');
('[2, 1]', '1'), INSERT INTO t2 VALUES ('[2, 1]', '[1, 2]');
('[2, [2, 3], 1]', '1'), INSERT INTO t2 VALUES ('[2, 1]', '[1, 0, 2]');
('[4, [2, 3], 1]', '2'), INSERT INTO t2 VALUES ('[2, 0, 3, 1]', '[1, 2]');
('[2, 1]', '[1, 2]'), INSERT INTO t2 VALUES ('{"b":[1,2], "a":1}', '{"a":1, "b":2}');
('[2, 1]', '[1, 0, 2]'), INSERT INTO t2 VALUES ('{"a":1}', '{}');
('[2, 0, 3, 1]', '[1, 2]'), INSERT INTO t2 VALUES ('[1, {"a":1}]', '{}');
('{"b":[1,2], "a":1}', '{"a":1, "b":2}'), INSERT INTO t2 VALUES ('[1, {"a":1}]', '{"a":1}');
('{"a":1}', '{}'), INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}]', '["foo","bar"]');
('[1, {"a":1}]', '{}'), INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]');
('[1, {"a":1}]', '{"a":1}'), INSERT INTO t2 VALUES ('[{"a":"b"},{"c":"d"}]', '{"c":"d"}');
('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'),
(
'[{"abc":"def", "def":"abc"}, "bar"]',
'["bar", {}]'
),
('[{"a":"b"},{"c":"d"}]', '{"c":"d"}');
SELECT SELECT
j AS json, j AS json,
v AS value, v AS value,

View File

@@ -5,16 +5,13 @@ USE json_contains_path_db;
# Test of JSON_CONTAINS_PATH function. # Test of JSON_CONTAINS_PATH function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
t1 INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]");
VALUES INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.ma");
('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"), INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1");
('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"), INSERT INTO t1 VALUES ('{ "a": true }', NULL, '$.a');
('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"), INSERT INTO t1 VALUES ('{ "a": true }', 'all', NULL);
('{"key1":1, "key2":[2,3]}', "one", "$.key1"), INSERT INTO t1 VALUES ('{"a":{"b":"c"}}', 'one', '$.a.*');
('{ "a": true }', NULL, '$.a'),
('{ "a": true }', 'all', NULL),
('{"a":{"b":"c"}}', 'one', '$.a.*');
SELECT SELECT
j AS json, j AS json,
r AS return_flag, r AS return_flag,
@@ -31,27 +28,9 @@ json return_flag path result
{ "a": true } all NULL NULL { "a": true } all NULL NULL
{"a":{"b":"c"}} one $.a.* 1 {"a":{"b":"c"}} one $.a.* 1
CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma");
t2 INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma");
VALUES INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2");
(
'{"key1":1, "key2":[2,3]}',
"one",
"$.key1",
"$.ma"
),
(
'{"key1":1, "key2":[2,3]}',
"aLl",
"$.key1",
"$.ma"
),
(
'{"key1":1, "key2":[2,3]}',
"aLl",
"$.key1",
"$.key2"
);
SELECT SELECT
j AS json, j AS json,
r AS return_flag, r AS return_flag,

View File

@@ -6,16 +6,12 @@ USE json_exists_db;
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Test case 0 # Test case 0
CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore;
SET SET @json = '{"key1":"xxxx", "key2":[1, 2, 3]}';
@json = '{"key1":"xxxx", "key2":[1, 2, 3]}'; INSERT INTO t1 VALUES (@json, '$.key1');
INSERT INTO INSERT INTO t1 VALUES (@json, '$.key1[0]');
t1 INSERT INTO t1 VALUES (@json, '$.key2');
VALUES INSERT INTO t1 VALUES (@json, '$.key2[1]');
(@json, '$.key1'), INSERT INTO t1 VALUES (@json, '$.key2[10]');
(@json, '$.key1[0]'),
(@json, '$.key2'),
(@json, '$.key2[1]'),
(@json, '$.key2[10]');
SELECT SELECT
j, j,
p, p,

View File

@@ -8,26 +8,22 @@ USE json_extract_db;
# Single path expression # Single path expression
CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE;
SET SET @json = '[1, "val2", [3.1, -4]]';
@json = '[1, "val2", [3.1, -4]]'; INSERT INTO t1 VALUES (@json, '$[0]');
INSERT INTO INSERT INTO t1 VALUES (@json, '$[1]');
t1 INSERT INTO t1 VALUES (@json, '$[2]');
VALUES INSERT INTO t1 VALUES (@json, '$[3]');
(@json, '$[0]'), INSERT INTO t1 VALUES (@json, '$[2][0]');
(@json, '$[1]'), INSERT INTO t1 VALUES (@json, '$[2][1]');
(@json, '$[2]'), INSERT INTO t1 VALUES (@json, '$[2][10]');
(@json, '$[3]'), INSERT INTO t1 VALUES (@json, '$');
(@json, '$[2][0]'), INSERT INTO t1 VALUES ('1', '$');
(@json, '$[2][1]'), INSERT INTO t1 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]');
(@json, '$[2][10]'), INSERT INTO t1 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1");
(@json, '$'), INSERT INTO t1 VALUES ('{"key0":true, "key1":"qwe"}', "$.key1");
('1', '$'), INSERT INTO t1 VALUES ('[10, 20, [30, 40]]', '$[2][*]');
('[10, 20, [30, 40], 1, 10]', '$[1]'), INSERT INTO t1 VALUES ('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]');
('{"key1":"asd", "key2":[2,3]}', "$.key1"), INSERT INTO t1 VALUES (json_object('foo', 'foobar'), '$');
('{"key0":true, "key1":"qwe"}', "$.key1"),
('[10, 20, [30, 40]]', '$[2][*]'),
('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'),
(json_object('foo', 'foobar'), '$');
SELECT SELECT
j, j,
p, p,
@@ -54,22 +50,11 @@ j p result
# Multiple path expression # Multiple path expression
CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY");
t2 INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2");
VALUES INSERT INTO t2 VALUES ('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2");
( INSERT INTO t2 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]');
'{"key1":"asd", "key2":[2,3]}', INSERT INTO t2 VALUES ('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a');
"$.keyX",
"$.keyY"
),
(
'{"key1":"asd", "key2":[2,3]}',
"$.key1",
"$.key2"
),
('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"),
('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'),
('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a');
SELECT SELECT
j, j,
p1, p1,

View File

@@ -5,34 +5,15 @@ USE json_insert_de;
# Test of JSON_INSERT|REPLACE|SET function. # Test of JSON_INSERT|REPLACE|SET function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word');
t1 INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3);
VALUES INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2);
( INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word');
'{"a":1, "b":{"c":1}, "d":[1, 2]}', INSERT INTO t1 VALUES ('1', '$[0]', 4);
'$.b.k1', INSERT INTO t1 VALUES ('[]', '$[0][0]', 100);
'word' INSERT INTO t1 VALUES ('1', '$[0][0]', 100);
), INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.a', 10);
('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3), INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.b', '[true, false]');
('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2),
(
'{"a":1, "b":{"c":1}, "d":[1, 2]}',
'$.b.c',
'word'
),
('1', '$[0]', 4),
('[]', '$[0][0]', 100),
('1', '$[0][0]', 100),
(
'{ "a": 1, "b": [2, 3]}',
'$.a',
10
),
(
'{ "a": 1, "b": [2, 3]}',
'$.b',
'[true, false]'
);
SELECT SELECT
j AS json, j AS json,
p AS path, p AS path,

View File

@@ -4,24 +4,23 @@ Note 1008 Can't drop database 'json_merge_patch_db'; database doesn't exist
CREATE DATABASE json_merge_patch_db; CREATE DATABASE json_merge_patch_db;
USE json_merge_patch_db; USE json_merge_patch_db;
CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore; CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore;
INSERT INTO t1(l1, l2) VALUES INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":"c"}');
('{"a":"b"}', '{"a":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"b":"c"}');
('{"a":"b"}', '{"b":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":null}');
('{"a":"b"}', '{"a":null}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b", "b":"c"}', '{"a":null}');
('{"a":"b", "b":"c"}', '{"a":null}'), INSERT INTO t1(l1, l2) VALUES ('{"a":["b"]}', '{"a":"c"}');
('{"a":["b"]}', '{"a":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"c"}', '{"a":["b"]}');
('{"a":"c"}', '{"a":["b"]}'), INSERT INTO t1(l1, l2) VALUES ('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}');
('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'), INSERT INTO t1(l1, l2) VALUES ('{"a":[{"b":"c"}]}', '{"a": [1]}');
('{"a":[{"b":"c"}]}', '{"a": [1]}'), INSERT INTO t1(l1, l2) VALUES ('["a","b"]', '["c","d"]');
('["a","b"]', '["c","d"]'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '["c"]');
('{"a":"b"}', '["c"]'), INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', 'null');
('{"a":"foo"}', 'null'), INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', '"bar"');
('{"a":"foo"}', '"bar"'), INSERT INTO t1(l1, l2) VALUES ('{"e":null}', '{"a":1}');
('{"e":null}', '{"a":1}'), INSERT INTO t1(l1, l2) VALUES ('[1,2]', '{"a":"b", "c":null}');
('[1,2]', '{"a":"b", "c":null}'), INSERT INTO t1(l1, l2) VALUES ('{}', '{"a":{"bb":{"ccc":null}}}');
('{}', '{"a":{"bb":{"ccc":null}}}'), INSERT INTO t1(l1, l2) VALUES (NULL, '{}');
(NULL, '{}'), INSERT INTO t1(l1, l2) VALUES ('{}', NULL);
('{}', NULL);
SELECT l1, l2, SELECT l1, l2,
JSON_MERGE_PATCH(l1, l2) AS `l1 + l2` JSON_MERGE_PATCH(l1, l2) AS `l1 + l2`
FROM t1; FROM t1;
@@ -45,11 +44,10 @@ NULL {} NULL
{} NULL NULL {} NULL NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore; CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore;
INSERT INTO t2 VALUES INSERT INTO t2 VALUES ('{"a":"b"}', NULL, '{"c":"d"}');
('{"a":"b"}', NULL, '{"c":"d"}'), INSERT INTO t2 VALUES (NULL, '[1,2,3]', '[4,5,6]');
(NULL, '[1,2,3]', '[4,5,6]'), INSERT INTO t2 VALUES (NULL, 'a', 'b');
(NULL, 'a', 'b'), INSERT INTO t2 VALUES ('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}');
('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}');
SELECT l1, l2, l3, SELECT l1, l2, l3,
JSON_MERGE_PATCH(l1, l2, l3) AS merged JSON_MERGE_PATCH(l1, l2, l3) AS merged
FROM t2; FROM t2;
@@ -62,12 +60,11 @@ DROP TABLE t2;
CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore; CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore;
SELECT JSON_MERGE_PATCH() FROM t3; SELECT JSON_MERGE_PATCH() FROM t3;
ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH' ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH'
INSERT INTO t3(l1, l2) VALUES('{}', '{"a":"c"}'); INSERT INTO t3(l1, l2) VALUES ('{}', '{"a":"c"}');
SELECT l1, JSON_MERGE_PATCH(l1) AS merged FROM t3; SELECT l1, JSON_MERGE_PATCH(l1) AS merged FROM t3;
ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH' ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH'
INSERT INTO t3(l1, l2) VALUES INSERT INTO t3(l1, l2) VALUES ('{', '[1,2,3]');
('{', '[1,2,3]'), INSERT INTO t3(l1, l2) VALUES ('{"a":"b"}', '[1,');
('{"a":"b"}', '[1,');
SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3; SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3;
l1 l2 merged l1 l2 merged
{} {"a":"c"} {"a": "c"} {} {"a":"c"} {"a": "c"}

View File

@@ -5,13 +5,10 @@ USE json_remove_db;
# Test of JSON_REMOVE function. # Test of JSON_REMOVE function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]');
t1 INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1]');
VALUES INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1][0]');
('["a", ["b", "c"], "d"]', '$[0]'), INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]');
('["a", ["b", "c"], "d"]', '$[1]'),
('["a", ["b", "c"], "d"]', '$[1][0]'),
('["a", ["b", "c"], "d"]', '$[0]');
SELECT SELECT
j AS json, j AS json,
p AS path, p AS path,
@@ -24,14 +21,11 @@ json path result
["a", ["b", "c"], "d"] $[1][0] ["a", ["c"], "d"] ["a", ["b", "c"], "d"] $[1][0] ["a", ["c"], "d"]
["a", ["b", "c"], "d"] $[0] [["b", "c"], "d"] ["a", ["b", "c"], "d"] $[0] [["b", "c"], "d"]
CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a');
t2 INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a[0]');
VALUES INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b');
('{"a": 1, "b": [2, 3]}', '$.a'), INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[0]');
('{"a": 1, "b": [2, 3]}', '$.a[0]'), INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[1]');
('{"a": 1, "b": [2, 3]}', '$.b'),
('{"a": 1, "b": [2, 3]}', '$.b[0]'),
('{"a": 1, "b": [2, 3]}', '$.b[1]');
SELECT SELECT
j AS json, j AS json,
p AS path, p AS path,

View File

@@ -8,23 +8,20 @@ USE json_valid_db;
# String literal - valid JSON # String literal - valid JSON
# #
CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('123');
t1 INSERT INTO t1 VALUES ('-123');
VALUES INSERT INTO t1 VALUES ('5000000000');
('123'), INSERT INTO t1 VALUES ('-5000000000');
('-123'), INSERT INTO t1 VALUES ('1.23');
('5000000000'), INSERT INTO t1 VALUES ('"123"');
('-5000000000'), INSERT INTO t1 VALUES ('true');
('1.23'), INSERT INTO t1 VALUES ('false');
('"123"'), INSERT INTO t1 VALUES ('null');
('true'), INSERT INTO t1 VALUES ('{"address": "Trondheim"}');
('false'), INSERT INTO t1 VALUES (JSON_OBJECT());
('null'), INSERT INTO t1 VALUES (JSON_OBJECT(1, 2));
('{"address": "Trondheim"}'), INSERT INTO t1 VALUES (JSON_ARRAY());
(JSON_OBJECT()), INSERT INTO t1 VALUES (JSON_ARRAY(1, 2));
(JSON_OBJECT(1, 2)),
(JSON_ARRAY()),
(JSON_ARRAY(1, 2));
SELECT SELECT
l AS raw, l AS raw,
JSON_VALID(l) AS is_valid, JSON_VALID(l) AS is_valid,
@@ -50,14 +47,11 @@ null 1 1
# String literal - invalid JSON # String literal - invalid JSON
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES ('12 3');
t1 INSERT INTO t1 VALUES ('{key:value}');
VALUES INSERT INTO t1 VALUES ('{key:value');
('12 3'), INSERT INTO t1 VALUES ('[1,2,]');
('{key:value}'), INSERT INTO t1 VALUES ('[1,2');
('{key:value'),
('[1,2,]'),
('[1,2');
SELECT SELECT
l AS raw, l AS raw,
JSON_VALID(l) AS is_valid, JSON_VALID(l) AS is_valid,
@@ -74,12 +68,8 @@ raw is_valid compact
# String literal - not in UTF-8 # String literal - not in UTF-8
# #
TRUNCATE t1; TRUNCATE t1;
SET SET NAMES 'ascii';
NAMES 'ascii'; INSERT INTO t1 VALUES ('123');
INSERT INTO
t1
VALUES
('123');
SELECT SELECT
l AS raw, l AS raw,
JSON_VALID(l) AS is_valid, JSON_VALID(l) AS is_valid,
@@ -88,16 +78,12 @@ FROM
t1; t1;
raw is_valid compact raw is_valid compact
123 1 1 123 1 1
SET SET NAMES 'utf8';
NAMES 'utf8';
# #
# Bare NULL # Bare NULL
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (NULL);
t1
VALUES
(NULL);
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM
@@ -108,10 +94,7 @@ NULL
# Function result - string # Function result - string
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (UPPER('"abc"'));
t1
VALUES
(UPPER('"abc"'));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM
@@ -122,28 +105,20 @@ JSON_VALID(l)
# Function result - string not in UTF-8 # Function result - string not in UTF-8
# #
TRUNCATE t1; TRUNCATE t1;
SET SET NAMES 'latin1';
NAMES 'latin1'; INSERT INTO t1 VALUES (UPPER('"abc"'));
INSERT INTO
t1
VALUES
(UPPER('"abc"'));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM
t1; t1;
JSON_VALID(l) JSON_VALID(l)
1 1
SET SET NAMES 'utf8';
NAMES 'utf8';
# #
# Function result - date, not valid as JSON without CAST # Function result - date, not valid as JSON without CAST
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (CAST('2015-01-15' AS DATE));
t1
VALUES
(CAST('2015-01-15' AS DATE));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM
@@ -154,13 +129,10 @@ JSON_VALID(l)
# The date string doesn't parse as JSON text, so wrong: # The date string doesn't parse as JSON text, so wrong:
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (
t1
VALUES
(
CAST( CAST(
CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8' CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8'
) )
); );
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
@@ -172,14 +144,8 @@ JSON_VALID(l)
# Function result - NULL # Function result - NULL
# #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (UPPER(NULL));
t1 INSERT INTO t1 VALUES (UPPER(CAST(NULL AS CHAR)));
VALUES
(UPPER(NULL));
INSERT INTO
t1
VALUES
(UPPER(CAST(NULL AS CHAR)));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM

View File

@@ -5,15 +5,17 @@ USE json_value_db;
# Test of JSON_VALUE function. # Test of JSON_VALUE function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(s TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(s TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO t1 VALUES('{"key1":123}', '$.key2'), INSERT INTO t1 VALUES ('{"key1":123}', '$.key2');
('{"key1":123}', '$.key1'), INSERT INTO t1 VALUES ('{"key1":123}', '$.key1');
('{"key1":[1,2,3]}', '$.key1'), INSERT INTO t1 VALUES ('{"key1":[1,2,3]}', '$.key1');
('{"key1": [1,2,3], "key1":123}', '$.key1'), INSERT INTO t1 VALUES ('{"key1": [1,2,3], "key1":123}', '$.key1');
('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z'), INSERT INTO t1 VALUES ('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }', '$.z');
('{"\\"key1":123}', '$."\\"key1"'), INSERT INTO t1 VALUES ('{"\\"key1":123}', '$."\\"key1"');
('{"\\"key1\\"":123}', '$."\\"key1\\""'), INSERT INTO t1 VALUES ('{"\\"key1\\"":123}', '$."\\"key1\\""');
('{"key 1":123}', '$."key 1"'); INSERT INTO t1 VALUES ('{"key 1":123}', '$."key 1"');
SELECT s as json_text, p as path, JSON_VALUE(s, p) as json_value, JSON_QUERY(s, p) as json_query SELECT s AS json_text, p AS path,
JSON_VALUE(s, p) AS json_value,
JSON_QUERY(s, p) AS json_query
FROM t1; FROM t1;
json_text path json_value json_query json_text path json_value json_query
{"key1":123} $.key2 NULL NULL {"key1":123} $.key2 NULL NULL
@@ -25,9 +27,9 @@ json_text path json_value json_query
{"\"key1\"":123} $."\"key1\"" 123 NULL {"\"key1\"":123} $."\"key1\"" 123 NULL
{"key 1":123} $."key 1" 123 NULL {"key 1":123} $."key 1" 123 NULL
CREATE TABLE t2(s TEXT) ENGINE = columnstore; CREATE TABLE t2(s TEXT) ENGINE = columnstore;
INSERT INTO t2 VALUES('{"key1":123, "key2":{"key3":"value3"}}'), INSERT INTO t2 VALUES ('{"key1":123, "key2":{"key3":"value3"}}');
('{"key1":123, "key3":[1,2,3]}'), INSERT INTO t2 VALUES ('{"key1":123, "key3":[1,2,3]}');
('{"key1":123, "key2":"[1]"}'); INSERT INTO t2 VALUES ('{"key1":123, "key2":"[1]"}');
SELECT s as json_text, '$.key1' , JSON_VALUE(s, '$.key1') as json_value, JSON_QUERY(s, '$.key1') as json_query SELECT s as json_text, '$.key1' , JSON_VALUE(s, '$.key1') as json_value, JSON_QUERY(s, '$.key1') as json_query
FROM t2; FROM t2;
json_text $.key1 json_value json_query json_text $.key1 json_value json_query
@@ -49,7 +51,15 @@ json_text $.key3 json_value json_query
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE zu (hu TEXT) ENGINE = COLUMNSTORE; CREATE TABLE zu (hu TEXT) ENGINE = COLUMNSTORE;
INSERT INTO zu(hu) VALUES ('{}'), (NULL), ('{ "": "huh", "10001" : "10001", "10002" : "10001", "10003" : "10001", "10004" : "10001", "10005" : "10001", "10006" : "10001", "10007" : "10001", "10008" : "10001", "10009" : "10001", "10010" : "10001", "10011" : "10001", "10012" : "10001", "10013" : "10001", "10014" : "10001", "10015" : "10001", "10016" : "10001", "10017" : "10001", "10018" : "10001", "10019" : "10001", "10020" : "10001", "buga" : ""}'); INSERT INTO zu(hu) VALUES ('{}');
INSERT INTO zu(hu) VALUES (NULL);
INSERT INTO zu(hu) VALUES (
'{ "": "huh", "10001" : "10001", "10002" : "10001", "10003" : "10001", "10004" : "10001",
"10005" : "10001", "10006" : "10001", "10007" : "10001", "10008" : "10001", "10009" : "10001",
"10010" : "10001", "10011" : "10001", "10012" : "10001", "10013" : "10001", "10014" : "10001",
"10015" : "10001", "10016" : "10001", "10017" : "10001", "10018" : "10001", "10019" : "10001",
"10020" : "10001", "buga" : "" }'
);
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;

View File

@@ -4,7 +4,14 @@ Note 1008 Can't drop database 'json_arrayagg_db'; database doesn't exist
CREATE DATABASE json_arrayagg_db; CREATE DATABASE json_arrayagg_db;
USE json_arrayagg_db; USE json_arrayagg_db;
CREATE TABLE t1 (a INT, b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1 (a INT, b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1, 1),(2, 1), (1, 1),(2, 1), (3, 2),(2, 2),(2, 2),(2, 2); INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (2, 1);
INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (2, 1);
INSERT INTO t1 VALUES (3, 2);
INSERT INTO t1 VALUES (2, 2);
INSERT INTO t1 VALUES (2, 2);
INSERT INTO t1 VALUES (2, 2);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(a)) JSON_VALID(JSON_ARRAYAGG(a))
1 1
@@ -20,7 +27,10 @@ DROP TABLE t1;
# Real aggregation # Real aggregation
# #
CREATE TABLE t1 (a FLOAT, b DOUBLE, c DECIMAL(10, 2))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a FLOAT, b DOUBLE, c DECIMAL(10, 2))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1.0, 2.0, 3.0),(1.0, 3.0, 9.0),(1.0, 4.0, 16.0),(1.0, 5.0, 25.0); INSERT INTO t1 VALUES (1.0, 2.0, 3.0);
INSERT INTO t1 VALUES (1.0, 3.0, 9.0);
INSERT INTO t1 VALUES (1.0, 4.0, 16.0);
INSERT INTO t1 VALUES (1.0, 5.0, 25.0);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(a)) JSON_VALID(JSON_ARRAYAGG(a))
1 1
@@ -32,7 +42,10 @@ DROP TABLE t1;
# Boolean aggregation # Boolean aggregation
# #
CREATE TABLE t1 (a BOOLEAN, b BOOLEAN)ENGINE=COLUMNSTORE; CREATE TABLE t1 (a BOOLEAN, b BOOLEAN)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (TRUE, TRUE), (TRUE, FALSE), (FALSE, TRUE), (FALSE, FALSE); INSERT INTO t1 VALUES (TRUE, TRUE);
INSERT INTO t1 VALUES (TRUE, FALSE);
INSERT INTO t1 VALUES (FALSE, TRUE);
INSERT INTO t1 VALUES (FALSE, FALSE);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(a)) JSON_VALID(JSON_ARRAYAGG(a))
1 1
@@ -51,9 +64,10 @@ DROP TABLE t1;
# Aggregation of strings with quoted # Aggregation of strings with quoted
# #
CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES ('"double_quoted_value"');
('"double_quoted_value"'), ("'single_quoted_value'"), INSERT INTO t1 VALUES ("'single_quoted_value'");
('"double_quoted_value"'), ("'single_quoted_value'"); INSERT INTO t1 VALUES ('"double_quoted_value"');
INSERT INTO t1 VALUES ("'single_quoted_value'");
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(a)) JSON_VALID(JSON_ARRAYAGG(a))
1 1
@@ -65,9 +79,20 @@ DROP TABLE t1;
# Strings and NULLs # Strings and NULLs
# #
CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES (1, "Hello");
(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL), INSERT INTO t1 VALUES (1, "World");
(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL); INSERT INTO t1 VALUES (2, "This");
INSERT INTO t1 VALUES (2, "Will");
INSERT INTO t1 VALUES (2, "Work");
INSERT INTO t1 VALUES (2, "!");
INSERT INTO t1 VALUES (3, NULL);
INSERT INTO t1 VALUES (1, "Hello");
INSERT INTO t1 VALUES (1, "World");
INSERT INTO t1 VALUES (2, "This");
INSERT INTO t1 VALUES (2, "Will");
INSERT INTO t1 VALUES (2, "Work");
INSERT INTO t1 VALUES (2, "!");
INSERT INTO t1 VALUES (3, NULL);
SELECT JSON_VALID(JSON_ARRAYAGG(b)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(b)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(b)) JSON_VALID(JSON_ARRAYAGG(b))
1 1
@@ -102,18 +127,6 @@ JSON_ARRAYAGG(b LIMIT 2)
["Hello","World","Hello","World"] ["Hello","World","Hello","World"]
["This","Will","Work","!","This","Will","Work","!"] ["This","Will","Work","!","This","Will","Work","!"]
[null,null] [null,null]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1;
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC)
[1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC) FROM t1;
JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC)
[null,"!","Hello","This","Will","Work","World"]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC LIMIT 2) FROM t1;
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC LIMIT 2)
[1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC LIMIT 2) FROM t1;
JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC LIMIT 2)
[null,"!","Hello","This","Will","Work","World"]
# #
# JSON aggregation # JSON aggregation
# #
@@ -184,43 +197,42 @@ json_object('x', json_arrayagg(json_object('a', 1)))
# #
# #
CREATE TABLE t1(a INT, b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1(a INT, b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(a)
[1,2,3,1,2,3] [1,2,3,1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; INSERT INTO t1 VALUES (NULL,NULL);
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) INSERT INTO t1 VALUES (NULL,NULL);
[1,2,3]
INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL);
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(a)
[1,2,3,1,2,3,null,null] [1,2,3,1,2,3,null,null]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1;
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC)
[null,1,2,3]
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(a VARCHAR(10), b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1(a VARCHAR(10), b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(a)
[1,2,3,1,2,3] [1,2,3,1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; INSERT INTO t1 VALUES (NULL,NULL);
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) INSERT INTO t1 VALUES (NULL,NULL);
[1,2,3]
INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL);
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(a)
[1,2,3,1,2,3,null,null] [1,2,3,1,2,3,null,null]
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1;
JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC)
[null,1,2,3]
DROP TABLE t1; DROP TABLE t1;
# #
# #
CREATE TABLE t1(a VARCHAR(255))ENGINE=COLUMNSTORE; CREATE TABLE t1(a VARCHAR(255))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES ('red'),('blue'); INSERT INTO t1 VALUES ('red');
INSERT INTO t1 VALUES ('blue');
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(a)
["red","blue"] ["red","blue"]
@@ -253,8 +265,13 @@ drop table t1;
SET group_concat_max_len= default; SET group_concat_max_len= default;
CREATE TABLE t1(id int, name varchar(50))ENGINE=COLUMNSTORE; CREATE TABLE t1(id int, name varchar(50))ENGINE=COLUMNSTORE;
CREATE TABLE t2(id int, owner_id int)ENGINE=COLUMNSTORE; CREATE TABLE t2(id int, owner_id int)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); INSERT INTO t1 VALUES (1, "name1");
INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); INSERT INTO t1 VALUES (2, "name2");
INSERT INTO t1 VALUES (3, "name3");
INSERT INTO t2 VALUES (1, 1);
INSERT INTO t2 VALUES (2, 1);
INSERT INTO t2 VALUES (3, 2);
INSERT INTO t2 VALUES (4, 3);
SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials
from t1 LEFT JOIN t2 on t1.id = t2.owner_id from t1 LEFT JOIN t2 on t1.id = t2.owner_id
GROUP BY t1.id ORDER BY id; GROUP BY t1.id ORDER BY id;
@@ -276,7 +293,8 @@ json_object('a', coalesce(json_object('b', 'c')))
# #
CREATE TABLE t (a VARCHAR(8))ENGINE=COLUMNSTORE; CREATE TABLE t (a VARCHAR(8))ENGINE=COLUMNSTORE;
CREATE VIEW v AS SELECT * FROM t; CREATE VIEW v AS SELECT * FROM t;
INSERT INTO t VALUES ('foo'),('bar'); INSERT INTO t VALUES ('foo');
INSERT INTO t VALUES ('bar');
SELECT JSON_ARRAYAGG(a) AS f FROM v; SELECT JSON_ARRAYAGG(a) AS f FROM v;
f f
["foo","bar"] ["foo","bar"]

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_array_append_db; DROP DATABASE IF EXISTS json_array_append_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_array_append_db; CREATE DATABASE json_array_append_db;
USE json_array_append_db; USE json_array_append_db;
@@ -10,37 +10,19 @@ USE json_array_append_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_ARRAY_APPEND function. --echo # Test of JSON_ARRAY_APPEND function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2);
t1 INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2);
VALUES INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1');
('[1,2,3]', '$[0]', 2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE);
('[1,2,3]', '$[0]', 1.2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false);
('[1,2,3]', '$[0]', 'key1'), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL);
('[1,2,3]', '$[0]', TRUE), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4);
('[1,2,3]', '$[0]', false), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape');
('[1,2,3]', '$[0]', NULL), INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.b', 4);
( INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.c', 'grape');
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.b',
4
),
(
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.c',
'grape'
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.b',
4
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.c',
'grape'
);
SELECT SELECT
a AS arrary, a AS arrary,
@@ -53,10 +35,7 @@ FROM
--echo # NULL args --echo # NULL args
CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('[1,2,3]');
t2
VALUES
('[1,2,3]');
SELECT SELECT
JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)),
@@ -66,10 +45,7 @@ FROM
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$.b');
t2
VALUES
('$.b');
SELECT SELECT
JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)), JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)),
@@ -79,10 +55,7 @@ FROM
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$**[0]');
t2
VALUES
('$**[0]');
--echo error ER_INVALID_JSON_PATH_WILDCARD --echo error ER_INVALID_JSON_PATH_WILDCARD
SELECT SELECT
@@ -91,7 +64,5 @@ FROM
t2; t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_array_append_db; DROP DATABASE json_array_append_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_array_insert_db; DROP DATABASE IF EXISTS json_array_insert_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_array_insert_db; CREATE DATABASE json_array_insert_db;
USE json_array_insert_db; USE json_array_insert_db;
@@ -10,37 +10,19 @@ USE json_array_insert_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_ARRAY_INSERT function. --echo # Test of JSON_ARRAY_INSERT function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2);
t1 INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2);
VALUES INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1');
('[1,2,3]', '$[0]', 2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE);
('[1,2,3]', '$[0]', 1.2), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false);
('[1,2,3]', '$[0]', 'key1'), INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL);
('[1,2,3]', '$[0]', TRUE), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4);
('[1,2,3]', '$[0]', false), INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape');
('[1,2,3]', '$[0]', NULL), INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.b', 4);
( INSERT INTO t1 VALUES ('{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}', '$.c', 'grape');
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.b',
4
),
(
'{"a": "foo", "b": "bar", "c": "wibble" }',
'$.c',
'grape'
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.b',
4
),
(
'{"a": "foo", "b": [1,2,3], "c": ["apple","pear"]}',
'$.c',
'grape'
);
SELECT SELECT
a AS arrary, a AS arrary,
@@ -53,10 +35,7 @@ FROM
--echo # NULL args --echo # NULL args
CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('[1,2,3]');
t2
VALUES
('[1,2,3]');
SELECT SELECT
JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)),
@@ -66,10 +45,7 @@ FROM
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$.b');
t2
VALUES
('$.b');
SELECT SELECT
JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)), JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)),
@@ -79,10 +55,7 @@ FROM
TRUNCATE t2; TRUNCATE t2;
INSERT INTO INSERT INTO t2 VALUES ('$**[0]');
t2
VALUES
('$**[0]');
--echo error ER_INVALID_JSON_PATH_WILDCARD --echo error ER_INVALID_JSON_PATH_WILDCARD
SELECT SELECT
@@ -91,7 +64,5 @@ FROM
t2; t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_array_insert_db; DROP DATABASE json_array_insert_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_contains_db; DROP DATABASE IF EXISTS json_contains_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_contains_db; CREATE DATABASE json_contains_db;
USE json_contains_db; USE json_contains_db;
@@ -10,18 +10,16 @@ USE json_contains_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_CONTAINS function. --echo # Test of JSON_CONTAINS function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore; CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t1 VALUES ('{"k1":123, "k2":345}', '123', '$.k1');
t1 INSERT INTO t1 VALUES ('', '', '$');
VALUES INSERT INTO t1 VALUES ('null', 'null', '$');
('{"k1":123, "k2":345}', '123', '$.k1'), INSERT INTO t1 VALUES ('"10"', '"10"', '$');
('', '', '$'), INSERT INTO t1 VALUES ('"10"', '10', '$');
('null', 'null', '$'), INSERT INTO t1 VALUES ('10.1', '10', '$');
('"10"', '"10"', '$'), INSERT INTO t1 VALUES ('10.0', '10', '$');
('"10"', '10', '$'),
('10.1', '10', '$'),
('10.0', '10', '$');
SELECT SELECT
j AS json, j AS json,
@@ -33,28 +31,22 @@ FROM
CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore; CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t2 VALUES ('"you"', '"you"');
t2 INSERT INTO t2 VALUES ('"youth"', '"you"');
VALUES INSERT INTO t2 VALUES ('[1]', '1');
('"you"', '"you"'), INSERT INTO t2 VALUES ('[2, 1]', '1');
('"youth"', '"you"'), INSERT INTO t2 VALUES ('[2, [2, 3], 1]', '1');
('[1]', '1'), INSERT INTO t2 VALUES ('[4, [2, 3], 1]', '2');
('[2, 1]', '1'), INSERT INTO t2 VALUES ('[2, 1]', '[1, 2]');
('[2, [2, 3], 1]', '1'), INSERT INTO t2 VALUES ('[2, 1]', '[1, 0, 2]');
('[4, [2, 3], 1]', '2'), INSERT INTO t2 VALUES ('[2, 0, 3, 1]', '[1, 2]');
('[2, 1]', '[1, 2]'), INSERT INTO t2 VALUES ('{"b":[1,2], "a":1}', '{"a":1, "b":2}');
('[2, 1]', '[1, 0, 2]'), INSERT INTO t2 VALUES ('{"a":1}', '{}');
('[2, 0, 3, 1]', '[1, 2]'), INSERT INTO t2 VALUES ('[1, {"a":1}]', '{}');
('{"b":[1,2], "a":1}', '{"a":1, "b":2}'), INSERT INTO t2 VALUES ('[1, {"a":1}]', '{"a":1}');
('{"a":1}', '{}'), INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}]', '["foo","bar"]');
('[1, {"a":1}]', '{}'), INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]');
('[1, {"a":1}]', '{"a":1}'), INSERT INTO t2 VALUES ('[{"a":"b"},{"c":"d"}]', '{"c":"d"}');
('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'),
(
'[{"abc":"def", "def":"abc"}, "bar"]',
'["bar", {}]'
),
('[{"a":"b"},{"c":"d"}]', '{"c":"d"}');
SELECT SELECT
j AS json, j AS json,
@@ -64,7 +56,5 @@ FROM
t2; t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_contains_db; DROP DATABASE json_contains_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_contains_path_db; DROP DATABASE IF EXISTS json_contains_path_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_contains_path_db; CREATE DATABASE json_contains_path_db;
USE json_contains_path_db; USE json_contains_path_db;
@@ -10,18 +10,16 @@ USE json_contains_path_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_CONTAINS_PATH function. --echo # Test of JSON_CONTAINS_PATH function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]");
t1 INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]");
VALUES INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.ma");
('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"), INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1");
('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"), INSERT INTO t1 VALUES ('{ "a": true }', NULL, '$.a');
('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"), INSERT INTO t1 VALUES ('{ "a": true }', 'all', NULL);
('{"key1":1, "key2":[2,3]}', "one", "$.key1"), INSERT INTO t1 VALUES ('{"a":{"b":"c"}}', 'one', '$.a.*');
('{ "a": true }', NULL, '$.a'),
('{ "a": true }', 'all', NULL),
('{"a":{"b":"c"}}', 'one', '$.a.*');
SELECT SELECT
j AS json, j AS json,
@@ -33,27 +31,9 @@ FROM
CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma");
t2 INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma");
VALUES INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2");
(
'{"key1":1, "key2":[2,3]}',
"one",
"$.key1",
"$.ma"
),
(
'{"key1":1, "key2":[2,3]}',
"aLl",
"$.key1",
"$.ma"
),
(
'{"key1":1, "key2":[2,3]}',
"aLl",
"$.key1",
"$.key2"
);
SELECT SELECT
j AS json, j AS json,
@@ -65,7 +45,5 @@ FROM
t2; t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_contains_path_db; DROP DATABASE json_contains_path_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_exists_db; DROP DATABASE IF EXISTS json_exists_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_exists_db; CREATE DATABASE json_exists_db;
USE json_exists_db; USE json_exists_db;
@@ -11,27 +11,23 @@ USE json_exists_db;
--echo # Test of JSON_EXISTS function. --echo # Test of JSON_EXISTS function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test case 0 --echo # Test case 0
CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore;
SET SET @json = '{"key1":"xxxx", "key2":[1, 2, 3]}';
@json = '{"key1":"xxxx", "key2":[1, 2, 3]}';
INSERT INTO INSERT INTO t1 VALUES (@json, '$.key1');
t1 INSERT INTO t1 VALUES (@json, '$.key1[0]');
VALUES INSERT INTO t1 VALUES (@json, '$.key2');
(@json, '$.key1'), INSERT INTO t1 VALUES (@json, '$.key2[1]');
(@json, '$.key1[0]'), INSERT INTO t1 VALUES (@json, '$.key2[10]');
(@json, '$.key2'),
(@json, '$.key2[1]'),
(@json, '$.key2[10]');
SELECT SELECT
j, j,
p, p,
JSON_EXISTS(j, p) AS result JSON_EXISTS(j, p) AS result
FROM FROM
t1; t1;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_exists_db; DROP DATABASE json_exists_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_extract_db; DROP DATABASE IF EXISTS json_extract_db;
--enable_warnings --enable_warnings
CREATE DATABASE json_extract_db; CREATE DATABASE json_extract_db;
USE json_extract_db; USE json_extract_db;
@@ -10,72 +10,58 @@ USE json_extract_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_EXTRACT function. --echo # Test of JSON_EXTRACT function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo --echo
--echo # Single path expression --echo # Single path expression
--echo --echo
CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE;
SET SET @json = '[1, "val2", [3.1, -4]]';
@json = '[1, "val2", [3.1, -4]]';
INSERT INTO INSERT INTO t1 VALUES (@json, '$[0]');
t1 INSERT INTO t1 VALUES (@json, '$[1]');
VALUES INSERT INTO t1 VALUES (@json, '$[2]');
(@json, '$[0]'), INSERT INTO t1 VALUES (@json, '$[3]');
(@json, '$[1]'), INSERT INTO t1 VALUES (@json, '$[2][0]');
(@json, '$[2]'), INSERT INTO t1 VALUES (@json, '$[2][1]');
(@json, '$[3]'), INSERT INTO t1 VALUES (@json, '$[2][10]');
(@json, '$[2][0]'), INSERT INTO t1 VALUES (@json, '$');
(@json, '$[2][1]'), INSERT INTO t1 VALUES ('1', '$');
(@json, '$[2][10]'), INSERT INTO t1 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]');
(@json, '$'), INSERT INTO t1 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1");
('1', '$'), INSERT INTO t1 VALUES ('{"key0":true, "key1":"qwe"}', "$.key1");
('[10, 20, [30, 40], 1, 10]', '$[1]'), INSERT INTO t1 VALUES ('[10, 20, [30, 40]]', '$[2][*]');
('{"key1":"asd", "key2":[2,3]}', "$.key1"), INSERT INTO t1 VALUES ('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]');
('{"key0":true, "key1":"qwe"}', "$.key1"), INSERT INTO t1 VALUES (json_object('foo', 'foobar'), '$');
('[10, 20, [30, 40]]', '$[2][*]'),
('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'),
(json_object('foo', 'foobar'), '$');
SELECT SELECT
j, j,
p, p,
JSON_EXTRACT(j, p) AS result JSON_EXTRACT(j, p) AS result
FROM FROM
t1; t1;
--echo --echo
--echo # Multiple path expression --echo # Multiple path expression
--echo --echo
CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY");
t2 INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2");
VALUES INSERT INTO t2 VALUES ('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2");
( INSERT INTO t2 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]');
'{"key1":"asd", "key2":[2,3]}', INSERT INTO t2 VALUES ('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a');
"$.keyX",
"$.keyY"
),
(
'{"key1":"asd", "key2":[2,3]}',
"$.key1",
"$.key2"
),
('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"),
('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'),
('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a');
SELECT SELECT
j, j,
p1, p1,
p2, p2,
JSON_EXTRACT(j, p1, p2) AS result JSON_EXTRACT(j, p1, p2) AS result
FROM FROM
t2; t2;
DROP TABLE t2; DROP TABLE t2;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_extract_db; DROP DATABASE json_extract_db;

View File

@@ -1,8 +1,8 @@
--source ../include/have_columnstore.inc --source ../include/have_columnstore.inc
--disable_warnings --disable_warnings
DROP DATABASE IF EXISTS json_insert_de; DROP DATABASE IF EXISTS json_insert_de;
--enable_warnings --enable_warnings
CREATE DATABASE json_insert_de; CREATE DATABASE json_insert_de;
USE json_insert_de; USE json_insert_de;
@@ -10,36 +10,18 @@ USE json_insert_de;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
--echo # Test of JSON_INSERT|REPLACE|SET function. --echo # Test of JSON_INSERT|REPLACE|SET function.
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word');
t1 INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3);
VALUES INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2);
( INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word');
'{"a":1, "b":{"c":1}, "d":[1, 2]}', INSERT INTO t1 VALUES ('1', '$[0]', 4);
'$.b.k1', INSERT INTO t1 VALUES ('[]', '$[0][0]', 100);
'word' INSERT INTO t1 VALUES ('1', '$[0][0]', 100);
), INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.a', 10);
('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3), INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.b', '[true, false]');
('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2),
(
'{"a":1, "b":{"c":1}, "d":[1, 2]}',
'$.b.c',
'word'
),
('1', '$[0]', 4),
('[]', '$[0][0]', 100),
('1', '$[0][0]', 100),
(
'{ "a": 1, "b": [2, 3]}',
'$.a',
10
),
(
'{ "a": 1, "b": [2, 3]}',
'$.b',
'[true, false]'
);
SELECT SELECT
j AS json, j AS json,
@@ -52,5 +34,4 @@ FROM
t1; t1;
DROP TABLE t1; DROP TABLE t1;
DROP DATABASE json_insert_de; DROP DATABASE json_insert_de;

View File

@@ -1,54 +1,64 @@
DROP DATABASE IF EXISTS json_merge_patch_db; DROP DATABASE IF EXISTS json_merge_patch_db;
CREATE DATABASE json_merge_patch_db; CREATE DATABASE json_merge_patch_db;
USE json_merge_patch_db; USE json_merge_patch_db;
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Test of JSON_MERGE_PATCH function. # Test of JSON_MERGE_PATCH function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore; CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore;
INSERT INTO t1(l1, l2) VALUES
('{"a":"b"}', '{"a":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":"c"}');
('{"a":"b"}', '{"b":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"b":"c"}');
('{"a":"b"}', '{"a":null}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":null}');
('{"a":"b", "b":"c"}', '{"a":null}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b", "b":"c"}', '{"a":null}');
('{"a":["b"]}', '{"a":"c"}'), INSERT INTO t1(l1, l2) VALUES ('{"a":["b"]}', '{"a":"c"}');
('{"a":"c"}', '{"a":["b"]}'), INSERT INTO t1(l1, l2) VALUES ('{"a":"c"}', '{"a":["b"]}');
('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'), INSERT INTO t1(l1, l2) VALUES ('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}');
('{"a":[{"b":"c"}]}', '{"a": [1]}'), INSERT INTO t1(l1, l2) VALUES ('{"a":[{"b":"c"}]}', '{"a": [1]}');
('["a","b"]', '["c","d"]'), INSERT INTO t1(l1, l2) VALUES ('["a","b"]', '["c","d"]');
('{"a":"b"}', '["c"]'), INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '["c"]');
('{"a":"foo"}', 'null'), INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', 'null');
('{"a":"foo"}', '"bar"'), INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', '"bar"');
('{"e":null}', '{"a":1}'), INSERT INTO t1(l1, l2) VALUES ('{"e":null}', '{"a":1}');
('[1,2]', '{"a":"b", "c":null}'), INSERT INTO t1(l1, l2) VALUES ('[1,2]', '{"a":"b", "c":null}');
('{}', '{"a":{"bb":{"ccc":null}}}'), INSERT INTO t1(l1, l2) VALUES ('{}', '{"a":{"bb":{"ccc":null}}}');
(NULL, '{}'), INSERT INTO t1(l1, l2) VALUES (NULL, '{}');
('{}', NULL); INSERT INTO t1(l1, l2) VALUES ('{}', NULL);
SELECT l1, l2, SELECT l1, l2,
JSON_MERGE_PATCH(l1, l2) AS `l1 + l2` JSON_MERGE_PATCH(l1, l2) AS `l1 + l2`
FROM t1; FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore; CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore;
INSERT INTO t2 VALUES
('{"a":"b"}', NULL, '{"c":"d"}'), INSERT INTO t2 VALUES ('{"a":"b"}', NULL, '{"c":"d"}');
(NULL, '[1,2,3]', '[4,5,6]'), INSERT INTO t2 VALUES (NULL, '[1,2,3]', '[4,5,6]');
(NULL, 'a', 'b'), INSERT INTO t2 VALUES (NULL, 'a', 'b');
('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}'); INSERT INTO t2 VALUES ('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}');
SELECT l1, l2, l3, SELECT l1, l2, l3,
JSON_MERGE_PATCH(l1, l2, l3) AS merged JSON_MERGE_PATCH(l1, l2, l3) AS merged
FROM t2; FROM t2;
DROP TABLE t2; DROP TABLE t2;
CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore; CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore;
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT JSON_MERGE_PATCH() FROM t3; SELECT JSON_MERGE_PATCH() FROM t3;
INSERT INTO t3(l1, l2) VALUES('{}', '{"a":"c"}');
INSERT INTO t3(l1, l2) VALUES ('{}', '{"a":"c"}');
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT l1, JSON_MERGE_PATCH(l1) AS merged FROM t3; SELECT l1, JSON_MERGE_PATCH(l1) AS merged FROM t3;
INSERT INTO t3(l1, l2) VALUES
('{', '[1,2,3]'), INSERT INTO t3(l1, l2) VALUES ('{', '[1,2,3]');
('{"a":"b"}', '[1,'); INSERT INTO t3(l1, l2) VALUES ('{"a":"b"}', '[1,');
SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3; SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3;
DROP TABLE t3; DROP TABLE t3;
DROP DATABASE json_merge_patch_db; DROP DATABASE json_merge_patch_db;

View File

@@ -12,13 +12,10 @@ USE json_remove_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]');
t1 INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1]');
VALUES INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1][0]');
('["a", ["b", "c"], "d"]', '$[0]'), INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]');
('["a", ["b", "c"], "d"]', '$[1]'),
('["a", ["b", "c"], "d"]', '$[1][0]'),
('["a", ["b", "c"], "d"]', '$[0]');
SELECT SELECT
j AS json, j AS json,
@@ -29,14 +26,11 @@ FROM
CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a');
t2 INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a[0]');
VALUES INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b');
('{"a": 1, "b": [2, 3]}', '$.a'), INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[0]');
('{"a": 1, "b": [2, 3]}', '$.a[0]'), INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[1]');
('{"a": 1, "b": [2, 3]}', '$.b'),
('{"a": 1, "b": [2, 3]}', '$.b[0]'),
('{"a": 1, "b": [2, 3]}', '$.b[1]');
SELECT SELECT
j AS json, j AS json,

View File

@@ -16,23 +16,20 @@ USE json_valid_db;
CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE; CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE;
INSERT INTO INSERT INTO t1 VALUES ('123');
t1 INSERT INTO t1 VALUES ('-123');
VALUES INSERT INTO t1 VALUES ('5000000000');
('123'), INSERT INTO t1 VALUES ('-5000000000');
('-123'), INSERT INTO t1 VALUES ('1.23');
('5000000000'), INSERT INTO t1 VALUES ('"123"');
('-5000000000'), INSERT INTO t1 VALUES ('true');
('1.23'), INSERT INTO t1 VALUES ('false');
('"123"'), INSERT INTO t1 VALUES ('null');
('true'), INSERT INTO t1 VALUES ('{"address": "Trondheim"}');
('false'), INSERT INTO t1 VALUES (JSON_OBJECT());
('null'), INSERT INTO t1 VALUES (JSON_OBJECT(1, 2));
('{"address": "Trondheim"}'), INSERT INTO t1 VALUES (JSON_ARRAY());
(JSON_OBJECT()), INSERT INTO t1 VALUES (JSON_ARRAY(1, 2));
(JSON_OBJECT(1, 2)),
(JSON_ARRAY()),
(JSON_ARRAY(1, 2));
SELECT SELECT
l AS raw, l AS raw,
@@ -46,14 +43,11 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES ('12 3');
t1 INSERT INTO t1 VALUES ('{key:value}');
VALUES INSERT INTO t1 VALUES ('{key:value');
('12 3'), INSERT INTO t1 VALUES ('[1,2,]');
('{key:value}'), INSERT INTO t1 VALUES ('[1,2');
('{key:value'),
('[1,2,]'),
('[1,2');
SELECT SELECT
l AS raw, l AS raw,
@@ -67,13 +61,9 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
SET SET NAMES 'ascii';
NAMES 'ascii';
INSERT INTO INSERT INTO t1 VALUES ('123');
t1
VALUES
('123');
SELECT SELECT
l AS raw, l AS raw,
@@ -82,18 +72,14 @@ SELECT
FROM FROM
t1; t1;
SET SET NAMES 'utf8';
NAMES 'utf8';
--echo # --echo #
--echo # Bare NULL --echo # Bare NULL
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (NULL);
t1
VALUES
(NULL);
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
@@ -105,10 +91,7 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (UPPER('"abc"'));
t1
VALUES
(UPPER('"abc"'));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
@@ -120,31 +103,23 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
SET SET NAMES 'latin1';
NAMES 'latin1';
INSERT INTO INSERT INTO t1 VALUES (UPPER('"abc"'));
t1
VALUES
(UPPER('"abc"'));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
FROM FROM
t1; t1;
SET SET NAMES 'utf8';
NAMES 'utf8';
--echo # --echo #
--echo # Function result - date, not valid as JSON without CAST --echo # Function result - date, not valid as JSON without CAST
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (CAST('2015-01-15' AS DATE));
t1
VALUES
(CAST('2015-01-15' AS DATE));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
@@ -156,14 +131,11 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (
t1 CAST(
VALUES CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8'
( )
CAST( );
CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8'
)
);
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)
@@ -175,15 +147,8 @@ FROM
--echo # --echo #
TRUNCATE t1; TRUNCATE t1;
INSERT INTO INSERT INTO t1 VALUES (UPPER(NULL));
t1 INSERT INTO t1 VALUES (UPPER(CAST(NULL AS CHAR)));
VALUES
(UPPER(NULL));
INSERT INTO
t1
VALUES
(UPPER(CAST(NULL AS CHAR)));
SELECT SELECT
JSON_VALID(l) JSON_VALID(l)

View File

@@ -11,22 +11,26 @@ USE json_value_db;
--echo # ---------------------------------------------------------------------- --echo # ----------------------------------------------------------------------
CREATE TABLE t1(s TEXT, p TEXT) ENGINE = columnstore; CREATE TABLE t1(s TEXT, p TEXT) ENGINE = columnstore;
INSERT INTO t1 VALUES('{"key1":123}', '$.key2'),
('{"key1":123}', '$.key1'),
('{"key1":[1,2,3]}', '$.key1'),
('{"key1": [1,2,3], "key1":123}', '$.key1'),
('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }','$.z'),
('{"\\"key1":123}', '$."\\"key1"'),
('{"\\"key1\\"":123}', '$."\\"key1\\""'),
('{"key 1":123}', '$."key 1"');
SELECT s as json_text, p as path, JSON_VALUE(s, p) as json_value, JSON_QUERY(s, p) as json_query INSERT INTO t1 VALUES ('{"key1":123}', '$.key2');
INSERT INTO t1 VALUES ('{"key1":123}', '$.key1');
INSERT INTO t1 VALUES ('{"key1":[1,2,3]}', '$.key1');
INSERT INTO t1 VALUES ('{"key1": [1,2,3], "key1":123}', '$.key1');
INSERT INTO t1 VALUES ('{ "x": [0,1], "y": "[0,1]", "z": "Mon\\\"t\\\"y" }', '$.z');
INSERT INTO t1 VALUES ('{"\\"key1":123}', '$."\\"key1"');
INSERT INTO t1 VALUES ('{"\\"key1\\"":123}', '$."\\"key1\\""');
INSERT INTO t1 VALUES ('{"key 1":123}', '$."key 1"');
SELECT s AS json_text, p AS path,
JSON_VALUE(s, p) AS json_value,
JSON_QUERY(s, p) AS json_query
FROM t1; FROM t1;
CREATE TABLE t2(s TEXT) ENGINE = columnstore; CREATE TABLE t2(s TEXT) ENGINE = columnstore;
INSERT INTO t2 VALUES('{"key1":123, "key2":{"key3":"value3"}}'),
('{"key1":123, "key3":[1,2,3]}'), INSERT INTO t2 VALUES ('{"key1":123, "key2":{"key3":"value3"}}');
('{"key1":123, "key2":"[1]"}'); INSERT INTO t2 VALUES ('{"key1":123, "key3":[1,2,3]}');
INSERT INTO t2 VALUES ('{"key1":123, "key2":"[1]"}');
SELECT s as json_text, '$.key1' , JSON_VALUE(s, '$.key1') as json_value, JSON_QUERY(s, '$.key1') as json_query SELECT s as json_text, '$.key1' , JSON_VALUE(s, '$.key1') as json_value, JSON_QUERY(s, '$.key1') as json_query
FROM t2; FROM t2;
@@ -42,7 +46,17 @@ DROP TABLE t1;
# check an absence of race bug in json_query. # check an absence of race bug in json_query.
CREATE TABLE zu (hu TEXT) ENGINE = COLUMNSTORE; CREATE TABLE zu (hu TEXT) ENGINE = COLUMNSTORE;
INSERT INTO zu(hu) VALUES ('{}'), (NULL), ('{ "": "huh", "10001" : "10001", "10002" : "10001", "10003" : "10001", "10004" : "10001", "10005" : "10001", "10006" : "10001", "10007" : "10001", "10008" : "10001", "10009" : "10001", "10010" : "10001", "10011" : "10001", "10012" : "10001", "10013" : "10001", "10014" : "10001", "10015" : "10001", "10016" : "10001", "10017" : "10001", "10018" : "10001", "10019" : "10001", "10020" : "10001", "buga" : ""}');
INSERT INTO zu(hu) VALUES ('{}');
INSERT INTO zu(hu) VALUES (NULL);
INSERT INTO zu(hu) VALUES (
'{ "": "huh", "10001" : "10001", "10002" : "10001", "10003" : "10001", "10004" : "10001",
"10005" : "10001", "10006" : "10001", "10007" : "10001", "10008" : "10001", "10009" : "10001",
"10010" : "10001", "10011" : "10001", "10012" : "10001", "10013" : "10001", "10014" : "10001",
"10015" : "10001", "10016" : "10001", "10017" : "10001", "10018" : "10001", "10019" : "10001",
"10020" : "10001", "buga" : "" }'
);
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;
INSERT INTO zu(hu) SELECT hu FROM zu; INSERT INTO zu(hu) SELECT hu FROM zu;

View File

@@ -6,7 +6,14 @@ USE json_arrayagg_db;
CREATE TABLE t1 (a INT, b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1 (a INT, b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1, 1),(2, 1), (1, 1),(2, 1), (3, 2),(2, 2),(2, 2),(2, 2); INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (2, 1);
INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (2, 1);
INSERT INTO t1 VALUES (3, 2);
INSERT INTO t1 VALUES (2, 2);
INSERT INTO t1 VALUES (2, 2);
INSERT INTO t1 VALUES (2, 2);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
@@ -18,7 +25,10 @@ DROP TABLE t1;
-- echo # Real aggregation -- echo # Real aggregation
-- echo # -- echo #
CREATE TABLE t1 (a FLOAT, b DOUBLE, c DECIMAL(10, 2))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a FLOAT, b DOUBLE, c DECIMAL(10, 2))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1.0, 2.0, 3.0),(1.0, 3.0, 9.0),(1.0, 4.0, 16.0),(1.0, 5.0, 25.0); INSERT INTO t1 VALUES (1.0, 2.0, 3.0);
INSERT INTO t1 VALUES (1.0, 3.0, 9.0);
INSERT INTO t1 VALUES (1.0, 4.0, 16.0);
INSERT INTO t1 VALUES (1.0, 5.0, 25.0);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b), JSON_ARRAYAGG(c) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b), JSON_ARRAYAGG(c) FROM t1;
@@ -28,7 +38,10 @@ DROP TABLE t1;
-- echo # Boolean aggregation -- echo # Boolean aggregation
-- echo # -- echo #
CREATE TABLE t1 (a BOOLEAN, b BOOLEAN)ENGINE=COLUMNSTORE; CREATE TABLE t1 (a BOOLEAN, b BOOLEAN)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (TRUE, TRUE), (TRUE, FALSE), (FALSE, TRUE), (FALSE, FALSE); INSERT INTO t1 VALUES (TRUE, TRUE);
INSERT INTO t1 VALUES (TRUE, FALSE);
INSERT INTO t1 VALUES (FALSE, TRUE);
INSERT INTO t1 VALUES (FALSE, FALSE);
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
@@ -42,9 +55,10 @@ DROP TABLE t1;
-- echo # Aggregation of strings with quoted -- echo # Aggregation of strings with quoted
-- echo # -- echo #
CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES ('"double_quoted_value"');
('"double_quoted_value"'), ("'single_quoted_value'"), INSERT INTO t1 VALUES ("'single_quoted_value'");
('"double_quoted_value"'), ("'single_quoted_value'"); INSERT INTO t1 VALUES ('"double_quoted_value"');
INSERT INTO t1 VALUES ("'single_quoted_value'");
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
@@ -54,9 +68,20 @@ DROP TABLE t1;
-- echo # Strings and NULLs -- echo # Strings and NULLs
-- echo # -- echo #
CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE; CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES (1, "Hello");
(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL), INSERT INTO t1 VALUES (1, "World");
(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL); INSERT INTO t1 VALUES (2, "This");
INSERT INTO t1 VALUES (2, "Will");
INSERT INTO t1 VALUES (2, "Work");
INSERT INTO t1 VALUES (2, "!");
INSERT INTO t1 VALUES (3, NULL);
INSERT INTO t1 VALUES (1, "Hello");
INSERT INTO t1 VALUES (1, "World");
INSERT INTO t1 VALUES (2, "This");
INSERT INTO t1 VALUES (2, "Will");
INSERT INTO t1 VALUES (2, "Work");
INSERT INTO t1 VALUES (2, "!");
INSERT INTO t1 VALUES (3, NULL);
SELECT JSON_VALID(JSON_ARRAYAGG(b)) FROM t1; SELECT JSON_VALID(JSON_ARRAYAGG(b)) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
@@ -75,13 +100,13 @@ SELECT JSON_ARRAYAGG(b LIMIT 1) FROM t1 GROUP BY b;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(b LIMIT 2) FROM t1 GROUP BY a; SELECT JSON_ARRAYAGG(b LIMIT 2) FROM t1 GROUP BY a;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT b) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC LIMIT 2) FROM t1; # SELECT JSON_ARRAYAGG(DISTINCT a LIMIT 2) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC LIMIT 2) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT b LIMIT 2) FROM t1;
-- echo # -- echo #
-- echo # JSON aggregation -- echo # JSON aggregation
@@ -113,10 +138,8 @@ SELECT JSON_ARRAYAGG(JSON_ARRAYAGG(a)) FROM t1;
-- echo # -- echo #
-- echo # -- echo #
DROP TABLE t1; DROP TABLE t1;
-- echo # -- echo #
-- echo # -- echo #
@@ -151,35 +174,45 @@ select json_object('x', json_arrayagg(json_object('a', 1)));
--echo # --echo #
CREATE TABLE t1(a INT, b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1(a INT, b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL); INSERT INTO t1 VALUES (NULL,NULL);
INSERT INTO t1 VALUES (NULL,NULL);
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(a VARCHAR(10), b INT)ENGINE=COLUMNSTORE; CREATE TABLE t1(a VARCHAR(10), b INT)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3); INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
INSERT INTO t1 VALUES (3,3);
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL); INSERT INTO t1 VALUES (NULL,NULL);
INSERT INTO t1 VALUES (NULL,NULL);
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; ## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
@@ -187,7 +220,8 @@ DROP TABLE t1;
--echo # --echo #
CREATE TABLE t1(a VARCHAR(255))ENGINE=COLUMNSTORE; CREATE TABLE t1(a VARCHAR(255))ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES ('red'),('blue'); INSERT INTO t1 VALUES ('red');
INSERT INTO t1 VALUES ('blue');
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) FROM t1; SELECT JSON_ARRAYAGG(a) FROM t1;
@@ -204,7 +238,8 @@ DROP TABLE t1;
set group_concat_max_len=64; set group_concat_max_len=64;
create table t1 (a varchar(254))ENGINE=COLUMNSTORE; create table t1 (a varchar(254))ENGINE=COLUMNSTORE;
insert into t1 values (concat('x64-', repeat('a', 60))); insert into t1 values (concat('x64-', repeat('a', 60)));
insert into t1 values (concat('x64-', repeat('b', 60))); insert into t1 values (concat('x64-', repeat('c', 60))); insert into t1 values (concat('x64-', repeat('b', 60)));
insert into t1 values (concat('x64-', repeat('c', 60)));
sorted_result; sorted_result;
select json_arrayagg(a) from t1; select json_arrayagg(a) from t1;
drop table t1; drop table t1;
@@ -215,8 +250,13 @@ SET group_concat_max_len= default;
CREATE TABLE t1(id int, name varchar(50))ENGINE=COLUMNSTORE; CREATE TABLE t1(id int, name varchar(50))ENGINE=COLUMNSTORE;
CREATE TABLE t2(id int, owner_id int)ENGINE=COLUMNSTORE; CREATE TABLE t2(id int, owner_id int)ENGINE=COLUMNSTORE;
INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); INSERT INTO t1 VALUES (1, "name1");
INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); INSERT INTO t1 VALUES (2, "name2");
INSERT INTO t1 VALUES (3, "name3");
INSERT INTO t2 VALUES (1, 1);
INSERT INTO t2 VALUES (2, 1);
INSERT INTO t2 VALUES (3, 2);
INSERT INTO t2 VALUES (4, 3);
SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials
from t1 LEFT JOIN t2 on t1.id = t2.owner_id from t1 LEFT JOIN t2 on t1.id = t2.owner_id
@@ -237,7 +277,8 @@ SELECT json_object('a', coalesce(json_object('b', 'c')));
CREATE TABLE t (a VARCHAR(8))ENGINE=COLUMNSTORE; CREATE TABLE t (a VARCHAR(8))ENGINE=COLUMNSTORE;
CREATE VIEW v AS SELECT * FROM t; CREATE VIEW v AS SELECT * FROM t;
INSERT INTO t VALUES ('foo'),('bar'); INSERT INTO t VALUES ('foo');
INSERT INTO t VALUES ('bar');
sorted_result; sorted_result;
SELECT JSON_ARRAYAGG(a) AS f FROM v; SELECT JSON_ARRAYAGG(a) AS f FROM v;
DROP VIEW v; DROP VIEW v;

View File

@@ -28,15 +28,11 @@ std::string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm&
return ""; return "";
const CHARSET_INFO* cs = getCharset(fp[0]); const CHARSET_INFO* cs = getCharset(fp[0]);
json_engine_t jsEg;
const uchar* arrEnd; const uchar* arrEnd;
size_t strRestLen; size_t strRestLen;
std::string retJS; std::string retJS;
retJS.reserve(js.length() + padding); retJS.reserve(js.length() + padding);
initJSPaths(paths, fp, 1, 2);
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++) for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++)
{ {

View File

@@ -1,6 +1,8 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "constantcolumn.h" #include "constantcolumn.h"
#include "json_lib.h"
#include "my_sys.h"
using namespace execplan; using namespace execplan;
#include "rowgroup.h" #include "rowgroup.h"
@@ -29,11 +31,9 @@ std::string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm&
const CHARSET_INFO* cs = getCharset(fp[0]); const CHARSET_INFO* cs = getCharset(fp[0]);
json_engine_t jsEg;
std::string retJS; std::string retJS;
retJS.reserve(js.length() + 8);
initJSPaths(paths, fp, 1, 2); retJS.reserve(js.length() + 8);
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++) for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++)
@@ -43,19 +43,34 @@ std::string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm&
JSONPath& path = paths[j]; JSONPath& path = paths[j];
if (!path.parsed) if (!path.parsed)
{ {
if (parseJSPath(path, row, fp[i]) || path.p.last_step - 1 < path.p.steps || #if MYSQL_VERSION_ID >= 120200
json_path_step_t *last_step= reinterpret_cast<json_path_step_t*>(mem_root_dynamic_array_get_val(&path.p.steps, path.p.last_step_idx)),
*initial_step= reinterpret_cast<json_path_step_t*>(path.p.steps.buffer);
#endif
#if MYSQL_VERSION_ID >= 120200
if (parseJSPath(path, row, fp[i]) || (last_step - 1) < initial_step ||
last_step->type != JSON_PATH_ARRAY)
#else
if (parseJSPath(path, row, fp[i]) || path.p.last_step - 1 < path.p.steps ||
path.p.last_step->type != JSON_PATH_ARRAY) path.p.last_step->type != JSON_PATH_ARRAY)
#endif
{ {
if (path.p.s.error == 0) if (path.p.s.error == 0)
path.p.s.error = SHOULD_END_WITH_ARRAY; path.p.s.error = SHOULD_END_WITH_ARRAY;
goto error; goto error;
} }
#if MYSQL_VERSION_ID >= 120200
path.p.last_step_idx--;
#else
path.p.last_step--; path.p.last_step--;
#endif
} }
initJSEngine(jsEg, cs, tmpJS); initJSEngine(jsEg, cs, tmpJS);
#if MYSQL_VERSION_ID < 120100
path.currStep = path.p.steps; path.currStep = path.p.steps;
#endif
int jsErr = 0; int jsErr = 0;
if (locateJSPath(jsEg, path, &jsErr)) if (locateJSPath(jsEg, path, &jsErr))
@@ -82,7 +97,13 @@ std::string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm&
while (json_scan_next(&jsEg) == 0 && jsEg.state != JST_ARRAY_END) while (json_scan_next(&jsEg) == 0 && jsEg.state != JST_ARRAY_END)
{ {
DBUG_ASSERT(jsEg.state == JST_VALUE); DBUG_ASSERT(jsEg.state == JST_VALUE);
#if MYSQL_VERSION_ID >= 120200
if (itemSize == ((reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val(&path.p.steps,
path.p.last_step_idx)))[1].n_item))
#else
if (itemSize == path.p.last_step[1].n_item) if (itemSize == path.p.last_step[1].n_item)
#endif
{ {
itemPos = (const char*)jsEg.s.c_str; itemPos = (const char*)jsEg.s.c_str;
break; break;

View File

@@ -1,6 +1,7 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "constantcolumn.h" #include "constantcolumn.h"
#include "json_lib.h"
#include "rowgroup.h" #include "rowgroup.h"
using namespace execplan; using namespace execplan;
using namespace rowgroup; using namespace rowgroup;
@@ -160,6 +161,7 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& /*type*/) CalpontSystemCatalog::ColType& /*type*/)
{ {
bool isNullJS = false, isNullVal = false; bool isNullJS = false, isNullVal = false;
const auto& js = fp[0]->data()->getStrVal(row, isNullJS); const auto& js = fp[0]->data()->getStrVal(row, isNullJS);
const auto& val = fp[1]->data()->getStrVal(row, isNullVal); const auto& val = fp[1]->data()->getStrVal(row, isNullVal);
if (isNullJS || isNullVal) if (isNullJS || isNullVal)
@@ -181,7 +183,6 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
arg2Parsed = arg2Const; arg2Parsed = arg2Const;
} }
json_engine_t jsEg;
initJSEngine(jsEg, getCharset(fp[0]), js); initJSEngine(jsEg, getCharset(fp[0]), js);
if (fp.size() > 2) if (fp.size() > 2)
@@ -193,7 +194,6 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
goto error; goto error;
} }
json_engine_t valEg;
initJSEngine(valEg, getCharset(fp[1]), arg2Val); initJSEngine(valEg, getCharset(fp[1]), arg2Val);
if (json_read_value(&jsEg) || json_read_value(&valEg)) if (json_read_value(&jsEg) || json_read_value(&valEg))

View File

@@ -17,7 +17,7 @@ using namespace funcexp::helpers;
namespace funcexp namespace funcexp
{ {
CalpontSystemCatalog::ColType Func_json_contains_path::operationType( CalpontSystemCatalog::ColType Func_json_contains_path::operationType(
FunctionParm& fp, CalpontSystemCatalog::ColType& /*resultType*/) FunctionParm& fp, [[maybe_unused]] CalpontSystemCatalog::ColType& resultType)
{ {
return fp[0]->data()->resultType(); return fp[0]->data()->resultType();
} }
@@ -26,7 +26,7 @@ CalpontSystemCatalog::ColType Func_json_contains_path::operationType(
* getBoolVal API definition * getBoolVal API definition
*/ */
bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
CalpontSystemCatalog::ColType& /*type*/) [[maybe_unused]] CalpontSystemCatalog::ColType& type)
{ {
const auto& js_ns = fp[0]->data()->getStrVal(row, isNull); const auto& js_ns = fp[0]->data()->getStrVal(row, isNull);
if (isNull) if (isNull)
@@ -61,7 +61,6 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul
isModeParsed = isModeConst; isModeParsed = isModeConst;
} }
initJSPaths(paths, fp, 2, 1);
if (paths.size() == 0) if (paths.size() == 0)
hasFound.assign(argSize, false); hasFound.assign(argSize, false);
@@ -82,8 +81,6 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul
} }
} }
json_engine_t jsEg;
json_path_t p;
json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)js.data(), (const uchar*)js.data() + js.size(), json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)js.data(), (const uchar*)js.data() + js.size(),
&p); &p);
@@ -99,12 +96,20 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul
while (json_get_path_next(&jsEg, &p) == 0) while (json_get_path_next(&jsEg, &p) == 0)
{ {
#if MYSQL_VERSION_ID >= 100900 #if MYSQL_VERSION_ID >= 100900
#if MYSQL_VERSION_ID >= 120200
json_path_step_t *last_step= reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val(&p.steps,
p.last_step_idx));
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounters + (last_step - reinterpret_cast<json_path_step_t*>(p.steps.buffer))))
#else
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps))) json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps)))
{ {
result = true; result = true;
break; break;
} }
#endif
#endif #endif
for (int restSize = argSize, curr = 0; restSize > 0; restSize--, curr++) for (int restSize = argSize, curr = 0; restSize > 0; restSize--, curr++)

View File

@@ -1,5 +1,6 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "json_lib.h"
using namespace execplan; using namespace execplan;
#include "rowgroup.h" #include "rowgroup.h"
@@ -29,7 +30,6 @@ int64_t Func_json_depth::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& i
int depth = 0, currDepth = 0; int depth = 0, currDepth = 0;
bool incDepth = true; bool incDepth = true;
json_engine_t jsEg;
initJSEngine(jsEg, getCharset(fp[0]), js); initJSEngine(jsEg, getCharset(fp[0]), js);
do do

View File

@@ -56,13 +56,22 @@ bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
const string_view js2 = js2_ns.unsafeStringRef(); const string_view js2 = js2_ns.unsafeStringRef();
bool result = false; bool result = false;
#if MYSQL_VERSION_ID >= 120200
if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]), NULL, &jsEg, &array))
#else
if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]))) if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0])))
#endif
{ {
isNull = true; isNull = true;
return result; return result;
} }
#if MYSQL_VERSION_ID >= 120200
if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]), NULL, &jsEg, &array))
#else
if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]))) if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1])))
#endif
{ {
isNull = true; isNull = true;
return result; return result;

View File

@@ -1,6 +1,7 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "constantcolumn.h" #include "constantcolumn.h"
#include "json_lib.h"
#include "rowgroup.h" #include "rowgroup.h"
using namespace execplan; using namespace execplan;
using namespace rowgroup; using namespace rowgroup;
@@ -29,9 +30,8 @@ bool Func_json_exists::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
return false; return false;
int jsErr = 0; int jsErr = 0;
json_engine_t jsEg;
initJSEngine(jsEg, getCharset(fp[0]), js);
initJSEngine(jsEg, getCharset(fp[0]), js);
if (!path.parsed && parseJSPath(path, row, fp[1])) if (!path.parsed && parseJSPath(path, row, fp[1]))
goto error; goto error;

View File

@@ -21,8 +21,6 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
if (isNull) if (isNull)
return 1; return 1;
const char* rawJS = js.str(); const char* rawJS = js.str();
json_engine_t jsEg, savJSEg;
json_path_t p;
const uchar* value; const uchar* value;
bool notFirstVal = false; bool notFirstVal = false;
size_t valLen; size_t valLen;
@@ -36,8 +34,6 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
const size_t argSize = fp.size(); const size_t argSize = fp.size();
std::string tmp; std::string tmp;
initJSPaths(paths, fp, 1, 1);
for (size_t i = 1; i < argSize; i++) for (size_t i = 1; i < argSize; i++)
{ {
JSONPath& path = paths[i - 1]; JSONPath& path = paths[i - 1];
@@ -71,8 +67,14 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t
while (json_get_path_next(&jsEg, &p) == 0) while (json_get_path_next(&jsEg, &p) == 0)
{ {
#if MYSQL_VERSION_ID >= 100900 #if MYSQL_VERSION_ID >= 100900
#if MYSQL_VERSION_ID >= 120200
json_path_step_t *last_step= reinterpret_cast<json_path_step_t*>(mem_root_dynamic_array_get_val(&p.steps, p.last_step_idx));
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounter + (last_step - reinterpret_cast<json_path_step_t*>(p.steps.buffer))))
#else
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps)))
#endif
return 1; return 1;
#endif #endif

View File

@@ -46,9 +46,9 @@ std::string Func_json_format::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
} }
} }
json_engine_t jsEg;
initJSEngine(jsEg, getCharset(fp[0]), js); initJSEngine(jsEg, getCharset(fp[0]), js);
std::string ret;
string ret;
if (doFormat(&jsEg, ret, fmt, tabSize)) if (doFormat(&jsEg, ret, fmt, tabSize))
{ {
isNull = true; isNull = true;

View File

@@ -30,15 +30,11 @@ std::string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
const bool isInsertMode = mode == INSERT || mode == SET; const bool isInsertMode = mode == INSERT || mode == SET;
const bool isReplaceMode = mode == REPLACE || mode == SET; const bool isReplaceMode = mode == REPLACE || mode == SET;
json_engine_t jsEg;
int jsErr = 0; int jsErr = 0;
json_string_t keyName; json_string_t keyName;
const CHARSET_INFO* cs = getCharset(fp[0]); const CHARSET_INFO* cs = getCharset(fp[0]);
json_string_set_cs(&keyName, cs); json_string_set_cs(&keyName, cs);
initJSPaths(paths, fp, 1, 2);
// Save the result of each merge and the result of the final merge separately // Save the result of each merge and the result of the final merge separately
std::string retJS; std::string retJS;
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
@@ -56,14 +52,27 @@ std::string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
if (parseJSPath(path, row, fp[i], false)) if (parseJSPath(path, row, fp[i], false))
goto error; goto error;
#if MYSQL_VERSION_ID >= 120200
path.p.last_step_idx--;
#else
path.p.last_step--; path.p.last_step--;
#endif
} }
initJSEngine(jsEg, cs, tmpJS); initJSEngine(jsEg, cs, tmpJS);
#if MYSQL_VERSION_ID >= 120200
if (path.p.last_step_idx < 0)
#else
if (path.p.last_step < path.p.steps) if (path.p.last_step < path.p.steps)
#endif
goto v_found; goto v_found;
#if MYSQL_VERSION_ID >= 120200
if (path.p.last_step_idx >= 0 && locateJSPath(jsEg, path, &jsErr))
#else
if (path.p.last_step >= path.p.steps && locateJSPath(jsEg, path, &jsErr)) if (path.p.last_step >= path.p.steps && locateJSPath(jsEg, path, &jsErr))
#endif
{ {
if (jsErr) if (jsErr)
goto error; goto error;
@@ -73,7 +82,23 @@ std::string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
if (json_read_value(&jsEg)) if (json_read_value(&jsEg))
goto error; goto error;
#if MYSQL_VERSION_ID >= 120200
if (path.p.last_step_idx < 0)
{
lastStep= (reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val(&path.p.steps,
0))) + path.p.last_step_idx + 1;
}
else
{
lastStep= (reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val(&path.p.steps,
path.p.last_step_idx))) + 1;
}
#else
lastStep = path.p.last_step + 1; lastStep = path.p.last_step + 1;
#endif
if (lastStep->type & JSON_PATH_ARRAY) if (lastStep->type & JSON_PATH_ARRAY)
{ {
IntType itemSize = 0; IntType itemSize = 0;

View File

@@ -60,7 +60,7 @@ std::string Func_json_keys::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool
IntType keySize = 0; IntType keySize = 0;
std::string ret; std::string ret;
json_engine_t jsEg;
initJSEngine(jsEg, getCharset(fp[0]), js); initJSEngine(jsEg, getCharset(fp[0]), js);
if (fp.size() > 1) if (fp.size() > 1)

View File

@@ -1,6 +1,7 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "constantcolumn.h" #include "constantcolumn.h"
#include "json_lib.h"
using namespace execplan; using namespace execplan;
#include "rowgroup.h" #include "rowgroup.h"
@@ -27,7 +28,6 @@ int64_t Func_json_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool&
if (isNull) if (isNull)
return 0; return 0;
json_engine_t jsEg;
int length = 0; int length = 0;
int err; int err;

View File

@@ -1,5 +1,6 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "json_lib.h"
using namespace execplan; using namespace execplan;
#include "rowgroup.h" #include "rowgroup.h"
@@ -223,8 +224,6 @@ std::string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, boo
const CHARSET_INFO* js1CS = getCharset(fp[0]); const CHARSET_INFO* js1CS = getCharset(fp[0]);
json_engine_t jsEg1, jsEg2;
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
std::string retJS; std::string retJS;
@@ -234,10 +233,10 @@ std::string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, boo
if (isNull) if (isNull)
goto error; goto error;
initJSEngine(jsEg1, js1CS, tmpJS); initJSEngine(jsEg, js1CS, tmpJS);
initJSEngine(jsEg2, getCharset(fp[i]), js2); initJSEngine(jsEg2, getCharset(fp[i]), js2);
if (doMerge(retJS, &jsEg1, &jsEg2)) if (doMerge(retJS, &jsEg, &jsEg2))
goto error; goto error;
// tmpJS save the merge result for next loop // tmpJS save the merge result for next loop
@@ -245,9 +244,9 @@ std::string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, boo
retJS.clear(); retJS.clear();
} }
initJSEngine(jsEg1, js1CS, tmpJS); initJSEngine(jsEg, js1CS, tmpJS);
retJS.clear(); retJS.clear();
if (doFormat(&jsEg1, retJS, Func_json_format::LOOSE)) if (doFormat(&jsEg, retJS, Func_json_format::LOOSE))
goto error; goto error;
isNull = false; isNull = false;

View File

@@ -1,5 +1,6 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "json_lib.h"
using namespace execplan; using namespace execplan;
#include "rowgroup.h" #include "rowgroup.h"
@@ -275,8 +276,7 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f
isNull = false; isNull = false;
json_engine_t jsEg1, jsEg2; jsEg.s.error = jsEg2.s.error = 0;
jsEg1.s.error = jsEg2.s.error = 0;
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
std::string retJS; std::string retJS;
@@ -304,8 +304,8 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f
goto next; goto next;
} }
initJSEngine(jsEg1, getCharset(fp[0]), tmpJS); initJSEngine(jsEg, getCharset(fp[0]), tmpJS);
if (doMergePatch(retJS, &jsEg1, &jsEg2, isEmpty)) if (doMergePatch(retJS, &jsEg, &jsEg2, isEmpty))
{ {
goto error; goto error;
} }
@@ -321,9 +321,9 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f
if (hasNullArg) if (hasNullArg)
goto error; goto error;
initJSEngine(jsEg1, getCharset(fp[0]), tmpJS); initJSEngine(jsEg, getCharset(fp[0]), tmpJS);
retJS.clear(); retJS.clear();
if (doFormat(&jsEg1, retJS, Func_json_format::LOOSE)) if (doFormat(&jsEg, retJS, Func_json_format::LOOSE))
goto error; goto error;
isNull = false; isNull = false;
return retJS; return retJS;

View File

@@ -36,7 +36,11 @@ std::string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp,
if (init_dynamic_string(str.get(), NULL, 0, 0)) if (init_dynamic_string(str.get(), NULL, 0, 0))
goto error; goto error;
#if MYSQL_VERSION_ID >= 120200
if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]), NULL, &jsEg, &array))
#else
if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]))) if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0])))
#endif
goto error; goto error;
return str->str; return str->str;

View File

@@ -1,5 +1,6 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "json_lib.h"
#include "rowgroup.h" #include "rowgroup.h"
using namespace execplan; using namespace execplan;
using namespace rowgroup; using namespace rowgroup;
@@ -279,20 +280,20 @@ bool Func_json_overlaps::getBoolVal(Row& row, FunctionParm& fp, bool& /*isNull*/
CalpontSystemCatalog::ColType& /*type*/) CalpontSystemCatalog::ColType& /*type*/)
{ {
bool isNullJS1 = false, isNullJS2 = false; bool isNullJS1 = false, isNullJS2 = false;
const auto js1 = fp[0]->data()->getStrVal(row, isNullJS1); const auto js1 = fp[0]->data()->getStrVal(row, isNullJS1);
const auto js2 = fp[1]->data()->getStrVal(row, isNullJS2); const auto js2 = fp[1]->data()->getStrVal(row, isNullJS2);
if (isNullJS1 || isNullJS2) if (isNullJS1 || isNullJS2)
return false; return false;
json_engine_t jsEg1, jsEg2; initJSEngine(jsEg, getCharset(fp[0]), js1);
initJSEngine(jsEg1, getCharset(fp[0]), js1);
initJSEngine(jsEg2, getCharset(fp[1]), js2); initJSEngine(jsEg2, getCharset(fp[1]), js2);
if (json_read_value(&jsEg1) || json_read_value(&jsEg2)) if (json_read_value(&jsEg) || json_read_value(&jsEg2))
return false; return false;
bool result = checkOverlaps(&jsEg1, &jsEg2, false); bool result = checkOverlaps(&jsEg, &jsEg2, false);
if (unlikely(jsEg1.s.error || jsEg2.s.error)) if (unlikely(jsEg.s.error || jsEg2.s.error))
return false; return false;
return result; return result;

View File

@@ -28,17 +28,14 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
if (isNull) if (isNull)
return ""; return "";
json_engine_t jsEg;
int jsErr = 0; int jsErr = 0;
json_string_t keyName; json_string_t keyName;
const CHARSET_INFO* cs = getCharset(fp[0]); const CHARSET_INFO* cs = getCharset(fp[0]);
json_string_set_cs(&keyName, cs); json_string_set_cs(&keyName, cs);
initJSPaths(paths, fp, 1, 1);
std::string retJS; std::string retJS;
utils::NullString tmpJS(js); utils::NullString tmpJS(js);
for (size_t i = 1, j = 0; i < fp.size(); i++, j++) for (size_t i = 1, j = 0; i < fp.size(); i++, j++)
{ {
const char* rawJS = tmpJS.str(); const char* rawJS = tmpJS.str();
@@ -49,13 +46,25 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
const char *remStart = nullptr, *remEnd = nullptr; const char *remStart = nullptr, *remEnd = nullptr;
IntType itemSize = 0; IntType itemSize = 0;
#if MYSQL_VERSION_ID >= 120200
json_path_step_t *curr_last_step= nullptr;
#endif
if (!path.parsed) if (!path.parsed)
{ {
if (parseJSPath(path, row, fp[i], false)) if (parseJSPath(path, row, fp[i], false))
goto error; goto error;
path.p.last_step--; #if MYSQL_VERSION_ID >= 120200
path.p.last_step_idx--;
curr_last_step= reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val(&path.p.steps,
path.p.last_step_idx));
if (curr_last_step < reinterpret_cast<json_path_step_t*>(path.p.steps.buffer))
#else
path.p.last_step--;
if (path.p.last_step < path.p.steps) if (path.p.last_step < path.p.steps)
#endif
{ {
path.p.s.error = TRIVIAL_PATH_NOT_ALLOWED; path.p.s.error = TRIVIAL_PATH_NOT_ALLOWED;
goto error; goto error;
@@ -64,7 +73,11 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
initJSEngine(jsEg, cs, tmpJS); initJSEngine(jsEg, cs, tmpJS);
#if MYSQL_VERSION_ID >= 120200
if (curr_last_step < reinterpret_cast<json_path_step_t*>(path.p.steps.buffer))
#else
if (path.p.last_step < path.p.steps) if (path.p.last_step < path.p.steps)
#endif
goto v_found; goto v_found;
if (locateJSPath(jsEg, path, &jsErr) && jsErr) if (locateJSPath(jsEg, path, &jsErr) && jsErr)
@@ -73,7 +86,12 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
if (json_read_value(&jsEg)) if (json_read_value(&jsEg))
goto error; goto error;
#if MYSQL_VERSION_ID >= 120200
lastStep = curr_last_step + 1;
#else
lastStep = path.p.last_step + 1; lastStep = path.p.last_step + 1;
#endif
if (lastStep->type & JSON_PATH_ARRAY) if (lastStep->type & JSON_PATH_ARRAY)
{ {
if (jsEg.value_type != JSON_VALUE_ARRAY) if (jsEg.value_type != JSON_VALUE_ARRAY)

View File

@@ -20,12 +20,20 @@ namespace
static bool appendJSPath(std::string& ret, const json_path_t* p) static bool appendJSPath(std::string& ret, const json_path_t* p)
{ {
const json_path_step_t* c; const json_path_step_t* c;
#if MYSQL_VERSION_ID >= 120200
const json_path_step_t* last_step= (const json_path_step_t*)
(mem_root_dynamic_array_get_val((MEM_ROOT_DYNAMIC_ARRAY*)&p->steps,
(size_t)p->last_step_idx));
#endif
try try
{ {
ret.append("\"$"); ret.append("\"$");
#if MYSQL_VERSION_ID >= 120200
for (c = reinterpret_cast<json_path_step_t*>(p->steps.buffer)+1; c <= last_step; c++)
#else
for (c = p->steps + 1; c <= p->last_step; c++) for (c = p->steps + 1; c <= p->last_step; c++)
#endif
{ {
if (c->type & JSON_PATH_KEY) if (c->type & JSON_PATH_KEY)
{ {
@@ -132,8 +140,6 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
escape = isNullEscape ? '\\' : escapeStr.safeString("")[0]; escape = isNullEscape ? '\\' : escapeStr.safeString("")[0];
} }
json_engine_t jsEg;
json_path_t p, savPath;
const CHARSET_INFO* cs = getCharset(fp[0]); const CHARSET_INFO* cs = getCharset(fp[0]);
#if MYSQL_VERSION_ID >= 100900 #if MYSQL_VERSION_ID >= 100900
@@ -142,11 +148,10 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
#endif #endif
int pathFound = 0; int pathFound = 0;
initJSPaths(paths, fp, 4, 1);
for (size_t i = 4; i < fp.size(); i++) for (size_t i = 4; i < fp.size(); i++)
{ {
JSONPath& path = paths[i - 4]; JSONPath& path = paths[i - 4];
if (!path.parsed) if (!path.parsed)
{ {
if (parseJSPath(path, row, fp[i])) if (parseJSPath(path, row, fp[i]))
@@ -162,8 +167,13 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
while (json_get_path_next(&jsEg, &p) == 0) while (json_get_path_next(&jsEg, &p) == 0)
{ {
#if MYSQL_VERSION_ID >= 100900 #if MYSQL_VERSION_ID >= 100900
#if MYSQL_VERSION_ID >= 120200
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounter + p.last_step_idx))
#else
if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps)))
#endif
goto error; goto error;
#endif #endif
@@ -180,7 +190,11 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo
if (pathFound == 1) if (pathFound == 1)
{ {
savPath = p; savPath = p;
#if MYSQL_VERSION_ID >= 120200
mem_root_dynamic_array_copy_values(&savPath.steps, &p.steps);
#else
savPath.last_step = savPath.steps + (p.last_step - p.steps); savPath.last_step = savPath.steps + (p.last_step - p.steps);
#endif
} }
else else
{ {

View File

@@ -26,7 +26,6 @@ std::string Func_json_type::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool
if (isNull) if (isNull)
return ""; return "";
json_engine_t jsEg;
std::string result; std::string result;
initJSEngine(jsEg, getCharset(fp[0]), js); initJSEngine(jsEg, getCharset(fp[0]), js);

View File

@@ -1,5 +1,6 @@
#include "functor_json.h" #include "functor_json.h"
#include "functioncolumn.h" #include "functioncolumn.h"
#include "json_lib.h"
#include "jsonhelpers.h" #include "jsonhelpers.h"
using namespace execplan; using namespace execplan;
@@ -26,10 +27,10 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b
if (isNull) if (isNull)
return ""; return "";
json_engine_t jsEg;
int strLen; int strLen;
const CHARSET_INFO* cs = type.getCharset(); const CHARSET_INFO* cs = type.getCharset();
initJSEngine(jsEg, cs, js); initJSEngine(jsEg, cs, js);
json_read_value(&jsEg); json_read_value(&jsEg);

View File

@@ -29,6 +29,10 @@ bool Func_json_valid::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
if (isNull) if (isNull)
return false; return false;
#if MYSQL_VERSION_ID >= 120200
return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0]), &jsEg);
#else
return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0])); return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0]));
#endif
} }
} // namespace funcexp } // namespace funcexp

View File

@@ -73,18 +73,31 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP
if (json_path_setup(&p, getCharset(funcParamPath), (const uchar*)sjsp.str(), (const uchar*)sjsp.end())) if (json_path_setup(&p, getCharset(funcParamPath), (const uchar*)sjsp.str(), (const uchar*)sjsp.end()))
return true; return true;
#if MYSQL_VERSION_ID >= 120200
JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast<const uchar*>(js.str()),
reinterpret_cast<const uchar*>(js.end()), je_stack);
#else
JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast<const uchar*>(js.str()), JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast<const uchar*>(js.str()),
reinterpret_cast<const uchar*>(js.end())); reinterpret_cast<const uchar*>(js.end()));
#endif
#if MYSQL_VERSION_ID >= 120200
currStep = reinterpret_cast<json_path_step_t*>(p.steps.buffer);
#else
currStep = p.steps; currStep = p.steps;
#endif
do do
{ {
if (error) if (error)
return true; return true;
#if MYSQL_VERSION_ID >= 120200
if (json_find_path(&je, &p, &currStep, &array))
#else
IntType arrayCounters[JSON_DEPTH_LIMIT]; IntType arrayCounters[JSON_DEPTH_LIMIT];
if (json_find_path(&je, &p, &currStep, arrayCounters)) if (json_find_path(&je, &p, &currStep, arrayCounters))
#endif
return true; return true;
if (json_read_value(&je)) if (json_read_value(&je))

View File

@@ -27,15 +27,130 @@ struct JSONPath
json_path_step_t* currStep; json_path_step_t* currStep;
}; };
class Func_json
{
protected:
json_engine_t jsEg;
#if MYSQL_VERSION_ID >= 120200
bool path_inited;
int jsEg_stack[JSON_DEPTH_LIMIT];
#endif
public:
Func_json()
{
#if MYSQL_VERSION_ID >= 120200
path_inited= false;
initJsonArray(NULL, &jsEg.stack, sizeof(int), &jsEg_stack[0],
MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
}
};
class Func_json_no_multipath : public Func_json
{
protected:
JSONPath path;
#if MYSQL_VERSION_ID >= 120200
json_path_step_t p_steps[JSON_DEPTH_LIMIT];
#endif
public:
void init_json_path_array()
{
#if MYSQL_VERSION_ID >= 120200
if (!path_inited)
{
initJsonArray(NULL, &path.p.steps, sizeof(json_path_step_t), &p_steps[0],
MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
path_inited= true;
}
#endif
return;
}
Func_json_no_multipath()
{
#if MYSQL_VERSION_ID >= 120200
init_json_path_array();
#endif
}
};
class Func_json_multipath : public Func_json
{
protected:
std::vector<JSONPath> paths;
#if MYSQL_VERSION_ID >= 120200
std::vector<std::vector<json_path_step_t>> p_steps_arr;
#endif
public:
inline void initJSPaths(std::vector<JSONPath>& paths, FunctionParm& fp,
const int start, const int step)
{
if (paths.empty())
for (size_t i = start; i < fp.size(); i += step)
paths.emplace_back();
}
#if MYSQL_VERSION_ID >= 120200
void init_json_multipath_array(bool& path_inited, std::vector<JSONPath>& paths,
std::vector<std::vector<json_path_step_t>>& p_steps_arr)
{
if (!path_inited)
{
for (size_t i=0; i<paths.size(); i++)
{
JSONPath& path = paths[i];
initJsonArray(NULL, &path.p.steps, sizeof(json_path_step_t), &p_steps_arr[i], MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
}
path_inited= true;
}
return;
}
#endif
Func_json_multipath() {}
Func_json_multipath(FunctionParm& fp, int start, int end)
{
initJSPaths(paths, fp, start, end);
#if MYSQL_VERSION_ID >= 120200
p_steps_arr = std::vector<std::vector<json_path_step_t>>(fp.size(),
std::vector<json_path_step_t>(JSON_DEPTH_LIMIT));
init_json_multipath_array(path_inited, paths, p_steps_arr);
#endif
}
~Func_json_multipath() {}
};
class JSONEgWrapper : public json_engine_t class JSONEgWrapper : public json_engine_t
{ {
public: public:
#if MYSQL_VERSION_ID >= 120200
JSONEgWrapper(CHARSET_INFO* cs, const uchar* str, const uchar* end, int *buffer)
#else
JSONEgWrapper(CHARSET_INFO* cs, const uchar* str, const uchar* end) JSONEgWrapper(CHARSET_INFO* cs, const uchar* str, const uchar* end)
#endif
{ {
#if MYSQL_VERSION_ID >= 120200
mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM,
&this->stack, sizeof(int), buffer,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
#endif
json_scan_start(this, cs, str, end); json_scan_start(this, cs, str, end);
} }
JSONEgWrapper(const std::string& str, CHARSET_INFO* cs) JSONEgWrapper(const std::string& str, CHARSET_INFO* cs)
: JSONEgWrapper(cs, (const uchar*)str.data(), (const uchar*)str.data() + str.size()) :
#if MYSQL_VERSION_ID >= 120200
JSONEgWrapper(cs, (const uchar*)str.data(), (const uchar*)str.data() + str.size(), NULL)
#else
JSONEgWrapper(cs, (const uchar*)str.data(), (const uchar*)str.data() + str.size())
#endif
{ {
} }
bool checkAndGetScalar(std::string& ret, int* error); bool checkAndGetScalar(std::string& ret, int* error);
@@ -44,17 +159,34 @@ class JSONEgWrapper : public json_engine_t
class JSONPathWrapper : public JSONPath class JSONPathWrapper : public JSONPath
{ {
private:
json_path_t p;
#if MYSQL_VERSION_ID >= 120200
int je_stack[JSON_DEPTH_LIMIT];
MEM_ROOT_DYNAMIC_ARRAY array;
json_path_step_t p_steps[JSON_DEPTH_LIMIT];
int arrayCounters[JSON_DEPTH_LIMIT];
#endif
protected: protected:
virtual ~JSONPathWrapper() = default; virtual ~JSONPathWrapper() = default;
virtual bool checkAndGetValue(JSONEgWrapper* je, std::string& ret, int* error) = 0; virtual bool checkAndGetValue(JSONEgWrapper* je, std::string& ret, int* error) = 0;
public: public:
JSONPathWrapper()
{
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &array, sizeof(int), &je_stack[0], MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
initJsonArray(NULL, &p.steps, sizeof(json_path_step_t), &p_steps, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
initJsonArray(NULL, &array, sizeof(int), &arrayCounters, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
}
bool extract(std::string& ret, rowgroup::Row& row, execplan::SPTP& funcParmJS, bool extract(std::string& ret, rowgroup::Row& row, execplan::SPTP& funcParmJS,
execplan::SPTP& funcParmPath); execplan::SPTP& funcParmPath);
}; };
/** @brief Func_json_valid class /** @brief Func_json_valid class
*/ */
class Func_json_valid : public Func_Bool class Func_json_valid : public Func_Bool, public Func_json
{ {
public: public:
Func_json_valid() : Func_Bool("json_valid") Func_json_valid() : Func_Bool("json_valid")
@@ -71,7 +203,7 @@ class Func_json_valid : public Func_Bool
/** @brief Func_json_depth class /** @brief Func_json_depth class
*/ */
class Func_json_depth : public Func_Int class Func_json_depth : public Func_Int, public Func_json
{ {
public: public:
Func_json_depth() : Func_Int("json_depth") Func_json_depth() : Func_Int("json_depth")
@@ -88,15 +220,11 @@ class Func_json_depth : public Func_Int
/** @brief Func_json_length class /** @brief Func_json_length class
*/ */
class Func_json_length : public Func_Int class Func_json_length : public Func_Int, public Func_json_no_multipath
{ {
protected:
JSONPath path;
public: public:
Func_json_length() : Func_Int("json_length") Func_json_length() : Func_Int("json_length"), Func_json_no_multipath()
{ {}
}
~Func_json_length() override = default; ~Func_json_length() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -108,11 +236,20 @@ class Func_json_length : public Func_Int
/** @brief Func_json_equals class /** @brief Func_json_equals class
*/ */
class Func_json_equals : public Func_Bool class Func_json_equals : public Func_Bool, public Func_json
{ {
private:
#if MYSQL_VERSION_ID >= 120200
MEM_ROOT_DYNAMIC_ARRAY array;
struct json_norm_value *buffer_array[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_equals() : Func_Bool("json_equals") Func_json_equals() : Func_Bool("json_equals")
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &array, sizeof(struct json_norm_value*), buffer_array, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_equals() override = default; ~Func_json_equals() override = default;
@@ -125,11 +262,19 @@ class Func_json_equals : public Func_Bool
/** @brief Func_json_normalize class /** @brief Func_json_normalize class
*/ */
class Func_json_normalize : public Func_Str class Func_json_normalize : public Func_Str, public Func_json
{ {
private:
#if MYSQL_VERSION_ID >= 120200
MEM_ROOT_DYNAMIC_ARRAY array;
struct json_norm_value *buffer_array[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_normalize() : Func_Str("json_normalize") Func_json_normalize() : Func_Str("json_normalize")
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &array, sizeof(struct json_norm_value*), buffer_array, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_normalize() override = default; ~Func_json_normalize() override = default;
@@ -142,7 +287,7 @@ class Func_json_normalize : public Func_Str
/** @brief Func_json_type class /** @brief Func_json_type class
*/ */
class Func_json_type : public Func_Str class Func_json_type : public Func_Str, public Func_json
{ {
public: public:
Func_json_type() : Func_Str("json_type") Func_json_type() : Func_Str("json_type")
@@ -192,13 +337,10 @@ class Func_json_array : public Func_Str
}; };
/** @brief Func_json_keys class /** @brief Func_json_keys class
*/ */
class Func_json_keys : public Func_Str class Func_json_keys : public Func_Str, public Func_json_no_multipath
{ {
protected:
JSONPath path;
public: public:
Func_json_keys() : Func_Str("json_keys") Func_json_keys() : Func_Str("json_keys"), Func_json_no_multipath()
{ {
} }
~Func_json_keys() override = default; ~Func_json_keys() override = default;
@@ -211,15 +353,11 @@ class Func_json_keys : public Func_Str
}; };
/** @brief Func_json_exists class /** @brief Func_json_exists class
*/ */
class Func_json_exists : public Func_Bool class Func_json_exists : public Func_Bool, public Func_json_no_multipath
{ {
protected:
JSONPath path;
public: public:
Func_json_exists() : Func_Bool("json_exists") Func_json_exists() : Func_Bool("json_exists"), Func_json_no_multipath()
{ {}
}
~Func_json_exists() override = default; ~Func_json_exists() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -231,15 +369,11 @@ class Func_json_exists : public Func_Bool
/** @brief Func_json_quote class /** @brief Func_json_quote class
*/ */
class Func_json_quote : public Func_Str class Func_json_quote : public Func_Str, public Func_json_no_multipath
{ {
protected:
JSONPath path;
public: public:
Func_json_quote() : Func_Str("json_quote") Func_json_quote() : Func_Str("json_quote"), Func_json_no_multipath()
{ {}
}
~Func_json_quote() override = default; ~Func_json_quote() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -251,15 +385,11 @@ class Func_json_quote : public Func_Str
/** @brief Func_json_unquote class /** @brief Func_json_unquote class
*/ */
class Func_json_unquote : public Func_Str class Func_json_unquote : public Func_Str, public Func_json_no_multipath
{ {
protected:
JSONPath path;
public: public:
Func_json_unquote() : Func_Str("json_unquote") Func_json_unquote() : Func_Str("json_unquote"), Func_json_no_multipath()
{ {}
}
~Func_json_unquote() override = default; ~Func_json_unquote() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -271,7 +401,7 @@ class Func_json_unquote : public Func_Str
/** @brief Func_json_format class /** @brief Func_json_format class
*/ */
class Func_json_format : public Func_Str class Func_json_format : public Func_Str, public Func_json
{ {
public: public:
enum FORMATS enum FORMATS
@@ -310,11 +440,19 @@ class Func_json_format : public Func_Str
}; };
/** @brief Func_json_merge_preserve class /** @brief Func_json_merge_preserve class
*/ */
class Func_json_merge : public Func_Str class Func_json_merge : public Func_Str, public Func_json
{ {
private:
json_engine_t jsEg2;
#if MYSQL_VERSION_ID >= 120200
int jsEg2_stack[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_merge() : Func_Str("json_merge_preserve") Func_json_merge() : Func_Str("json_merge_preserve")
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &jsEg2.stack, sizeof(int), &jsEg2_stack, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_merge() override = default; ~Func_json_merge() override = default;
@@ -327,11 +465,20 @@ class Func_json_merge : public Func_Str
/** @brief Func_json_merge_patch class /** @brief Func_json_merge_patch class
*/ */
class Func_json_merge_patch : public Func_Str class Func_json_merge_patch : public Func_Str, public Func_json
{ {
private:
json_engine_t jsEg2;
#if MYSQL_VERSION_ID >= 120200
int jsEg2_stack[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_merge_patch() : Func_Str("json_merge_patch") Func_json_merge_patch() : Func_Str("json_merge_patch")
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &jsEg2.stack, sizeof(int), &jsEg2_stack, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_merge_patch() override = default; ~Func_json_merge_patch() override = default;
@@ -348,8 +495,7 @@ class Func_json_value : public Func_Str
{ {
public: public:
Func_json_value() : Func_Str("json_value") Func_json_value() : Func_Str("json_value")
{ {}
}
~Func_json_value() override = default; ~Func_json_value() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -377,17 +523,24 @@ class Func_json_query : public Func_Str
}; };
/** @brief Func_json_contains class /** @brief Func_json_contains class
*/ */
class Func_json_contains : public Func_Bool class Func_json_contains : public Func_Bool, public Func_json_no_multipath
{ {
protected: protected:
JSONPath path;
bool arg2Const; bool arg2Const;
bool arg2Parsed; // argument 2 is a constant or has been parsed bool arg2Parsed; // argument 2 is a constant or has been parsed
utils::NullString arg2Val; utils::NullString arg2Val;
json_engine_t valEg;
#if MYSQL_VERSION_ID >= 120200
int valEg_stack[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_contains() : Func_Bool("json_contains"), arg2Const(false), arg2Parsed(false), arg2Val("") Func_json_contains() : Func_Bool("json_contains"), arg2Const(false),
arg2Parsed(false), arg2Val("")
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &valEg.stack, sizeof(int), &valEg_stack, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_contains() override = default; ~Func_json_contains() override = default;
@@ -399,15 +552,14 @@ class Func_json_contains : public Func_Bool
}; };
/** @brief Func_json_array_append class /** @brief Func_json_array_append class
*/ */
class Func_json_array_append : public Func_Str class Func_json_array_append : public Func_Str, public Func_json_multipath
{ {
protected:
std::vector<JSONPath> paths;
public: public:
Func_json_array_append() : Func_Str("json_array_append") Func_json_array_append() : Func_Str("json_array_append"), Func_json_multipath()
{ {}
} Func_json_array_append(FunctionParm& fp) : Func_Str("json_array_append"),
Func_json_multipath(fp, 1, 2)
{}
~Func_json_array_append() override = default; ~Func_json_array_append() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -421,15 +573,14 @@ class Func_json_array_append : public Func_Str
}; };
/** @brief Func_json_array_insert class /** @brief Func_json_array_insert class
*/ */
class Func_json_array_insert : public Func_Str class Func_json_array_insert : public Func_Str, public Func_json_multipath
{ {
protected:
std::vector<JSONPath> paths;
public: public:
Func_json_array_insert() : Func_Str("json_array_insert") Func_json_array_insert() : Func_Str("json_array_insert"), Func_json_multipath()
{ {}
} Func_json_array_insert(FunctionParm& fp) : Func_Str("json_array_insert"),
Func_json_multipath(fp, 1, 2)
{}
~Func_json_array_insert() override = default; ~Func_json_array_insert() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -441,7 +592,7 @@ class Func_json_array_insert : public Func_Str
/** @brief Func_json_insert class /** @brief Func_json_insert class
*/ */
class Func_json_insert : public Func_Str class Func_json_insert : public Func_json_multipath, public Func_Str
{ {
public: public:
enum MODE enum MODE
@@ -454,12 +605,14 @@ class Func_json_insert : public Func_Str
protected: protected:
MODE mode; MODE mode;
std::vector<JSONPath> paths;
public: public:
Func_json_insert() : Func_Str("json_insert"), mode(INSERT) Func_json_insert() : Func_json_multipath(), Func_Str("json_insert"), mode(INSERT)
{ {}
} Func_json_insert(FunctionParm& fp) :Func_json_multipath(fp, 1, 2),
Func_Str("json_insert"), mode(INSERT)
{}
explicit Func_json_insert(MODE m) : mode(m) explicit Func_json_insert(MODE m) : mode(m)
{ {
assert(m != NONE); assert(m != NONE);
@@ -471,6 +624,18 @@ class Func_json_insert : public Func_Str
default: break; default: break;
} }
} }
explicit Func_json_insert(FunctionParm& fp, MODE m) : Func_json_multipath(fp, 1, 2), mode(m)
{
assert(m != NONE);
switch (m)
{
case INSERT: Func_Str::Func::funcName("json_insert"); break;
case REPLACE: Func_Str::Func::funcName("json_replace"); break;
case SET: Func_Str::Func::funcName("json_set"); break;
default: break;
}
}
~Func_json_insert() override = default; ~Func_json_insert() override = default;
MODE getMode() const MODE getMode() const
@@ -486,15 +651,14 @@ class Func_json_insert : public Func_Str
}; };
/** @brief Func_json_remove class /** @brief Func_json_remove class
*/ */
class Func_json_remove : public Func_Str class Func_json_remove : public Func_Str, public Func_json_multipath
{ {
protected:
std::vector<JSONPath> paths;
public: public:
Func_json_remove() : Func_Str("json_remove") Func_json_remove() : Func_Str("json_remove"), Func_json_multipath()
{ {}
} Func_json_remove(FunctionParm& fp) : Func_Str("json_remove"), Func_json_multipath(fp, 1, 1)
{}
~Func_json_remove() override = default; ~Func_json_remove() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -506,19 +670,30 @@ class Func_json_remove : public Func_Str
/** @brief Func_json_contains_path class /** @brief Func_json_contains_path class
*/ */
class Func_json_contains_path : public Func_Bool class Func_json_contains_path : public Func_json_multipath, public Func_Bool
{ {
protected: protected:
std::vector<JSONPath> paths;
std::vector<bool> hasFound; std::vector<bool> hasFound;
bool isModeOne; bool isModeOne;
bool isModeConst; bool isModeConst;
bool isModeParsed; bool isModeParsed;
#if MYSQL_VERSION_ID >= 120200
json_path_step_t p_steps[JSON_DEPTH_LIMIT];
#endif
json_path_t p;
public: public:
Func_json_contains_path() Func_json_contains_path()
: Func_Bool("json_contains_path"), isModeOne(false), isModeConst(false), isModeParsed(false) : Func_json_multipath(), Func_Bool("json_contains_path"),
isModeOne(false), isModeConst(false), isModeParsed(false)
{}
Func_json_contains_path(FunctionParm& fp)
: Func_json_multipath(fp, 2, 1), Func_Bool("json_contains_path"),
isModeOne(false), isModeConst(false), isModeParsed(false)
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &p.steps, sizeof(json_path_step_t), &p_steps, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_contains_path() override = default; ~Func_json_contains_path() override = default;
@@ -531,14 +706,20 @@ class Func_json_contains_path : public Func_Bool
/** @brief Func_json_overlaps class /** @brief Func_json_overlaps class
*/ */
class Func_json_overlaps : public Func_Bool class Func_json_overlaps : public Func_Bool, public Func_json_no_multipath
{ {
protected: private:
JSONPath path; json_engine_t jsEg2;
#if MYSQL_VERSION_ID >= 120200
int jsEg2_stack[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_overlaps() : Func_Bool("json_overlaps") Func_json_overlaps() : Func_Bool("json_overlaps"), Func_json_no_multipath()
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &jsEg2.stack, sizeof(int), &jsEg2_stack, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_overlaps() override = default; ~Func_json_overlaps() override = default;
@@ -550,20 +731,36 @@ class Func_json_overlaps : public Func_Bool
}; };
/** @brief Func_json_search class /** @brief Func_json_search class
*/ */
class Func_json_search : public Func_Str class Func_json_search : public Func_json_multipath, public Func_Str
{ {
protected: protected:
std::vector<JSONPath> paths;
bool isModeParsed; bool isModeParsed;
bool isModeConst; bool isModeConst;
bool isModeOne; bool isModeOne;
int escape; int escape;
json_path_t p, savPath;
#if MYSQL_VERSION_ID >= 120200
json_path_step_t p_steps[JSON_DEPTH_LIMIT],
savPath_steps[JSON_DEPTH_LIMIT];
#endif
public: public:
Func_json_search() Func_json_search()
: Func_Str("json_search"), isModeParsed(false), isModeConst(false), isModeOne(false), escape('\\') : Func_json_multipath(), Func_Str("json_search"), isModeParsed(false),
isModeConst(false), isModeOne(false), escape('\\')
{ {
} }
Func_json_search(FunctionParm& fp)
: Func_json_multipath(fp, 4, 1), Func_Str("json_search"),
isModeParsed(false), isModeConst(false), isModeOne(false), escape('\\')
{
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &savPath.steps, sizeof(json_path_step_t), &savPath_steps, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
initJsonArray(NULL, &p.steps, sizeof(json_path_step_t), &p_steps, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
}
~Func_json_search() override = default; ~Func_json_search() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(
@@ -577,15 +774,29 @@ class Func_json_search : public Func_Str
}; };
/** @brief Func_json_extract_string class /** @brief Func_json_extract_string class
*/ */
class Func_json_extract : public Func_Str class Func_json_extract : public Func_Str, public Func_json_multipath
{ {
protected: json_engine_t savJSEg;
std::vector<JSONPath> paths; #if MYSQL_VERSION_ID >= 120200
int savJSEg_stack[JSON_DEPTH_LIMIT];
json_path_step_t p_steps[JSON_DEPTH_LIMIT];
#endif
json_path_t p;
public: public:
Func_json_extract() : Func_Str("json_extract") Func_json_extract() :Func_Str("json_extract"), Func_json_multipath()
{}
Func_json_extract(FunctionParm& fp) : Func_Str("json_extract"),
Func_json_multipath(fp, 1, 1)
{ {
#if MYSQL_VERSION_ID >= 120200
initJsonArray(NULL, &savJSEg.stack, sizeof(int),
&savJSEg_stack, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
initJsonArray(NULL, &p.steps, sizeof(json_path_step_t),
&p_steps, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
#endif
} }
~Func_json_extract() override = default; ~Func_json_extract() override = default;
execplan::CalpontSystemCatalog::ColType operationType( execplan::CalpontSystemCatalog::ColType operationType(

View File

@@ -335,7 +335,17 @@ int cmpPartJSPath(const json_path_step_t* a, const json_path_step_t* aEnd, const
int cmpJSPath(const json_path_t* a, const json_path_t* b, enum json_value_types vt, const int* arraySize) int cmpJSPath(const json_path_t* a, const json_path_t* b, enum json_value_types vt, const int* arraySize)
{ {
#if MYSQL_VERSION_ID >= 120200
json_path_step_t *a_last_step= reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val((MEM_ROOT_DYNAMIC_ARRAY*)&a->steps, (size_t)a->last_step_idx));
json_path_step_t *b_last_step= reinterpret_cast<json_path_step_t*>
(mem_root_dynamic_array_get_val((MEM_ROOT_DYNAMIC_ARRAY*)&b->steps, (size_t)b->last_step_idx));
return cmpPartJSPath((reinterpret_cast<json_path_step_t*>(a->steps.buffer)) + 1, a_last_step,
(reinterpret_cast<json_path_step_t*>(b->steps.buffer)) + 1, b_last_step,
vt, arraySize);
#else
return cmpPartJSPath(a->steps + 1, a->last_step, b->steps + 1, b->last_step, vt, arraySize); return cmpPartJSPath(a->steps + 1, a->last_step, b->steps + 1, b->last_step, vt, arraySize);
#endif
} }
int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards) int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards)
@@ -355,7 +365,7 @@ int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool w
return 0; return 0;
} }
bool matchJSPath(const vector<funcexp::JSONPath>& paths, const json_path_t* p, json_value_types valType, bool matchJSPath(const std::vector<funcexp::JSONPath>& paths, const json_path_t* p, json_value_types valType,
[[maybe_unused]] const int* arrayCounter, bool exact) [[maybe_unused]] const int* arrayCounter, bool exact)
{ {
for (size_t curr = 0; curr < paths.size(); curr++) for (size_t curr = 0; curr < paths.size(); curr++)
@@ -371,5 +381,7 @@ bool matchJSPath(const vector<funcexp::JSONPath>& paths, const json_path_t* p, j
} }
return false; return false;
} }
} // namespace helpers } // namespace helpers
} // namespace funcexp } // namespace funcexp

View File

@@ -63,8 +63,18 @@ using IntType = uint;
inline static int locateJSPath(json_engine_t& jsEg, JSONPath& path, int* jsErr = nullptr) inline static int locateJSPath(json_engine_t& jsEg, JSONPath& path, int* jsErr = nullptr)
{ {
IntType arrayCounters[JSON_DEPTH_LIMIT]; IntType arrayCounters[JSON_DEPTH_LIMIT];
#if MYSQL_VERSION_ID >= 120200
MEM_ROOT_DYNAMIC_ARRAY array;
initJsonArray(NULL, &array, sizeof(int), &arrayCounters, MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE);
path.currStep = reinterpret_cast<json_path_step_t*>(path.p.steps.buffer);
if (json_find_path(&jsEg, &path.p, &path.currStep, &array))
#else
path.currStep = path.p.steps; path.currStep = path.p.steps;
if (json_find_path(&jsEg, &path.p, &path.currStep, arrayCounters)) if (json_find_path(&jsEg, &path.p, &path.currStep, arrayCounters))
#endif
{ {
if (jsErr && jsEg.s.error) if (jsErr && jsEg.s.error)
*jsErr = 1; *jsErr = 1;
@@ -94,13 +104,6 @@ inline void initJSEngine(json_engine_t& jsEg, const CHARSET_INFO* jsCS, const ut
int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards = true); int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards = true);
inline void initJSPaths(std::vector<JSONPath>& paths, FunctionParm& fp, const int start, const int step)
{
if (paths.empty())
for (size_t i = start; i < fp.size(); i += step)
paths.emplace_back();
}
bool matchJSPath(const std::vector<funcexp::JSONPath>& paths, const json_path_t* p, json_value_types valType, bool matchJSPath(const std::vector<funcexp::JSONPath>& paths, const json_path_t* p, json_value_types valType,
const int* arrayCounter = nullptr, bool exact = true); const int* arrayCounter = nullptr, bool exact = true);
} // namespace funcexp::helpers } // namespace funcexp::helpers