should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,453 @@
# name: test/sql/json/scalar/json_nested_casts.test
# description: Casts to and from nested types with JSON
# group: [scalar]
require json
require notwindows
statement ok
PRAGMA enable_verification
# list with varchar to json
statement ok
create table t2(blobs json[])
statement ok
insert into t2 values(json('[1,2]'));
query I
SELECT * FROM t2
----
[1, 2]
# varchar to list of json
query I
select cast(json('[1,2]') as json[]);
----
[1, 2]
statement error
select cast(['boom'] as json[]);
----
Conversion Error
query I
select cast(['[1, 2]', '[3, 4]'] as json[]);
----
[[1, 2], [3, 4]]
# struct with varchar to json
query I
SELECT {'a': '[1, 2]'}::ROW(a JSON)
----
{'a': '[1, 2]'}
query I
SELECT {'a': 42, 'b': '[1, 2]'}::ROW(a JSON, b JSON)
----
{'a': 42, 'b': '[1, 2]'}
query I
SELECT {'a': 42, 'b': '[1, 2]'}::ROW(a JSON, b INT[])
----
{'a': 42, 'b': [1, 2]}
statement error
SELECT {'a': 'boom', 'b': '[1, 2]'}::ROW(a JSON, b INT[])
----
Conversion Error
# varchar to struct of json
query I
SELECT '{a: [1, 2]}'::ROW(a JSON)
----
{'a': '[1, 2]'}
# map with varchar to json
query I
SELECT MAP(['42'], ['88'])::MAP(JSON, JSON)
----
{42=88}
# varchar to map of json
query I
SELECT '{42=88}'::MAP(JSON, JSON)
----
{42=88}
# varchar to union with json
query I
SELECT '42'::UNION(u JSON)
----
42
# union with varchar to union with json
query I
SELECT '42'::UNION(u VARCHAR)::UNION(u JSON)
----
42
query I
SELECT ['42']::UNION(u JSON)[]
----
[42]
query I
SELECT '42'::UNION(u VARCHAR)::JSON
----
{"u":"42"}
# try_cast works too
query I
SELECT TRY_CAST('{"duck":42' AS JSON)
----
NULL
# we support our nested to and from JSON (just calls to_json and from_json - well tested)
query I
SELECT {duck: 42}::JSON
----
{"duck":42}
query I
SELECT '{"duck":42}'::JSON::STRUCT(duck INTEGER)
----
{'duck': 42}
query I
SELECT ['duck']::JSON
----
["duck"]
query I
SELECT '["duck"]'::JSON::VARCHAR[]
----
[duck]
query I
SELECT MAP(['duck'], [42])::JSON
----
{"duck":42}
query I
SELECT '{"duck":42}'::JSON::MAP(VARCHAR, INTEGER)
----
{duck=42}
# casting should be strict
statement error
SELECT '{"duck":42}'::JSON::STRUCT(goose INTEGER)
----
Conversion Error
statement error
SELECT '["a", "b", "c"]'::JSON::INT[]
----
Conversion Error
statement error
SELECT '{"duck":42}'::JSON::MAP(INTEGER, INTEGER)
----
Conversion Error
# however, when we encounter a conversion error in a nested type with TRY, only that becomes NULL
query I
SELECT TRY_CAST('{"duck":42}'::JSON AS STRUCT(goose INTEGER))
----
{'goose': NULL}
query I
SELECT TRY_CAST('["a", "b", "c"]'::JSON AS INT[])
----
[NULL, NULL, NULL]
# map keys cannot be NULL
statement error
SELECT TRY_CAST('{"duck":42}'::JSON AS MAP(INTEGER, INTEGER))
----
Conversion Error
# but values can
query I
SELECT TRY_CAST('{"42":"duck"}'::JSON AS MAP(INTEGER, INTEGER))
----
{42=NULL}
# we can also cast implicitly to our types
statement ok
CREATE TABLE structs (v STRUCT(duck INTEGER))
statement ok
CREATE TABLE lists (v VARCHAR[])
statement ok
CREATE table maps (v MAP(VARCHAR, INTEGER))
statement ok
INSERT INTO structs VALUES ('{"duck":42}'::JSON)
statement ok
INSERT INTO lists VALUES ('["duck"]'::JSON)
statement ok
INSERT INTO maps VALUES ('{"duck":42}'::JSON)
query I
SELECT * FROM structs
----
{'duck': 42}
query I
SELECT * FROM lists
----
[duck]
query I
SELECT * FROM maps
----
{duck=42}
# and back to JSON
statement ok
CREATE TABLE jsons (j JSON)
statement ok
INSERT INTO jsons SELECT * FROM structs
statement ok
INSERT INTO jsons SELECT * FROM lists
statement ok
INSERT INTO jsons SELECT * FROM maps
query I
SELECT * FROM jsons
----
{"duck":42}
["duck"]
{"duck":42}
# test_all_types roundtrip, excludes:
# 1. varchar (special case - input is not valid JSON)
# 2. blob - contains '\0'
# 3. bit - contains '\0'
# 4. medium_enum - don't want to create this enum
# 5. large_enum - don't want to create this enum
# and casts DECIMALs with large precision to DOUBLE because JSON can only deal with DOUBLE, and we lose some precision
statement ok
create type small_enum as enum ('DUCK_DUCK_ENUM', 'GOOSE');
query I nosort q0
select bool,
tinyint,
smallint,
int,
bigint,
hugeint,
uhugeint,
utinyint,
usmallint,
uint,
ubigint,
date,
time,
timestamp,
timestamp_s,
timestamp_ms,
timestamp_ns,
time_tz,
timestamp_tz,
float,
double,
dec_4_1,
dec_9_4,
dec_18_6::DOUBLE as dec_18_6,
dec38_10::DOUBLE as dec38_10,
uuid,
interval,
small_enum,
int_array,
double_array,
date_array,
timestamp_array,
timestamptz_array,
varchar_array,
nested_int_array,
struct,
struct_of_arrays,
array_of_structs,
map,
from test_all_types()
----
statement ok
create table all_types_json as
select bool::JSON as bool,
tinyint::JSON as tinyint,
smallint::JSON as smallint,
int::JSON as int,
bigint::JSON as bigint,
hugeint::JSON as hugeint,
uhugeint::JSON as uhugeint,
utinyint::JSON as utinyint,
usmallint::JSON as usmallint,
uint::JSON as uint,
ubigint::JSON as ubigint,
date::JSON as date,
time::JSON as time,
timestamp::JSON as timestamp,
timestamp_s::JSON as timestamp_s,
timestamp_ms::JSON as timestamp_ms,
timestamp_ns::JSON as timestamp_ns,
time_tz::JSON as time_tz,
timestamp_tz::JSON as timestamp_tz,
float::JSON as float,
double::JSON as double,
dec_4_1::JSON as dec_4_1,
dec_9_4::JSON as dec_9_4,
dec_18_6::DOUBLE::JSON as dec_18_6,
dec38_10::DOUBLE::JSON as dec38_10,
uuid::JSON as uuid,
interval::JSON as interval,
small_enum::JSON as small_enum,
int_array::JSON as int_array,
double_array::JSON as double_array,
date_array::JSON as date_array,
timestamp_array::JSON as timestamp_array,
timestamptz_array::JSON as timestamptz_array,
varchar_array::JSON as varchar_array,
nested_int_array::JSON as nested_int_array,
struct::JSON as struct,
struct_of_arrays::JSON as struct_of_arrays,
array_of_structs::JSON as array_of_structs,
map::JSON as map,
from test_all_types()
statement ok
create table roundtrip as
select bool::BOOLEAN as bool,
tinyint::TINYINT as tinyint,
smallint::SMALLINT as smallint,
int::INTEGER as int,
bigint::BIGINT as bigint,
hugeint::HUGEINT as hugeint,
uhugeint::UHUGEINT as uhugeint,
utinyint::UTINYINT as utinyint,
usmallint::USMALLINT as usmallint,
uint::UINTEGER as uint,
ubigint::UBIGINT as ubigint,
date::DATE as date,
time::TIME as time,
timestamp::TIMESTAMP as timestamp,
timestamp_s::TIMESTAMP_S as timestamp_s,
timestamp_ms::TIMESTAMP_MS as timestamp_ms,
timestamp_ns::TIMESTAMP_NS as timestamp_ns,
time_tz::TIME WITH TIME ZONE as time_tz,
timestamp_tz::TIMESTAMP WITH TIME ZONE as timestamp_tz,
float::FLOAT as float,
double::DOUBLE as double,
dec_4_1::DECIMAL(4,1) as dec_4_1,
dec_9_4::DECIMAL(9,4) as dec_9_4,
dec_18_6::DOUBLE as dec_18_6,
dec38_10::DOUBLE as dec38_10,
uuid::UUID as uuid,
interval::INTERVAL as interval,
small_enum::small_enum as small_enum,
int_array::INTEGER[] as int_array,
double_array::DOUBLE[] as double_array,
date_array::DATE[] as date_array,
timestamp_array::TIMESTAMP[] as timestamp_array,
timestamptz_array::TIMESTAMP WITH TIME ZONE[] as timestamptz_array,
varchar_array::VARCHAR[] as varchar_array,
nested_int_array::INTEGER[][] as nested_int_array,
struct::STRUCT(a INTEGER, b VARCHAR) as struct,
struct_of_arrays::STRUCT(a INTEGER[], b VARCHAR[]) as struct_of_arrays,
array_of_structs::STRUCT(a INTEGER, b VARCHAR)[] as array_of_structs,
map::MAP(VARCHAR, VARCHAR) as map
from all_types_json
query I nosort q0
select * from roundtrip
----
# also check that we handle vector types properly
foreach all_flat true false
query I nosort q1
select v from test_vector_types(null::int[], all_flat=${all_flat}) tbl(v)
----
query I nosort q1
select v::JSON::INT[] from test_vector_types(null::int[], all_flat=${all_flat}) tbl(v)
----
query I nosort q2
select v from test_vector_types(NULL::ROW(i INTEGER, j VARCHAR), all_flat=${all_flat}) tbl(v)
----
query I nosort q2
select v::JSON::ROW(i INTEGER, j VARCHAR) from test_vector_types(NULL::ROW(i INTEGER, j VARCHAR), all_flat=${all_flat}) tbl(v)
----
endloop
# we only cast our strings to JSON if they start with an alphabetic character, so this won't work
statement error
select ''::JSON
----
Conversion Error
statement error
select ' '::JSON
----
Conversion Error
# JSON cannot contain the NULL byte
statement error
select chr(0)::JSON
----
Conversion Error
statement error
select ('duck' || chr(0))::JSON
----
Conversion Error
# some varchar -> json[] and json[] -> varchar tests
# this is needed because our varchar -> varchar[] (and vice versa) escape quotes or add them
# this tests the special-case implementation for these casts
# issue 17647
query I
select '[{"some_key":"some_v}alue"}]'::json[];
----
[{"some_key":"some_v}alue"}]
# internal issue 5498
query I
with cte1 as (select 'a' as a),
cte2 as (select array_agg(cte1::json) as value from cte1)
select value::json[] from cte2;
----
[{"a":"a"}]
# larger test
query II
with cte1 as (
select array_agg({duck:42}::json) json_list_value
from range(5_000)
), cte2 as (
select '[' || string_agg('{"duck":42}', ', ') || ']' string_value
from range(5_000)
)
select json_list_value::varchar = string_value, json_list_value = string_value::json[]
from cte1, cte2
----
true true

