1--
2-- encoding-sensitive tests for json and jsonb
3--
4
5-- We provide expected-results files for UTF8 (json_encoding.out)
6-- and for SQL_ASCII (json_encoding_1.out).  Skip otherwise.
7SELECT getdatabaseencoding() NOT IN ('UTF8', 'SQL_ASCII')
8       AS skip_test \gset
9\if :skip_test
10\quit
11\endif
12
13SELECT getdatabaseencoding();           -- just to label the results files
14
15-- first json
16
17-- basic unicode input
18SELECT '"\u"'::json;			-- ERROR, incomplete escape
19SELECT '"\u00"'::json;			-- ERROR, incomplete escape
20SELECT '"\u000g"'::json;		-- ERROR, g is not a hex digit
21SELECT '"\u0000"'::json;		-- OK, legal escape
22SELECT '"\uaBcD"'::json;		-- OK, uppercase and lower case both OK
23
24-- handling of unicode surrogate pairs
25
26select json '{ "a":  "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8;
27select json '{ "a":  "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row
28select json '{ "a":  "\ude04\ud83d" }' -> 'a'; -- surrogates in wrong order
29select json '{ "a":  "\ud83dX" }' -> 'a'; -- orphan high surrogate
30select json '{ "a":  "\ude04X" }' -> 'a'; -- orphan low surrogate
31
32--handling of simple unicode escapes
33
34select json '{ "a":  "the Copyright \u00a9 sign" }' as correct_in_utf8;
35select json '{ "a":  "dollar \u0024 character" }' as correct_everywhere;
36select json '{ "a":  "dollar \\u0024 character" }' as not_an_escape;
37select json '{ "a":  "null \u0000 escape" }' as not_unescaped;
38select json '{ "a":  "null \\u0000 escape" }' as not_an_escape;
39
40select json '{ "a":  "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8;
41select json '{ "a":  "dollar \u0024 character" }' ->> 'a' as correct_everywhere;
42select json '{ "a":  "dollar \\u0024 character" }' ->> 'a' as not_an_escape;
43select json '{ "a":  "null \u0000 escape" }' ->> 'a' as fails;
44select json '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
45
46-- then jsonb
47
48-- basic unicode input
49SELECT '"\u"'::jsonb;			-- ERROR, incomplete escape
50SELECT '"\u00"'::jsonb;			-- ERROR, incomplete escape
51SELECT '"\u000g"'::jsonb;		-- ERROR, g is not a hex digit
52SELECT '"\u0045"'::jsonb;		-- OK, legal escape
53SELECT '"\u0000"'::jsonb;		-- ERROR, we don't support U+0000
54-- use octet_length here so we don't get an odd unicode char in the
55-- output
56SELECT octet_length('"\uaBcD"'::jsonb::text); -- OK, uppercase and lower case both OK
57
58-- handling of unicode surrogate pairs
59
60SELECT octet_length((jsonb '{ "a":  "\ud83d\ude04\ud83d\udc36" }' -> 'a')::text) AS correct_in_utf8;
61SELECT jsonb '{ "a":  "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row
62SELECT jsonb '{ "a":  "\ude04\ud83d" }' -> 'a'; -- surrogates in wrong order
63SELECT jsonb '{ "a":  "\ud83dX" }' -> 'a'; -- orphan high surrogate
64SELECT jsonb '{ "a":  "\ude04X" }' -> 'a'; -- orphan low surrogate
65
66-- handling of simple unicode escapes
67
68SELECT jsonb '{ "a":  "the Copyright \u00a9 sign" }' as correct_in_utf8;
69SELECT jsonb '{ "a":  "dollar \u0024 character" }' as correct_everywhere;
70SELECT jsonb '{ "a":  "dollar \\u0024 character" }' as not_an_escape;
71SELECT jsonb '{ "a":  "null \u0000 escape" }' as fails;
72SELECT jsonb '{ "a":  "null \\u0000 escape" }' as not_an_escape;
73
74SELECT jsonb '{ "a":  "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8;
75SELECT jsonb '{ "a":  "dollar \u0024 character" }' ->> 'a' as correct_everywhere;
76SELECT jsonb '{ "a":  "dollar \\u0024 character" }' ->> 'a' as not_an_escape;
77SELECT jsonb '{ "a":  "null \u0000 escape" }' ->> 'a' as fails;
78SELECT jsonb '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
79