mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-08-04 18:18:03 +00:00
921 lines
26 KiB
Tcl
Executable file
921 lines
26 KiB
Tcl
Executable file
#!/usr/bin/env tclsh
|
||
|
||
set testdir [file dirname $argv0]
|
||
source $testdir/tester.tcl
|
||
|
||
do_execsql_test json5-ecma-script-1 {
|
||
select json('{a:5,b:6}') ;
|
||
} {{{"a":5,"b":6}}}
|
||
|
||
do_execsql_test json5-ecma-script-2 {
|
||
select json('{a:5,a:3}') ;
|
||
} {{{"a":5,"a":3}}}
|
||
|
||
do_execsql_test json5-ecma-script-3 {
|
||
SELECT json('{ MNO_123$xyz : 789 }');
|
||
} {{{"MNO_123$xyz":789}}}
|
||
|
||
do_execsql_test json5-with-single-trailing-comma-valid {
|
||
select json('{"a":5, "b":6, }');
|
||
} {{{"a":5,"b":6}}}
|
||
|
||
do_execsql_test json5-single-quoted {
|
||
SELECT json('{"a": ''abcd''}');
|
||
} {{{"a":"abcd"}}}
|
||
|
||
do_execsql_test json5-hexadecimal-1 {
|
||
SELECT json('{a: 0x0}')
|
||
} {{{"a":0}}}
|
||
|
||
do_execsql_test json5-hexadecimal-2 {
|
||
SELECT json('{a: 0xabcdef}')
|
||
} {{{"a":11259375}}}
|
||
|
||
do_execsql_test json5-hexadecimal-2 {
|
||
SELECT json('{a: -0xabcdef}')
|
||
} {{{"a":-11259375}}}
|
||
|
||
do_execsql_test json5-number-1 {
|
||
SELECT json('{x: 4.}')
|
||
} {{{"x":4.0}}}
|
||
|
||
do_execsql_test json5-number-2 {
|
||
SELECT json('{x: +4.}')
|
||
} {{{"x":4.0}}}
|
||
|
||
do_execsql_test json5-number-3 {
|
||
SELECT json('{x: -4.}')
|
||
} {{{"x":-4.0}}}
|
||
|
||
do_execsql_test json5-number-5 {
|
||
SELECT json('{x: Infinity}')
|
||
} {{{"x":9e999}}}
|
||
|
||
do_execsql_test json5-number-6 {
|
||
SELECT json('{x: -Infinity}')
|
||
} {{{"x":-9e999}}}
|
||
|
||
do_execsql_test json5-multi-comment {
|
||
SELECT json(' /* abc */ { /*def*/ aaa /* xyz */ : // to the end of line
|
||
123 /* xyz */ , /* 123 */ }')
|
||
} {{{"aaa":123}}}
|
||
|
||
do_execsql_test json5-ecma-script-1-pretty {
|
||
select json_pretty('{a:5,b:6}') ;
|
||
} {{{
|
||
"a": 5,
|
||
"b": 6
|
||
}}}
|
||
|
||
do_execsql_test json5-ecma-script-2-pretty {
|
||
select json_pretty('{a:5,a:3}') ;
|
||
} {{{
|
||
"a": 5,
|
||
"a": 3
|
||
}}}
|
||
|
||
do_execsql_test json5-ecma-script-3-pretty {
|
||
SELECT json_pretty('{ MNO_123$xyz : 789 }');
|
||
} {{{
|
||
"MNO_123$xyz": 789
|
||
}}}
|
||
|
||
do_execsql_test json5-with-single-trailing-comma-valid-pretty {
|
||
select json_pretty('{"a":5, "b":6, }');
|
||
} {{{
|
||
"a": 5,
|
||
"b": 6
|
||
}}}
|
||
|
||
do_execsql_test json5-single-quoted-pretty {
|
||
SELECT json_pretty('{"a": ''abcd''}');
|
||
} {{{
|
||
"a": "abcd"
|
||
}}}
|
||
|
||
do_execsql_test json5-hexadecimal-1-pretty {
|
||
SELECT json_pretty('{a: 0x0}');
|
||
} {{{
|
||
"a": 0
|
||
}}}
|
||
|
||
do_execsql_test json5-hexadecimal-2-pretty {
|
||
SELECT json_pretty('{a: 0xabcdef}');
|
||
} {{{
|
||
"a": 11259375
|
||
}}}
|
||
|
||
do_execsql_test json5-hexadecimal-2-pretty {
|
||
SELECT json_pretty('{a: -0xabcdef}');
|
||
} {{{
|
||
"a": -11259375
|
||
}}}
|
||
|
||
do_execsql_test json5-number-1-pretty {
|
||
SELECT json_pretty('{x: 4.}');
|
||
} {{{
|
||
"x": 4.0
|
||
}}}
|
||
|
||
do_execsql_test json5-number-2-pretty {
|
||
SELECT json_pretty('{x: +4.}');
|
||
} {{{
|
||
"x": 4.0
|
||
}}}
|
||
|
||
do_execsql_test json5-number-3-pretty {
|
||
SELECT json_pretty('{x: -4.}');
|
||
} {{{
|
||
"x": -4.0
|
||
}}}
|
||
|
||
do_execsql_test json5-number-5-pretty {
|
||
SELECT json_pretty('{x: Infinity}');
|
||
} {{{
|
||
"x": 9e999
|
||
}}}
|
||
|
||
do_execsql_test json5-number-6-pretty {
|
||
SELECT json_pretty('{x: -Infinity}');
|
||
} {{{
|
||
"x": -9e999
|
||
}}}
|
||
|
||
do_execsql_test json5-multi-comment-pretty {
|
||
SELECT json_pretty(' /* abc */ { /*def*/ aaa /* xyz */ : // to the end of line
|
||
123 /* xyz */ , /* 123 */ }');
|
||
} {{{
|
||
"aaa": 123
|
||
}}}
|
||
|
||
do_execsql_test json-pretty-ident-1 {
|
||
SELECT json_pretty('{x: 1}', '');
|
||
} {{{
|
||
"x": 1
|
||
}}}
|
||
|
||
do_execsql_test json-pretty-ident-2 {
|
||
SELECT json_pretty('{x: 1}', '11');
|
||
} {{{
|
||
11"x": 1
|
||
}}}
|
||
|
||
do_execsql_test json-pretty-ident-null {
|
||
SELECT json_pretty('{x: 1}', NULL);
|
||
} {{{
|
||
"x": 1
|
||
}}}
|
||
|
||
do_execsql_test json-pretty-ident-blob-1 {
|
||
SELECT json_pretty('{x: 1}', x'33');
|
||
} {{{
|
||
3"x": 1
|
||
}}}
|
||
|
||
# TODO
|
||
# Currently conversion from blob to string is not exactly the same as in sqlite.
|
||
# The blob below should evaluate to two whitespaces TEXT value
|
||
|
||
# do_execsql_test json-pretty-ident-blob-2 {
|
||
# SELECT json_pretty('{x: 1}', x'1111');
|
||
# } {{{
|
||
# "x": 1
|
||
# }}}
|
||
|
||
do_execsql_test json_array_str {
|
||
SELECT json_array('a')
|
||
} {{["a"]}}
|
||
|
||
do_execsql_test json_array_numbers {
|
||
SELECT json_array(1, 1.5)
|
||
} {{[1,1.5]}}
|
||
|
||
do_execsql_test json_array_numbers_2 {
|
||
SELECT json_array(1., +2., -2.)
|
||
} {{[1.0,2.0,-2.0]}}
|
||
|
||
do_execsql_test json_array_null {
|
||
SELECT json_array(null)
|
||
} {{[null]}}
|
||
|
||
do_execsql_test json_array_not_json {
|
||
SELECT json_array('{"a":1}')
|
||
} {{["{\"a\":1}"]}}
|
||
|
||
do_execsql_test json_array_json {
|
||
SELECT json_array(json('{"a":1}'))
|
||
} {{[{"a":1}]}}
|
||
|
||
do_execsql_test json_array_nested {
|
||
SELECT json_array(json_array(1,2,3), json('[1,2,3]'), '[1,2,3]')
|
||
} {{[[1,2,3],[1,2,3],"[1,2,3]"]}}
|
||
|
||
|
||
do_execsql_test json_extract_null {
|
||
SELECT json_extract(null, '$')
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_json_null_type {
|
||
SELECT typeof(json_extract('null', '$'))
|
||
} {{null}}
|
||
|
||
do_execsql_test json_arrow_json_null_type {
|
||
SELECT typeof('null' -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_json_null_type {
|
||
SELECT typeof('null' ->> '$')
|
||
} {{null}}
|
||
|
||
do_execsql_test json_extract_empty {
|
||
SELECT json_extract()
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_single_param {
|
||
SELECT json_extract(1)
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_null_invalid_path {
|
||
SELECT json_extract(null, 1)
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_null_invalid_path_2 {
|
||
SELECT json_extract(null, CAST(1 AS BLOB))
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_multiple_nulls {
|
||
SELECT json_extract(null, CAST(1 AS BLOB), null, 1, 2, 3)
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_number {
|
||
SELECT json_extract(1, '$')
|
||
} {{1}}
|
||
|
||
do_execsql_test json_extract_number_type {
|
||
SELECT typeof(json_extract(1, '$'))
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_arrow_number {
|
||
SELECT 1 -> '$'
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_number_type {
|
||
SELECT typeof(1 -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_number {
|
||
SELECT 1 -> '$'
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_shift_number_type {
|
||
SELECT typeof(1 ->> '$')
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_extract_object_1 {
|
||
SELECT json_extract('{"a": [1,2,3]}', '$.a')
|
||
} {{[1,2,3]}}
|
||
|
||
do_execsql_test json_arrow_object {
|
||
SELECT '{"a": [1,2,3]}' -> '$.a'
|
||
} {{[1,2,3]}}
|
||
|
||
do_execsql_test json_arrow_shift_object {
|
||
SELECT '{"a": [1,2,3]}' ->> '$.a'
|
||
} {{[1,2,3]}}
|
||
|
||
do_execsql_test json_extract_object_2 {
|
||
SELECT json_extract('{"a": [1,2,3]}', '$.a', '$.a[0]', '$.a[1]', '$.a[3]')
|
||
} {{[[1,2,3],1,2,null]}}
|
||
|
||
do_execsql_test json_extract_object_3 {
|
||
SELECT json_extract('{"a": [1,2,3]}', '$.a', '$.a[0]', '$.a[1]', null, '$.a[3]')
|
||
} {{}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
# \x61 is the ASCII code for 'a'
|
||
# do_execsql_test json_extract_with_escaping {
|
||
# SELECT json_extract('{"\x61": 1}', '$.a')
|
||
# } {{1}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
#do_execsql_test json_extract_with_escaping_2 {
|
||
# SELECT json_extract('{"\x61": 1}', '$.\x61')
|
||
#} {{1}}
|
||
|
||
do_execsql_test json_extract_null_path {
|
||
SELECT json_extract(1, null)
|
||
} {{}}
|
||
|
||
do_execsql_test json_arrow_null_path {
|
||
SELECT 1 -> null
|
||
} {{}}
|
||
|
||
do_execsql_test json_arrow_shift_null_path {
|
||
SELECT 1 ->> null
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_float {
|
||
SELECT typeof(json_extract(1.0, '$'))
|
||
} {{real}}
|
||
|
||
do_execsql_test json_arrow_float {
|
||
SELECT typeof(1.0 -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_float {
|
||
SELECT typeof(1.0 ->> '$')
|
||
} {{real}}
|
||
|
||
do_execsql_test json_extract_true {
|
||
SELECT json_extract('true', '$')
|
||
} {{1}}
|
||
|
||
do_execsql_test json_extract_true_type {
|
||
SELECT typeof(json_extract('true', '$'))
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_arrow_true {
|
||
SELECT 'true' -> '$'
|
||
} {{true}}
|
||
|
||
do_execsql_test json_arrow_true_type {
|
||
SELECT typeof('true' -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_true {
|
||
SELECT 'true' ->> '$'
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_shift_true_type {
|
||
SELECT typeof('true' ->> '$')
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_extract_false {
|
||
SELECT json_extract('false', '$')
|
||
} {{0}}
|
||
|
||
do_execsql_test json_extract_false_type {
|
||
SELECT typeof(json_extract('false', '$'))
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_arrow_false {
|
||
SELECT 'false' -> '$'
|
||
} {{false}}
|
||
|
||
do_execsql_test json_arrow_false_type {
|
||
SELECT typeof('false' -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_false {
|
||
SELECT 'false' ->> '$'
|
||
} {{0}}
|
||
|
||
do_execsql_test json_arrow_shift_false_type {
|
||
SELECT typeof('false' ->> '$')
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_extract_string {
|
||
SELECT json_extract('"string"', '$')
|
||
} {{string}}
|
||
|
||
do_execsql_test json_extract_string_type {
|
||
SELECT typeof(json_extract('"string"', '$'))
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_string {
|
||
SELECT '"string"' -> '$'
|
||
} {{"string"}}
|
||
|
||
do_execsql_test json_arrow_string_type {
|
||
SELECT typeof('"string"' -> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_shift_string {
|
||
SELECT '"string"' ->> '$'
|
||
} {{string}}
|
||
|
||
do_execsql_test json_arrow_shift_string_type {
|
||
SELECT typeof('"string"' ->> '$')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_arrow_implicit_root_path {
|
||
SELECT '{"a":1}' -> 'a';
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_root_path {
|
||
SELECT '{"a":1}' ->> 'a';
|
||
} {{1}}
|
||
|
||
# TODO: fix me after rebasing on top of https://github.com/tursodatabase/limbo/pull/631 - use the Option value in json_extract_single
|
||
#do_execsql_test json_arrow_implicit_root_path_undefined_key {
|
||
# SELECT '{"a":1}' -> 'x';
|
||
#} {{}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_root_path_undefined_key {
|
||
SELECT '{"a":1}' ->> 'x';
|
||
} {{}}
|
||
|
||
do_execsql_test json_arrow_implicit_root_path_array {
|
||
SELECT '[1,2,3]' -> 1;
|
||
} {{2}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_root_path_array {
|
||
SELECT '[1,2,3]' ->> 1;
|
||
} {{2}}
|
||
|
||
do_execsql_test json_arrow_implicit_root_path_array_negative_idx {
|
||
SELECT '[1,2,3]' -> -1;
|
||
} {{3}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_root_path_array_negative_idx {
|
||
SELECT '[1,2,3]' ->> -1;
|
||
} {{3}}
|
||
|
||
do_execsql_test json_arrow_implicit_real_cast {
|
||
SELECT '{"1.5":"abc"}' -> 1.5;
|
||
} {{"abc"}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_real_cast {
|
||
SELECT '{"1.5":"abc"}' -> 1.5;
|
||
} {{"abc"}}
|
||
|
||
do_execsql_test json_arrow_implicit_true_cast {
|
||
SELECT '[1,2,3]' -> true
|
||
} {{2}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_true_cast {
|
||
SELECT '[1,2,3]' ->> true
|
||
} {{2}}
|
||
|
||
do_execsql_test json_arrow_implicit_false_cast {
|
||
SELECT '[1,2,3]' -> false
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_shift_implicit_false_cast {
|
||
SELECT '[1,2,3]' ->> false
|
||
} {{1}}
|
||
|
||
do_execsql_test json_arrow_chained {
|
||
select '{"a":2,"c":[4,5,{"f":7}]}' -> 'c' -> 2 ->> 'f'
|
||
} {{7}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
do_execsql_test json_extract_multiple_null_paths {
|
||
SELECT json_extract(1, null, null, null)
|
||
} {{}}
|
||
|
||
do_execsql_test json_extract_array {
|
||
SELECT json_extract('[1,2,3]', '$')
|
||
} {{[1,2,3]}}
|
||
|
||
do_execsql_test json_arrow_array {
|
||
SELECT '[1,2,3]' -> '$'
|
||
} {{[1,2,3]}}
|
||
|
||
do_execsql_test json_arrow_shift_array {
|
||
SELECT '[1,2,3]' ->> '$'
|
||
} {{[1,2,3]}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
#do_execsql_test json_extract_quote {
|
||
# SELECT json_extract('{"\"":1 }', '$.\"')
|
||
#} {{1}}
|
||
|
||
# Overflows 2**32 is equivalent to 0
|
||
do_execsql_test json_extract_overflow_int32_1 {
|
||
SELECT json_extract('[1,2,3]', '$[4294967296]')
|
||
} {{1}}
|
||
|
||
# Overflows 2**32 + 1 is equivalent to 1
|
||
do_execsql_test json_extract_overflow_int32_2 {
|
||
SELECT json_extract('[1,2,3]', '$[4294967297]')
|
||
} {{2}}
|
||
|
||
# Overflows -2**32 - 1 is equivalent to -1
|
||
do_execsql_test json_extract_overflow_int32_3 {
|
||
SELECT json_extract('[1,2,3]', '$[#-4294967297]')
|
||
} {{3}}
|
||
|
||
# Overflows -2**32 - 2 is equivalent to -2
|
||
do_execsql_test json_extract_overflow_int32_3 {
|
||
SELECT json_extract('[1,2,3]', '$[#-4294967298]')
|
||
} {{2}}
|
||
|
||
# pow(2,63) + 1 == 9223372036854775808
|
||
do_execsql_test json_extract_overflow_int64 {
|
||
SELECT json_extract('[1,2,3]', '$[9223372036854775808]');
|
||
} {{1}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
# pow(2, 127) + 1 == 170141183460469231731687303715884105729
|
||
#do_execsql_test json_extract_overflow_int128 {
|
||
# SELECT json_extract('[1, 2, 3]', '$[170141183460469231731687303715884105729]');
|
||
#} {{2}}
|
||
|
||
# TODO: fix me - this passes on SQLite and needs to be fixed in Limbo.
|
||
#do_execsql_test json_extract_blob {
|
||
# select json_extract(CAST('[1,2,3]' as BLOB), '$[1]')
|
||
#} {{2}}
|
||
|
||
do_execsql_test json_array_length {
|
||
SELECT json_array_length('[1,2,3,4]');
|
||
} {{4}}
|
||
|
||
do_execsql_test json_array_length_empty {
|
||
SELECT json_array_length('[]');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_array_length_root {
|
||
SELECT json_array_length('[1,2,3,4]', '$');
|
||
} {{4}}
|
||
|
||
do_execsql_test json_array_length_not_array {
|
||
SELECT json_array_length('{"one":[1,2,3]}');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_array_length_via_prop {
|
||
SELECT json_array_length('{"one":[1,2,3]}', '$.one');
|
||
} {{3}}
|
||
|
||
do_execsql_test json_array_length_via_index {
|
||
SELECT json_array_length('[[1,2,3,4]]', '$[0]');
|
||
} {{4}}
|
||
|
||
do_execsql_test json_array_length_via_index_not_array {
|
||
SELECT json_array_length('[1,2,3,4]', '$[2]');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_array_length_via_bad_prop {
|
||
SELECT json_array_length('{"one":[1,2,3]}', '$.two');
|
||
} {{}}
|
||
|
||
do_execsql_test json_array_length_nested {
|
||
SELECT json_array_length('{"one":[[1,2,3],2,3]}', '$.one[0]');
|
||
} {{3}}
|
||
|
||
do_execsql_test json_type_no_path {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}')
|
||
} {{object}}
|
||
|
||
do_execsql_test json_type_root_path {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$')
|
||
} {{object}}
|
||
|
||
do_execsql_test json_type_array {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a')
|
||
} {{array}}
|
||
|
||
do_execsql_test json_type_integer {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]')
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_type_real {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]')
|
||
} {{real}}
|
||
|
||
do_execsql_test json_type_true {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]')
|
||
} {{true}}
|
||
|
||
do_execsql_test json_type_false {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]')
|
||
} {{false}}
|
||
|
||
do_execsql_test json_type_null {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]')
|
||
} {{null}}
|
||
|
||
do_execsql_test json_type_text {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]')
|
||
} {{text}}
|
||
|
||
do_execsql_test json_type_NULL {
|
||
select json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]')
|
||
} {{}}
|
||
|
||
do_execsql_test json_type_cast {
|
||
select json_type(1)
|
||
} {{integer}}
|
||
|
||
do_execsql_test json_type_null_arg {
|
||
select json_type(null)
|
||
} {{}}
|
||
|
||
do_execsql_test json_error_position_valid {
|
||
SELECT json_error_position('{"a":55,"b":72,}');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_error_position_valid_ws {
|
||
SELECT json_error_position('{"a":55,"b":72 , }');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_error_position_object {
|
||
SELECT json_error_position('{"a":55,"b":72,,}');
|
||
} {{16}}
|
||
|
||
do_execsql_test json_error_position_array_valid {
|
||
SELECT json_error_position('["a",55,"b",72,]');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_error_position_array_valid_ws {
|
||
SELECT json_error_position('["a",55,"b",72 , ]');
|
||
} {{0}}
|
||
|
||
do_execsql_test json_error_position_array {
|
||
SELECT json_error_position('["a",55,"b",72,,]');
|
||
} {{16}}
|
||
|
||
do_execsql_test json_error_position_null {
|
||
SELECT json_error_position(NULL);
|
||
} {{}}
|
||
|
||
do_execsql_test json_error_position_complex {
|
||
SELECT json_error_position('{a:null,{"h":[1,[1,2,3]],"j":"abc"}:true}');
|
||
} {{9}}
|
||
|
||
do_execsql_test json_object_simple {
|
||
SELECT json_object('key', 'value');
|
||
} {{{"key":"value"}}}
|
||
|
||
do_execsql_test json_object_nested {
|
||
SELECT json_object('grandparent',json_object('parent', json_object('child', 'value')));
|
||
} {{{"grandparent":{"parent":{"child":"value"}}}}}
|
||
|
||
do_execsql_test json_object_quoted_json {
|
||
SELECT json_object('parent', '{"child":"value"}');
|
||
} {{{"parent":"{\"child\":\"value\"}"}}}
|
||
|
||
do_execsql_test json_object_unquoted_json {
|
||
SELECT json_object('parent', json('{"child":"value"}'));
|
||
} {{{"parent":{"child":"value"}}}}
|
||
|
||
do_execsql_test json_object_multiple_values {
|
||
SELECT json_object('text', 'value', 'json', json_object('key', 'value'), 'int', 1, 'float', 1.5, 'null', null);
|
||
} {{{"text":"value","json":{"key":"value"},"int":1,"float":1.5,"null":null}}}
|
||
|
||
do_execsql_test json_object_empty {
|
||
SELECT json_object();
|
||
} {{{}}}
|
||
|
||
do_execsql_test json_object_json_array {
|
||
SELECT json_object('ex',json('[52,3]'));
|
||
} {{{"ex":[52,3]}}}
|
||
|
||
do_execsql_test json_from_json_object {
|
||
SELECT json(json_object('key','value'));
|
||
} {{{"key":"value"}}}
|
||
|
||
# FIXME: this behaviour differs from sqlite. Although, sqlite docs states
|
||
# that this could change in a "future enhancement" (https://www.sqlite.org/json1.html#jobj)
|
||
#do_execsql_test json_object_duplicated_keys {
|
||
# SELECT json_object('key', 'value', 'key', 'value2');
|
||
#} {{{"key":"value2"}}}
|
||
#
|
||
|
||
do_execsql_test json_valid_1 {
|
||
SELECT json_valid('{"a":55,"b":72}');
|
||
} {1}
|
||
do_execsql_test json_valid_2 {
|
||
SELECT json_valid('["a",55,"b",72]');
|
||
} {1}
|
||
do_execsql_test json_valid_3 {
|
||
SELECT json_valid( CAST('{"a":1}' AS BLOB) );
|
||
} {1}
|
||
do_execsql_test json_valid_4 {
|
||
SELECT json_valid(123);
|
||
} {1}
|
||
do_execsql_test json_valid_5 {
|
||
SELECT json_valid(12.3);
|
||
} {1}
|
||
do_execsql_test json_valid_6 {
|
||
SELECT json_valid('not a valid json');
|
||
} {0}
|
||
do_execsql_test json_valid_7 {
|
||
SELECT json_valid('{"a":"55,"b":72}');
|
||
} {0}
|
||
do_execsql_test json_valid_8 {
|
||
SELECT json_valid('{"a":55 "b":72}');
|
||
} {0}
|
||
do_execsql_test json_valid_3 {
|
||
SELECT json_valid( CAST('{"a":"1}' AS BLOB) );
|
||
} {0}
|
||
do_execsql_test json_valid_9 {
|
||
SELECT json_valid(NULL);
|
||
} {}
|
||
do_execsql_test json-patch-basic-1 {
|
||
select json_patch('{"a":1}', '{"b":2}');
|
||
} {{{"a":1,"b":2}}}
|
||
do_execsql_test json-patch-basic-2 {
|
||
select json_patch('{"x":100,"y":200}', '{"z":300}');
|
||
} {{{"x":100,"y":200,"z":300}}}
|
||
do_execsql_test json-patch-preserve-duplicates-1 {
|
||
select json_patch('{"x":100,"x":200}', '{"z":300}');
|
||
} {{{"x":100,"x":200,"z":300}}}
|
||
do_execsql_test json-patch-preserve-duplicates-2 {
|
||
select json_patch('{"x":100,"x":200}', '{"x":900}');
|
||
} {{{"x":900,"x":200}}}
|
||
do_execsql_test json-patch-last-update-wins {
|
||
select json_patch('{"x":100,"c":200}', '{"x":900, "x":null}');
|
||
} {{{"c":200}}}
|
||
do_execsql_test json-patch-override-1 {
|
||
select json_patch('{"a":1,"b":2}', '{"b":3}');
|
||
} {{{"a":1,"b":3}}}
|
||
do_execsql_test json-patch-override-2 {
|
||
select json_patch('{"name":"john","age":25}', '{"age":26,"city":"NYC"}');
|
||
} {{{"name":"john","age":26,"city":"NYC"}}}
|
||
do_execsql_test json-patch-nested-1 {
|
||
select json_patch('{"user":{"name":"john"}}', '{"user":{"age":30}}');
|
||
} {{{"user":{"name":"john","age":30}}}}
|
||
do_execsql_test json-patch-nested-2 {
|
||
select json_patch('{"settings":{"theme":"dark"}}', '{"settings":{"theme":"light","font":"arial"}}');
|
||
} {{{"settings":{"theme":"light","font":"arial"}}}}
|
||
do_execsql_test json-patch-array-1 {
|
||
select json_patch('{"arr":[1,2,3]}', '{"arr":[4,5,6]}');
|
||
} {{{"arr":[4,5,6]}}}
|
||
do_execsql_test json-patch-array-2 {
|
||
select json_patch('{"list":["a","b"]}', '{"list":["c"]}');
|
||
} {{{"list":["c"]}}}
|
||
do_execsql_test json-patch-empty-1 {
|
||
select json_patch('{}', '{"a":1}');
|
||
} {{{"a":1}}}
|
||
do_execsql_test json-patch-empty-2 {
|
||
select json_patch('{"a":1}', '{}');
|
||
} {{{"a":1}}}
|
||
do_execsql_test json-patch-deep-nested-1 {
|
||
select json_patch(
|
||
'{"level1":{"level2":{"value":100}}}',
|
||
'{"level1":{"level2":{"newValue":200}}}'
|
||
);
|
||
} {{{"level1":{"level2":{"value":100,"newValue":200}}}}}
|
||
do_execsql_test json-patch-mixed-types-1 {
|
||
select json_patch(
|
||
'{"str":"hello","num":42,"bool":true}',
|
||
'{"arr":[1,2,3],"obj":{"x":1}}'
|
||
);
|
||
} {{{"str":"hello","num":42,"bool":true,"arr":[1,2,3],"obj":{"x":1}}}}
|
||
do_execsql_test json-patch-add-all-dup-keys-from-patch {
|
||
select json_patch(
|
||
'{"x":100,"x":200}',
|
||
'{"z":{}, "z":5, "z":100}'
|
||
);
|
||
} {{{"x":100,"x":200,"z":100}}}
|
||
do_execsql_test json-patch-first-occurance-patch {
|
||
select json_patch('{"x":100,"x":200}','{"x":{}, "x":5, "x":100}');
|
||
} {{{"x":100,"x":200}}}
|
||
do_execsql_test json-patch-complex-nested-dup-keys {
|
||
select json_patch(
|
||
'{"a":{"x":1,"x":2},"a":{"y":3},"b":[{"z":4,"z":5}]}',
|
||
'{"a":{"w":6},"b":[{"z":7,"z":8}],"b":{"z":9}}'
|
||
);
|
||
} {{{"a":{"x":1,"x":2,"w":6},"a":{"y":3},"b":{"z":9}}}}
|
||
do_execsql_test json-patch-unicode-dup-keys {
|
||
select json_patch(
|
||
'{"🔑":1,"🔑":2}',
|
||
'{"🗝️":3,"🗝️":4}'
|
||
);
|
||
} {{{"🔑":1,"🔑":2,"🗝️":4}}}
|
||
do_execsql_test json-patch-empty-string-dup-keys {
|
||
select json_patch(
|
||
'{"":1,"":2}',
|
||
'{"":3,"":4}'
|
||
);
|
||
} {{{"":4,"":2}}}
|
||
do_execsql_test json-patch-multiple-types-dup-keys {
|
||
select json_patch(
|
||
'{"x":100,"x":"str","x":true,"x":null}',
|
||
'{"y":1,"y":{},"y":[],"y":false}'
|
||
);
|
||
} {{{"x":100,"x":"str","x":true,"x":null,"y":false}}}
|
||
do_execsql_test json-patch-deep-nested-dup-keys {
|
||
select json_patch(
|
||
'{"a":{"b":{"c":1}},"a":{"b":{"c":2}},"a":{"b":{"d":3}}}',
|
||
'{"x":{"y":{"z":4}},"x":{"y":{"z":5}}}'
|
||
);
|
||
} {{{"a":{"b":{"c":1}},"a":{"b":{"c":2}},"a":{"b":{"d":3}},"x":{"y":{"z":5}}}}}
|
||
do_execsql_test json-patch-abomination {
|
||
select json_patch(
|
||
'{"a":{"b":{"x":1,"x":2,"y":{"z":3,"z":{"w":4}}},"b":[{"c":5,"c":6},{"d":{"e":7,"e":null}}],"f":{"g":[1,2,3],"g":{"h":8,"h":[4,5,6]}},"i":{"j":true,"j":{"k":false,"k":{"l":null,"l":"string"}}},"m":{"n":{"o":{"p":9,"p":{"q":10}},"o":{"r":11}}},"m":[{"s":{"t":12}},{"s":{"t":13,"t":{"u":14}}}]},"a":{"v":{"w":{"x":{"y":{"z":15}}}},"v":{"w":{"x":16,"x":{"y":17}}},"aa":[{"bb":{"cc":18,"cc":{"dd":19}}},{"bb":{"cc":{"dd":20},"cc":21}}]}}',
|
||
'{"a":{"b":{"x":{"new":"value"},"y":null},"b":{"c":{"updated":true},"d":{"e":{"replaced":100}}},"f":{"g":{"h":{"nested":"deep"}}},"i":{"j":{"k":{"l":{"modified":false}}}},"m":{"n":{"o":{"p":{"q":{"extra":"level"}}}},"s":null},"aa":[{"bb":{"cc":{"dd":{"ee":"new"}}}},{"bb":{"cc":{"dd":{"ff":"value"}}}}],"v":{"w":{"x":{"y":{"z":{"final":"update"}}}}}},"newTop":{"level":{"key":{"with":{"deep":{"nesting":true}}},"key":[{"array":{"in":{"deep":{"structure":null}}}}]}}}'
|
||
);
|
||
} {{{"a":{"b":{"x":{"new":"value"},"x":2,"c":{"updated":true},"d":{"e":{"replaced":100}}},"b":[{"c":5,"c":6},{"d":{"e":7,"e":null}}],"f":{"g":{"h":{"nested":"deep"}},"g":{"h":8,"h":[4,5,6]}},"i":{"j":{"k":{"l":{"modified":false}}},"j":{"k":false,"k":{"l":null,"l":"string"}}},"m":{"n":{"o":{"p":{"q":{"extra":"level"}},"p":{"q":10}},"o":{"r":11}}},"m":[{"s":{"t":12}},{"s":{"t":13,"t":{"u":14}}}],"aa":[{"bb":{"cc":{"dd":{"ee":"new"}}}},{"bb":{"cc":{"dd":{"ff":"value"}}}}],"v":{"w":{"x":{"y":{"z":{"final":"update"}}}}}},"a":{"v":{"w":{"x":{"y":{"z":15}}}},"v":{"w":{"x":16,"x":{"y":17}}},"aa":[{"bb":{"cc":18,"cc":{"dd":19}}},{"bb":{"cc":{"dd":20},"cc":21}}]},"newTop":{"level":{"key":[{"array":{"in":{"deep":{"structure":null}}}}]}}}}}
|
||
|
||
do_execsql_test json-remove-1 {
|
||
select json_remove('{"a": 5, "a": [5,4,3,2,1]}','$.a', '$.a[4]', '$.a[5]', '$.a');
|
||
} {{{}}}
|
||
|
||
do_execsql_test json-remove-2 {
|
||
SELECT json_remove('{"a": {"b": {"c": 1, "c": 2}, "b": [1,2,3]}}', '$.a.b.c', '$.a.b[1]');
|
||
} {{{"a":{"b":{"c":2},"b":[1,2,3]}}}}
|
||
|
||
do_execsql_test json-remove-3 {
|
||
SELECT json_remove('[1,2,3,4,5]', '$[0]', '$[4]', '$[5]');
|
||
} {{[2,3,4,5]}}
|
||
|
||
do_execsql_test json-remove-4 {
|
||
SELECT json_remove('{"arr": [1,2,3,4,5]}', '$.arr[#-1]', '$.arr[#-3]', '$.arr[#-1]');
|
||
} {{{"arr":[1,3]}}}
|
||
|
||
do_execsql_test json-remove-5 {
|
||
SELECT json_remove('{}', '$.a');
|
||
} {{{}}}
|
||
|
||
do_execsql_test json-remove-6 {
|
||
SELECT json_remove('{"a": [[1,2], [3,4]]}', '$.a[0][1]', '$.a[1]');
|
||
} {{{"a":[[1]]}}}
|
||
|
||
do_execsql_test json-remove-7 {
|
||
SELECT json_remove('{"a": 1, "b": [1,2], "c": {"d": 3}}', '$.a', '$.b[0]', '$.c.d');
|
||
} {{{"b":[2],"c":{}}}}
|
||
|
||
do_execsql_test json_set_field_empty_object {
|
||
SELECT json_set('{}', '$.field', 'value');
|
||
} {{{"field":"value"}}}
|
||
|
||
do_execsql_test json_set_replace_field {
|
||
SELECT json_set('{"field":"old_value"}', '$.field', 'new_value');
|
||
} {{{"field":"new_value"}}}
|
||
|
||
do_execsql_test json_set_set_deeply_nested_key {
|
||
SELECT json_set('{}', '$.object.doesnt.exist', 'value');
|
||
} {{{"object":{"doesnt":{"exist":"value"}}}}}
|
||
|
||
do_execsql_test json_set_add_value_to_empty_array {
|
||
SELECT json_set('[]', '$[0]', 'value');
|
||
} {{["value"]}}
|
||
|
||
do_execsql_test json_set_add_value_to_nonexistent_array {
|
||
SELECT json_set('{}', '$.some_array[0]', 123);
|
||
} {{{"some_array":[123]}}}
|
||
|
||
do_execsql_test json_set_add_value_to_array {
|
||
SELECT json_set('[123]', '$[1]', 456);
|
||
} {{[123,456]}}
|
||
|
||
do_execsql_test json_set_add_value_to_array_out_of_bounds {
|
||
SELECT json_set('[123]', '$[200]', 456);
|
||
} {{[123]}}
|
||
|
||
do_execsql_test json_set_replace_value_in_array {
|
||
SELECT json_set('[123]', '$[0]', 456);
|
||
} {{[456]}}
|
||
|
||
do_execsql_test json_set_null_path {
|
||
SELECT json_set('{}', NULL, 456);
|
||
} {{{}}}
|
||
|
||
do_execsql_test json_set_multiple_keys {
|
||
SELECT json_set('[123]', '$[0]', 456, '$[1]', 789);
|
||
} {{[456,789]}}
|
||
|
||
do_execsql_test json_set_add_array_in_nested_object {
|
||
SELECT json_set('{}', '$.object[0].field', 123);
|
||
} {{{"object":[{"field":123}]}}}
|
||
|
||
do_execsql_test json_set_add_array_in_array_in_nested_object {
|
||
SELECT json_set('{}', '$.object[0][0]', 123);
|
||
} {{{"object":[[123]]}}}
|
||
|
||
do_execsql_test json_set_add_array_in_array_in_nested_object_out_of_bounds {
|
||
SELECT json_set('{}', '$.object[123].another', 'value', '$.field', 'value');
|
||
} {{{"field":"value"}}}
|
||
|
||
# The json_quote() function transforms an SQL value into a JSON value.
|
||
# String values are quoted and interior quotes are escaped. NULL values
|
||
# are rendered as the unquoted string "null".
|
||
#
|
||
do_execsql_test json_quote_string_literal {
|
||
SELECT json_quote('abc"xyz');
|
||
} {{"abc\"xyz"}}
|
||
do_execsql_test json_quote_float {
|
||
SELECT json_quote(3.14159);
|
||
} {3.14159}
|
||
do_execsql_test json_quote_integer {
|
||
SELECT json_quote(12345);
|
||
} {12345}
|
||
do_execsql_test json_quote_null {
|
||
SELECT json_quote(null);
|
||
} {"null"}
|
||
do_execsql_test json_quote_null_caps {
|
||
SELECT json_quote(NULL);
|
||
} null
|
||
do_execsql_test json_quote_json_value {
|
||
SELECT json_quote(json('{a:1, b: "test"}'));
|
||
} {{{"a":1,"b":"test"}}}
|
||
|
||
|
||
# Escape character tests in sqlite source depend on json_valid
|
||
# See https://github.com/sqlite/sqlite/blob/255548562b125e6c148bb27d49aaa01b2fe61dba/test/json102.test#L690
|
||
# So for now not all control characters escaped are tested
|
||
|
||
|
||
# TODO No catchsql tests function to test these on
|
||
#do_catchsql_test json_quote_blob {
|
||
# SELECT json_quote(x'3031323334');
|
||
#} {1 {JSON cannot hold BLOB values}}
|
||
#do_catchsql_test json_quote_more_than_one_arg {
|
||
# SELECT json_quote(123,456)
|
||
#} {1 {json_quote function called with not exactly 1 arguments}}
|
||
#do_catchsql_test json_quote_no_args {
|
||
# SELECT json_quote()
|
||
#} {1 {json_quote function with no arguments}}
|
||
|