View File

@@ -0,0 +1,59 @@
# name: test/sql/json/scalar/test_json_array_length.test
# description: Test JSON array length
# group: [scalar]
require json
statement ok
pragma enable_verification
statement ok
create table test (j varchar)
statement ok
insert into test values ('{}'), ('[]'), ('[1, 2, 3]')
query T
select json_array_length(j) from test
----
0
0
3
query T
select json_array_length(j, '$[1]') from test
----
NULL
NULL
0
# some SQLite json_array_length tests
query T
SELECT json_array_length('[1,2,3,4]');
----
4
query T
SELECT json_array_length('[1,2,3,4]', '$');
----
4
query T
SELECT json_array_length('[1,2,3,4]', '$[2]');
----
0
query T
SELECT json_array_length('{"one":[1,2,3]}');
----
0
query T
SELECT json_array_length('{"one":[1,2,3]}', '$.one');
----
3
query T
SELECT json_array_length('{"one":[1,2,3]}', '$.two');
----
NULL

View File

@@ -0,0 +1,25 @@
# name: test/sql/json/scalar/test_json_arrow_expr.test
# description: Test subquery binding of partially bound arrow expressions
# group: [scalar]
require json
statement ok
CREATE TABLE testjson AS SELECT JSON '{ "key" : "value" }' AS example;
query I
SELECT (SELECT (example)->k AS v FROM (SELECT 'key' AS k) keys)
FROM testjson;
----
"value"
query I
SELECT (SELECT json_extract(example, k) AS v FROM (SELECT 'key' AS k) keys)
FROM testjson;
----
"value"
query I
SELECT (SELECT (JSON '{ "key" : "value" }')->k AS v FROM (SELECT 'key' AS k) keys);
----
"value"

View File

@@ -0,0 +1,93 @@
# name: test/sql/json/scalar/test_json_contains.test
# description: Test JSON merge patch
# group: [scalar]
require json
statement ok
pragma enable_verification
# some examples copied from the first link I clicked when googling json_contains:
# https://database.guide/json_contains-examples-in-mysql/
query T
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 3}}', '{"c": {"d": 3}}') AS Result;
----
True
statement error
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 3}}', '"c": {"d": 3}') AS Result;
----
# some home-made tests
# empty list is contained in the list
query T
select json_contains('[1, 2]', '[]')
----
True
query T
select json_contains('[1, 2]', '2');
----
True
query T
select json_contains('[1, 2]', '[1, 2]');
----
True
query T
select json_contains('[1, 2, 3]', '[1, 2]');
----
True
# order-independent (follows MySQL behaviour)
query T
select json_contains('[1, 2]', '[2, 1]');
----
True
# {"d": 2} is contained in {"c": 1, "d": 2}, so it counts
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '{"d": 2}')
----
True
# same with {"c": 1}
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '{"c": 1}')
----
True
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '{"c": 1, "d": 2}')
----
True
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '[{"d": 2, "c": 1}]')
----
True
# same reasoning with the lists here as before, empty list is contained in the list
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '{"a": {"b": []}}')
----
True
query T
select json_contains('{"a": {"b": [{"c": 1, "d": 2}]}}', '[]')
----
True
# Issue 5960
query T
select json_contains(json('{"key":"value"}'),json('{"blah":"value"}'))
----
False
# Check if the recursion properly stops
query T
select json_contains('{"a": {"b": 42}}', '{"a": 42}')
----
False

View File

@@ -0,0 +1,325 @@
# name: test/sql/json/scalar/test_json_create.test
# description: Test JSON create functions {json_object(), json_array(), json_quote()}
# group: [scalar]
require json
statement ok
pragma enable_verification
# issue #7727
query T
SELECT TRY_CAST('{{P{P{{{{ASD{AS{D{' AS JSON);
----
NULL
query T
select json_quote({n: 42})
----
{"n":42}
# alias
query T
select to_json({n: 42})
----
{"n":42}
statement error
select to_json({n: 42}, {extra: 'argument'})
----
to_json() takes exactly one argument
query T
select to_json(union_value(n := 42))
----
{"n":42}
query T
SELECT to_json(union_value(a := NULL)::UNION(a INTEGER, b VARCHAR))
----
{"a":null}
query T
SELECT to_json(union_value(b := 'abc')::UNION(a INTEGER, b VARCHAR, c FLOAT))
----
{"b":"abc"}
query I
select to_json(i::UNION(a varchar, b bool)) from (VALUES (null), ('test')) tbl(i);
----
{"a":null}
{"a":"test"}
query I
select to_json(null::UNION(a varchar, b bool));
----
NULL
query T
select json_object('duck', 42)
----
{"duck":42}
query T
select json_object('duck', '{"goose": [1, 2, 3, 4, 5, 6, 7]}'::JSON)
----
{"duck":{"goose":[1,2,3,4,5,6,7]}}
query T
select json_object('nested', {duck: 42})
----
{"nested":{"duck":42}}
query T
select json_object('nested', [{duck: 42}, NULL])
----
{"nested":[{"duck":42},null]}
query T
select json_object('nested', map(['duck'], [42]))
----
{"nested":{"duck":42}}
query T
select json_object('nested', map(['duck', 'goose'], [42, 7]))
----
{"nested":{"duck":42,"goose":7}}
query T
select json_object('nested', map(['0', 'goose'], [42, 7]))
----
{"nested":{"0":42,"goose":7}}
query T
select json_object('nested', map(['duck', 'goose'], [NULL, 7]))
----
{"nested":{"duck":null,"goose":7}}
query T
select json_object('nested', [1, 2, 3])
----
{"nested":[1,2,3]}
query T
select json_object('nested', {nested2: [1, 2, 3]})
----
{"nested":{"nested2":[1,2,3]}}
query T
select json_object('nested', [{nested2: 1}, {nested2: 2}, {nested2: 3}])
----
{"nested":[{"nested2":1},{"nested2":2},{"nested2":3}]}
statement ok
create table test (a int, b double, c varchar, d int[], e uinteger)
statement ok
insert into test values
(0, 0.5, 'short', [0, 1, 2, 3, 4, 5, 6, 7, 9], 33),
(42, 1, 'looooooooooooooong', [], 42),
(-42, 0.42, 2, [1, 2, 3], 1111),
(777, 19.96, 'duck', NULL, 1),
(-777, 4.2, 'goose', [4, 2], NULL)
# a b c d e
query T
select json_quote(struct_pack(a := a, b := b, c := c, d := d, e := e)) from test
----
{"a":0,"b":0.5,"c":"short","d":[0,1,2,3,4,5,6,7,9],"e":33}
{"a":42,"b":1.0,"c":"looooooooooooooong","d":[],"e":42}
{"a":-42,"b":0.42,"c":"2","d":[1,2,3],"e":1111}
{"a":777,"b":19.96,"c":"duck","d":null,"e":1}
{"a":-777,"b":4.2,"c":"goose","d":[4,2],"e":null}
query T
select json_array(a, b, c, d, e) from test
----
[0,0.5,"short",[0,1,2,3,4,5,6,7,9],33]
[42,1.0,"looooooooooooooong",[],42]
[-42,0.42,"2",[1,2,3],1111]
[777,19.96,"duck",null,1]
[-777,4.2,"goose",[4,2],null]
query T
select json_object(a::varchar, a, b::varchar, b, c, c, d::varchar, d, e::varchar, e) from test
----
{"0":0,"0.5":0.5,"short":"short","[0, 1, 2, 3, 4, 5, 6, 7, 9]":[0,1,2,3,4,5,6,7,9],"33":33}
{"42":42,"1.0":1.0,"looooooooooooooong":"looooooooooooooong","[]":[],"42":42}
{"-42":-42,"0.42":0.42,"2":"2","[1, 2, 3]":[1,2,3],"1111":1111}
{"777":777,"19.96":19.96,"duck":"duck","1":1}
{"-777":-777,"4.2":4.2,"goose":"goose","[4, 2]":[4,2]}
query T
select json_quote(map(list(a), list(b))) from test
----
{"0":0.5,"42":1.0,"-42":0.42,"777":19.96,"-777":4.2}
query T
select json_quote(map(list(b), list(c))) from test
----
{"0.5":"short","1.0":"looooooooooooooong","0.42":"2","19.96":"duck","4.2":"goose"}
query T
select json_quote(map(list(c), list(d))) from test
----
{"short":[0,1,2,3,4,5,6,7,9],"looooooooooooooong":[],"2":[1,2,3],"duck":null,"goose":[4,2]}
# Histogram not implemented for INT[]
statement error
select json_quote(map(list(d), list(e))) from test
----
query T
select json_quote(map(list(c), list(e))) from test
----
{"short":33,"looooooooooooooong":42,"2":1111,"duck":1,"goose":null}
# some postgres aliases
query T
select row_to_json({a: 42})
----
{"a":42}
statement error
select row_to_json({a: 42}, false)
----
row_to_json() takes exactly one argument
query T
select row_to_json(NULL)
----
NULL
statement error
select row_to_json([42])
----
query T
select array_to_json([42])
----
[42]
statement error
select array_to_json([42], [21])
----
array_to_json() takes exactly one argument
query T
select array_to_json(NULL)
----
NULL
statement error
select array_to_json({a: 42})
----
# Some SQLite tests
query T
SELECT json_array(1,json_object('abc',2.5,'def',null,'ghi','hello'),99);
----
[1,{"abc":2.5,"def":null,"ghi":"hello"},99]
query T
SELECT json_object('a',1,'b',2.5,'c',null,'d','String Test');
----
{"a":1,"b":2.5,"c":null,"d":"String Test"}
# must have even number of args
statement error
SELECT json_object('a',1,'b');
----
query T
SELECT json_array(1,2.5,null,'hello');
----
[1,2.5,null,"hello"]
query T
SELECT json_array(1,'{"abc":2.5,"def":null,"ghi":hello}',99);
----
[1,"{\"abc\":2.5,\"def\":null,\"ghi\":hello}",99]
query T
SELECT json_array(1,json_quote('{"abc":2.5,"def":null,"ghi":"hello"}'),99);
----
[1,"{\"abc\":2.5,\"def\":null,\"ghi\":\"hello\"}",99]
query T
SELECT json_array(1,json_object('abc',2.5,'def',null,'ghi','hello'),99);
----
[1,{"abc":2.5,"def":null,"ghi":"hello"},99]
query T
SELECT json_object('ex','[52,3.14159]');
----
{"ex":"[52,3.14159]"}
query T
SELECT json_object('ex','[52,3.14159]'::JSON);
----
{"ex":[52,3.14159]}
query T
SELECT json_object('ex',json_array(52,3.14159));
----
{"ex":[52,3.14159]}
query T
SELECT json_object('a',2,'c',4);
----
{"a":2,"c":4}
query T
SELECT json_object('a',2,'c','{e:5}');
----
{"a":2,"c":"{e:5}"}
query T
SELECT json_object('a',2,'c',json_object('e',5));
----
{"a":2,"c":{"e":5}}
query T
SELECT json_array(1,2,'3',4);
----
[1,2,"3",4]
query T
SELECT json_array('[1,2]');
----
["[1,2]"]
query T
SELECT json_array(json_array(1,2));
----
[[1,2]]
query T
SELECT json_array(1,null,'3','[4,5]','{"six":7.7}');
----
[1,null,"3","[4,5]","{\"six\":7.7}"]
query T
SELECT json_array(1,null,'3','[4,5]'::JSON,'{"six":7.7}'::JSON);
----
[1,null,"3",[4,5],{"six":7.7}]
query T
SELECT json_array(
-9223372036854775808,9223372036854775807,0,1,-1,
0.0, 1.0, -1.0, -1e99, +2e100,
'one','two','three',
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, NULL, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ',
99);
----
[-9223372036854775808,9223372036854775807,0,1,-1,0.0,1.0,-1.0,-1e99,2e100,"one","two","three",4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,null,21,22,23,24,25,26,27,28,29,30,31,"abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWXYZ",99]
# test issue 12002
query I
SELECT CAST((MAP([5, 3, 4], ['a', 'b', 'c']), 2) AS JSON);
----
{"":{"5":"a","3":"b","4":"c"},"":2}

