diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-11 11:28:15 -0500 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-12-11 11:28:15 -0500 |
| commit | c60c9badba9b4db3155eef081ae0b923f983168c (patch) | |
| tree | 60b12d49fa9f01feff7707cef18fac7ebf24ab18 /src/test | |
| parent | 50428a301d5ad46316cac2192f2ca8d91898aa3c (diff) | |
| download | postgresql-c60c9badba9b4db3155eef081ae0b923f983168c.tar.gz | |
Convert json_in and jsonb_in to report errors softly.
This requires a bit of further infrastructure-extension to allow
trapping errors reported by numeric_in and pg_unicode_to_server,
but otherwise it's pretty straightforward.
In the case of jsonb_in, we are only capturing errors reported
during the initial "parse" phase. The value-construction phase
(JsonbValueToJsonb) can also throw errors if assorted implementation
limits are exceeded. We should improve that, but it seems like a
separable project.
Andrew Dunstan and Tom Lane
Discussion: https://postgr.es/m/3bac9841-fe07-713d-fa42-606c225567d6@dunslane.net
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/json.out | 19 | ||||
| -rw-r--r-- | src/test/regress/expected/json_encoding.out | 7 | ||||
| -rw-r--r-- | src/test/regress/expected/json_encoding_1.out | 31 | ||||
| -rw-r--r-- | src/test/regress/expected/jsonb.out | 25 | ||||
| -rw-r--r-- | src/test/regress/sql/json.sql | 5 | ||||
| -rw-r--r-- | src/test/regress/sql/json_encoding.sql | 4 | ||||
| -rw-r--r-- | src/test/regress/sql/jsonb.sql | 6 |
7 files changed, 91 insertions, 6 deletions
diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index cb181226e9..af96ce4180 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -320,6 +320,25 @@ LINE 1: SELECT '{ DETAIL: Expected JSON value, but found "}". CONTEXT: JSON data, line 4: ...yveryveryveryveryveryveryveryverylongfieldname":} -- ERROR missing value for last field +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'json'); + pg_input_is_valid +------------------- + t +(1 row) + +select pg_input_is_valid('{"a":true', 'json'); + pg_input_is_valid +------------------- + f +(1 row) + +select pg_input_error_message('{"a":true', 'json'); + pg_input_error_message +------------------------------------ + invalid input syntax for type json +(1 row) + --constructors -- array_to_json SELECT array_to_json(array(select 1 as a)); diff --git a/src/test/regress/expected/json_encoding.out b/src/test/regress/expected/json_encoding.out index f343f74fe1..083621fb21 100644 --- a/src/test/regress/expected/json_encoding.out +++ b/src/test/regress/expected/json_encoding.out @@ -260,3 +260,10 @@ SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape; null \u0000 escape (1 row) +-- soft error for input-time failure +select pg_input_error_message('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb'); + pg_input_error_message +------------------------ + +(1 row) + diff --git a/src/test/regress/expected/json_encoding_1.out b/src/test/regress/expected/json_encoding_1.out index e2fc131b0f..021d226f8d 100644 --- a/src/test/regress/expected/json_encoding_1.out +++ b/src/test/regress/expected/json_encoding_1.out @@ -48,7 +48,9 @@ SELECT '"\uaBcD"'::json; -- OK, uppercase and lower case both OK -- handling of unicode surrogate pairs select json '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8; -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: { "a":... select json '{ "a": "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row ERROR: invalid input syntax for type json DETAIL: Unicode high surrogate must not follow a high surrogate. @@ -97,7 +99,9 @@ select json '{ "a": "null \\u0000 escape" }' as not_an_escape; (1 row) select json '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8; -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: { "a":... select json '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere; correct_everywhere -------------------- @@ -155,14 +159,18 @@ CONTEXT: JSON data, line 1: ... -- use octet_length here so we don't get an odd unicode char in the -- output SELECT octet_length('"\uaBcD"'::jsonb::text); -- OK, uppercase and lower case both OK -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence LINE 1: SELECT octet_length('"\uaBcD"'::jsonb::text); ^ +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: ... -- handling of unicode surrogate pairs SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8; -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence LINE 1: SELECT octet_length((jsonb '{ "a": "\ud83d\ude04\ud83d\udc3... ^ +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: { "a":... SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row ERROR: invalid input syntax for type json LINE 1: SELECT jsonb '{ "a": "\ud83d\ud83d" }' -> 'a'; @@ -189,9 +197,11 @@ DETAIL: Unicode low surrogate must follow a high surrogate. CONTEXT: JSON data, line 1: { "a":... -- handling of simple unicode escapes SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' as correct_in_utf8; -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence LINE 1: SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' as corr... ^ +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: { "a":... SELECT jsonb '{ "a": "dollar \u0024 character" }' as correct_everywhere; correct_everywhere ----------------------------- @@ -217,9 +227,11 @@ SELECT jsonb '{ "a": "null \\u0000 escape" }' as not_an_escape; (1 row) SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8; -ERROR: conversion between UTF8 and SQL_ASCII is not supported +ERROR: unsupported Unicode escape sequence LINE 1: SELECT jsonb '{ "a": "the Copyright \u00a9 sign" }' ->> 'a'... ^ +DETAIL: Unicode escape value could not be translated to the server's encoding SQL_ASCII. +CONTEXT: JSON data, line 1: { "a":... SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere; correct_everywhere -------------------- @@ -244,3 +256,10 @@ SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape; null \u0000 escape (1 row) +-- soft error for input-time failure +select pg_input_error_message('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb'); + pg_input_error_message +------------------------------------- + unsupported Unicode escape sequence +(1 row) + diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index b2b3677482..be85676b5b 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -310,6 +310,31 @@ LINE 1: SELECT '{ DETAIL: Expected JSON value, but found "}". CONTEXT: JSON data, line 4: ...yveryveryveryveryveryveryveryverylongfieldname":} -- ERROR missing value for last field +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'jsonb'); + pg_input_is_valid +------------------- + t +(1 row) + +select pg_input_is_valid('{"a":true', 'jsonb'); + pg_input_is_valid +------------------- + f +(1 row) + +select pg_input_error_message('{"a":true', 'jsonb'); + pg_input_error_message +------------------------------------ + invalid input syntax for type json +(1 row) + +select pg_input_error_message('{"a":1e1000000}', 'jsonb'); + pg_input_error_message +-------------------------------- + value overflows numeric format +(1 row) + -- make sure jsonb is passed through json generators without being escaped SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']); array_to_json diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index 589e0cea36..21534ed959 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -81,6 +81,11 @@ SELECT '{ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::json; -- ERROR missing value for last field +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'json'); +select pg_input_is_valid('{"a":true', 'json'); +select pg_input_error_message('{"a":true', 'json'); + --constructors -- array_to_json diff --git a/src/test/regress/sql/json_encoding.sql b/src/test/regress/sql/json_encoding.sql index d7fac69733..f87b3bd4f3 100644 --- a/src/test/regress/sql/json_encoding.sql +++ b/src/test/regress/sql/json_encoding.sql @@ -76,3 +76,7 @@ SELECT jsonb '{ "a": "dollar \u0024 character" }' ->> 'a' as correct_everywhere SELECT jsonb '{ "a": "dollar \\u0024 character" }' ->> 'a' as not_an_escape; SELECT jsonb '{ "a": "null \u0000 escape" }' ->> 'a' as fails; SELECT jsonb '{ "a": "null \\u0000 escape" }' ->> 'a' as not_an_escape; + +-- soft error for input-time failure + +select pg_input_error_message('{ "a": "\ud83d\ude04\ud83d\udc36" }', 'jsonb'); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index 8d25966267..bc44ad1518 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -86,6 +86,12 @@ SELECT '{ "averyveryveryveryveryveryveryveryveryverylongfieldname":}'::jsonb; -- ERROR missing value for last field +-- test non-error-throwing input +select pg_input_is_valid('{"a":true}', 'jsonb'); +select pg_input_is_valid('{"a":true', 'jsonb'); +select pg_input_error_message('{"a":true', 'jsonb'); +select pg_input_error_message('{"a":1e1000000}', 'jsonb'); + -- make sure jsonb is passed through json generators without being escaped SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']); |
