summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-12-11 11:28:15 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-12-11 11:28:15 -0500
commitc60c9badba9b4db3155eef081ae0b923f983168c (patch)
tree60b12d49fa9f01feff7707cef18fac7ebf24ab18 /src/test
parent50428a301d5ad46316cac2192f2ca8d91898aa3c (diff)
downloadpostgresql-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.out19
-rw-r--r--src/test/regress/expected/json_encoding.out7
-rw-r--r--src/test/regress/expected/json_encoding_1.out31
-rw-r--r--src/test/regress/expected/jsonb.out25
-rw-r--r--src/test/regress/sql/json.sql5
-rw-r--r--src/test/regress/sql/json_encoding.sql4
-rw-r--r--src/test/regress/sql/jsonb.sql6
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]}']);