View File

@@ -0,0 +1,220 @@
# name: test/sql/json/scalar/test_json_dot_syntax.test
# description: Test JSON extract with dot syntax
# group: [scalar]
require json
statement ok
pragma enable_verification
# should work within other functions (no conflict with list Lambda functions)
query T
SELECT json_structure(json('{"duck":"goose"}').duck);
----
"VARCHAR"
# should go to our NULL
query T
select json('{"foo": null}').foo
----
null
query T
select json('{"foo": null}').foo.bar
----
NULL
# also supports this syntax
query T
select json('{"foo": null}')['foo']
----
null
query T
select json('{"foo": null}')['foo']['bar']
----
NULL
query T
select json('null')
----
null
query T
select json('[null]')."0"
----
NULL
# this doesn't work, we can't extract array elements using dots
query T
select json('{"my_field": {"my_nested_field": ["goose", "duck"]}}').my_field.my_nested_field."1"
----
NULL
# but we can using array extract syntax
query T
select json('{"my_field": {"my_nested_field": ["goose", "duck"]}}').my_field.my_nested_field[1]
----
"duck"
# again, this won't work
query T
select ('{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON).my_field.my_nested_field."1"
----
NULL
# but this will
query T
select ('{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON).my_field.my_nested_field[1]
----
"duck"
# can also access from back
query T
select ('{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON).my_field.my_nested_field[-1]
----
"duck"
# array slicing doesn't work (yet) for json extract
# this looks a bit weird, but this actually does a string slice
query T
select ('{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON).my_field.my_nested_field[0:1]
----
[
query T
select json('{"my_field": {"my_nested_field": ["goose", "duck"]}}').my_field.my_nested_field[1]
----
"duck"
query T
select json('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}').my_field.my_nested_field[1]
----
"duckduckduckduck"
query T
select ('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}'::JSON).my_field.my_nested_field[1]
----
"duckduckduckduck"
query T
select json('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}').my_field.my_nested_field[1]
----
"duckduckduckduck"
# doesn't work
query T
select json('[1, 2, 42]')."2"
----
NULL
# works!
query T
select json('[1, 2, 42]')[2]
----
42
query T
select json('[1, 2, 42]')[2]::text
----
42
# chained
query T
select ('{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON).my_field.my_nested_field[1]
----
"duck"
# some sqlite tests
query T
SELECT json('{"a":2,"c":[4,5,{"f":7}]}').c
----
[4,5,{"f":7}]
query T
SELECT json('{"a":2,"c":[4,5,{"f":7}]}').c[2]
----
{"f":7}
query T
SELECT json('{"a":2,"c":[4,5,{"f":7}]}').c[2].f
----
7
query T
SELECT json('{"a":2,"c":[4,5,{"f":7}]}').x
----
NULL
statement ok
CREATE TABLE obj(x varchar);
statement ok
INSERT INTO obj VALUES('{"a":1,"b":2}');
query T
SELECT json(x).b FROM obj;
----
2
query T
SELECT json(x)."b" FROM obj;
----
2
statement ok
CREATE TABLE t12(x varchar);
statement ok
INSERT INTO t12(x) VALUES(
'{"settings":
{"layer2":
{"hapax.legomenon":
{"forceDisplay":true,
"transliterate":true,
"add.footnote":true,
"summary.report":true},
"dis.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":true},
"tris.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":false}
}
}
}');
query T
SELECT json(x).settings.layer2."tris.legomenon"."summary.report" FROM t12;
----
false
query T
SELECT (x::JSON).settings.layer2."tris.legomenon"."summary.report" FROM t12;
----
false
# this will be upcast to JSON, cannot parse 'bar'
statement error
SELECT json('{"foo": "bar"}').foo = 'bar';
----
Conversion Error
query T
SELECT json('{"foo": "bar"}').foo = '"bar"';
----
true
query T
SELECT json('{"foo": 1}').foo = 1;
----
true
query T
SELECT json('{"foo": "bar"}') = {foo: 'bar'}
----
true

View File

@@ -0,0 +1,39 @@
# name: test/sql/json/scalar/test_json_exists.test
# description: Test JSON exists
# group: [scalar]
require json
statement ok
pragma enable_verification
query I
SELECT json_exists('{"duck": null}', '$.duck')
----
true
query I
with path AS (
SELECT '$.duck' p
)
SELECT json_exists('{"duck": null}', p) FROM path
----
true
query I
SELECT json_exists('{"duck": null}', '$.goose')
----
false
query I
with path AS (
SELECT '$.goose' p
)
SELECT json_exists('{"duck": null}', p) FROM path
----
false
query I
SELECT json_exists('{"duck": null}', ['$.duck', '$.goose'])
----
[true, false]

View File

@@ -0,0 +1,374 @@
# name: test/sql/json/scalar/test_json_extract.test
# description: Test JSON extract
# group: [scalar]
require json
statement ok
pragma enable_verification
# should work within other functions (no conflict with list Lambda functions)
query T
SELECT json_structure('{"duck":"goose"}'->'duck');
----
"VARCHAR"
# should go to our NULL
query T
select json_extract('{"foo": null}', '$.foo')
----
null
query T
select json_extract('{"foo": null}', '$.foo.bar')
----
NULL
query T
select json_extract('null', '$')
----
null
query T
select json_extract('[null]', '$[0]')
----
null
query T
select json_extract('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '/my_field/my_nested_field/1')
----
"duck"
query T
select json_extract_path('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '/my_field/my_nested_field/1')
----
"duck"
query T
select '{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON->'/my_field/my_nested_field/1'
----
"duck"
query T
select json_extract_string('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '/my_field/my_nested_field/1')
----
duck
query T
select json_extract_path_text('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '/my_field/my_nested_field/1')
----
duck
query T
select '{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON->>'/my_field/my_nested_field/1'
----
duck
query T
select json_extract('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}', '/my_field/my_nested_field/1')
----
"duckduckduckduck"
query T
select '{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}'::JSON->'/my_field/my_nested_field/1'
----
"duckduckduckduck"
query T
select json_extract_string('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}', '/my_field/my_nested_field/1')
----
duckduckduckduck
query T
select '{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}'::JSON->>'/my_field/my_nested_field/1'
----
duckduckduckduck
query T
select json_extract('[1, 2, 42]', 2)
----
42
query T
select json_extract_string('[1, 2, 42]', 2)
----
42
# chained
query T
select '{"my_field": {"my_nested_field": ["goose", "duck"]}}'::JSON->'my_field'->'my_nested_field'->>1
----
duck
# some sqlite tests
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$');
----
{"a":2,"c":[4,5,{"f":7}]}
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c');
----
[4,5,{"f":7}]
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]');
----
{"f":7}
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f');
----
7
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x');
----
NULL
# list of paths must be constant
statement error
with tbl as (
select '{"a":2,"c":[4,5],"f":7}' j, ['$.c','$.a'] p
)
SELECT json_extract(j, p);
----
Binder Error
query T
SELECT json_extract('{"a":2,"c":[4,5],"f":7}', ['$.c','$.a']);
----
[[4,5], 2]
query T
SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', ['$.x', '$.a']);
----
[NULL, 2]
query T
SELECT json_extract(NULL, ['$.x', '$.a']);
----
NULL
statement ok
CREATE TABLE t1(j varchar);
statement ok
INSERT INTO t1(j) VALUES('{"a":1,"b":[1,[2,3],4],"c":99}');
query T
SELECT json_extract(j, '$.b[#]') FROM t1;
----
NULL
# -0 is interpreted as just 0, just like in python
query II
SELECT json_extract(j, '$.b[#-0]') a, a = json_extract(j, '$.b[-0]') FROM t1;
----
1 true
query II
SELECT json_extract(j, '$.b[#-1]') a, a = json_extract(j, '$.b[-1]') FROM t1;
----
4 true
query TT
SELECT json_extract(j, '$.b[#-2]') a, a = json_extract(j, '$.b[-2]') FROM t1;
----
[2,3] true
query TT
SELECT json_extract(j, '$.b[#-02]') a, a = json_extract(j, '$.b[-02]') FROM t1;
----
[2,3] true
query TT
SELECT json_extract(j, '$.b[#-3]') a, a = json_extract(j, '$.b[-3]') FROM t1;
----
1 true
query TT
SELECT json_extract(j, '$.b[#-4]'), json_extract(j, '$.b[-4]') FROM t1;
----
NULL NULL
query TT
SELECT json_extract(j, '$.b[#-2][#-1]') a, a = json_extract(j, '$.b[-2][-1]') FROM t1;
----
3 true
query TT
SELECT j::JSON->'$.b[#-2][#-1]' a, a = (j::JSON->'$.b[-2][-1]') FROM t1;
----
3 true
query TT
SELECT json_extract(j, ['$.b[0]', '$.b[#-1]']) a, a = json_extract(j, ['$.b[0]', '$.b[-1]']) FROM t1;
----
[1, 4] true
query TT
SELECT j::JSON->['$.b[0]', '$.b[#-1]'] a, a = (j::JSON->['$.b[0]', '$.b[-1]']) FROM t1;
----
[1, 4] true
query TT
SELECT json_extract(j, '$.a[#-1]'), json_extract(j, '$.a[-1]') FROM t1;
----
NULL NULL
query TT
SELECT json_extract(j, '$.b[#-000001]') a, a = json_extract(j, '$.b[-000001]') FROM t1;
----
4 true
query TT
SELECT j::JSON->'$.b[#-000001]' a, a = (j::JSON->'$.b[-000001]') FROM t1;
----
4 true
statement error
SELECT json_extract(j, '$.b[#-]') FROM t1;
----
statement error
SELECT json_extract(j, '$.b[-]') FROM t1;
----
statement error
SELECT json_extract(j, '$.b[#9]') FROM t1;
----
statement error
SELECT json_extract(j, '$.b[#+2]') FROM t1;
----
statement error
SELECT json_extract(j, '$.b[#-1') FROM t1;
----
statement error
SELECT json_extract(j, '$.b[#-1x]') FROM t1;
----
statement ok
CREATE TABLE obj(x varchar);
statement ok
INSERT INTO obj VALUES('{"a":1,"b":2}');
query T
SELECT json_extract(x, '$.b') FROM obj;
----
2
query T
SELECT json_extract(x, '$."b"') FROM obj;
----
2
statement ok
CREATE TABLE t12(x varchar);
statement ok
INSERT INTO t12(x) VALUES(
'{"settings":
{"layer2":
{"hapax.legomenon":
{"forceDisplay":true,
"transliterate":true,
"add.footnote":true,
"summary.report":true},
"dis.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":true},
"tris.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":false}
}
}
}');
query T
SELECT json_extract(x, '$.settings.layer2."tris.legomenon"."summary.report"') FROM t12;
----
false
query T
SELECT x::JSON->'$.settings.layer2."tris.legomenon"."summary.report"' FROM t12;
----
false
# test issue #5063
statement ok
create table test5063 as select '{"a": 1, "b": 2}' js
statement ok
prepare q1 as SELECT js->CAST(? AS STRING) FROM test5063
query T
execute q1('a')
----
1
# test issue 11997
query I
select json_extract_string(json('{"j[so]n_\"key": 67}'), '$."j[so]n_\"key"');
----
67
query I
select '{"\"duck\"": 42}'->'$."\"duck\""';
----
42
query I
select '{"\"du\\ck\"": 42}'->'$."\"du\\ck\""';
----
42
query I
select '{"\"du\\ck\"": 42}'->'$."\"du\ck\""';
----
42
query I
select '{"du\\ck": 42}'->'$.du\ck';
----
42
# characters other than \\ or \" get ignored (for now)
query I
select '{"\"du\nck\"": 42}'->'$."\"du\nck\""';
----
NULL
# need to use chr(10) for \n
query I
select '{"\"du\nck\"": 42}'->('$."\"du' || chr(10) || 'ck\""');
----
42
# json_extract gets the JSON null (PostgreSQL behavior)
query I
select '{"duck":null}'->'$.duck'
----
null
# json_extract_string gets a SQL NULL (PostgreSQL behavior)
query I
select '{"duck":null}'->>'$.duck'
----
NULL
# issue 15217 (we should be able to extract the root using JSONPointer)
# the issue is wrong - using '/' should extract the field with an empty string as key
# but we should still be able to extract the root using a completely empty string
query I
select json_extract('{"hello":1}', '')
----
{"hello":1}

View File

@@ -0,0 +1,58 @@
# name: test/sql/json/scalar/test_json_keys.test
# description: Test JSON keys function
# group: [scalar]
require json
statement ok
pragma enable_verification
query T
select json_keys('{"duck": 42}');
----
[duck]
query T
select json_keys('{"duck": 42, "goose": 43}');
----
[duck, goose]
query T
select json_keys('["duck", "goose"]');
----
[]
query T
select json_keys(NULL)
----
NULL
query T
select json_keys('{"duck": {"key1": 42}, "goose": {"key1": 42, "key2": 43}}', ['duck', 'goose'])
----
[[key1], [key1, key2]]
statement ok
create table t1 as
select range, case when range % 2 = 0 then '{"duck": 42}' else '{"duck": 42, "goose": 43}' end j
from range(10000)
query TT
select range % 2 g, sum(length(json_keys(j))) c
from t1
group by g
order by all
----
0 5000
1 10000
statement ok
create table t2 as
select range, '{"duck": {"key1": 42}, "goose": {"key1": 42, "key2": 43}}' j
from range(10000)
query T
select sum(list_sum([length(l) for l in json_keys(j, ['duck', 'goose'])])) s
from t2
----
30000

View File

@@ -0,0 +1,107 @@
# name: test/sql/json/scalar/test_json_merge_patch.test
# description: Test JSON merge patch
# group: [scalar]
require json
statement ok
pragma enable_verification
# from issue 4227
query T
SELECT json_merge_patch('{"a": 1}', '{"a": 2}')
----
{"a":2}
query T
SELECT json_merge_patch('{"a": 1}', '{"b": 2}')
----
{"a":1,"b":2}
query T
SELECT json_merge_patch('{"a": {"c": 1}}', '{"a": {"d": 2}}')
----
{"a":{"c":1,"d":2}}
query T
SELECT json_merge_patch('{"a": {"b": 1}}', '{"a": {"b": 2}}')
----
{"a":{"b":2}}
# from MySQL documentation
query T
SELECT JSON_MERGE_PATCH('[1, 2]', '[true, false]');
----
[true,false]
query T
SELECT JSON_MERGE_PATCH('{"name": "x"}', '{"id": 47}');
----
{"name":"x","id":47}
query T
SELECT JSON_MERGE_PATCH('1', 'true');
----
true
query T
SELECT JSON_MERGE_PATCH('[1, 2]', '{"id": 47}');
----
{"id":47}
query T
SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }');
----
{"b":2,"a":3,"c":4}
query T
SELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }','{ "a": 5, "d":6 }');
----
{"b":2,"c":4,"a":5,"d":6}
query T
SELECT JSON_MERGE_PATCH('{"a":1, "b":2}', '{"b":null}');
----
{"a":1}
query T
SELECT JSON_MERGE_PATCH('{"a":{"x":1}}', '{"a":{"y":2}}');
----
{"a":{"x":1,"y":2}}
# test NULL behaviour
query T
select json_merge_patch(NULL, '3')
----
3
query T
select json_merge_patch('3', NULL)
----
NULL
query T
select json_merge_patch(NULL, NULL)
----
NULL
# test vararg behaviour
query T
select json_merge_patch('{"a":1}', '{"b":2}', '{"c":3}')
----
{"a":1,"b":2,"c":3}
query T
select json_merge_patch(NULL, '{"b":2}', '{"c":3}')
----
{"b":2,"c":3}
query T
select json_merge_patch('{"a":1}', NULL, '{"c":3}')
----
{"c":3}
query T
select json_merge_patch('{"a":1}', '{"b":2}', NULL)
----
NULL

View File

@@ -0,0 +1,267 @@
# name: test/sql/json/scalar/test_json_path.test
# description: Test JSON extract (path notation)
# group: [scalar]
require json
statement ok
pragma enable_verification
# this used to error but the json pointer spec says we should be able to extract the root using the empty string
query I
select json_extract('{"my_field": "duck"}', '')
----
{"my_field":"duck"}
query T
select json_extract('{"my_field": "duck"}', '$.my_field')
----
"duck"
query T
select json_extract('[0, 1, 2]', '$[1]')
----
1
query T
select json_extract('[[1]]', '$[0][0]')
----
1
statement ok
create table test (j varchar, q varchar)
statement ok
insert into test values ('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '$.my_field.my_nested_field[0]')
# wrong syntax
statement error
select json_extract(j, '$.my_field.my_nested_field[]') from test
----
Binder Error
query T
select json_extract(j, '$.my_field.my_nested_field[0]') from test
----
"goose"
# SQLite's indexing from back of the list requires '#'
query T
select json_extract(j, '$.my_field.my_nested_field[#-1]') from test
----
"duck"
query T
select json_extract(j, '$.my_field.my_nested_field[#-2]') from test
----
"goose"
query T
select json_extract(j, '$.my_field.my_nested_field[#-3]') from test
----
NULL
query T
select json_extract(j, '$.my_field.my_nested_field[#]') from test
----
NULL
# we can also do without '#'
query T
select json_extract(j, '$.my_field.my_nested_field[-1]') from test
----
"duck"
query T
select json_extract(j, '$.my_field.my_nested_field[-2]') from test
----
"goose"
query T
select json_extract(j, '$.my_field.my_nested_field[-3]') from test
----
NULL
query T
select json_extract(j, q) from test
----
"goose"
query T
select json_extract('{"my_field": [{"my_nested_field": ["duck", "goose"]}]}', '$.my_field[0].my_nested_field[0]')
----
"duck"
query T
select json_extract('{"my_field": [{"my_nested_field": ["duck", "goose"]}]}', '$.my_field[#-1].my_nested_field[#-1]')
----
"goose"
# some NULLs
query T
select json_extract(j, '$.my_field.my_nested_field.3') from test
----
NULL
# invalid path error that happens during execution, not binding
statement error
with tbl as (
select '[{"duck":42},{"duck":43}]' j, '$duck' p
)
select json_extract(j, p) from tbl
----
Invalid Input Error
# path error
statement error
select json_extract('{"a": {"b": "c"}}', '$[]');
----
statement error
select json_extract('{"a": {"b": "c"}}', '$[#');
----
statement error
select json_extract(j, '$.my_field[my_nested_field[#-3]') from test
----
statement error
select json_extract(j, '$.my_field.my_nested_field[!]') from test
----
statement error
select json_extract('{"a": {"b": "c"}}', '$.a..');
----
statement error
select json_extract('{"a": {"b": "c"}}', '$[[');
----
statement error
select json_extract('{"a": {"b": "c"}}', '$[.');
----
statement error
select json_extract('{"a": {"b": "c"}}', '$]');
----
# with JSON path we support wildcards in arrays and objects, this results in a LIST
query T
select json_extract('[{"duck":42},{"duck":43}]', '$[*].duck')
----
[42, 43]
query T
select json_extract('{"duck":42, "goose":43}', '$.*');
----
[42, 43]
# check for invalid syntax
statement error
select json_extract('[{"duck":42},{"duck":43}]', '$[*.duck')
----
Binder Error: JSON path error
statement error
select json_extract('[{"duck":42},{"duck":43}]', '$*.duck')
----
Binder Error: JSON path error
statement error
select json_extract('{"duck":42, "goose":43}', '$.[*]');
----
Binder Error: JSON path error
# wildcards yields empty list if none are found
query T
select json_extract('[{"duck":42},{"duck":43}]', '$.*')
----
[]
query T
select json_extract('{"duck":[42,43]}', '$.*[-1]')
----
[43]
# can have multiple wildcards
query T
select json_extract('[{"duck":42},{"duck":43}]', '$[*].*')
----
[42, 43]
# wildcards do not work when path param is not foldable
statement error
with tbl as (
select '[{"duck":42},{"duck":43}]' j, '$[*].duck' p
)
select json_extract(j, p) from tbl
----
Invalid Input Error
# wildcards do not work inside of a multi-extract
statement error
select json_extract('[{"duck":42},{"goose":43}]', ['$[*].duck', '$[*].goose'])
----
Binder Error
# test with a larger input
query T
select sum((to_json({duck:range})->'$.*')[1]::int) = sum(range) from range(10000)
----
1
# test some nulls (JSON Path reference implementation returns NULLs in wildcards),
# if the path is not there, it's not added to the LIST
query T
select json_extract('[{"duck":null},{"duck":42},{"duck":null},{}]', '$[*].*')
----
[null, 42, null]
# test recursive wildcard path
query T
select json_extract('{"a":{"b":1,"c":2},"d":["g","h",[{"b":5},{"x":42}]]}', '$..*')
----
[{"b":1,"c":2}, ["g","h",[{"b":5},{"x":42}]], 1, 2, "g", "h", [{"b":5},{"x":42}], {"b":5}, {"x":42}, 5, 42]
# alternative syntax
query T
select json_extract('{"a":{"b":1,"c":2},"d":["g","h",[{"b":5},{"x":42}]]}', '$.**')
----
[{"b":1,"c":2}, ["g","h",[{"b":5},{"x":42}]], 1, 2, "g", "h", [{"b":5},{"x":42}], {"b":5}, {"x":42}, 5, 42]
# recursive non-wildcard path
query T
select json_extract('{"a":{"b":1,"c":2},"d":["g","h",[{"b":5},{"x":42}]]}', '$..b')
----
[1, 5]
query T
select json_extract('{"a":{"b":1,"c":2},"d":["g","h",[{"b":5},{"x":42}]]}', '$..[0]')
----
["g", {"b":5}]
query I
with tbl as (
select '[{"duck":42},{"duck":{"a":43,"b":null}}]' j
)
select json_extract(j, '$[*]..*') from tbl
----
[42, {"a":43,"b":null}, 43, null]
query T
with tbl as (
select '{"duck":[{"goose":42},{"goose":43}],"goose":null}' j
)
select json_extract(j, '$.duck[*]..goose') from tbl
----
[42, 43]
query T
select json_extract(j,'$..[*]') from test
----
["goose", "duck"]
query T
select json_extract('[[{"a":[1,2,3]}], [{"a":[4,5,6]}]]','$[*]..a[*]')
----
[1, 2, 3, 4, 5, 6]

View File

@@ -0,0 +1,46 @@
# name: test/sql/json/scalar/test_json_pretty.test
# description: Test JSON pretty printer
# group: [scalar]
require json
statement ok
pragma enable_verification
query I
SELECT json_pretty('[1,2,{"a":43, "g":[true, true]}]') = '[
1,
2,
{
"a": 43,
"g": [
true,
true
]
}
]'
----
true
query I
SELECT json_pretty(NULL)
----
NULL
query I
SELECT json_pretty('null'::json);
----
null
query I
SELECT json_pretty('[1,2,null, {"a": null}, 42]'::json) = '[
1,
2,
null,
{
"a": null
},
42
]'
----
true

View File

@@ -0,0 +1,186 @@
# name: test/sql/json/scalar/test_json_structure.test
# description: Test json_structure() function
# group: [scalar]
require json
statement ok
pragma enable_verification
# singletons
query T
select json_structure('42')
----
"UBIGINT"
query T
select json_structure('4.2')
----
"DOUBLE"
query T
select json_structure('null')
----
"NULL"
query T
select json_structure('true')
----
"BOOLEAN"
query T
select json_structure('"duck"')
----
"VARCHAR"
# simple values
query T
select json_structure('{"a": 42}')
----
{"a":"UBIGINT"}
query T
select json_structure('{"a": 4.2}')
----
{"a":"DOUBLE"}
query T
select json_structure('{"a": "42"}')
----
{"a":"VARCHAR"}
query T
select json_structure('{"a": "looooooooooooooooong"}')
----
{"a":"VARCHAR"}
query T
select json_structure('{"a": null}')
----
{"a":"NULL"}
query T
select json_structure('{"a": true}')
----
{"a":"BOOLEAN"}
query T
select json_structure('{"a": []}')
----
{"a":["NULL"]}
query T
select json_structure('{"a": [42]}')
----
{"a":["UBIGINT"]}
query T
select json_structure('{"a": {"b": 42}}')
----
{"a":{"b":"UBIGINT"}}
# we want strong typing for JSON arrays. If we find inconsistent types, we just set the type to JSON
query T
select json_structure('[null,null]')
----
["NULL"]
query T
select json_structure('[true,null,false]')
----
["BOOLEAN"]
query T
select json_structure('[true,null,false,1]')
----
["JSON"]
query T
select json_structure('[true,null,false,1,-1]')
----
["JSON"]
query T
select json_structure('[true,null,false,1,-1,0.42]')
----
["JSON"]
query T
select json_structure('[true,null,false,1,-1,0.42,"42"]')
----
["JSON"]
# nested stuff
query T
select json_structure('[{"a": 42}, {"a": null}]')
----
[{"a":"UBIGINT"}]
query T
select json_structure('[{"a": 42}, {"b": 4.2}]')
----
[{"a":"UBIGINT","b":"DOUBLE"}]
query T
select json_structure('[{"a": [42, null]}, {"a": [7]}]')
----
[{"a":["UBIGINT"]}]
query T
select json_structure('[{"a": [{"b": 42}, {"b": null}]}, {"a": [{"b": 7}]}]')
----
[{"a":[{"b":"UBIGINT"}]}]
query T
select json_structure('[{"a": [{"b": 42}, {"b": null}]}, {"a": [{"c": 7}]}]')
----
[{"a":[{"b":"UBIGINT","c":"UBIGINT"}]}]
# inconsistent types
query T
select json_structure('[1, [1]]')
----
["JSON"]
query T
select json_structure('[1, {"a": 1}]')
----
["JSON"]
query T
select json_structure('[[1], {"a": 1}]')
----
["JSON"]
# duplicate key, used to throw an error, now the error is ignored
query I
select json_structure('{"a": 42, "a": 7}')
----
{"a":"UBIGINT"}
# from a table
statement ok
create table test (j json);
statement ok
insert into test values
('{"family": "anatidae", "species": ["duck", "goose", "swan", null], "coolness": 1000}'),
('{"family": "canidae", "species": ["labrador", null, "bulldog", "shepherd"], "hair": true, "coolness": 999}'),
(NULL),
('{"family": null, "species": null, "hair": null, "coolness": null}'),
('{"family": "felidae", "species": ["tiger", "lion", null, "british shorthair"], "hair": true, "coolness": 999}')
query T
select json_structure(j) from test
----
{"family":"VARCHAR","species":["VARCHAR"],"coolness":"UBIGINT"}
{"family":"VARCHAR","species":["VARCHAR"],"hair":"BOOLEAN","coolness":"UBIGINT"}
NULL
{"family":"NULL","species":"NULL","hair":"NULL","coolness":"NULL"}
{"family":"VARCHAR","species":["VARCHAR"],"hair":"BOOLEAN","coolness":"UBIGINT"}
# issue 11886
query I
select json_structure('{"a": 1, "A": 1}');
----
{"a":"UBIGINT","A":"UBIGINT"}

View File

@@ -0,0 +1,549 @@
# name: test/sql/json/scalar/test_json_transform.test
# description: Test json_transform function
# group: [scalar]
require json
statement ok
pragma enable_verification
# aliases
query T
select from_json('42', '"UBIGINT"')
----
42
query T
select from_json_strict('42', '"UBIGINT"')
----
42
statement error
select from_json_strict('42', '"DATE"')
----
<REGEX>:.*Invalid Input Error.*Unable to cast.*
# singletons
statement error
select json_transform('42', '42')
----
<REGEX>:.*Binder Error.*invalid JSON structure.*
query T
select json_transform('42', '"UBIGINT"')
----
42
query T
select json_transform('4.2', '"DOUBLE"')
----
4.2
query T
select json_transform('null', '"NULL"')
----
NULL
query T
select json_transform('true', '"BOOLEAN"')
----
True
query T
select json_transform('"duck"', '"VARCHAR"')
----
duck
query T
select json_transform('"duuuuuuuuuuuuuuuuck"', '"VARCHAR"')
----
duuuuuuuuuuuuuuuuck
# simple structs
query T
select json_transform('{"a": 42}', '{"a":"UBIGINT"}')
----
{'a': 42}
statement error
select json_transform_strict('{"a": 42, "a":43}', '{"a":"UBIGINT"}')
----
<REGEX>:.*Invalid Input Error.*has duplicate key.*
statement error
select json_transform_strict('{}', '{"a":"UBIGINT"}')
----
<REGEX>:.*Invalid Input Error.*does not have key.*
statement error
select json_transform_strict('{}', '["UBIGINT"]')
----
<REGEX>:.*Invalid Input Error.*Expected ARRAY, but got OBJECT.*
query T
select json_transform('[{}, [42]]', '[["UBIGINT"]]')
----
[NULL, [42]]
query T
select json_transform('{"a": null}', '{"a":"UBIGINT"}')
----
{'a': NULL}
query T
select json_transform('{"a": 42}', '{"a":"NULL"}')
----
{'a': NULL}
statement error
select json_transform('{"a": 42}', '{"a":"ARRAY"}')
----
<REGEX>:.*Invalid Input Error.*can not be converted to a DuckDB Type.*
# arrays
statement error
select json_transform('[1,2,3]', '["UBIGINT", "BIGINT"]')
----
<REGEX>:.*Binder Error.*Too many values in array.*
query T
select list_sum(json_transform(range(5000)::JSON, '["UBIGINT"]'))::UBIGINT s
----
12497500
query T
select json_transform('[1,2,3]', '["UBIGINT"]')
----
[1, 2, 3]
query T
select json_transform('[1,2,3]', '["NULL"]')
----
[NULL, NULL, NULL]
query T
select json_transform('[{"a": 42}, {"a": null}, {"a": 7}]', '[{"a": "UBIGINT"}]')
----
[{'a': 42}, {'a': NULL}, {'a': 7}]
# we can have missing keys, these become NULL
query T
select json_transform('[{"a": 42}, {"a": null, "b": 33}, {"b": 7}]', '[{"a": "UBIGINT", "b": "UBIGINT"}]')
----
[{'a': 42, 'b': NULL}, {'a': NULL, 'b': 33}, {'a': NULL, 'b': 7}]
statement ok
create table test (j json);
statement ok
insert into test values
('{"family": "anatidae", "species": ["duck", "goose", "swan", null], "coolness": 1000}'),
('{"family": "canidae", "species": ["labrador", null, "bulldog", "shepherd"], "hair": true, "coolness": 999}'),
(NULL),
('{"family": null, "species": null, "hair": null, "coolness": null}'),
('{"family": "felidae", "species": ["tiger", "lion", null, "british shorthair"], "hair": true, "coolness": 999}')
query T
select json_transform(j, '{"family": "VARCHAR", "coolness": "UBIGINT", "species": ["VARCHAR"]}') from test
----
{'family': anatidae, 'coolness': 1000, 'species': [duck, goose, swan, NULL]}
{'family': canidae, 'coolness': 999, 'species': [labrador, NULL, bulldog, shepherd]}
NULL
{'family': NULL, 'coolness': NULL, 'species': NULL}
{'family': felidae, 'coolness': 999, 'species': [tiger, lion, NULL, british shorthair]}
# conflicting names
statement error
select json_transform('{"a": 4, "a": 2}', '{"a": "UBIGINT", "a": "UBIGINT"}')
----
<REGEX>:.*Invalid Input Error.*Duplicate keys in object.*
# can actually get parts of the JSON back as string
query T
select json_transform('{"a": {"duck": 42, "goose": 7}}', '{"a": "JSON"}')
----
{'a': '{"duck":42,"goose":7}'}
# loops over all types for coverage
# all integer types
foreach type <integral>
query T
select json_transform('42', '"${type}"')
----
42
query T
select json_transform('42.42', '"${type}"')
----
42
query T
select json_transform('"42"', '"${type}"')
----
42
query T
select json_transform('true', '"${type}"')
----
1
query T
select json_transform('false', '"${type}"')
----
0
query T
select json_transform('[]', '"${type}"')
----
NULL
query T
select json_transform('{}', '"${type}"')
----
NULL
statement error
select json_transform_strict('[]', '"${type}"')
----
<REGEX>:.*Invalid Input Error.*Failed to cast value to numerical.*
statement error
select json_transform_strict('{}', '"${type}"')
----
<REGEX>:.*Invalid Input Error.*Failed to cast value to numerical.*
query T
select json_transform('null', '"${type}"')
----
NULL
endloop
query T
select json_transform('-42', '"INTEGER"')
----
-42
query T
select json_transform('-42', '"UINTEGER"')
----
NULL
statement error
select json_transform_strict('-42', '"UINTEGER"')
----
<REGEX>:.*Invalid Input Error.*Failed to cast value to numerical.*
# varchar
query T
select json_transform('42', '"VARCHAR"')
----
42
query T
select json_transform('42', '"JSON"')
----
42
query T
select json_transform('42', '"BLOB"')
----
42
query T
select json_transform('-42', '"VARCHAR"')
----
-42
query T
select json_transform('42.42', '"VARCHAR"')
----
42.42
query T
select json_transform('true', '"VARCHAR"')
----
true
query T
select json_transform('[]', '"VARCHAR"')
----
[]
query T
select json_transform('{}', '"VARCHAR"')
----
{}
query T
select json_transform('null', '"VARCHAR"')
----
NULL
# decimal
query T
select json_transform('42', '"DECIMAL"')
----
42.000
query T
select json_transform('42', '"DECIMAL(2)"')
----
42
query T
select json_transform('42', '"DECIMAL(3,1)"')
----
42.0
query T
select json_transform('-42', '"DECIMAL(3,1)"')
----
-42.0
query T
select json_transform('"42"', '"DECIMAL(3,1)"')
----
42.0
query T
select json_transform('42.42', '"DECIMAL(4,2)"')
----
42.42
query T
select json_transform('42.42', '"DECIMAL(10,2)"')
----
42.42
query T
select json_transform('42.42', '"DECIMAL(20,2)"')
----
42.42
query T
select json_transform('42.42', '"DECIMAL(38,2)"')
----
42.42
query T
select json_transform('42.42', '"DECIMAL(38,17)"')
----
42.42000000000000000
query T
select json_transform('true', '"DECIMAL(3,1)"')
----
1.0
query T
select json_transform('false', '"DECIMAL(3,1)"')
----
0.0
query T
select json_transform('null', '"DECIMAL(3,1)"')
----
NULL
query T
select json_transform('42', '"DECIMAL(2,1)"')
----
NULL
query T
select json_transform('[]', '"DECIMAL(2,1)"')
----
NULL
query T
select json_transform('{}', '"DECIMAL(2,1)"')
----
NULL
statement error
select json_transform_strict('42', '"DECIMAL(2,1)"')
----
<REGEX>:.*Invalid Input Error.*Failed to cast value to decimal.*
statement error
select json_transform('42', '"DECIMAL(39)"')
----
<REGEX>:.*Invalid Input Error.*can not be converted to a DuckDB Type.*
statement error
select json_transform('42', '"DECIMAL(2,4)"')
----
<REGEX>:.*Invalid Input Error.*can not be converted to a DuckDB Type.*
statement error
select json_transform('42', '"DECIMAL(5,1,1)"')
----
<REGEX>:.*Invalid Input Error.*can not be converted to a DuckDB Type.*
# uuid
query T
select json_transform('"A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11"', '"UUID"')
----
a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
query T
select json_transform('42', '"UUID"')
----
NULL
statement error
select json_transform_strict('42', '"UUID"')
----
<REGEX>:.*Invalid Input Error.*Unable to cast.*
query T
select json_transform('-42', '"UUID"')
----
NULL
query T
select json_transform('42.42', '"UUID"')
----
NULL
query T
select json_transform('true', '"UUID"')
----
NULL
query T
select json_transform('false', '"UUID"')
----
NULL
query T
select json_transform('null', '"UUID"')
----
NULL
statement error
select json_transform_strict('42', '"UUID"')
----
<REGEX>:.*Invalid Input Error.*Unable to cast.*
# date / time
query T
select json_transform('"1996-03-27"', '"DATE"')
----
1996-03-27
query T
select json_transform('"11:59:59"', '"TIME"')
----
11:59:59
query T
select json_transform('42', '"DATE"')
----
NULL
query T
select json_transform('-42', '"DATE"')
----
NULL
query T
select json_transform('42.42', '"DATE"')
----
NULL
query T
select json_transform('"42"', '"DATE"')
----
NULL
query T
select json_transform('null', '"DATE"')
----
NULL
query T
select json_transform('true', '"DATE"')
----
NULL
query T
select json_transform('false', '"DATE"')
----
NULL
query T
select json_transform('[]', '"DATE"')
----
NULL
query T
select json_transform('{}', '"DATE"')
----
NULL
statement error
select json_transform_strict('false', '"DATE"')
----
<REGEX>:.*Invalid Input Error.*Unable to cast.*
# timestamp
query T
select json_transform('"1996-03-27 11:59:59"', '"TIMESTAMP"')
----
1996-03-27 11:59:59
query T
select json_transform('"1996-03-27 11:59:59"', '"TIMESTAMP_MS"')
----
1996-03-27 11:59:59
query T
select json_transform('"1996-03-27 11:59:59"', '"TIMESTAMP_NS"')
----
1996-03-27 11:59:59
query T
select json_transform('"1996-03-27 11:59:59"', '"TIMESTAMP_S"')
----
1996-03-27 11:59:59
query T
select json_transform('null', '"TIMESTAMP"')
----
NULL
query T
select json_transform('42', '"TIMESTAMP"')
----
NULL
statement error
select json_transform_strict('42', '"TIMESTAMP"')
----
<REGEX>:.*Invalid Input Error.*Unable to cast.*
# enum tests
statement ok
CREATE OR REPLACE TYPE test_enum AS ENUM ('a', 'b', 'c');
query T
select json_transform('{"test": "a"}', '{"test": "test_enum"}')
----
{'test': a}
query T
select json_transform('{"test": ["a","b"]}', '{"test": "test_enum[]"}')
----
{'test': [a, b]}
query T
select json_transform('{"test": ["a","b"]}', '{"test": "test_enum[2]"}')
----
{'test': [a, b]}
statement ok
DROP TYPE test_enum;

View File

@@ -0,0 +1,236 @@
# name: test/sql/json/scalar/test_json_type.test
# description: Test JSON type
# group: [scalar]
require json
statement ok
pragma enable_verification
# unary type function
query T
select json_type('{"str": 42}')
----
OBJECT
query T
select json_type('[1, 2, 3]')
----
ARRAY
# invalid JSON but we can still get the type of the singleton
query T
select json_type('"other"')
----
VARCHAR
query T
select json_type('42')
----
UBIGINT
query T
select json_type('NaN')
----
DOUBLE
query T
select json_type('null')
----
NULL
query T
select json_type(NULL)
----
NULL
# binary type function
# tests with constant input and constant query
query T
select json_type('{"str": 42}', 'str')
----
UBIGINT
query T
select json_type('{"str": "quack"}', 'str')
----
VARCHAR
query T
select json_type('{"str": "quack"}', 'str2')
----
NULL
query T
select json_type('{"str": "quack"}', NULL)
----
NULL
query T
select json_type(NULL, 'str')
----
NULL
# NaN and Infinity should become DOUBLE
query T
select json_type('{"null": NaN}', 'null')
----
DOUBLE
query T
select json_type('{"null": nan}', 'null')
----
DOUBLE
query T
select json_type('{"null": Infinity}', 'null')
----
DOUBLE
query T
select json_type('{"null": -Infinity}', 'null')
----
DOUBLE
statement ok
create table test(json varchar, query varchar)
statement ok
insert into test values
('{"str": "quack", "int": 4, "double": 0.42, "bool": true, "arr": [], "nested": {"val": 1}}', '/nested/val'),
('{"str": "woof", "int": -4, "double": -0.42, "bool": false, "arr": [0, 1, 2], "nested": {"val": 42}}', '/arr/2'),
('{"str": null, "int": null, "double": null, "bool": null, "arr": null, "nested": null}', 'bool')
# tests with columnref input and constant query
query T
select json_type(json, 'str') from test
----
VARCHAR
VARCHAR
NULL
query T
select json_type(json, 'int') from test
----
UBIGINT
BIGINT
NULL
query T
select json_type(json, 'double') from test
----
DOUBLE
DOUBLE
NULL
query T
select json_type(json, 'bool') from test
----
BOOLEAN
BOOLEAN
NULL
query T
select json_type(json, 'arr') from test
----
ARRAY
ARRAY
NULL
# json path queries
query T
select json_type(json, '/arr/0') from test
----
NULL
UBIGINT
NULL
query T
select json_type(json, '/nested/val') from test
----
UBIGINT
UBIGINT
NULL
# query multiple paths
query T
select json_type(json, ['str', '/nested/val']) from test
----
[VARCHAR, UBIGINT]
[VARCHAR, UBIGINT]
['NULL', NULL]
# test with columnref input and columnref query
query T
select json_type(json, query) from test
----
UBIGINT
UBIGINT
NULL
# some SQLite json_type tests
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}');
----
OBJECT
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$');
----
OBJECT
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a');
----
ARRAY
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]');
----
UBIGINT
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]');
----
DOUBLE
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]');
----
BOOLEAN
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]');
----
BOOLEAN
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]');
----
NULL
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]');
----
VARCHAR
query T
SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]');
----
NULL
# test LIST(JSON) compatibility
query T
select json_type(json_extract('{"duck":[1,2,3]}', '$..duck'))
----
ARRAY
query T
select json_type(json_extract('{"a":{"duck":[1]},"b":{"duck":[2,3]}}', '$..duck'))
----
ARRAY
query T
select json_type(json_extract('{"duck":[1,2,3]}', '$.duck[*]'))
----
ARRAY

