From 9fe37d5919f2dd7eb31d1f23ec2439c4f2cb4928 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Thu, 22 May 2025 15:42:12 +0530 Subject: [PATCH] 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. --- dbcon/execplan/functioncolumn.cpp | 14 +- .../basic/r/func_json_array_append.result | 54 +-- .../basic/r/func_json_array_insert.result | 54 +-- .../basic/r/func_json_contains.result | 55 ++- .../basic/r/func_json_contains_path.result | 41 +- .../basic/r/func_json_exists.result | 16 +- .../basic/r/func_json_extract.result | 57 +-- .../basic/r/func_json_insert.result | 37 +- .../basic/r/func_json_merge_patch.result | 51 ++- .../basic/r/func_json_remove.result | 24 +- .../basic/r/func_json_valid.result | 98 ++--- .../basic/r/func_json_value.result | 36 +- .../basic/r/func_jsonarrayagg.result | 104 +++-- .../basic/t/func_json_array_append.test | 59 +-- .../basic/t/func_json_array_insert.test | 59 +-- .../basic/t/func_json_contains.test | 60 ++- .../basic/t/func_json_contains_path.test | 46 +-- .../columnstore/basic/t/func_json_exists.test | 28 +- .../basic/t/func_json_extract.test | 82 ++-- .../columnstore/basic/t/func_json_insert.test | 41 +- .../basic/t/func_json_merge_patch.test | 66 +-- .../columnstore/basic/t/func_json_remove.test | 24 +- .../columnstore/basic/t/func_json_valid.test | 105 ++--- .../columnstore/basic/t/func_json_value.test | 40 +- .../basic/t/func_jsonarrayagg.test | 101 +++-- utils/funcexp/func_json_array_append.cpp | 4 - utils/funcexp/func_json_array_insert.cpp | 29 +- utils/funcexp/func_json_contains.cpp | 4 +- utils/funcexp/func_json_contains_path.cpp | 15 +- utils/funcexp/func_json_depth.cpp | 2 +- utils/funcexp/func_json_equals.cpp | 9 + utils/funcexp/func_json_exists.cpp | 4 +- utils/funcexp/func_json_extract.cpp | 10 +- utils/funcexp/func_json_format.cpp | 4 +- utils/funcexp/func_json_insert.cpp | 33 +- utils/funcexp/func_json_keys.cpp | 2 +- utils/funcexp/func_json_length.cpp | 2 +- utils/funcexp/func_json_merge.cpp | 11 +- utils/funcexp/func_json_merge_patch.cpp | 12 +- utils/funcexp/func_json_normalize.cpp | 4 + utils/funcexp/func_json_overlaps.cpp | 11 +- utils/funcexp/func_json_remove.cpp | 28 +- utils/funcexp/func_json_search.cpp | 24 +- utils/funcexp/func_json_type.cpp | 1 - utils/funcexp/func_json_unquote.cpp | 3 +- utils/funcexp/func_json_valid.cpp | 4 + utils/funcexp/func_json_value.cpp | 15 +- utils/funcexp/functor_json.h | 385 ++++++++++++++---- utils/funcexp/jsonhelpers.cpp | 14 +- utils/funcexp/jsonhelpers.h | 17 +- 50 files changed, 1047 insertions(+), 952 deletions(-) diff --git a/dbcon/execplan/functioncolumn.cpp b/dbcon/execplan/functioncolumn.cpp index 7f10e0193..abcbfa535 100644 --- a/dbcon/execplan/functioncolumn.cpp +++ b/dbcon/execplan/functioncolumn.cpp @@ -354,25 +354,25 @@ void FunctionColumn::unserialize(messageqcpp::ByteStream& b) fFunctor = fDynamicFunctor = new Func_json_contains(); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_array_append(); + fFunctor = fDynamicFunctor = new Func_json_array_append(fFunctionParms); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_array_insert(); + fFunctor = fDynamicFunctor = new Func_json_array_insert(fFunctionParms); if (auto f = dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_insert(f->getMode()); + fFunctor = fDynamicFunctor = new Func_json_insert(fFunctionParms, f->getMode()); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_remove(); + fFunctor = fDynamicFunctor = new Func_json_remove(fFunctionParms); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_contains_path(); + fFunctor = fDynamicFunctor = new Func_json_contains_path(fFunctionParms); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_search(); + fFunctor = fDynamicFunctor = new Func_json_search(fFunctionParms); if (dynamic_cast(fFunctor)) - fFunctor = fDynamicFunctor = new Func_json_extract(); + fFunctor = fDynamicFunctor = new Func_json_extract(fFunctionParms); } bool FunctionColumn::operator==(const FunctionColumn& t) const diff --git a/mysql-test/columnstore/basic/r/func_json_array_append.result b/mysql-test/columnstore/basic/r/func_json_array_append.result index 145b56bbf..2c9d0e7c5 100644 --- a/mysql-test/columnstore/basic/r/func_json_array_append.result +++ b/mysql-test/columnstore/basic/r/func_json_array_append.result @@ -5,35 +5,16 @@ USE json_array_append_db; # Test of JSON_ARRAY_APPEND function. # ---------------------------------------------------------------------- CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t1 -VALUES -('[1,2,3]', '$[0]', 2), -('[1,2,3]', '$[0]', 1.2), -('[1,2,3]', '$[0]', 'key1'), -('[1,2,3]', '$[0]', TRUE), -('[1,2,3]', '$[0]', false), -('[1,2,3]', '$[0]', NULL), -( -'{"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' - ); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1'); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape'); +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'); SELECT a AS arrary, 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"]} # NULL args CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t2 -VALUES -('[1,2,3]'); +INSERT INTO t2 VALUES ('[1,2,3]'); SELECT JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_APPEND(a, '$', NULL) @@ -66,10 +44,7 @@ t2; JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_APPEND(a, '$', NULL) NULL [1, 2, 3, null] TRUNCATE t2; -INSERT INTO -t2 -VALUES -('$.b'); +INSERT INTO t2 VALUES ('$.b'); SELECT JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)), 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) NULL NULL TRUNCATE t2; -INSERT INTO -t2 -VALUES -('$**[0]'); +INSERT INTO t2 VALUES ('$**[0]'); error ER_INVALID_JSON_PATH_WILDCARD SELECT JSON_ARRAY_APPEND(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6) diff --git a/mysql-test/columnstore/basic/r/func_json_array_insert.result b/mysql-test/columnstore/basic/r/func_json_array_insert.result index f600ba7eb..bcd58075c 100644 --- a/mysql-test/columnstore/basic/r/func_json_array_insert.result +++ b/mysql-test/columnstore/basic/r/func_json_array_insert.result @@ -5,35 +5,16 @@ USE json_array_insert_db; # Test of JSON_ARRAY_INSERT function. # ---------------------------------------------------------------------- CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t1 -VALUES -('[1,2,3]', '$[0]', 2), -('[1,2,3]', '$[0]', 1.2), -('[1,2,3]', '$[0]', 'key1'), -('[1,2,3]', '$[0]', TRUE), -('[1,2,3]', '$[0]', false), -('[1,2,3]', '$[0]', NULL), -( -'{"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' - ); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1'); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape'); +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'); SELECT a AS arrary, p AS path, @@ -54,10 +35,7 @@ arrary path value result {"a": "foo", "b": [1,2,3], "c": ["apple","pear"]} $.c grape NULL # NULL args CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t2 -VALUES -('[1,2,3]'); +INSERT INTO t2 VALUES ('[1,2,3]'); SELECT JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)), JSON_ARRAY_INSERT(a, '$', NULL) @@ -66,10 +44,7 @@ t2; JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)) JSON_ARRAY_INSERT(a, '$', NULL) NULL NULL TRUNCATE t2; -INSERT INTO -t2 -VALUES -('$.b'); +INSERT INTO t2 VALUES ('$.b'); SELECT JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)), 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) NULL NULL TRUNCATE t2; -INSERT INTO -t2 -VALUES -('$**[0]'); +INSERT INTO t2 VALUES ('$**[0]'); error ER_INVALID_JSON_PATH_WILDCARD SELECT JSON_ARRAY_INSERT(JSON_COMPACT('{"a": {"b": [3]}}'), a, 6) diff --git a/mysql-test/columnstore/basic/r/func_json_contains.result b/mysql-test/columnstore/basic/r/func_json_contains.result index 06bf099aa..09cfbf5a0 100644 --- a/mysql-test/columnstore/basic/r/func_json_contains.result +++ b/mysql-test/columnstore/basic/r/func_json_contains.result @@ -5,16 +5,13 @@ USE json_contains_db; # Test of JSON_CONTAINS function. # ---------------------------------------------------------------------- CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore; -INSERT INTO -t1 -VALUES -('{"k1":123, "k2":345}', '123', '$.k1'), -('', '', '$'), -('null', 'null', '$'), -('"10"', '"10"', '$'), -('"10"', '10', '$'), -('10.1', '10', '$'), -('10.0', '10', '$'); +INSERT INTO t1 VALUES ('{"k1":123, "k2":345}', '123', '$.k1'); +INSERT INTO t1 VALUES ('', '', '$'); +INSERT INTO t1 VALUES ('null', 'null', '$'); +INSERT INTO t1 VALUES ('"10"', '"10"', '$'); +INSERT INTO t1 VALUES ('"10"', '10', '$'); +INSERT INTO t1 VALUES ('10.1', '10', '$'); +INSERT INTO t1 VALUES ('10.0', '10', '$'); SELECT j AS json, v AS value, @@ -31,28 +28,22 @@ null null $ 1 10.1 10 $ 0 10.0 10 $ 1 CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore; -INSERT INTO -t2 -VALUES -('"you"', '"you"'), -('"youth"', '"you"'), -('[1]', '1'), -('[2, 1]', '1'), -('[2, [2, 3], 1]', '1'), -('[4, [2, 3], 1]', '2'), -('[2, 1]', '[1, 2]'), -('[2, 1]', '[1, 0, 2]'), -('[2, 0, 3, 1]', '[1, 2]'), -('{"b":[1,2], "a":1}', '{"a":1, "b":2}'), -('{"a":1}', '{}'), -('[1, {"a":1}]', '{}'), -('[1, {"a":1}]', '{"a":1}'), -('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'), -( -'[{"abc":"def", "def":"abc"}, "bar"]', -'["bar", {}]' - ), -('[{"a":"b"},{"c":"d"}]', '{"c":"d"}'); +INSERT INTO t2 VALUES ('"you"', '"you"'); +INSERT INTO t2 VALUES ('"youth"', '"you"'); +INSERT INTO t2 VALUES ('[1]', '1'); +INSERT INTO t2 VALUES ('[2, 1]', '1'); +INSERT INTO t2 VALUES ('[2, [2, 3], 1]', '1'); +INSERT INTO t2 VALUES ('[4, [2, 3], 1]', '2'); +INSERT INTO t2 VALUES ('[2, 1]', '[1, 2]'); +INSERT INTO t2 VALUES ('[2, 1]', '[1, 0, 2]'); +INSERT INTO t2 VALUES ('[2, 0, 3, 1]', '[1, 2]'); +INSERT INTO t2 VALUES ('{"b":[1,2], "a":1}', '{"a":1, "b":2}'); +INSERT INTO t2 VALUES ('{"a":1}', '{}'); +INSERT INTO t2 VALUES ('[1, {"a":1}]', '{}'); +INSERT INTO t2 VALUES ('[1, {"a":1}]', '{"a":1}'); +INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'); +INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]'); +INSERT INTO t2 VALUES ('[{"a":"b"},{"c":"d"}]', '{"c":"d"}'); SELECT j AS json, v AS value, diff --git a/mysql-test/columnstore/basic/r/func_json_contains_path.result b/mysql-test/columnstore/basic/r/func_json_contains_path.result index ec3168dda..b2e55368f 100644 --- a/mysql-test/columnstore/basic/r/func_json_contains_path.result +++ b/mysql-test/columnstore/basic/r/func_json_contains_path.result @@ -5,16 +5,13 @@ USE json_contains_path_db; # Test of JSON_CONTAINS_PATH function. # ---------------------------------------------------------------------- CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t1 -VALUES -('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"), -('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"), -('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"), -('{"key1":1, "key2":[2,3]}', "one", "$.key1"), -('{ "a": true }', NULL, '$.a'), -('{ "a": true }', 'all', NULL), -('{"a":{"b":"c"}}', 'one', '$.a.*'); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1"); +INSERT INTO t1 VALUES ('{ "a": true }', NULL, '$.a'); +INSERT INTO t1 VALUES ('{ "a": true }', 'all', NULL); +INSERT INTO t1 VALUES ('{"a":{"b":"c"}}', 'one', '$.a.*'); SELECT j AS json, r AS return_flag, @@ -31,27 +28,9 @@ json return_flag path result { "a": true } all NULL NULL {"a":{"b":"c"}} one $.a.* 1 CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t2 -VALUES -( -'{"key1":1, "key2":[2,3]}', -"one", -"$.key1", -"$.ma" - ), -( -'{"key1":1, "key2":[2,3]}', -"aLl", -"$.key1", -"$.ma" - ), -( -'{"key1":1, "key2":[2,3]}', -"aLl", -"$.key1", -"$.key2" - ); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma"); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma"); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2"); SELECT j AS json, r AS return_flag, diff --git a/mysql-test/columnstore/basic/r/func_json_exists.result b/mysql-test/columnstore/basic/r/func_json_exists.result index 1ea2927fa..87c1b8a6e 100644 --- a/mysql-test/columnstore/basic/r/func_json_exists.result +++ b/mysql-test/columnstore/basic/r/func_json_exists.result @@ -6,16 +6,12 @@ USE json_exists_db; # ---------------------------------------------------------------------- # Test case 0 CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; -SET -@json = '{"key1":"xxxx", "key2":[1, 2, 3]}'; -INSERT INTO -t1 -VALUES -(@json, '$.key1'), -(@json, '$.key1[0]'), -(@json, '$.key2'), -(@json, '$.key2[1]'), -(@json, '$.key2[10]'); +SET @json = '{"key1":"xxxx", "key2":[1, 2, 3]}'; +INSERT INTO t1 VALUES (@json, '$.key1'); +INSERT INTO t1 VALUES (@json, '$.key1[0]'); +INSERT INTO t1 VALUES (@json, '$.key2'); +INSERT INTO t1 VALUES (@json, '$.key2[1]'); +INSERT INTO t1 VALUES (@json, '$.key2[10]'); SELECT j, p, diff --git a/mysql-test/columnstore/basic/r/func_json_extract.result b/mysql-test/columnstore/basic/r/func_json_extract.result index 836e9d1d6..10c7fb42c 100644 --- a/mysql-test/columnstore/basic/r/func_json_extract.result +++ b/mysql-test/columnstore/basic/r/func_json_extract.result @@ -8,26 +8,22 @@ USE json_extract_db; # Single path expression CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE; -SET -@json = '[1, "val2", [3.1, -4]]'; -INSERT INTO -t1 -VALUES -(@json, '$[0]'), -(@json, '$[1]'), -(@json, '$[2]'), -(@json, '$[3]'), -(@json, '$[2][0]'), -(@json, '$[2][1]'), -(@json, '$[2][10]'), -(@json, '$'), -('1', '$'), -('[10, 20, [30, 40], 1, 10]', '$[1]'), -('{"key1":"asd", "key2":[2,3]}', "$.key1"), -('{"key0":true, "key1":"qwe"}', "$.key1"), -('[10, 20, [30, 40]]', '$[2][*]'), -('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'), -(json_object('foo', 'foobar'), '$'); +SET @json = '[1, "val2", [3.1, -4]]'; +INSERT INTO t1 VALUES (@json, '$[0]'); +INSERT INTO t1 VALUES (@json, '$[1]'); +INSERT INTO t1 VALUES (@json, '$[2]'); +INSERT INTO t1 VALUES (@json, '$[3]'); +INSERT INTO t1 VALUES (@json, '$[2][0]'); +INSERT INTO t1 VALUES (@json, '$[2][1]'); +INSERT INTO t1 VALUES (@json, '$[2][10]'); +INSERT INTO t1 VALUES (@json, '$'); +INSERT INTO t1 VALUES ('1', '$'); +INSERT INTO t1 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]'); +INSERT INTO t1 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1"); +INSERT INTO t1 VALUES ('{"key0":true, "key1":"qwe"}', "$.key1"); +INSERT INTO t1 VALUES ('[10, 20, [30, 40]]', '$[2][*]'); +INSERT INTO t1 VALUES ('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); +INSERT INTO t1 VALUES (json_object('foo', 'foobar'), '$'); SELECT j, p, @@ -54,22 +50,11 @@ j p result # Multiple path expression CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t2 -VALUES -( -'{"key1":"asd", "key2":[2,3]}', -"$.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'); +INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY"); +INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2"); +INSERT INTO t2 VALUES ('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"); +INSERT INTO t2 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'); +INSERT INTO t2 VALUES ('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a'); SELECT j, p1, diff --git a/mysql-test/columnstore/basic/r/func_json_insert.result b/mysql-test/columnstore/basic/r/func_json_insert.result index e4accb8f6..c2e17d6f4 100644 --- a/mysql-test/columnstore/basic/r/func_json_insert.result +++ b/mysql-test/columnstore/basic/r/func_json_insert.result @@ -5,34 +5,15 @@ USE json_insert_de; # Test of JSON_INSERT|REPLACE|SET function. # ---------------------------------------------------------------------- CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t1 -VALUES -( -'{"a":1, "b":{"c":1}, "d":[1, 2]}', -'$.b.k1', -'word' - ), -('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3), -('{"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]' - ); +INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); +INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); +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'); +INSERT INTO t1 VALUES ('1', '$[0]', 4); +INSERT INTO t1 VALUES ('[]', '$[0][0]', 100); +INSERT INTO t1 VALUES ('1', '$[0][0]', 100); +INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.a', 10); +INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.b', '[true, false]'); SELECT j AS json, p AS path, diff --git a/mysql-test/columnstore/basic/r/func_json_merge_patch.result b/mysql-test/columnstore/basic/r/func_json_merge_patch.result index 606dbc24b..dbc5619ee 100644 --- a/mysql-test/columnstore/basic/r/func_json_merge_patch.result +++ b/mysql-test/columnstore/basic/r/func_json_merge_patch.result @@ -4,24 +4,23 @@ Note 1008 Can't drop database 'json_merge_patch_db'; database doesn't exist CREATE DATABASE json_merge_patch_db; USE json_merge_patch_db; CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore; -INSERT INTO t1(l1, l2) VALUES -('{"a":"b"}', '{"a":"c"}'), -('{"a":"b"}', '{"b":"c"}'), -('{"a":"b"}', '{"a":null}'), -('{"a":"b", "b":"c"}', '{"a":null}'), -('{"a":["b"]}', '{"a":"c"}'), -('{"a":"c"}', '{"a":["b"]}'), -('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'), -('{"a":[{"b":"c"}]}', '{"a": [1]}'), -('["a","b"]', '["c","d"]'), -('{"a":"b"}', '["c"]'), -('{"a":"foo"}', 'null'), -('{"a":"foo"}', '"bar"'), -('{"e":null}', '{"a":1}'), -('[1,2]', '{"a":"b", "c":null}'), -('{}', '{"a":{"bb":{"ccc":null}}}'), -(NULL, '{}'), -('{}', NULL); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"b":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":null}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b", "b":"c"}', '{"a":null}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":["b"]}', '{"a":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"c"}', '{"a":["b"]}'); +INSERT INTO t1(l1, l2) VALUES ('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":[{"b":"c"}]}', '{"a": [1]}'); +INSERT INTO t1(l1, l2) VALUES ('["a","b"]', '["c","d"]'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '["c"]'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', 'null'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', '"bar"'); +INSERT INTO t1(l1, l2) VALUES ('{"e":null}', '{"a":1}'); +INSERT INTO t1(l1, l2) VALUES ('[1,2]', '{"a":"b", "c":null}'); +INSERT INTO t1(l1, l2) VALUES ('{}', '{"a":{"bb":{"ccc":null}}}'); +INSERT INTO t1(l1, l2) VALUES (NULL, '{}'); +INSERT INTO t1(l1, l2) VALUES ('{}', NULL); SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS `l1 + l2` FROM t1; @@ -45,11 +44,10 @@ NULL {} NULL {} NULL NULL DROP TABLE t1; CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore; -INSERT INTO t2 VALUES -('{"a":"b"}', NULL, '{"c":"d"}'), -(NULL, '[1,2,3]', '[4,5,6]'), -(NULL, 'a', 'b'), -('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}'); +INSERT INTO t2 VALUES ('{"a":"b"}', NULL, '{"c":"d"}'); +INSERT INTO t2 VALUES (NULL, '[1,2,3]', '[4,5,6]'); +INSERT INTO t2 VALUES (NULL, 'a', 'b'); +INSERT INTO t2 VALUES ('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}'); SELECT l1, l2, l3, JSON_MERGE_PATCH(l1, l2, l3) AS merged FROM t2; @@ -62,12 +60,11 @@ DROP TABLE t2; CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore; SELECT JSON_MERGE_PATCH() FROM t3; 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; ERROR 42000: Incorrect parameter count in the call to native function 'JSON_MERGE_PATCH' -INSERT INTO t3(l1, l2) VALUES -('{', '[1,2,3]'), -('{"a":"b"}', '[1,'); +INSERT INTO t3(l1, l2) VALUES ('{', '[1,2,3]'); +INSERT INTO t3(l1, l2) VALUES ('{"a":"b"}', '[1,'); SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3; l1 l2 merged {} {"a":"c"} {"a": "c"} diff --git a/mysql-test/columnstore/basic/r/func_json_remove.result b/mysql-test/columnstore/basic/r/func_json_remove.result index feeda8ca8..b6155a2ae 100644 --- a/mysql-test/columnstore/basic/r/func_json_remove.result +++ b/mysql-test/columnstore/basic/r/func_json_remove.result @@ -5,13 +5,10 @@ USE json_remove_db; # Test of JSON_REMOVE function. # ---------------------------------------------------------------------- CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; -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]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1][0]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]'); SELECT j AS json, p AS path, @@ -24,14 +21,11 @@ json path result ["a", ["b", "c"], "d"] $[1][0] ["a", ["c"], "d"] ["a", ["b", "c"], "d"] $[0] [["b", "c"], "d"] CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore; -INSERT INTO -t2 -VALUES -('{"a": 1, "b": [2, 3]}', '$.a'), -('{"a": 1, "b": [2, 3]}', '$.a[0]'), -('{"a": 1, "b": [2, 3]}', '$.b'), -('{"a": 1, "b": [2, 3]}', '$.b[0]'), -('{"a": 1, "b": [2, 3]}', '$.b[1]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a[0]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[0]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[1]'); SELECT j AS json, p AS path, diff --git a/mysql-test/columnstore/basic/r/func_json_valid.result b/mysql-test/columnstore/basic/r/func_json_valid.result index 5dab14023..86efa3e13 100644 --- a/mysql-test/columnstore/basic/r/func_json_valid.result +++ b/mysql-test/columnstore/basic/r/func_json_valid.result @@ -8,23 +8,20 @@ USE json_valid_db; # String literal - valid JSON # CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE; -INSERT INTO -t1 -VALUES -('123'), -('-123'), -('5000000000'), -('-5000000000'), -('1.23'), -('"123"'), -('true'), -('false'), -('null'), -('{"address": "Trondheim"}'), -(JSON_OBJECT()), -(JSON_OBJECT(1, 2)), -(JSON_ARRAY()), -(JSON_ARRAY(1, 2)); +INSERT INTO t1 VALUES ('123'); +INSERT INTO t1 VALUES ('-123'); +INSERT INTO t1 VALUES ('5000000000'); +INSERT INTO t1 VALUES ('-5000000000'); +INSERT INTO t1 VALUES ('1.23'); +INSERT INTO t1 VALUES ('"123"'); +INSERT INTO t1 VALUES ('true'); +INSERT INTO t1 VALUES ('false'); +INSERT INTO t1 VALUES ('null'); +INSERT INTO t1 VALUES ('{"address": "Trondheim"}'); +INSERT INTO t1 VALUES (JSON_OBJECT()); +INSERT INTO t1 VALUES (JSON_OBJECT(1, 2)); +INSERT INTO t1 VALUES (JSON_ARRAY()); +INSERT INTO t1 VALUES (JSON_ARRAY(1, 2)); SELECT l AS raw, JSON_VALID(l) AS is_valid, @@ -50,14 +47,11 @@ null 1 1 # String literal - invalid JSON # TRUNCATE t1; -INSERT INTO -t1 -VALUES -('12 3'), -('{key:value}'), -('{key:value'), -('[1,2,]'), -('[1,2'); +INSERT INTO t1 VALUES ('12 3'); +INSERT INTO t1 VALUES ('{key:value}'); +INSERT INTO t1 VALUES ('{key:value'); +INSERT INTO t1 VALUES ('[1,2,]'); +INSERT INTO t1 VALUES ('[1,2'); SELECT l AS raw, JSON_VALID(l) AS is_valid, @@ -74,12 +68,8 @@ raw is_valid compact # String literal - not in UTF-8 # TRUNCATE t1; -SET -NAMES 'ascii'; -INSERT INTO -t1 -VALUES -('123'); +SET NAMES 'ascii'; +INSERT INTO t1 VALUES ('123'); SELECT l AS raw, JSON_VALID(l) AS is_valid, @@ -88,16 +78,12 @@ FROM t1; raw is_valid compact 123 1 1 -SET -NAMES 'utf8'; +SET NAMES 'utf8'; # # Bare NULL # TRUNCATE t1; -INSERT INTO -t1 -VALUES -(NULL); +INSERT INTO t1 VALUES (NULL); SELECT JSON_VALID(l) FROM @@ -108,10 +94,7 @@ NULL # Function result - string # TRUNCATE t1; -INSERT INTO -t1 -VALUES -(UPPER('"abc"')); +INSERT INTO t1 VALUES (UPPER('"abc"')); SELECT JSON_VALID(l) FROM @@ -122,28 +105,20 @@ JSON_VALID(l) # Function result - string not in UTF-8 # TRUNCATE t1; -SET -NAMES 'latin1'; -INSERT INTO -t1 -VALUES -(UPPER('"abc"')); +SET NAMES 'latin1'; +INSERT INTO t1 VALUES (UPPER('"abc"')); SELECT JSON_VALID(l) FROM t1; JSON_VALID(l) 1 -SET -NAMES 'utf8'; +SET NAMES 'utf8'; # # Function result - date, not valid as JSON without CAST # TRUNCATE t1; -INSERT INTO -t1 -VALUES -(CAST('2015-01-15' AS DATE)); +INSERT INTO t1 VALUES (CAST('2015-01-15' AS DATE)); SELECT JSON_VALID(l) FROM @@ -154,13 +129,10 @@ JSON_VALID(l) # The date string doesn't parse as JSON text, so wrong: # TRUNCATE t1; -INSERT INTO -t1 -VALUES -( +INSERT INTO t1 VALUES ( CAST( CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8' - ) + ) ); SELECT JSON_VALID(l) @@ -172,14 +144,8 @@ JSON_VALID(l) # Function result - NULL # TRUNCATE t1; -INSERT INTO -t1 -VALUES -(UPPER(NULL)); -INSERT INTO -t1 -VALUES -(UPPER(CAST(NULL AS CHAR))); +INSERT INTO t1 VALUES (UPPER(NULL)); +INSERT INTO t1 VALUES (UPPER(CAST(NULL AS CHAR))); SELECT JSON_VALID(l) FROM diff --git a/mysql-test/columnstore/basic/r/func_json_value.result b/mysql-test/columnstore/basic/r/func_json_value.result index 009703c02..4469fca03 100644 --- a/mysql-test/columnstore/basic/r/func_json_value.result +++ b/mysql-test/columnstore/basic/r/func_json_value.result @@ -5,15 +5,17 @@ USE json_value_db; # Test of JSON_VALUE function. # ---------------------------------------------------------------------- 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; json_text path json_value json_query {"key1":123} $.key2 NULL NULL @@ -25,9 +27,9 @@ json_text path json_value json_query {"\"key1\"":123} $."\"key1\"" 123 NULL {"key 1":123} $."key 1" 123 NULL CREATE TABLE t2(s TEXT) ENGINE = columnstore; -INSERT INTO t2 VALUES('{"key1":123, "key2":{"key3":"value3"}}'), -('{"key1":123, "key3":[1,2,3]}'), -('{"key1":123, "key2":"[1]"}'); +INSERT INTO t2 VALUES ('{"key1":123, "key2":{"key3":"value3"}}'); +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 FROM t2; json_text $.key1 json_value json_query @@ -49,7 +51,15 @@ json_text $.key3 json_value json_query DROP TABLE t2; DROP TABLE t1; 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; diff --git a/mysql-test/columnstore/basic/r/func_jsonarrayagg.result b/mysql-test/columnstore/basic/r/func_jsonarrayagg.result index 6160fb43b..63f6d4c6e 100644 --- a/mysql-test/columnstore/basic/r/func_jsonarrayagg.result +++ b/mysql-test/columnstore/basic/r/func_jsonarrayagg.result @@ -4,7 +4,14 @@ Note 1008 Can't drop database 'json_arrayagg_db'; database doesn't exist CREATE DATABASE json_arrayagg_db; USE json_arrayagg_db; 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; JSON_VALID(JSON_ARRAYAGG(a)) 1 @@ -20,7 +27,10 @@ DROP TABLE t1; # Real aggregation # 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; JSON_VALID(JSON_ARRAYAGG(a)) 1 @@ -32,7 +42,10 @@ DROP TABLE t1; # Boolean aggregation # 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; JSON_VALID(JSON_ARRAYAGG(a)) 1 @@ -51,9 +64,10 @@ DROP TABLE t1; # Aggregation of strings with quoted # CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES -('"double_quoted_value"'), ("'single_quoted_value'"), -('"double_quoted_value"'), ("'single_quoted_value'"); +INSERT INTO t1 VALUES ('"double_quoted_value"'); +INSERT INTO t1 VALUES ("'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; JSON_VALID(JSON_ARRAYAGG(a)) 1 @@ -65,9 +79,20 @@ DROP TABLE t1; # Strings and NULLs # CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES -(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL), -(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (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); +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; JSON_VALID(JSON_ARRAYAGG(b)) 1 @@ -102,18 +127,6 @@ JSON_ARRAYAGG(b LIMIT 2) ["Hello","World","Hello","World"] ["This","Will","Work","!","This","Will","Work","!"] [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 # @@ -184,43 +197,42 @@ json_object('x', json_arrayagg(json_object('a', 1))) # # 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), (2,2), (3,3); +INSERT INTO t1 VALUES (1,1); +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; JSON_ARRAYAGG(a) [1,2,3,1,2,3] -SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; -JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) -[1,2,3] -INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL); +INSERT INTO t1 VALUES (NULL,NULL); +INSERT INTO t1 VALUES (NULL,NULL); SELECT JSON_ARRAYAGG(a) FROM t1; JSON_ARRAYAGG(a) [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; 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), (2,2), (3,3); +INSERT INTO t1 VALUES (1,1); +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; JSON_ARRAYAGG(a) [1,2,3,1,2,3] -SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; -JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) -[1,2,3] -INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL); +INSERT INTO t1 VALUES (NULL,NULL); +INSERT INTO t1 VALUES (NULL,NULL); SELECT JSON_ARRAYAGG(a) FROM t1; JSON_ARRAYAGG(a) [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; # # 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; JSON_ARRAYAGG(a) ["red","blue"] @@ -253,8 +265,13 @@ drop table t1; SET group_concat_max_len= default; CREATE TABLE t1(id int, name varchar(50))ENGINE=COLUMNSTORE; CREATE TABLE t2(id int, owner_id int)ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); -INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); +INSERT INTO t1 VALUES (1, "name1"); +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 from t1 LEFT JOIN t2 on t1.id = t2.owner_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 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; f ["foo","bar"] diff --git a/mysql-test/columnstore/basic/t/func_json_array_append.test b/mysql-test/columnstore/basic/t/func_json_array_append.test index 3d906381a..0ecb84fca 100644 --- a/mysql-test/columnstore/basic/t/func_json_array_append.test +++ b/mysql-test/columnstore/basic/t/func_json_array_append.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_array_append_db; - --enable_warnings + CREATE DATABASE json_array_append_db; USE json_array_append_db; @@ -10,37 +10,19 @@ USE json_array_append_db; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_ARRAY_APPEND function. --echo # ---------------------------------------------------------------------- + CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t1 -VALUES - ('[1,2,3]', '$[0]', 2), - ('[1,2,3]', '$[0]', 1.2), - ('[1,2,3]', '$[0]', 'key1'), - ('[1,2,3]', '$[0]', TRUE), - ('[1,2,3]', '$[0]', false), - ('[1,2,3]', '$[0]', NULL), - ( - '{"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' - ); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1'); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape'); +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'); SELECT a AS arrary, @@ -53,10 +35,7 @@ FROM --echo # NULL args CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t2 -VALUES - ('[1,2,3]'); +INSERT INTO t2 VALUES ('[1,2,3]'); SELECT JSON_ARRAY_APPEND(a, NULL, JSON_COMPACT(1)), @@ -66,10 +45,7 @@ FROM TRUNCATE t2; -INSERT INTO - t2 -VALUES - ('$.b'); +INSERT INTO t2 VALUES ('$.b'); SELECT JSON_ARRAY_APPEND(NULL, a, JSON_COMPACT(1)), @@ -79,10 +55,7 @@ FROM TRUNCATE t2; -INSERT INTO - t2 -VALUES - ('$**[0]'); +INSERT INTO t2 VALUES ('$**[0]'); --echo error ER_INVALID_JSON_PATH_WILDCARD SELECT @@ -91,7 +64,5 @@ FROM t2; DROP TABLE t2; - DROP TABLE t1; - DROP DATABASE json_array_append_db; diff --git a/mysql-test/columnstore/basic/t/func_json_array_insert.test b/mysql-test/columnstore/basic/t/func_json_array_insert.test index a6c4e66fe..e08d03335 100644 --- a/mysql-test/columnstore/basic/t/func_json_array_insert.test +++ b/mysql-test/columnstore/basic/t/func_json_array_insert.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_array_insert_db; - --enable_warnings + CREATE DATABASE json_array_insert_db; USE json_array_insert_db; @@ -10,37 +10,19 @@ USE json_array_insert_db; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_ARRAY_INSERT function. --echo # ---------------------------------------------------------------------- + CREATE TABLE t1(a TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t1 -VALUES - ('[1,2,3]', '$[0]', 2), - ('[1,2,3]', '$[0]', 1.2), - ('[1,2,3]', '$[0]', 'key1'), - ('[1,2,3]', '$[0]', TRUE), - ('[1,2,3]', '$[0]', false), - ('[1,2,3]', '$[0]', NULL), - ( - '{"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' - ); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 1.2); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', 'key1'); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', TRUE); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', false); +INSERT INTO t1 VALUES ('[1,2,3]', '$[0]', NULL); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.b', 4); +INSERT INTO t1 VALUES ('{"a": "foo", "b": "bar", "c": "wibble" }', '$.c', 'grape'); +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'); SELECT a AS arrary, @@ -53,10 +35,7 @@ FROM --echo # NULL args CREATE TABLE t2(a TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t2 -VALUES - ('[1,2,3]'); +INSERT INTO t2 VALUES ('[1,2,3]'); SELECT JSON_ARRAY_INSERT(a, NULL, JSON_COMPACT(1)), @@ -66,10 +45,7 @@ FROM TRUNCATE t2; -INSERT INTO - t2 -VALUES - ('$.b'); +INSERT INTO t2 VALUES ('$.b'); SELECT JSON_ARRAY_INSERT(NULL, a, JSON_COMPACT(1)), @@ -79,10 +55,7 @@ FROM TRUNCATE t2; -INSERT INTO - t2 -VALUES - ('$**[0]'); +INSERT INTO t2 VALUES ('$**[0]'); --echo error ER_INVALID_JSON_PATH_WILDCARD SELECT @@ -91,7 +64,5 @@ FROM t2; DROP TABLE t2; - DROP TABLE t1; - DROP DATABASE json_array_insert_db; diff --git a/mysql-test/columnstore/basic/t/func_json_contains.test b/mysql-test/columnstore/basic/t/func_json_contains.test index bc75c2af9..451377e5d 100644 --- a/mysql-test/columnstore/basic/t/func_json_contains.test +++ b/mysql-test/columnstore/basic/t/func_json_contains.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_contains_db; - --enable_warnings + CREATE DATABASE json_contains_db; USE json_contains_db; @@ -10,18 +10,16 @@ USE json_contains_db; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_CONTAINS function. --echo # ---------------------------------------------------------------------- + CREATE TABLE t1(j LONGTEXT, v LONGTEXT, p LONGTEXT) ENGINE = columnstore; -INSERT INTO - t1 -VALUES - ('{"k1":123, "k2":345}', '123', '$.k1'), - ('', '', '$'), - ('null', 'null', '$'), - ('"10"', '"10"', '$'), - ('"10"', '10', '$'), - ('10.1', '10', '$'), - ('10.0', '10', '$'); +INSERT INTO t1 VALUES ('{"k1":123, "k2":345}', '123', '$.k1'); +INSERT INTO t1 VALUES ('', '', '$'); +INSERT INTO t1 VALUES ('null', 'null', '$'); +INSERT INTO t1 VALUES ('"10"', '"10"', '$'); +INSERT INTO t1 VALUES ('"10"', '10', '$'); +INSERT INTO t1 VALUES ('10.1', '10', '$'); +INSERT INTO t1 VALUES ('10.0', '10', '$'); SELECT j AS json, @@ -33,28 +31,22 @@ FROM CREATE TABLE t2(j LONGTEXT, v LONGTEXT) ENGINE = columnstore; -INSERT INTO - t2 -VALUES - ('"you"', '"you"'), - ('"youth"', '"you"'), - ('[1]', '1'), - ('[2, 1]', '1'), - ('[2, [2, 3], 1]', '1'), - ('[4, [2, 3], 1]', '2'), - ('[2, 1]', '[1, 2]'), - ('[2, 1]', '[1, 0, 2]'), - ('[2, 0, 3, 1]', '[1, 2]'), - ('{"b":[1,2], "a":1}', '{"a":1, "b":2}'), - ('{"a":1}', '{}'), - ('[1, {"a":1}]', '{}'), - ('[1, {"a":1}]', '{"a":1}'), - ('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'), - ( - '[{"abc":"def", "def":"abc"}, "bar"]', - '["bar", {}]' - ), - ('[{"a":"b"},{"c":"d"}]', '{"c":"d"}'); +INSERT INTO t2 VALUES ('"you"', '"you"'); +INSERT INTO t2 VALUES ('"youth"', '"you"'); +INSERT INTO t2 VALUES ('[1]', '1'); +INSERT INTO t2 VALUES ('[2, 1]', '1'); +INSERT INTO t2 VALUES ('[2, [2, 3], 1]', '1'); +INSERT INTO t2 VALUES ('[4, [2, 3], 1]', '2'); +INSERT INTO t2 VALUES ('[2, 1]', '[1, 2]'); +INSERT INTO t2 VALUES ('[2, 1]', '[1, 0, 2]'); +INSERT INTO t2 VALUES ('[2, 0, 3, 1]', '[1, 2]'); +INSERT INTO t2 VALUES ('{"b":[1,2], "a":1}', '{"a":1, "b":2}'); +INSERT INTO t2 VALUES ('{"a":1}', '{}'); +INSERT INTO t2 VALUES ('[1, {"a":1}]', '{}'); +INSERT INTO t2 VALUES ('[1, {"a":1}]', '{"a":1}'); +INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}]', '["foo","bar"]'); +INSERT INTO t2 VALUES ('[{"abc":"def", "def":"abc"}, "bar"]', '["bar", {}]'); +INSERT INTO t2 VALUES ('[{"a":"b"},{"c":"d"}]', '{"c":"d"}'); SELECT j AS json, @@ -64,7 +56,5 @@ FROM t2; DROP TABLE t2; - DROP TABLE t1; - DROP DATABASE json_contains_db; diff --git a/mysql-test/columnstore/basic/t/func_json_contains_path.test b/mysql-test/columnstore/basic/t/func_json_contains_path.test index efa1b5b22..a126bbe93 100644 --- a/mysql-test/columnstore/basic/t/func_json_contains_path.test +++ b/mysql-test/columnstore/basic/t/func_json_contains_path.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_contains_path_db; - --enable_warnings + CREATE DATABASE json_contains_path_db; USE json_contains_path_db; @@ -10,18 +10,16 @@ USE json_contains_path_db; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_CONTAINS_PATH function. --echo # ---------------------------------------------------------------------- + CREATE TABLE t1(j TEXT, r TEXT, p TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t1 -VALUES - ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"), - ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"), - ('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"), - ('{"key1":1, "key2":[2,3]}', "one", "$.key1"), - ('{ "a": true }', NULL, '$.a'), - ('{ "a": true }', 'all', NULL), - ('{"a":{"b":"c"}}', 'one', '$.a.*'); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[1]"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.key2[10]"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "oNE", "$.ma"); +INSERT INTO t1 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1"); +INSERT INTO t1 VALUES ('{ "a": true }', NULL, '$.a'); +INSERT INTO t1 VALUES ('{ "a": true }', 'all', NULL); +INSERT INTO t1 VALUES ('{"a":{"b":"c"}}', 'one', '$.a.*'); SELECT j AS json, @@ -33,27 +31,9 @@ FROM CREATE TABLE t2(j TEXT, r TEXT, p1 TEXT, p2 TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t2 -VALUES - ( - '{"key1":1, "key2":[2,3]}', - "one", - "$.key1", - "$.ma" - ), - ( - '{"key1":1, "key2":[2,3]}', - "aLl", - "$.key1", - "$.ma" - ), - ( - '{"key1":1, "key2":[2,3]}', - "aLl", - "$.key1", - "$.key2" - ); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "one", "$.key1", "$.ma"); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.ma"); +INSERT INTO t2 VALUES ('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2"); SELECT j AS json, @@ -65,7 +45,5 @@ FROM t2; DROP TABLE t2; - DROP TABLE t1; - DROP DATABASE json_contains_path_db; diff --git a/mysql-test/columnstore/basic/t/func_json_exists.test b/mysql-test/columnstore/basic/t/func_json_exists.test index fa863f771..ba62a2bcc 100644 --- a/mysql-test/columnstore/basic/t/func_json_exists.test +++ b/mysql-test/columnstore/basic/t/func_json_exists.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_exists_db; - --enable_warnings + CREATE DATABASE json_exists_db; USE json_exists_db; @@ -11,27 +11,23 @@ USE json_exists_db; --echo # Test of JSON_EXISTS function. --echo # ---------------------------------------------------------------------- --echo # Test case 0 + CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; -SET - @json = '{"key1":"xxxx", "key2":[1, 2, 3]}'; +SET @json = '{"key1":"xxxx", "key2":[1, 2, 3]}'; -INSERT INTO - t1 -VALUES - (@json, '$.key1'), - (@json, '$.key1[0]'), - (@json, '$.key2'), - (@json, '$.key2[1]'), - (@json, '$.key2[10]'); +INSERT INTO t1 VALUES (@json, '$.key1'); +INSERT INTO t1 VALUES (@json, '$.key1[0]'); +INSERT INTO t1 VALUES (@json, '$.key2'); +INSERT INTO t1 VALUES (@json, '$.key2[1]'); +INSERT INTO t1 VALUES (@json, '$.key2[10]'); SELECT - j, - p, - JSON_EXISTS(j, p) AS result + j, + p, + JSON_EXISTS(j, p) AS result FROM - t1; + t1; DROP TABLE t1; - DROP DATABASE json_exists_db; diff --git a/mysql-test/columnstore/basic/t/func_json_extract.test b/mysql-test/columnstore/basic/t/func_json_extract.test index 38410a566..914d56462 100644 --- a/mysql-test/columnstore/basic/t/func_json_extract.test +++ b/mysql-test/columnstore/basic/t/func_json_extract.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_extract_db; - --enable_warnings + CREATE DATABASE json_extract_db; USE json_extract_db; @@ -10,72 +10,58 @@ USE json_extract_db; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_EXTRACT function. --echo # ---------------------------------------------------------------------- + --echo --echo # Single path expression --echo + CREATE TABLE t1(j LONGTEXT, p LONGTEXT) ENGINE = COLUMNSTORE; -SET - @json = '[1, "val2", [3.1, -4]]'; +SET @json = '[1, "val2", [3.1, -4]]'; -INSERT INTO - t1 -VALUES - (@json, '$[0]'), - (@json, '$[1]'), - (@json, '$[2]'), - (@json, '$[3]'), - (@json, '$[2][0]'), - (@json, '$[2][1]'), - (@json, '$[2][10]'), - (@json, '$'), - ('1', '$'), - ('[10, 20, [30, 40], 1, 10]', '$[1]'), - ('{"key1":"asd", "key2":[2,3]}', "$.key1"), - ('{"key0":true, "key1":"qwe"}', "$.key1"), - ('[10, 20, [30, 40]]', '$[2][*]'), - ('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'), - (json_object('foo', 'foobar'), '$'); +INSERT INTO t1 VALUES (@json, '$[0]'); +INSERT INTO t1 VALUES (@json, '$[1]'); +INSERT INTO t1 VALUES (@json, '$[2]'); +INSERT INTO t1 VALUES (@json, '$[3]'); +INSERT INTO t1 VALUES (@json, '$[2][0]'); +INSERT INTO t1 VALUES (@json, '$[2][1]'); +INSERT INTO t1 VALUES (@json, '$[2][10]'); +INSERT INTO t1 VALUES (@json, '$'); +INSERT INTO t1 VALUES ('1', '$'); +INSERT INTO t1 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]'); +INSERT INTO t1 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1"); +INSERT INTO t1 VALUES ('{"key0":true, "key1":"qwe"}', "$.key1"); +INSERT INTO t1 VALUES ('[10, 20, [30, 40]]', '$[2][*]'); +INSERT INTO t1 VALUES ('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); +INSERT INTO t1 VALUES (json_object('foo', 'foobar'), '$'); SELECT - j, - p, - JSON_EXTRACT(j, p) AS result + j, + p, + JSON_EXTRACT(j, p) AS result FROM - t1; + t1; --echo --echo # Multiple path expression --echo + CREATE TABLE t2(j LONGTEXT, p1 LONGTEXT, p2 LONGTEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t2 -VALUES - ( - '{"key1":"asd", "key2":[2,3]}', - "$.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'); +INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY"); +INSERT INTO t2 VALUES ('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2"); +INSERT INTO t2 VALUES ('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"); +INSERT INTO t2 VALUES ('[10, 20, [30, 40], 1, 10]', '$[1]', '$[25]'); +INSERT INTO t2 VALUES ('[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a'); SELECT - j, - p1, - p2, - JSON_EXTRACT(j, p1, p2) AS result + j, + p1, + p2, + JSON_EXTRACT(j, p1, p2) AS result FROM - t2; + t2; DROP TABLE t2; - DROP TABLE t1; - DROP DATABASE json_extract_db; diff --git a/mysql-test/columnstore/basic/t/func_json_insert.test b/mysql-test/columnstore/basic/t/func_json_insert.test index 2b26ed34b..c736c8331 100644 --- a/mysql-test/columnstore/basic/t/func_json_insert.test +++ b/mysql-test/columnstore/basic/t/func_json_insert.test @@ -1,8 +1,8 @@ --source ../include/have_columnstore.inc --disable_warnings DROP DATABASE IF EXISTS json_insert_de; - --enable_warnings + CREATE DATABASE json_insert_de; USE json_insert_de; @@ -10,36 +10,18 @@ USE json_insert_de; --echo # ---------------------------------------------------------------------- --echo # Test of JSON_INSERT|REPLACE|SET function. --echo # ---------------------------------------------------------------------- + CREATE TABLE t1(j TEXT, p TEXT, v TEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t1 -VALUES - ( - '{"a":1, "b":{"c":1}, "d":[1, 2]}', - '$.b.k1', - 'word' - ), - ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3), - ('{"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]' - ); +INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); +INSERT INTO t1 VALUES ('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); +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'); +INSERT INTO t1 VALUES ('1', '$[0]', 4); +INSERT INTO t1 VALUES ('[]', '$[0][0]', 100); +INSERT INTO t1 VALUES ('1', '$[0][0]', 100); +INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.a', 10); +INSERT INTO t1 VALUES ('{ "a": 1, "b": [2, 3]}', '$.b', '[true, false]'); SELECT j AS json, @@ -52,5 +34,4 @@ FROM t1; DROP TABLE t1; - DROP DATABASE json_insert_de; diff --git a/mysql-test/columnstore/basic/t/func_json_merge_patch.test b/mysql-test/columnstore/basic/t/func_json_merge_patch.test index 58e9ce620..c2fac54a4 100644 --- a/mysql-test/columnstore/basic/t/func_json_merge_patch.test +++ b/mysql-test/columnstore/basic/t/func_json_merge_patch.test @@ -1,54 +1,64 @@ DROP DATABASE IF EXISTS json_merge_patch_db; CREATE DATABASE json_merge_patch_db; USE json_merge_patch_db; + # ---------------------------------------------------------------------- # Test of JSON_MERGE_PATCH function. # ---------------------------------------------------------------------- + CREATE TABLE t1(l1 TEXT, l2 TEXT) ENGINE = columnstore; -INSERT INTO t1(l1, l2) VALUES -('{"a":"b"}', '{"a":"c"}'), -('{"a":"b"}', '{"b":"c"}'), -('{"a":"b"}', '{"a":null}'), -('{"a":"b", "b":"c"}', '{"a":null}'), -('{"a":["b"]}', '{"a":"c"}'), -('{"a":"c"}', '{"a":["b"]}'), -('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'), -('{"a":[{"b":"c"}]}', '{"a": [1]}'), -('["a","b"]', '["c","d"]'), -('{"a":"b"}', '["c"]'), -('{"a":"foo"}', 'null'), -('{"a":"foo"}', '"bar"'), -('{"e":null}', '{"a":1}'), -('[1,2]', '{"a":"b", "c":null}'), -('{}', '{"a":{"bb":{"ccc":null}}}'), -(NULL, '{}'), -('{}', NULL); + +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"b":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '{"a":null}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b", "b":"c"}', '{"a":null}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":["b"]}', '{"a":"c"}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"c"}', '{"a":["b"]}'); +INSERT INTO t1(l1, l2) VALUES ('{"a": {"b":"c"}}', '{"a": {"b":"d", "c":null}}'); +INSERT INTO t1(l1, l2) VALUES ('{"a":[{"b":"c"}]}', '{"a": [1]}'); +INSERT INTO t1(l1, l2) VALUES ('["a","b"]', '["c","d"]'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"b"}', '["c"]'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', 'null'); +INSERT INTO t1(l1, l2) VALUES ('{"a":"foo"}', '"bar"'); +INSERT INTO t1(l1, l2) VALUES ('{"e":null}', '{"a":1}'); +INSERT INTO t1(l1, l2) VALUES ('[1,2]', '{"a":"b", "c":null}'); +INSERT INTO t1(l1, l2) VALUES ('{}', '{"a":{"bb":{"ccc":null}}}'); +INSERT INTO t1(l1, l2) VALUES (NULL, '{}'); +INSERT INTO t1(l1, l2) VALUES ('{}', NULL); + SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS `l1 + l2` FROM t1; + DROP TABLE t1; CREATE TABLE t2(l1 TEXT, l2 TEXT, l3 TEXT) ENGINE = columnstore; -INSERT INTO t2 VALUES -('{"a":"b"}', NULL, '{"c":"d"}'), -(NULL, '[1,2,3]', '[4,5,6]'), -(NULL, 'a', 'b'), -('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}'); + +INSERT INTO t2 VALUES ('{"a":"b"}', NULL, '{"c":"d"}'); +INSERT INTO t2 VALUES (NULL, '[1,2,3]', '[4,5,6]'); +INSERT INTO t2 VALUES (NULL, 'a', 'b'); +INSERT INTO t2 VALUES ('{"a":"b"}', '[1,2,3]', '{"c":null,"d":"e"}'); + SELECT l1, l2, l3, JSON_MERGE_PATCH(l1, l2, l3) AS merged FROM t2; + DROP TABLE t2; - CREATE TABLE t3(l1 TEXT, l2 TEXT) ENGINE = columnstore; + --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 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 SELECT l1, JSON_MERGE_PATCH(l1) AS merged FROM t3; -INSERT INTO t3(l1, l2) VALUES -('{', '[1,2,3]'), -('{"a":"b"}', '[1,'); + +INSERT INTO t3(l1, l2) VALUES ('{', '[1,2,3]'); +INSERT INTO t3(l1, l2) VALUES ('{"a":"b"}', '[1,'); + SELECT l1, l2, JSON_MERGE_PATCH(l1, l2) AS merged FROM t3; + DROP TABLE t3; DROP DATABASE json_merge_patch_db; diff --git a/mysql-test/columnstore/basic/t/func_json_remove.test b/mysql-test/columnstore/basic/t/func_json_remove.test index caf2f1e94..7345a0dd5 100644 --- a/mysql-test/columnstore/basic/t/func_json_remove.test +++ b/mysql-test/columnstore/basic/t/func_json_remove.test @@ -12,13 +12,10 @@ USE json_remove_db; --echo # ---------------------------------------------------------------------- CREATE TABLE t1(j TEXT, p TEXT) ENGINE = columnstore; -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]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[1][0]'); +INSERT INTO t1 VALUES ('["a", ["b", "c"], "d"]', '$[0]'); SELECT j AS json, @@ -29,14 +26,11 @@ FROM CREATE TABLE t2(j TEXT, p TEXT) ENGINE = columnstore; -INSERT INTO - t2 -VALUES - ('{"a": 1, "b": [2, 3]}', '$.a'), - ('{"a": 1, "b": [2, 3]}', '$.a[0]'), - ('{"a": 1, "b": [2, 3]}', '$.b'), - ('{"a": 1, "b": [2, 3]}', '$.b[0]'), - ('{"a": 1, "b": [2, 3]}', '$.b[1]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.a[0]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[0]'); +INSERT INTO t2 VALUES ('{"a": 1, "b": [2, 3]}', '$.b[1]'); SELECT j AS json, diff --git a/mysql-test/columnstore/basic/t/func_json_valid.test b/mysql-test/columnstore/basic/t/func_json_valid.test index 51cd37629..5632374db 100644 --- a/mysql-test/columnstore/basic/t/func_json_valid.test +++ b/mysql-test/columnstore/basic/t/func_json_valid.test @@ -16,23 +16,20 @@ USE json_valid_db; CREATE TABLE t1(l LONGTEXT) ENGINE = COLUMNSTORE; -INSERT INTO - t1 -VALUES - ('123'), - ('-123'), - ('5000000000'), - ('-5000000000'), - ('1.23'), - ('"123"'), - ('true'), - ('false'), - ('null'), - ('{"address": "Trondheim"}'), - (JSON_OBJECT()), - (JSON_OBJECT(1, 2)), - (JSON_ARRAY()), - (JSON_ARRAY(1, 2)); +INSERT INTO t1 VALUES ('123'); +INSERT INTO t1 VALUES ('-123'); +INSERT INTO t1 VALUES ('5000000000'); +INSERT INTO t1 VALUES ('-5000000000'); +INSERT INTO t1 VALUES ('1.23'); +INSERT INTO t1 VALUES ('"123"'); +INSERT INTO t1 VALUES ('true'); +INSERT INTO t1 VALUES ('false'); +INSERT INTO t1 VALUES ('null'); +INSERT INTO t1 VALUES ('{"address": "Trondheim"}'); +INSERT INTO t1 VALUES (JSON_OBJECT()); +INSERT INTO t1 VALUES (JSON_OBJECT(1, 2)); +INSERT INTO t1 VALUES (JSON_ARRAY()); +INSERT INTO t1 VALUES (JSON_ARRAY(1, 2)); SELECT l AS raw, @@ -46,14 +43,11 @@ FROM --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - ('12 3'), - ('{key:value}'), - ('{key:value'), - ('[1,2,]'), - ('[1,2'); +INSERT INTO t1 VALUES ('12 3'); +INSERT INTO t1 VALUES ('{key:value}'); +INSERT INTO t1 VALUES ('{key:value'); +INSERT INTO t1 VALUES ('[1,2,]'); +INSERT INTO t1 VALUES ('[1,2'); SELECT l AS raw, @@ -67,13 +61,9 @@ FROM --echo # TRUNCATE t1; -SET - NAMES 'ascii'; +SET NAMES 'ascii'; -INSERT INTO - t1 -VALUES - ('123'); +INSERT INTO t1 VALUES ('123'); SELECT l AS raw, @@ -82,18 +72,14 @@ SELECT FROM t1; -SET - NAMES 'utf8'; +SET NAMES 'utf8'; --echo # --echo # Bare NULL --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - (NULL); +INSERT INTO t1 VALUES (NULL); SELECT JSON_VALID(l) @@ -105,10 +91,7 @@ FROM --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - (UPPER('"abc"')); +INSERT INTO t1 VALUES (UPPER('"abc"')); SELECT JSON_VALID(l) @@ -120,31 +103,23 @@ FROM --echo # TRUNCATE t1; -SET - NAMES 'latin1'; +SET NAMES 'latin1'; -INSERT INTO - t1 -VALUES - (UPPER('"abc"')); +INSERT INTO t1 VALUES (UPPER('"abc"')); SELECT JSON_VALID(l) FROM t1; -SET - NAMES 'utf8'; +SET NAMES 'utf8'; --echo # --echo # Function result - date, not valid as JSON without CAST --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - (CAST('2015-01-15' AS DATE)); +INSERT INTO t1 VALUES (CAST('2015-01-15' AS DATE)); SELECT JSON_VALID(l) @@ -156,14 +131,11 @@ FROM --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - ( - CAST( - CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8' - ) - ); +INSERT INTO t1 VALUES ( + CAST( + CAST('2015-01-15' AS DATE) AS CHAR CHARACTER SET 'utf8' + ) +); SELECT JSON_VALID(l) @@ -175,15 +147,8 @@ FROM --echo # TRUNCATE t1; -INSERT INTO - t1 -VALUES - (UPPER(NULL)); - -INSERT INTO - t1 -VALUES - (UPPER(CAST(NULL AS CHAR))); +INSERT INTO t1 VALUES (UPPER(NULL)); +INSERT INTO t1 VALUES (UPPER(CAST(NULL AS CHAR))); SELECT JSON_VALID(l) diff --git a/mysql-test/columnstore/basic/t/func_json_value.test b/mysql-test/columnstore/basic/t/func_json_value.test index f73568be9..292c3e6fe 100644 --- a/mysql-test/columnstore/basic/t/func_json_value.test +++ b/mysql-test/columnstore/basic/t/func_json_value.test @@ -11,22 +11,26 @@ USE json_value_db; --echo # ---------------------------------------------------------------------- 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; CREATE TABLE t2(s TEXT) ENGINE = columnstore; -INSERT INTO t2 VALUES('{"key1":123, "key2":{"key3":"value3"}}'), -('{"key1":123, "key3":[1,2,3]}'), -('{"key1":123, "key2":"[1]"}'); + +INSERT INTO t2 VALUES ('{"key1":123, "key2":{"key3":"value3"}}'); +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 FROM t2; @@ -42,7 +46,17 @@ DROP TABLE t1; # check an absence of race bug in json_query. 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; diff --git a/mysql-test/columnstore/basic/t/func_jsonarrayagg.test b/mysql-test/columnstore/basic/t/func_jsonarrayagg.test index d12f9f79b..05ac5e582 100644 --- a/mysql-test/columnstore/basic/t/func_jsonarrayagg.test +++ b/mysql-test/columnstore/basic/t/func_jsonarrayagg.test @@ -6,7 +6,14 @@ USE json_arrayagg_db; 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; sorted_result; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; @@ -18,7 +25,10 @@ DROP TABLE t1; -- echo # Real aggregation -- echo # 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; sorted_result; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b), JSON_ARRAYAGG(c) FROM t1; @@ -28,7 +38,10 @@ DROP TABLE t1; -- echo # Boolean aggregation -- echo # 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; sorted_result; SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1; @@ -42,9 +55,10 @@ DROP TABLE t1; -- echo # Aggregation of strings with quoted -- echo # CREATE TABLE t1 (a VARCHAR(80))ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES - ('"double_quoted_value"'), ("'single_quoted_value'"), - ('"double_quoted_value"'), ("'single_quoted_value'"); +INSERT INTO t1 VALUES ('"double_quoted_value"'); +INSERT INTO t1 VALUES ("'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; sorted_result; SELECT JSON_ARRAYAGG(a) FROM t1; @@ -54,9 +68,20 @@ DROP TABLE t1; -- echo # Strings and NULLs -- echo # CREATE TABLE t1 (a INT, b VARCHAR(80))ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES - (1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL), - (1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (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); +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; sorted_result; 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; SELECT JSON_ARRAYAGG(b LIMIT 2) FROM t1 GROUP BY a; sorted_result; -SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; +## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1; sorted_result; -SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC) FROM t1; +## SELECT JSON_ARRAYAGG(DISTINCT b) FROM t1; 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; -SELECT JSON_ARRAYAGG(DISTINCT b ORDER BY b ASC LIMIT 2) FROM t1; +## SELECT JSON_ARRAYAGG(DISTINCT b LIMIT 2) FROM t1; -- echo # -- echo # JSON aggregation @@ -113,10 +138,8 @@ SELECT JSON_ARRAYAGG(JSON_ARRAYAGG(a)) FROM t1; -- echo # -- echo # - DROP TABLE t1; - -- echo # -- echo # @@ -151,35 +174,45 @@ select json_object('x', json_arrayagg(json_object('a', 1))); --echo # 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), (2,2), (3,3); +INSERT INTO t1 VALUES (1,1); +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; SELECT JSON_ARRAYAGG(a) FROM t1; 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; SELECT JSON_ARRAYAGG(a) FROM t1; sorted_result; -SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; +## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1; DROP TABLE t1; 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), (2,2), (3,3); +INSERT INTO t1 VALUES (1,1); +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; SELECT JSON_ARRAYAGG(a) FROM t1; 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; SELECT JSON_ARRAYAGG(a) FROM t1; sorted_result; -SELECT JSON_ARRAYAGG(DISTINCT a ORDER BY a ASC) FROM t1; +## SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1; DROP TABLE t1; @@ -187,7 +220,8 @@ DROP TABLE t1; --echo # 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; SELECT JSON_ARRAYAGG(a) FROM t1; @@ -204,7 +238,8 @@ DROP TABLE t1; set group_concat_max_len=64; create table t1 (a varchar(254))ENGINE=COLUMNSTORE; 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; select json_arrayagg(a) from 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 t2(id int, owner_id int)ENGINE=COLUMNSTORE; -INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); -INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); +INSERT INTO t1 VALUES (1, "name1"); +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 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 VIEW v AS SELECT * FROM t; -INSERT INTO t VALUES ('foo'),('bar'); +INSERT INTO t VALUES ('foo'); +INSERT INTO t VALUES ('bar'); sorted_result; SELECT JSON_ARRAYAGG(a) AS f FROM v; DROP VIEW v; diff --git a/utils/funcexp/func_json_array_append.cpp b/utils/funcexp/func_json_array_append.cpp index a163cf869..b47b973fa 100644 --- a/utils/funcexp/func_json_array_append.cpp +++ b/utils/funcexp/func_json_array_append.cpp @@ -28,15 +28,11 @@ std::string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& return ""; const CHARSET_INFO* cs = getCharset(fp[0]); - - json_engine_t jsEg; const uchar* arrEnd; size_t strRestLen; std::string retJS; retJS.reserve(js.length() + padding); - initJSPaths(paths, fp, 1, 2); - utils::NullString tmpJS(js); for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++) { diff --git a/utils/funcexp/func_json_array_insert.cpp b/utils/funcexp/func_json_array_insert.cpp index 5c6ee56ed..1d273b2b3 100644 --- a/utils/funcexp/func_json_array_insert.cpp +++ b/utils/funcexp/func_json_array_insert.cpp @@ -1,6 +1,8 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" +#include "my_sys.h" using namespace execplan; #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]); - json_engine_t jsEg; std::string retJS; - retJS.reserve(js.length() + 8); - initJSPaths(paths, fp, 1, 2); + retJS.reserve(js.length() + 8); utils::NullString tmpJS(js); 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]; 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(mem_root_dynamic_array_get_val(&path.p.steps, path.p.last_step_idx)), + *initial_step= reinterpret_cast(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) +#endif { if (path.p.s.error == 0) path.p.s.error = SHOULD_END_WITH_ARRAY; goto error; } +#if MYSQL_VERSION_ID >= 120200 + path.p.last_step_idx--; +#else path.p.last_step--; +#endif } initJSEngine(jsEg, cs, tmpJS); +#if MYSQL_VERSION_ID < 120100 path.currStep = path.p.steps; +#endif int jsErr = 0; 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) { DBUG_ASSERT(jsEg.state == JST_VALUE); +#if MYSQL_VERSION_ID >= 120200 + if (itemSize == ((reinterpret_cast + (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) +#endif { itemPos = (const char*)jsEg.s.c_str; break; diff --git a/utils/funcexp/func_json_contains.cpp b/utils/funcexp/func_json_contains.cpp index f399ddc60..95261324c 100644 --- a/utils/funcexp/func_json_contains.cpp +++ b/utils/funcexp/func_json_contains.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -160,6 +161,7 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& /*type*/) { bool isNullJS = false, isNullVal = false; + const auto& js = fp[0]->data()->getStrVal(row, isNullJS); const auto& val = fp[1]->data()->getStrVal(row, isNullVal); if (isNullJS || isNullVal) @@ -181,7 +183,6 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, arg2Parsed = arg2Const; } - json_engine_t jsEg; initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 2) @@ -193,7 +194,6 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, goto error; } - json_engine_t valEg; initJSEngine(valEg, getCharset(fp[1]), arg2Val); if (json_read_value(&jsEg) || json_read_value(&valEg)) diff --git a/utils/funcexp/func_json_contains_path.cpp b/utils/funcexp/func_json_contains_path.cpp index 2d3bb8393..0eb2df407 100644 --- a/utils/funcexp/func_json_contains_path.cpp +++ b/utils/funcexp/func_json_contains_path.cpp @@ -17,7 +17,7 @@ using namespace funcexp::helpers; namespace funcexp { CalpontSystemCatalog::ColType Func_json_contains_path::operationType( - FunctionParm& fp, CalpontSystemCatalog::ColType& /*resultType*/) + FunctionParm& fp, [[maybe_unused]] CalpontSystemCatalog::ColType& resultType) { return fp[0]->data()->resultType(); } @@ -26,7 +26,7 @@ CalpontSystemCatalog::ColType Func_json_contains_path::operationType( * getBoolVal API definition */ 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); if (isNull) @@ -61,7 +61,6 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul isModeParsed = isModeConst; } - initJSPaths(paths, fp, 2, 1); if (paths.size() == 0) 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(), &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) { #if MYSQL_VERSION_ID >= 100900 +#if MYSQL_VERSION_ID >= 120200 + json_path_step_t *last_step= reinterpret_cast + (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(p.steps.buffer)))) +#else if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps))) { result = true; break; } +#endif #endif for (int restSize = argSize, curr = 0; restSize > 0; restSize--, curr++) diff --git a/utils/funcexp/func_json_depth.cpp b/utils/funcexp/func_json_depth.cpp index 66bcc22c9..662bbbd11 100644 --- a/utils/funcexp/func_json_depth.cpp +++ b/utils/funcexp/func_json_depth.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #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; bool incDepth = true; - json_engine_t jsEg; initJSEngine(jsEg, getCharset(fp[0]), js); do diff --git a/utils/funcexp/func_json_equals.cpp b/utils/funcexp/func_json_equals.cpp index 0e0270cc2..012731e44 100644 --- a/utils/funcexp/func_json_equals.cpp +++ b/utils/funcexp/func_json_equals.cpp @@ -56,13 +56,22 @@ bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, const string_view js2 = js2_ns.unsafeStringRef(); 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]))) +#endif { isNull = true; 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]))) +#endif { isNull = true; return result; diff --git a/utils/funcexp/func_json_exists.cpp b/utils/funcexp/func_json_exists.cpp index f7a3325ee..386b3dfd3 100644 --- a/utils/funcexp/func_json_exists.cpp +++ b/utils/funcexp/func_json_exists.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -29,9 +30,8 @@ bool Func_json_exists::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, return false; 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])) goto error; diff --git a/utils/funcexp/func_json_extract.cpp b/utils/funcexp/func_json_extract.cpp index d07986faf..d8cca02d2 100644 --- a/utils/funcexp/func_json_extract.cpp +++ b/utils/funcexp/func_json_extract.cpp @@ -21,8 +21,6 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t if (isNull) return 1; const char* rawJS = js.str(); - json_engine_t jsEg, savJSEg; - json_path_t p; const uchar* value; bool notFirstVal = false; 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(); std::string tmp; - initJSPaths(paths, fp, 1, 1); - for (size_t i = 1; i < argSize; i++) { 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) { #if MYSQL_VERSION_ID >= 100900 +#if MYSQL_VERSION_ID >= 120200 + json_path_step_t *last_step= reinterpret_cast(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, arrayCounter + (last_step - reinterpret_cast(p.steps.buffer)))) +#else + if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) +#endif return 1; #endif diff --git a/utils/funcexp/func_json_format.cpp b/utils/funcexp/func_json_format.cpp index 71759a0ec..149aa7cdd 100644 --- a/utils/funcexp/func_json_format.cpp +++ b/utils/funcexp/func_json_format.cpp @@ -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); - std::string ret; + + string ret; if (doFormat(&jsEg, ret, fmt, tabSize)) { isNull = true; diff --git a/utils/funcexp/func_json_insert.cpp b/utils/funcexp/func_json_insert.cpp index df464a64a..743f2c318 100644 --- a/utils/funcexp/func_json_insert.cpp +++ b/utils/funcexp/func_json_insert.cpp @@ -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 isReplaceMode = mode == REPLACE || mode == SET; - json_engine_t jsEg; - int jsErr = 0; json_string_t keyName; const CHARSET_INFO* cs = getCharset(fp[0]); 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 std::string retJS; 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)) goto error; +#if MYSQL_VERSION_ID >= 120200 + path.p.last_step_idx--; +#else path.p.last_step--; +#endif } 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) +#endif 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)) +#endif { if (jsErr) goto error; @@ -73,7 +82,23 @@ std::string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo if (json_read_value(&jsEg)) goto error; +#if MYSQL_VERSION_ID >= 120200 + if (path.p.last_step_idx < 0) + { + lastStep= (reinterpret_cast + (mem_root_dynamic_array_get_val(&path.p.steps, + 0))) + path.p.last_step_idx + 1; + } + else + { + lastStep= (reinterpret_cast + (mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx))) + 1; + } +#else lastStep = path.p.last_step + 1; +#endif + if (lastStep->type & JSON_PATH_ARRAY) { IntType itemSize = 0; diff --git a/utils/funcexp/func_json_keys.cpp b/utils/funcexp/func_json_keys.cpp index d926ff8b3..c4598bfe9 100644 --- a/utils/funcexp/func_json_keys.cpp +++ b/utils/funcexp/func_json_keys.cpp @@ -60,7 +60,7 @@ std::string Func_json_keys::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool IntType keySize = 0; std::string ret; - json_engine_t jsEg; + initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 1) diff --git a/utils/funcexp/func_json_length.cpp b/utils/funcexp/func_json_length.cpp index 474e8bbca..9665c7588 100644 --- a/utils/funcexp/func_json_length.cpp +++ b/utils/funcexp/func_json_length.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -27,7 +28,6 @@ int64_t Func_json_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& if (isNull) return 0; - json_engine_t jsEg; int length = 0; int err; diff --git a/utils/funcexp/func_json_merge.cpp b/utils/funcexp/func_json_merge.cpp index 24dc9d069..a4093489c 100644 --- a/utils/funcexp/func_json_merge.cpp +++ b/utils/funcexp/func_json_merge.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #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]); - json_engine_t jsEg1, jsEg2; - utils::NullString tmpJS(js); std::string retJS; @@ -234,10 +233,10 @@ std::string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, boo if (isNull) goto error; - initJSEngine(jsEg1, js1CS, tmpJS); + initJSEngine(jsEg, js1CS, tmpJS); initJSEngine(jsEg2, getCharset(fp[i]), js2); - if (doMerge(retJS, &jsEg1, &jsEg2)) + if (doMerge(retJS, &jsEg, &jsEg2)) goto error; // 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(); } - initJSEngine(jsEg1, js1CS, tmpJS); + initJSEngine(jsEg, js1CS, tmpJS); retJS.clear(); - if (doFormat(&jsEg1, retJS, Func_json_format::LOOSE)) + if (doFormat(&jsEg, retJS, Func_json_format::LOOSE)) goto error; isNull = false; diff --git a/utils/funcexp/func_json_merge_patch.cpp b/utils/funcexp/func_json_merge_patch.cpp index cf02445b9..7ad3cf2f2 100644 --- a/utils/funcexp/func_json_merge_patch.cpp +++ b/utils/funcexp/func_json_merge_patch.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -275,8 +276,7 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f isNull = false; - json_engine_t jsEg1, jsEg2; - jsEg1.s.error = jsEg2.s.error = 0; + jsEg.s.error = jsEg2.s.error = 0; utils::NullString tmpJS(js); std::string retJS; @@ -304,8 +304,8 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f goto next; } - initJSEngine(jsEg1, getCharset(fp[0]), tmpJS); - if (doMergePatch(retJS, &jsEg1, &jsEg2, isEmpty)) + initJSEngine(jsEg, getCharset(fp[0]), tmpJS); + if (doMergePatch(retJS, &jsEg, &jsEg2, isEmpty)) { goto error; } @@ -321,9 +321,9 @@ std::string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& f if (hasNullArg) goto error; - initJSEngine(jsEg1, getCharset(fp[0]), tmpJS); + initJSEngine(jsEg, getCharset(fp[0]), tmpJS); retJS.clear(); - if (doFormat(&jsEg1, retJS, Func_json_format::LOOSE)) + if (doFormat(&jsEg, retJS, Func_json_format::LOOSE)) goto error; isNull = false; return retJS; diff --git a/utils/funcexp/func_json_normalize.cpp b/utils/funcexp/func_json_normalize.cpp index f25f2f6fe..01e0d8eab 100644 --- a/utils/funcexp/func_json_normalize.cpp +++ b/utils/funcexp/func_json_normalize.cpp @@ -36,7 +36,11 @@ std::string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp, if (init_dynamic_string(str.get(), NULL, 0, 0)) 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]))) +#endif goto error; return str->str; diff --git a/utils/funcexp/func_json_overlaps.cpp b/utils/funcexp/func_json_overlaps.cpp index b8933a79b..85c006065 100644 --- a/utils/funcexp/func_json_overlaps.cpp +++ b/utils/funcexp/func_json_overlaps.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -279,20 +280,20 @@ bool Func_json_overlaps::getBoolVal(Row& row, FunctionParm& fp, bool& /*isNull*/ CalpontSystemCatalog::ColType& /*type*/) { bool isNullJS1 = false, isNullJS2 = false; + const auto js1 = fp[0]->data()->getStrVal(row, isNullJS1); const auto js2 = fp[1]->data()->getStrVal(row, isNullJS2); if (isNullJS1 || isNullJS2) return false; - json_engine_t jsEg1, jsEg2; - initJSEngine(jsEg1, getCharset(fp[0]), js1); + initJSEngine(jsEg, getCharset(fp[0]), js1); 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; - bool result = checkOverlaps(&jsEg1, &jsEg2, false); - if (unlikely(jsEg1.s.error || jsEg2.s.error)) + bool result = checkOverlaps(&jsEg, &jsEg2, false); + if (unlikely(jsEg.s.error || jsEg2.s.error)) return false; return result; diff --git a/utils/funcexp/func_json_remove.cpp b/utils/funcexp/func_json_remove.cpp index 35745dff2..16d62827d 100644 --- a/utils/funcexp/func_json_remove.cpp +++ b/utils/funcexp/func_json_remove.cpp @@ -28,17 +28,14 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo if (isNull) return ""; - json_engine_t jsEg; - int jsErr = 0; json_string_t keyName; const CHARSET_INFO* cs = getCharset(fp[0]); json_string_set_cs(&keyName, cs); - initJSPaths(paths, fp, 1, 1); - std::string retJS; utils::NullString tmpJS(js); + for (size_t i = 1, j = 0; i < fp.size(); i++, j++) { 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; IntType itemSize = 0; +#if MYSQL_VERSION_ID >= 120200 + json_path_step_t *curr_last_step= nullptr; +#endif + if (!path.parsed) { if (parseJSPath(path, row, fp[i], false)) goto error; - path.p.last_step--; +#if MYSQL_VERSION_ID >= 120200 + path.p.last_step_idx--; + curr_last_step= reinterpret_cast + (mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx)); + if (curr_last_step < reinterpret_cast(path.p.steps.buffer)) +#else + path.p.last_step--; if (path.p.last_step < path.p.steps) +#endif { path.p.s.error = TRIVIAL_PATH_NOT_ALLOWED; goto error; @@ -64,7 +73,11 @@ std::string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo initJSEngine(jsEg, cs, tmpJS); +#if MYSQL_VERSION_ID >= 120200 + if (curr_last_step < reinterpret_cast(path.p.steps.buffer)) +#else if (path.p.last_step < path.p.steps) +#endif goto v_found; 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)) goto error; +#if MYSQL_VERSION_ID >= 120200 + lastStep = curr_last_step + 1; +#else lastStep = path.p.last_step + 1; +#endif + if (lastStep->type & JSON_PATH_ARRAY) { if (jsEg.value_type != JSON_VALUE_ARRAY) diff --git a/utils/funcexp/func_json_search.cpp b/utils/funcexp/func_json_search.cpp index 1365064cf..ab1311f4c 100644 --- a/utils/funcexp/func_json_search.cpp +++ b/utils/funcexp/func_json_search.cpp @@ -20,12 +20,20 @@ namespace static bool appendJSPath(std::string& ret, const json_path_t* p) { 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 { ret.append("\"$"); +#if MYSQL_VERSION_ID >= 120200 + for (c = reinterpret_cast(p->steps.buffer)+1; c <= last_step; c++) +#else for (c = p->steps + 1; c <= p->last_step; c++) +#endif { 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]; } - json_engine_t jsEg; - json_path_t p, savPath; const CHARSET_INFO* cs = getCharset(fp[0]); #if MYSQL_VERSION_ID >= 100900 @@ -142,11 +148,10 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo #endif int pathFound = 0; - initJSPaths(paths, fp, 4, 1); - for (size_t i = 4; i < fp.size(); i++) { JSONPath& path = paths[i - 4]; + if (!path.parsed) { 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) { #if MYSQL_VERSION_ID >= 100900 +#if MYSQL_VERSION_ID >= 120200 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))) +#endif goto error; #endif @@ -180,7 +190,11 @@ std::string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo if (pathFound == 1) { 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); +#endif } else { diff --git a/utils/funcexp/func_json_type.cpp b/utils/funcexp/func_json_type.cpp index 6b75f75e1..fafd6ae14 100644 --- a/utils/funcexp/func_json_type.cpp +++ b/utils/funcexp/func_json_type.cpp @@ -26,7 +26,6 @@ std::string Func_json_type::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool if (isNull) return ""; - json_engine_t jsEg; std::string result; initJSEngine(jsEg, getCharset(fp[0]), js); diff --git a/utils/funcexp/func_json_unquote.cpp b/utils/funcexp/func_json_unquote.cpp index 9eefec324..8c1bee1e9 100644 --- a/utils/funcexp/func_json_unquote.cpp +++ b/utils/funcexp/func_json_unquote.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" #include "jsonhelpers.h" using namespace execplan; @@ -26,10 +27,10 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b if (isNull) return ""; - json_engine_t jsEg; int strLen; const CHARSET_INFO* cs = type.getCharset(); + initJSEngine(jsEg, cs, js); json_read_value(&jsEg); diff --git a/utils/funcexp/func_json_valid.cpp b/utils/funcexp/func_json_valid.cpp index 8d118c75f..4faef428b 100644 --- a/utils/funcexp/func_json_valid.cpp +++ b/utils/funcexp/func_json_valid.cpp @@ -29,6 +29,10 @@ bool Func_json_valid::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, if (isNull) 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])); +#endif } } // namespace funcexp diff --git a/utils/funcexp/func_json_value.cpp b/utils/funcexp/func_json_value.cpp index 95849bcf2..fd78e09cd 100644 --- a/utils/funcexp/func_json_value.cpp +++ b/utils/funcexp/func_json_value.cpp @@ -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())) return true; + +#if MYSQL_VERSION_ID >= 120200 + JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast(js.str()), + reinterpret_cast(js.end()), je_stack); +#else JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast(js.str()), reinterpret_cast(js.end())); +#endif +#if MYSQL_VERSION_ID >= 120200 + currStep = reinterpret_cast(p.steps.buffer); +#else currStep = p.steps; +#endif do { if (error) return true; - +#if MYSQL_VERSION_ID >= 120200 + if (json_find_path(&je, &p, &currStep, &array)) +#else IntType arrayCounters[JSON_DEPTH_LIMIT]; if (json_find_path(&je, &p, &currStep, arrayCounters)) +#endif return true; if (json_read_value(&je)) diff --git a/utils/funcexp/functor_json.h b/utils/funcexp/functor_json.h index 55c4d1b5f..2e374c195 100644 --- a/utils/funcexp/functor_json.h +++ b/utils/funcexp/functor_json.h @@ -27,15 +27,130 @@ struct JSONPath 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 paths; +#if MYSQL_VERSION_ID >= 120200 + std::vector> p_steps_arr; +#endif + + public: + + inline void initJSPaths(std::vector& 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& paths, + std::vector>& p_steps_arr) + { + if (!path_inited) + { + for (size_t i=0; i= 120200 + p_steps_arr = std::vector>(fp.size(), + std::vector(JSON_DEPTH_LIMIT)); + init_json_multipath_array(path_inited, paths, p_steps_arr); +#endif + } + + ~Func_json_multipath() {} +}; + class JSONEgWrapper : public json_engine_t { 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) +#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); } 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); @@ -44,17 +159,34 @@ class JSONEgWrapper : public json_engine_t 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: virtual ~JSONPathWrapper() = default; virtual bool checkAndGetValue(JSONEgWrapper* je, std::string& ret, int* error) = 0; 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, execplan::SPTP& funcParmPath); }; /** @brief Func_json_valid class */ -class Func_json_valid : public Func_Bool +class Func_json_valid : public Func_Bool, public Func_json { public: Func_json_valid() : Func_Bool("json_valid") @@ -71,7 +203,7 @@ class Func_json_valid : public Func_Bool /** @brief Func_json_depth class */ -class Func_json_depth : public Func_Int +class Func_json_depth : public Func_Int, public Func_json { public: Func_json_depth() : Func_Int("json_depth") @@ -88,15 +220,11 @@ class Func_json_depth : public Func_Int /** @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: - Func_json_length() : Func_Int("json_length") - { - } + Func_json_length() : Func_Int("json_length"), Func_json_no_multipath() + {} ~Func_json_length() override = default; execplan::CalpontSystemCatalog::ColType operationType( @@ -108,11 +236,20 @@ class Func_json_length : public Func_Int /** @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: 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; @@ -125,11 +262,19 @@ class Func_json_equals : public Func_Bool /** @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: 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; @@ -142,7 +287,7 @@ class Func_json_normalize : public Func_Str /** @brief Func_json_type class */ -class Func_json_type : public Func_Str +class Func_json_type : public Func_Str, public Func_json { public: Func_json_type() : Func_Str("json_type") @@ -192,13 +337,10 @@ class Func_json_array : public Func_Str }; /** @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: - Func_json_keys() : Func_Str("json_keys") + Func_json_keys() : Func_Str("json_keys"), Func_json_no_multipath() { } ~Func_json_keys() override = default; @@ -211,15 +353,11 @@ class Func_json_keys : public Func_Str }; /** @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: - Func_json_exists() : Func_Bool("json_exists") - { - } + Func_json_exists() : Func_Bool("json_exists"), Func_json_no_multipath() + {} ~Func_json_exists() override = default; execplan::CalpontSystemCatalog::ColType operationType( @@ -231,15 +369,11 @@ class Func_json_exists : public Func_Bool /** @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: - Func_json_quote() : Func_Str("json_quote") - { - } + Func_json_quote() : Func_Str("json_quote"), Func_json_no_multipath() + {} ~Func_json_quote() override = default; execplan::CalpontSystemCatalog::ColType operationType( @@ -251,15 +385,11 @@ class Func_json_quote : public Func_Str /** @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: - Func_json_unquote() : Func_Str("json_unquote") - { - } + Func_json_unquote() : Func_Str("json_unquote"), Func_json_no_multipath() + {} ~Func_json_unquote() override = default; execplan::CalpontSystemCatalog::ColType operationType( @@ -271,7 +401,7 @@ class Func_json_unquote : public Func_Str /** @brief Func_json_format class */ -class Func_json_format : public Func_Str +class Func_json_format : public Func_Str, public Func_json { public: enum FORMATS @@ -310,11 +440,19 @@ class Func_json_format : public Func_Str }; /** @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: 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; @@ -327,11 +465,20 @@ class Func_json_merge : public Func_Str /** @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: 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; @@ -348,8 +495,7 @@ class Func_json_value : public Func_Str { public: Func_json_value() : Func_Str("json_value") - { - } + {} ~Func_json_value() override = default; execplan::CalpontSystemCatalog::ColType operationType( @@ -377,17 +523,24 @@ class Func_json_query : public Func_Str }; /** @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: - JSONPath path; bool arg2Const; bool arg2Parsed; // argument 2 is a constant or has been parsed utils::NullString arg2Val; + json_engine_t valEg; +#if MYSQL_VERSION_ID >= 120200 + int valEg_stack[JSON_DEPTH_LIMIT]; +#endif 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; @@ -399,15 +552,14 @@ class Func_json_contains : public Func_Bool }; /** @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 paths; - 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; execplan::CalpontSystemCatalog::ColType operationType( @@ -421,15 +573,14 @@ class Func_json_array_append : public Func_Str }; /** @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 paths; - 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; execplan::CalpontSystemCatalog::ColType operationType( @@ -441,7 +592,7 @@ class Func_json_array_insert : public Func_Str /** @brief Func_json_insert class */ -class Func_json_insert : public Func_Str +class Func_json_insert : public Func_json_multipath, public Func_Str { public: enum MODE @@ -454,12 +605,14 @@ class Func_json_insert : public Func_Str protected: MODE mode; - std::vector paths; 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) { assert(m != NONE); @@ -471,6 +624,18 @@ class Func_json_insert : public Func_Str 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; MODE getMode() const @@ -486,15 +651,14 @@ class Func_json_insert : public Func_Str }; /** @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 paths; - 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; execplan::CalpontSystemCatalog::ColType operationType( @@ -506,19 +670,30 @@ class Func_json_remove : public Func_Str /** @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: - std::vector paths; std::vector hasFound; bool isModeOne; bool isModeConst; bool isModeParsed; +#if MYSQL_VERSION_ID >= 120200 + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; +#endif + json_path_t p; public: 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; @@ -531,14 +706,20 @@ class Func_json_contains_path : public Func_Bool /** @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: - JSONPath path; + private: + json_engine_t jsEg2; +#if MYSQL_VERSION_ID >= 120200 + int jsEg2_stack[JSON_DEPTH_LIMIT]; +#endif 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; @@ -550,20 +731,36 @@ class Func_json_overlaps : public Func_Bool }; /** @brief Func_json_search class */ -class Func_json_search : public Func_Str +class Func_json_search : public Func_json_multipath, public Func_Str { protected: - std::vector paths; bool isModeParsed; bool isModeConst; bool isModeOne; 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: 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; execplan::CalpontSystemCatalog::ColType operationType( @@ -577,15 +774,29 @@ class Func_json_search : public Func_Str }; /** @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: - std::vector paths; + json_engine_t savJSEg; +#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: - 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; execplan::CalpontSystemCatalog::ColType operationType( diff --git a/utils/funcexp/jsonhelpers.cpp b/utils/funcexp/jsonhelpers.cpp index 760a0c3d1..cb1640edd 100644 --- a/utils/funcexp/jsonhelpers.cpp +++ b/utils/funcexp/jsonhelpers.cpp @@ -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) { +#if MYSQL_VERSION_ID >= 120200 + json_path_step_t *a_last_step= reinterpret_cast + (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 + (mem_root_dynamic_array_get_val((MEM_ROOT_DYNAMIC_ARRAY*)&b->steps, (size_t)b->last_step_idx)); + return cmpPartJSPath((reinterpret_cast(a->steps.buffer)) + 1, a_last_step, + (reinterpret_cast(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); +#endif } 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; } -bool matchJSPath(const vector& paths, const json_path_t* p, json_value_types valType, +bool matchJSPath(const std::vector& paths, const json_path_t* p, json_value_types valType, [[maybe_unused]] const int* arrayCounter, bool exact) { for (size_t curr = 0; curr < paths.size(); curr++) @@ -371,5 +381,7 @@ bool matchJSPath(const vector& paths, const json_path_t* p, j } return false; } + + } // namespace helpers } // namespace funcexp diff --git a/utils/funcexp/jsonhelpers.h b/utils/funcexp/jsonhelpers.h index 7047677c9..9956d899d 100644 --- a/utils/funcexp/jsonhelpers.h +++ b/utils/funcexp/jsonhelpers.h @@ -63,8 +63,18 @@ using IntType = uint; inline static int locateJSPath(json_engine_t& jsEg, JSONPath& path, int* jsErr = nullptr) { 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(path.p.steps.buffer); + if (json_find_path(&jsEg, &path.p, &path.currStep, &array)) +#else path.currStep = path.p.steps; if (json_find_path(&jsEg, &path.p, &path.currStep, arrayCounters)) +#endif { if (jsErr && jsEg.s.error) *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); -inline void initJSPaths(std::vector& 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& paths, const json_path_t* p, json_value_types valType, const int* arrayCounter = nullptr, bool exact = true); } // namespace funcexp::helpers