View File

@@ -0,0 +1,621 @@
# name: test/sql/json/scalar/test_json_valid.test
# description: Test JSON valid
# group: [scalar]
require json
statement ok
pragma enable_verification
# there was a bug with infinity handling in yyjson, therefore we have these tests
# it has since been fixed
query T
select json_valid('{"bla": inf}')
----
true
query T
select json_valid('{"bla": infinity}')
----
true
# some SQLite JSON valid tests
statement ok
CREATE TABLE j1(x varchar);
statement ok
INSERT INTO j1(x)
VALUES('true'),('false'),('null'),('123'),('-234'),('34.5e+6'),
('""'),('"\""'),('"\\"'),('"abcdefghijlmnopqrstuvwxyz"'),
('[]'),('{}'),('[true,false,null,123,-234,34.5e+6,{},[]]'),
('{"a":true,"b":{"c":false}}');
query T
SELECT * FROM j1 WHERE NOT json_valid(x);
----
query T
SELECT json_valid('{"a":55,"b":72,}');
----
true
query T
SELECT json_valid('{"a":55,"b":72}');
----
true
query T
SELECT json_valid('["a",55,"b",72,]');
----
true
query T
SELECT json_valid('["a",55,"b",72]');
----
true
query T
SELECT json_valid('" \ "');
----
false
query T
SELECT json_valid('" \! "');
----
0
query T
SELECT json_valid('" \" "');
----
1
query T
SELECT json_valid('" \# "');
----
0
query T
SELECT json_valid('" \$ "');
----
0
query T
SELECT json_valid('" \% "');
----
0
query T
SELECT json_valid('" \& "');
----
0
query T
SELECT json_valid('" \'' "');
----
0
query T
SELECT json_valid('" \( "');
----
0
query T
SELECT json_valid('" \) "');
----
0
query T
SELECT json_valid('" \* "');
----
0
query T
SELECT json_valid('" \+ "');
----
0
query T
SELECT json_valid('" \, "');
----
0
query T
SELECT json_valid('" \- "');
----
0
query T
SELECT json_valid('" \. "');
----
0
query T
SELECT json_valid('" \/ "');
----
1
query T
SELECT json_valid('" \0 "');
----
0
query T
SELECT json_valid('" \1 "');
----
0
query T
SELECT json_valid('" \2 "');
----
0
query T
SELECT json_valid('" \3 "');
----
0
query T
SELECT json_valid('" \4 "');
----
0
query T
SELECT json_valid('" \5 "');
----
0
query T
SELECT json_valid('" \6 "');
----
0
query T
SELECT json_valid('" \7 "');
----
0
query T
SELECT json_valid('" \8 "');
----
0
query T
SELECT json_valid('" \9 "');
----
0
query T
SELECT json_valid('" \: "');
----
0
query T
SELECT json_valid('" \; "');
----
0
query T
SELECT json_valid('" \< "');
----
0
query T
SELECT json_valid('" \= "');
----
0
query T
SELECT json_valid('" \> "');
----
0
query T
SELECT json_valid('" \? "');
----
0
query T
SELECT json_valid('" \@ "');
----
0
query T
SELECT json_valid('" \A "');
----
0
query T
SELECT json_valid('" \B "');
----
0
query T
SELECT json_valid('" \C "');
----
0
query T
SELECT json_valid('" \D "');
----
0
query T
SELECT json_valid('" \E "');
----
0
query T
SELECT json_valid('" \F "');
----
0
query T
SELECT json_valid('" \G "');
----
0
query T
SELECT json_valid('" \H "');
----
0
query T
SELECT json_valid('" \I "');
----
0
query T
SELECT json_valid('" \J "');
----
0
query T
SELECT json_valid('" \K "');
----
0
query T
SELECT json_valid('" \L "');
----
0
query T
SELECT json_valid('" \M "');
----
0
query T
SELECT json_valid('" \N "');
----
0
query T
SELECT json_valid('" \O "');
----
0
query T
SELECT json_valid('" \P "');
----
0
query T
SELECT json_valid('" \Q "');
----
0
query T
SELECT json_valid('" \R "');
----
0
query T
SELECT json_valid('" \S "');
----
0
query T
SELECT json_valid('" \T "');
----
0
query T
SELECT json_valid('" \U "');
----
0
query T
SELECT json_valid('" \V "');
----
0
query T
SELECT json_valid('" \W "');
----
0
query T
SELECT json_valid('" \X "');
----
0
query T
SELECT json_valid('" \Y "');
----
0
query T
SELECT json_valid('" \Z "');
----
0
query T
SELECT json_valid('" \[ "');
----
0
query T
SELECT json_valid('" \\ "');
----
1
query T
SELECT json_valid('" \] "');
----
0
query T
SELECT json_valid('" \^ "');
----
0
query T
SELECT json_valid('" \_ "');
----
0
query T
SELECT json_valid('" \` "');
----
0
query T
SELECT json_valid('" \a "');
----
0
query T
SELECT json_valid('" \b "');
----
1
query T
SELECT json_valid('" \c "');
----
0
query T
SELECT json_valid('" \d "');
----
0
query T
SELECT json_valid('" \e "');
----
0
query T
SELECT json_valid('" \f "');
----
1
query T
SELECT json_valid('" \g "');
----
0
query T
SELECT json_valid('" \h "');
----
0
query T
SELECT json_valid('" \i "');
----
0
query T
SELECT json_valid('" \j "');
----
0
query T
SELECT json_valid('" \k "');
----
0
query T
SELECT json_valid('" \l "');
----
0
query T
SELECT json_valid('" \m "');
----
0
query T
SELECT json_valid('" \n "');
----
1
query T
SELECT json_valid('" \o "');
----
0
query T
SELECT json_valid('" \p "');
----
0
query T
SELECT json_valid('" \q "');
----
0
query T
SELECT json_valid('" \r "');
----
1
query T
SELECT json_valid('" \s "');
----
0
query T
SELECT json_valid('" \t "');
----
1
query T
SELECT json_valid('" \u "');
----
0
query T
SELECT json_valid('" \ua "');
----
0
query T
SELECT json_valid('" \uab "');
----
0
query T
SELECT json_valid('" \uabc "');
----
0
query T
SELECT json_valid('" \uabcd "');
----
1
query T
SELECT json_valid('" \uFEDC "');
----
1
query T
SELECT json_valid('" \u1234 "');
----
1
query T
SELECT json_valid('" \v "');
----
0
query T
SELECT json_valid('" \w "');
----
0
query T
SELECT json_valid('" \x "');
----
0
query T
SELECT json_valid('" \y "');
----
0
query T
SELECT json_valid('" \z "');
----
0
query T
SELECT json_valid('" \{ "');
----
0
query T
SELECT json_valid('" \| "');
----
0
query T
SELECT json_valid('" \} "');
----
0
query T
SELECT json_valid('" \~ "');
----
0
query T
SELECT json_valid('{"x":01}')
----
0
query T
SELECT json_valid('{"x":-01}')
----
0
query T
SELECT json_valid('{"x":0}')
----
1
query T
SELECT json_valid('{"x":-0}')
----
1
query T
SELECT json_valid('{"x":0.1}')
----
1
query T
SELECT json_valid('{"x":-0.1}')
----
1
query T
SELECT json_valid('{"x":0.0000}')
----
1
query T
SELECT json_valid('{"x":-0.0000}')
----
1
query T
SELECT json_valid('{"x":01.5}')
----
0
query T
SELECT json_valid('{"x":-01.5}')
----
0
query T
SELECT json_valid('{"x":00}')
----
0
query T
SELECT json_valid('{"x":-00}')
----
0

View File

@@ -0,0 +1,193 @@
# name: test/sql/json/scalar/test_json_value.test
# description: Test JSON value
# group: [scalar]
require json
statement ok
pragma enable_verification
# unlike JSON extract, this goes our NULL
query T
select json_value('{"foo": null}', '$.foo')
----
NULL
query T
select json_value('{"foo": null}', '$.foo.bar')
----
NULL
query T
select json_value('null', '$')
----
NULL
query T
select json_value('[null]', '$[0]')
----
NULL
query T
select json_value('{"my_field": {"my_nested_field": ["goose", "duck"]}}', '/my_field/my_nested_field/1')
----
"duck"
query T
select json_value('{"my_field": {"my_nested_field": ["goose", "duckduckduckduck"]}}', '/my_field/my_nested_field/1')
----
"duckduckduckduck"
query T
select json_value('[1, 2, 42]', 2)
----
42
# some sqlite tests
# this one returns NULL because the extracted value is not scalar
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', '$');
----
NULL
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', '$.c');
----
NULL
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]');
----
NULL
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f');
----
7
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', '$.x');
----
NULL
# list of paths must be constant
statement error
with tbl as (
select '{"a":2,"c":[4,5],"f":7}' j, ['$.c','$.a'] p
)
SELECT json_value(j, p);
----
Binder Error
# first value is not scalar, so it is set to NULL
query T
SELECT json_value('{"a":2,"c":[4,5],"f":7}', ['$.c','$.a']);
----
[NULL, 2]
query T
SELECT json_value('{"a":2,"c":[4,5,{"f":7}]}', ['$.x', '$.a']);
----
[NULL, 2]
query T
SELECT json_value(NULL, ['$.x', '$.a']);
----
NULL
statement ok
CREATE TABLE t1(j varchar);
statement ok
INSERT INTO t1(j) VALUES('{"a":1,"b":[1,[2,3],4],"c":99}');
query T
SELECT json_value(j, '$.b[#]') FROM t1;
----
NULL
query TT
SELECT json_value(j, '$.a[#-1]'), json_value(j, '$.a[-1]') FROM t1;
----
NULL NULL
query TT
SELECT json_value(j, '$.b[#-000001]') a, a = json_value(j, '$.b[-000001]') FROM t1;
----
4 true
statement error
SELECT json_value(j, '$.b[#-]') FROM t1;
----
statement error
SELECT json_value(j, '$.b[-]') FROM t1;
----
statement error
SELECT json_value(j, '$.b[#9]') FROM t1;
----
statement error
SELECT json_value(j, '$.b[#+2]') FROM t1;
----
statement error
SELECT json_value(j, '$.b[#-1') FROM t1;
----
statement error
SELECT json_value(j, '$.b[#-1x]') FROM t1;
----
statement ok
CREATE TABLE obj(x varchar);
statement ok
INSERT INTO obj VALUES('{"a":1,"b":2}');
query T
SELECT json_value(x, '$.b') FROM obj;
----
2
query T
SELECT json_value(x, '$."b"') FROM obj;
----
2
statement ok
CREATE TABLE t12(x varchar);
statement ok
INSERT INTO t12(x) VALUES(
'{"settings":
{"layer2":
{"hapax.legomenon":
{"forceDisplay":true,
"transliterate":true,
"add.footnote":true,
"summary.report":true},
"dis.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":true},
"tris.legomenon":
{"forceDisplay":true,
"transliterate":false,
"add.footnote":false,
"summary.report":false}
}
}
}');
query T
SELECT json_value(x, '$.settings.layer2."tris.legomenon"."summary.report"') FROM t12;
----
false
query T
SELECT json_value(x, '$.settings.layer2."tris.legomenon"') FROM t12;
----
NULL