]> granicus.if.org Git - postgresql/blob - src/test/regress/expected/json.out
Render infinite date/timestamps as 'infinity' for json/jsonb
[postgresql] / src / test / regress / expected / json.out
1 -- Strings.
2 SELECT '""'::json;                              -- OK.
3  json 
4 ------
5  ""
6 (1 row)
7
8 SELECT $$''$$::json;                    -- ERROR, single quotes are not allowed
9 ERROR:  invalid input syntax for type json
10 LINE 1: SELECT $$''$$::json;
11                ^
12 DETAIL:  Token "'" is invalid.
13 CONTEXT:  JSON data, line 1: '...
14 SELECT '"abc"'::json;                   -- OK
15  json  
16 -------
17  "abc"
18 (1 row)
19
20 SELECT '"abc'::json;                    -- ERROR, quotes not closed
21 ERROR:  invalid input syntax for type json
22 LINE 1: SELECT '"abc'::json;
23                ^
24 DETAIL:  Token ""abc" is invalid.
25 CONTEXT:  JSON data, line 1: "abc
26 SELECT '"abc
27 def"'::json;                                    -- ERROR, unescaped newline in string constant
28 ERROR:  invalid input syntax for type json
29 LINE 1: SELECT '"abc
30                ^
31 DETAIL:  Character with value 0x0a must be escaped.
32 CONTEXT:  JSON data, line 1: "abc
33 SELECT '"\n\"\\"'::json;                -- OK, legal escapes
34    json   
35 ----------
36  "\n\"\\"
37 (1 row)
38
39 SELECT '"\v"'::json;                    -- ERROR, not a valid JSON escape
40 ERROR:  invalid input syntax for type json
41 LINE 1: SELECT '"\v"'::json;
42                ^
43 DETAIL:  Escape sequence "\v" is invalid.
44 CONTEXT:  JSON data, line 1: "\v...
45 SELECT '"\u"'::json;                    -- ERROR, incomplete escape
46 ERROR:  invalid input syntax for type json
47 LINE 1: SELECT '"\u"'::json;
48                ^
49 DETAIL:  "\u" must be followed by four hexadecimal digits.
50 CONTEXT:  JSON data, line 1: "\u"
51 SELECT '"\u00"'::json;                  -- ERROR, incomplete escape
52 ERROR:  invalid input syntax for type json
53 LINE 1: SELECT '"\u00"'::json;
54                ^
55 DETAIL:  "\u" must be followed by four hexadecimal digits.
56 CONTEXT:  JSON data, line 1: "\u00"
57 SELECT '"\u000g"'::json;                -- ERROR, g is not a hex digit
58 ERROR:  invalid input syntax for type json
59 LINE 1: SELECT '"\u000g"'::json;
60                ^
61 DETAIL:  "\u" must be followed by four hexadecimal digits.
62 CONTEXT:  JSON data, line 1: "\u000g...
63 SELECT '"\u0000"'::json;                -- OK, legal escape
64    json   
65 ----------
66  "\u0000"
67 (1 row)
68
69 SELECT '"\uaBcD"'::json;                -- OK, uppercase and lower case both OK
70    json   
71 ----------
72  "\uaBcD"
73 (1 row)
74
75 -- Numbers.
76 SELECT '1'::json;                               -- OK
77  json 
78 ------
79  1
80 (1 row)
81
82 SELECT '0'::json;                               -- OK
83  json 
84 ------
85  0
86 (1 row)
87
88 SELECT '01'::json;                              -- ERROR, not valid according to JSON spec
89 ERROR:  invalid input syntax for type json
90 LINE 1: SELECT '01'::json;
91                ^
92 DETAIL:  Token "01" is invalid.
93 CONTEXT:  JSON data, line 1: 01
94 SELECT '0.1'::json;                             -- OK
95  json 
96 ------
97  0.1
98 (1 row)
99
100 SELECT '9223372036854775808'::json;     -- OK, even though it's too large for int8
101         json         
102 ---------------------
103  9223372036854775808
104 (1 row)
105
106 SELECT '1e100'::json;                   -- OK
107  json  
108 -------
109  1e100
110 (1 row)
111
112 SELECT '1.3e100'::json;                 -- OK
113   json   
114 ---------
115  1.3e100
116 (1 row)
117
118 SELECT '1f2'::json;                             -- ERROR
119 ERROR:  invalid input syntax for type json
120 LINE 1: SELECT '1f2'::json;
121                ^
122 DETAIL:  Token "1f2" is invalid.
123 CONTEXT:  JSON data, line 1: 1f2
124 SELECT '0.x1'::json;                    -- ERROR
125 ERROR:  invalid input syntax for type json
126 LINE 1: SELECT '0.x1'::json;
127                ^
128 DETAIL:  Token "0.x1" is invalid.
129 CONTEXT:  JSON data, line 1: 0.x1
130 SELECT '1.3ex100'::json;                -- ERROR
131 ERROR:  invalid input syntax for type json
132 LINE 1: SELECT '1.3ex100'::json;
133                ^
134 DETAIL:  Token "1.3ex100" is invalid.
135 CONTEXT:  JSON data, line 1: 1.3ex100
136 -- Arrays.
137 SELECT '[]'::json;                              -- OK
138  json 
139 ------
140  []
141 (1 row)
142
143 SELECT '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'::json;  -- OK
144                                                                                                    json                                                                                                   
145 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
146  [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
147 (1 row)
148
149 SELECT '[1,2]'::json;                   -- OK
150  json  
151 -------
152  [1,2]
153 (1 row)
154
155 SELECT '[1,2,]'::json;                  -- ERROR, trailing comma
156 ERROR:  invalid input syntax for type json
157 LINE 1: SELECT '[1,2,]'::json;
158                ^
159 DETAIL:  Expected JSON value, but found "]".
160 CONTEXT:  JSON data, line 1: [1,2,]
161 SELECT '[1,2'::json;                    -- ERROR, no closing bracket
162 ERROR:  invalid input syntax for type json
163 LINE 1: SELECT '[1,2'::json;
164                ^
165 DETAIL:  The input string ended unexpectedly.
166 CONTEXT:  JSON data, line 1: [1,2
167 SELECT '[1,[2]'::json;                  -- ERROR, no closing bracket
168 ERROR:  invalid input syntax for type json
169 LINE 1: SELECT '[1,[2]'::json;
170                ^
171 DETAIL:  The input string ended unexpectedly.
172 CONTEXT:  JSON data, line 1: [1,[2]
173 -- Objects.
174 SELECT '{}'::json;                              -- OK
175  json 
176 ------
177  {}
178 (1 row)
179
180 SELECT '{"abc"}'::json;                 -- ERROR, no value
181 ERROR:  invalid input syntax for type json
182 LINE 1: SELECT '{"abc"}'::json;
183                ^
184 DETAIL:  Expected ":", but found "}".
185 CONTEXT:  JSON data, line 1: {"abc"}
186 SELECT '{"abc":1}'::json;               -- OK
187    json    
188 -----------
189  {"abc":1}
190 (1 row)
191
192 SELECT '{1:"abc"}'::json;               -- ERROR, keys must be strings
193 ERROR:  invalid input syntax for type json
194 LINE 1: SELECT '{1:"abc"}'::json;
195                ^
196 DETAIL:  Expected string or "}", but found "1".
197 CONTEXT:  JSON data, line 1: {1...
198 SELECT '{"abc",1}'::json;               -- ERROR, wrong separator
199 ERROR:  invalid input syntax for type json
200 LINE 1: SELECT '{"abc",1}'::json;
201                ^
202 DETAIL:  Expected ":", but found ",".
203 CONTEXT:  JSON data, line 1: {"abc",...
204 SELECT '{"abc"=1}'::json;               -- ERROR, totally wrong separator
205 ERROR:  invalid input syntax for type json
206 LINE 1: SELECT '{"abc"=1}'::json;
207                ^
208 DETAIL:  Token "=" is invalid.
209 CONTEXT:  JSON data, line 1: {"abc"=...
210 SELECT '{"abc"::1}'::json;              -- ERROR, another wrong separator
211 ERROR:  invalid input syntax for type json
212 LINE 1: SELECT '{"abc"::1}'::json;
213                ^
214 DETAIL:  Expected JSON value, but found ":".
215 CONTEXT:  JSON data, line 1: {"abc"::...
216 SELECT '{"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}'::json; -- OK
217                           json                           
218 ---------------------------------------------------------
219  {"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}}
220 (1 row)
221
222 SELECT '{"abc":1:2}'::json;             -- ERROR, colon in wrong spot
223 ERROR:  invalid input syntax for type json
224 LINE 1: SELECT '{"abc":1:2}'::json;
225                ^
226 DETAIL:  Expected "," or "}", but found ":".
227 CONTEXT:  JSON data, line 1: {"abc":1:...
228 SELECT '{"abc":1,3}'::json;             -- ERROR, no value
229 ERROR:  invalid input syntax for type json
230 LINE 1: SELECT '{"abc":1,3}'::json;
231                ^
232 DETAIL:  Expected string, but found "3".
233 CONTEXT:  JSON data, line 1: {"abc":1,3...
234 -- Miscellaneous stuff.
235 SELECT 'true'::json;                    -- OK
236  json 
237 ------
238  true
239 (1 row)
240
241 SELECT 'false'::json;                   -- OK
242  json  
243 -------
244  false
245 (1 row)
246
247 SELECT 'null'::json;                    -- OK
248  json 
249 ------
250  null
251 (1 row)
252
253 SELECT ' true '::json;                  -- OK, even with extra whitespace
254   json  
255 --------
256   true 
257 (1 row)
258
259 SELECT 'true false'::json;              -- ERROR, too many values
260 ERROR:  invalid input syntax for type json
261 LINE 1: SELECT 'true false'::json;
262                ^
263 DETAIL:  Expected end of input, but found "false".
264 CONTEXT:  JSON data, line 1: true false
265 SELECT 'true, false'::json;             -- ERROR, too many values
266 ERROR:  invalid input syntax for type json
267 LINE 1: SELECT 'true, false'::json;
268                ^
269 DETAIL:  Expected end of input, but found ",".
270 CONTEXT:  JSON data, line 1: true,...
271 SELECT 'truf'::json;                    -- ERROR, not a keyword
272 ERROR:  invalid input syntax for type json
273 LINE 1: SELECT 'truf'::json;
274                ^
275 DETAIL:  Token "truf" is invalid.
276 CONTEXT:  JSON data, line 1: truf
277 SELECT 'trues'::json;                   -- ERROR, not a keyword
278 ERROR:  invalid input syntax for type json
279 LINE 1: SELECT 'trues'::json;
280                ^
281 DETAIL:  Token "trues" is invalid.
282 CONTEXT:  JSON data, line 1: trues
283 SELECT ''::json;                                -- ERROR, no value
284 ERROR:  invalid input syntax for type json
285 LINE 1: SELECT ''::json;
286                ^
287 DETAIL:  The input string ended unexpectedly.
288 CONTEXT:  JSON data, line 1: 
289 SELECT '    '::json;                    -- ERROR, no value
290 ERROR:  invalid input syntax for type json
291 LINE 1: SELECT '    '::json;
292                ^
293 DETAIL:  The input string ended unexpectedly.
294 CONTEXT:  JSON data, line 1:     
295 --constructors
296 -- array_to_json
297 SELECT array_to_json(array(select 1 as a));
298  array_to_json 
299 ---------------
300  [1]
301 (1 row)
302
303 SELECT array_to_json(array_agg(q),false) from (select x as b, x * 2 as c from generate_series(1,3) x) q;
304                 array_to_json                
305 ---------------------------------------------
306  [{"b":1,"c":2},{"b":2,"c":4},{"b":3,"c":6}]
307 (1 row)
308
309 SELECT array_to_json(array_agg(q),true) from (select x as b, x * 2 as c from generate_series(1,3) x) q;
310   array_to_json  
311 -----------------
312  [{"b":1,"c":2},+
313   {"b":2,"c":4},+
314   {"b":3,"c":6}]
315 (1 row)
316
317 SELECT array_to_json(array_agg(q),false)
318   FROM ( SELECT $$a$$ || x AS b, y AS c,
319                ARRAY[ROW(x.*,ARRAY[1,2,3]),
320                ROW(y.*,ARRAY[4,5,6])] AS z
321          FROM generate_series(1,2) x,
322               generate_series(4,5) y) q;
323                                                                                                                                  array_to_json                                                                                                                                 
324 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
325  [{"b":"a1","c":4,"z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]},{"b":"a1","c":5,"z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]},{"b":"a2","c":4,"z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]},{"b":"a2","c":5,"z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}]
326 (1 row)
327
328 SELECT array_to_json(array_agg(x),false) from generate_series(5,10) x;
329  array_to_json  
330 ----------------
331  [5,6,7,8,9,10]
332 (1 row)
333
334 SELECT array_to_json('{{1,5},{99,100}}'::int[]);
335   array_to_json   
336 ------------------
337  [[1,5],[99,100]]
338 (1 row)
339
340 -- row_to_json
341 SELECT row_to_json(row(1,'foo'));
342      row_to_json     
343 ---------------------
344  {"f1":1,"f2":"foo"}
345 (1 row)
346
347 SELECT row_to_json(q)
348 FROM (SELECT $$a$$ || x AS b,
349          y AS c,
350          ARRAY[ROW(x.*,ARRAY[1,2,3]),
351                ROW(y.*,ARRAY[4,5,6])] AS z
352       FROM generate_series(1,2) x,
353            generate_series(4,5) y) q;
354                             row_to_json                             
355 --------------------------------------------------------------------
356  {"b":"a1","c":4,"z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
357  {"b":"a1","c":5,"z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
358  {"b":"a2","c":4,"z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
359  {"b":"a2","c":5,"z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
360 (4 rows)
361
362 SELECT row_to_json(q,true)
363 FROM (SELECT $$a$$ || x AS b,
364          y AS c,
365          ARRAY[ROW(x.*,ARRAY[1,2,3]),
366                ROW(y.*,ARRAY[4,5,6])] AS z
367       FROM generate_series(1,2) x,
368            generate_series(4,5) y) q;
369                      row_to_json                     
370 -----------------------------------------------------
371  {"b":"a1",                                         +
372   "c":4,                                            +
373   "z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
374  {"b":"a1",                                         +
375   "c":5,                                            +
376   "z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
377  {"b":"a2",                                         +
378   "c":4,                                            +
379   "z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
380  {"b":"a2",                                         +
381   "c":5,                                            +
382   "z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
383 (4 rows)
384
385 CREATE TEMP TABLE rows AS
386 SELECT x, 'txt' || x as y
387 FROM generate_series(1,3) AS x;
388 SELECT row_to_json(q,true)
389 FROM rows q;
390  row_to_json  
391 --------------
392  {"x":1,     +
393   "y":"txt1"}
394  {"x":2,     +
395   "y":"txt2"}
396  {"x":3,     +
397   "y":"txt3"}
398 (3 rows)
399
400 SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)),false);
401       row_to_json      
402 -----------------------
403  {"f1":[5,6,7,8,9,10]}
404 (1 row)
405
406 -- to_json, timestamps
407 select to_json(timestamp '2014-05-28 12:22:35.614298');
408            to_json            
409 ------------------------------
410  "2014-05-28T12:22:35.614298"
411 (1 row)
412
413 BEGIN;
414 SET LOCAL TIME ZONE 10.5;
415 select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
416               to_json               
417 ------------------------------------
418  "2014-05-29T02:52:35.614298+10:30"
419 (1 row)
420
421 SET LOCAL TIME ZONE -8;
422 select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
423               to_json               
424 ------------------------------------
425  "2014-05-28T08:22:35.614298-08:00"
426 (1 row)
427
428 COMMIT;
429 select to_json(date '2014-05-28');
430    to_json    
431 --------------
432  "2014-05-28"
433 (1 row)
434
435 select to_json(date 'Infinity');
436   to_json   
437 ------------
438  "infinity"
439 (1 row)
440
441 select to_json(timestamp 'Infinity');
442   to_json   
443 ------------
444  "infinity"
445 (1 row)
446
447 select to_json(timestamptz 'Infinity');
448   to_json   
449 ------------
450  "infinity"
451 (1 row)
452
453 --json_agg
454 SELECT json_agg(q)
455   FROM ( SELECT $$a$$ || x AS b, y AS c,
456                ARRAY[ROW(x.*,ARRAY[1,2,3]),
457                ROW(y.*,ARRAY[4,5,6])] AS z
458          FROM generate_series(1,2) x,
459               generate_series(4,5) y) q;
460                                json_agg                                
461 -----------------------------------------------------------------------
462  [{"b":"a1","c":4,"z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}, +
463   {"b":"a1","c":5,"z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}, +
464   {"b":"a2","c":4,"z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}, +
465   {"b":"a2","c":5,"z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}]
466 (1 row)
467
468 SELECT json_agg(q)
469   FROM rows q;
470        json_agg        
471 -----------------------
472  [{"x":1,"y":"txt1"}, +
473   {"x":2,"y":"txt2"}, +
474   {"x":3,"y":"txt3"}]
475 (1 row)
476
477 -- non-numeric output
478 SELECT row_to_json(q)
479 FROM (SELECT 'NaN'::float8 AS "float8field") q;
480       row_to_json      
481 -----------------------
482  {"float8field":"NaN"}
483 (1 row)
484
485 SELECT row_to_json(q)
486 FROM (SELECT 'Infinity'::float8 AS "float8field") q;
487         row_to_json         
488 ----------------------------
489  {"float8field":"Infinity"}
490 (1 row)
491
492 SELECT row_to_json(q)
493 FROM (SELECT '-Infinity'::float8 AS "float8field") q;
494          row_to_json         
495 -----------------------------
496  {"float8field":"-Infinity"}
497 (1 row)
498
499 -- json input
500 SELECT row_to_json(q)
501 FROM (SELECT '{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}'::json AS "jsonfield") q;
502                            row_to_json                            
503 ------------------------------------------------------------------
504  {"jsonfield":{"a":1,"b": [2,3,4,"d","e","f"],"c":{"p":1,"q":2}}}
505 (1 row)
506
507 -- json extraction functions
508 CREATE TEMP TABLE test_json (
509        json_type text,
510        test_json json
511 );
512 INSERT INTO test_json VALUES
513 ('scalar','"a scalar"'),
514 ('array','["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}]'),
515 ('object','{"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}}');
516 SELECT test_json -> 'x'
517 FROM test_json
518 WHERE json_type = 'scalar';
519  ?column? 
520 ----------
521  
522 (1 row)
523
524 SELECT test_json -> 'x'
525 FROM test_json
526 WHERE json_type = 'array';
527  ?column? 
528 ----------
529  
530 (1 row)
531
532 SELECT test_json -> 'x'
533 FROM test_json
534 WHERE json_type = 'object';
535  ?column? 
536 ----------
537  
538 (1 row)
539
540 SELECT test_json->'field2'
541 FROM test_json
542 WHERE json_type = 'object';
543  ?column? 
544 ----------
545  "val2"
546 (1 row)
547
548 SELECT test_json->>'field2'
549 FROM test_json
550 WHERE json_type = 'object';
551  ?column? 
552 ----------
553  val2
554 (1 row)
555
556 SELECT test_json -> 2
557 FROM test_json
558 WHERE json_type = 'scalar';
559  ?column? 
560 ----------
561  
562 (1 row)
563
564 SELECT test_json -> 2
565 FROM test_json
566 WHERE json_type = 'array';
567  ?column? 
568 ----------
569  "two"
570 (1 row)
571
572 SELECT test_json -> 2
573 FROM test_json
574 WHERE json_type = 'object';
575  ?column? 
576 ----------
577  
578 (1 row)
579
580 SELECT test_json->>2
581 FROM test_json
582 WHERE json_type = 'array';
583  ?column? 
584 ----------
585  two
586 (1 row)
587
588 SELECT test_json ->> 6 FROM test_json WHERE json_type = 'array';
589  ?column? 
590 ----------
591  [1,2,3]
592 (1 row)
593
594 SELECT test_json ->> 7 FROM test_json WHERE json_type = 'array';
595  ?column? 
596 ----------
597  {"f1":9}
598 (1 row)
599
600 SELECT test_json ->> 'field4' FROM test_json WHERE json_type = 'object';
601  ?column? 
602 ----------
603  4
604 (1 row)
605
606 SELECT test_json ->> 'field5' FROM test_json WHERE json_type = 'object';
607  ?column? 
608 ----------
609  [1,2,3]
610 (1 row)
611
612 SELECT test_json ->> 'field6' FROM test_json WHERE json_type = 'object';
613  ?column? 
614 ----------
615  {"f1":9}
616 (1 row)
617
618 SELECT json_object_keys(test_json)
619 FROM test_json
620 WHERE json_type = 'scalar';
621 ERROR:  cannot call json_object_keys on a scalar
622 SELECT json_object_keys(test_json)
623 FROM test_json
624 WHERE json_type = 'array';
625 ERROR:  cannot call json_object_keys on an array
626 SELECT json_object_keys(test_json)
627 FROM test_json
628 WHERE json_type = 'object';
629  json_object_keys 
630 ------------------
631  field1
632  field2
633  field3
634  field4
635  field5
636  field6
637 (6 rows)
638
639 -- test extending object_keys resultset - initial resultset size is 256
640 select count(*) from
641     (select json_object_keys(json_object(array_agg(g)))
642      from (select unnest(array['f'||n,n::text])as g
643            from generate_series(1,300) as n) x ) y;
644  count 
645 -------
646    300
647 (1 row)
648
649 -- nulls
650 select (test_json->'field3') is null as expect_false
651 from test_json
652 where json_type = 'object';
653  expect_false 
654 --------------
655  f
656 (1 row)
657
658 select (test_json->>'field3') is null as expect_true
659 from test_json
660 where json_type = 'object';
661  expect_true 
662 -------------
663  t
664 (1 row)
665
666 select (test_json->3) is null as expect_false
667 from test_json
668 where json_type = 'array';
669  expect_false 
670 --------------
671  f
672 (1 row)
673
674 select (test_json->>3) is null as expect_true
675 from test_json
676 where json_type = 'array';
677  expect_true 
678 -------------
679  t
680 (1 row)
681
682 -- corner cases
683 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::text;
684  ?column? 
685 ----------
686  
687 (1 row)
688
689 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::int;
690  ?column? 
691 ----------
692  
693 (1 row)
694
695 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 1;
696  ?column? 
697 ----------
698  
699 (1 row)
700
701 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 'z';
702  ?column? 
703 ----------
704  
705 (1 row)
706
707 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> '';
708  ?column? 
709 ----------
710  
711 (1 row)
712
713 select '[{"b": "c"}, {"b": "cc"}]'::json -> 1;
714   ?column?   
715 -------------
716  {"b": "cc"}
717 (1 row)
718
719 select '[{"b": "c"}, {"b": "cc"}]'::json -> 3;
720  ?column? 
721 ----------
722  
723 (1 row)
724
725 select '[{"b": "c"}, {"b": "cc"}]'::json -> 'z';
726  ?column? 
727 ----------
728  
729 (1 row)
730
731 select '{"a": "c", "b": null}'::json -> 'b';
732  ?column? 
733 ----------
734  null
735 (1 row)
736
737 select '"foo"'::json -> 1;
738  ?column? 
739 ----------
740  
741 (1 row)
742
743 select '"foo"'::json -> 'z';
744  ?column? 
745 ----------
746  
747 (1 row)
748
749 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::text;
750  ?column? 
751 ----------
752  
753 (1 row)
754
755 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> null::int;
756  ?column? 
757 ----------
758  
759 (1 row)
760
761 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 1;
762  ?column? 
763 ----------
764  
765 (1 row)
766
767 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> 'z';
768  ?column? 
769 ----------
770  
771 (1 row)
772
773 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json ->> '';
774  ?column? 
775 ----------
776  
777 (1 row)
778
779 select '[{"b": "c"}, {"b": "cc"}]'::json ->> 1;
780   ?column?   
781 -------------
782  {"b": "cc"}
783 (1 row)
784
785 select '[{"b": "c"}, {"b": "cc"}]'::json ->> 3;
786  ?column? 
787 ----------
788  
789 (1 row)
790
791 select '[{"b": "c"}, {"b": "cc"}]'::json ->> 'z';
792  ?column? 
793 ----------
794  
795 (1 row)
796
797 select '{"a": "c", "b": null}'::json ->> 'b';
798  ?column? 
799 ----------
800  
801 (1 row)
802
803 select '"foo"'::json ->> 1;
804  ?column? 
805 ----------
806  
807 (1 row)
808
809 select '"foo"'::json ->> 'z';
810  ?column? 
811 ----------
812  
813 (1 row)
814
815 -- array length
816 SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]');
817  json_array_length 
818 -------------------
819                  5
820 (1 row)
821
822 SELECT json_array_length('[]');
823  json_array_length 
824 -------------------
825                  0
826 (1 row)
827
828 SELECT json_array_length('{"f1":1,"f2":[5,6]}');
829 ERROR:  cannot get array length of a non-array
830 SELECT json_array_length('4');
831 ERROR:  cannot get array length of a scalar
832 -- each
833 select json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null}');
834      json_each     
835 -------------------
836  (f1,"[1,2,3]")
837  (f2,"{""f3"":1}")
838  (f4,null)
839 (3 rows)
840
841 select * from json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q;
842  key |   value   
843 -----+-----------
844  f1  | [1,2,3]
845  f2  | {"f3":1}
846  f4  | null
847  f5  | 99
848  f6  | "stringy"
849 (5 rows)
850
851 select json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"}');
852   json_each_text   
853 -------------------
854  (f1,"[1,2,3]")
855  (f2,"{""f3"":1}")
856  (f4,)
857  (f5,null)
858 (4 rows)
859
860 select * from json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q;
861  key |  value   
862 -----+----------
863  f1  | [1,2,3]
864  f2  | {"f3":1}
865  f4  | 
866  f5  | 99
867  f6  | stringy
868 (5 rows)
869
870 -- extract_path, extract_path_as_text
871 select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6');
872  json_extract_path 
873 -------------------
874  "stringy"
875 (1 row)
876
877 select json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2');
878  json_extract_path 
879 -------------------
880  {"f3":1}
881 (1 row)
882
883 select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text);
884  json_extract_path 
885 -------------------
886  "f3"
887 (1 row)
888
889 select json_extract_path('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text);
890  json_extract_path 
891 -------------------
892  1
893 (1 row)
894
895 select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f4','f6');
896  json_extract_path_text 
897 ------------------------
898  stringy
899 (1 row)
900
901 select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}','f2');
902  json_extract_path_text 
903 ------------------------
904  {"f3":1}
905 (1 row)
906
907 select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',0::text);
908  json_extract_path_text 
909 ------------------------
910  f3
911 (1 row)
912
913 select json_extract_path_text('{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}','f2',1::text);
914  json_extract_path_text 
915 ------------------------
916  1
917 (1 row)
918
919 -- extract_path nulls
920 select json_extract_path('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_false;
921  expect_false 
922 --------------
923  f
924 (1 row)
925
926 select json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}}','f4','f5') is null as expect_true;
927  expect_true 
928 -------------
929  t
930 (1 row)
931
932 select json_extract_path('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_false;
933  expect_false 
934 --------------
935  f
936 (1 row)
937
938 select json_extract_path_text('{"f2":{"f3":1},"f4":[0,1,2,null]}','f4','3') is null as expect_true;
939  expect_true 
940 -------------
941  t
942 (1 row)
943
944 -- extract_path operators
945 select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f4','f6'];
946  ?column?  
947 -----------
948  "stringy"
949 (1 row)
950
951 select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2'];
952  ?column? 
953 ----------
954  {"f3":1}
955 (1 row)
956
957 select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','0'];
958  ?column? 
959 ----------
960  "f3"
961 (1 row)
962
963 select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>array['f2','1'];
964  ?column? 
965 ----------
966  1
967 (1 row)
968
969 select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f4','f6'];
970  ?column? 
971 ----------
972  stringy
973 (1 row)
974
975 select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2'];
976  ?column? 
977 ----------
978  {"f3":1}
979 (1 row)
980
981 select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','0'];
982  ?column? 
983 ----------
984  f3
985 (1 row)
986
987 select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','1'];
988  ?column? 
989 ----------
990  1
991 (1 row)
992
993 -- corner cases for same
994 select '{"a": {"b":{"c": "foo"}}}'::json #> '{}';
995          ?column?          
996 ---------------------------
997  {"a": {"b":{"c": "foo"}}}
998 (1 row)
999
1000 select '[1,2,3]'::json #> '{}';
1001  ?column? 
1002 ----------
1003  [1,2,3]
1004 (1 row)
1005
1006 select '"foo"'::json #> '{}';
1007  ?column? 
1008 ----------
1009  "foo"
1010 (1 row)
1011
1012 select '42'::json #> '{}';
1013  ?column? 
1014 ----------
1015  42
1016 (1 row)
1017
1018 select 'null'::json #> '{}';
1019  ?column? 
1020 ----------
1021  null
1022 (1 row)
1023
1024 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a'];
1025       ?column?      
1026 --------------------
1027  {"b":{"c": "foo"}}
1028 (1 row)
1029
1030 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', null];
1031  ?column? 
1032 ----------
1033  
1034 (1 row)
1035
1036 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a', ''];
1037  ?column? 
1038 ----------
1039  
1040 (1 row)
1041
1042 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b'];
1043    ?column?   
1044 --------------
1045  {"c": "foo"}
1046 (1 row)
1047
1048 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c'];
1049  ?column? 
1050 ----------
1051  "foo"
1052 (1 row)
1053
1054 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c','d'];
1055  ?column? 
1056 ----------
1057  
1058 (1 row)
1059
1060 select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','z','c'];
1061  ?column? 
1062 ----------
1063  
1064 (1 row)
1065
1066 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','1','b'];
1067  ?column? 
1068 ----------
1069  "cc"
1070 (1 row)
1071
1072 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','z','b'];
1073  ?column? 
1074 ----------
1075  
1076 (1 row)
1077
1078 select '[{"b": "c"}, {"b": "cc"}]'::json #> array['1','b'];
1079  ?column? 
1080 ----------
1081  "cc"
1082 (1 row)
1083
1084 select '[{"b": "c"}, {"b": "cc"}]'::json #> array['z','b'];
1085  ?column? 
1086 ----------
1087  
1088 (1 row)
1089
1090 select '[{"b": "c"}, {"b": null}]'::json #> array['1','b'];
1091  ?column? 
1092 ----------
1093  null
1094 (1 row)
1095
1096 select '"foo"'::json #> array['z'];
1097  ?column? 
1098 ----------
1099  
1100 (1 row)
1101
1102 select '42'::json #> array['f2'];
1103  ?column? 
1104 ----------
1105  
1106 (1 row)
1107
1108 select '42'::json #> array['0'];
1109  ?column? 
1110 ----------
1111  
1112 (1 row)
1113
1114 select '{"a": {"b":{"c": "foo"}}}'::json #>> '{}';
1115          ?column?          
1116 ---------------------------
1117  {"a": {"b":{"c": "foo"}}}
1118 (1 row)
1119
1120 select '[1,2,3]'::json #>> '{}';
1121  ?column? 
1122 ----------
1123  [1,2,3]
1124 (1 row)
1125
1126 select '"foo"'::json #>> '{}';
1127  ?column? 
1128 ----------
1129  foo
1130 (1 row)
1131
1132 select '42'::json #>> '{}';
1133  ?column? 
1134 ----------
1135  42
1136 (1 row)
1137
1138 select 'null'::json #>> '{}';
1139  ?column? 
1140 ----------
1141  
1142 (1 row)
1143
1144 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a'];
1145       ?column?      
1146 --------------------
1147  {"b":{"c": "foo"}}
1148 (1 row)
1149
1150 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', null];
1151  ?column? 
1152 ----------
1153  
1154 (1 row)
1155
1156 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a', ''];
1157  ?column? 
1158 ----------
1159  
1160 (1 row)
1161
1162 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b'];
1163    ?column?   
1164 --------------
1165  {"c": "foo"}
1166 (1 row)
1167
1168 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c'];
1169  ?column? 
1170 ----------
1171  foo
1172 (1 row)
1173
1174 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c','d'];
1175  ?column? 
1176 ----------
1177  
1178 (1 row)
1179
1180 select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','z','c'];
1181  ?column? 
1182 ----------
1183  
1184 (1 row)
1185
1186 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','1','b'];
1187  ?column? 
1188 ----------
1189  cc
1190 (1 row)
1191
1192 select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','z','b'];
1193  ?column? 
1194 ----------
1195  
1196 (1 row)
1197
1198 select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['1','b'];
1199  ?column? 
1200 ----------
1201  cc
1202 (1 row)
1203
1204 select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['z','b'];
1205  ?column? 
1206 ----------
1207  
1208 (1 row)
1209
1210 select '[{"b": "c"}, {"b": null}]'::json #>> array['1','b'];
1211  ?column? 
1212 ----------
1213  
1214 (1 row)
1215
1216 select '"foo"'::json #>> array['z'];
1217  ?column? 
1218 ----------
1219  
1220 (1 row)
1221
1222 select '42'::json #>> array['f2'];
1223  ?column? 
1224 ----------
1225  
1226 (1 row)
1227
1228 select '42'::json #>> array['0'];
1229  ?column? 
1230 ----------
1231  
1232 (1 row)
1233
1234 -- array_elements
1235 select json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]');
1236   json_array_elements  
1237 -----------------------
1238  1
1239  true
1240  [1,[2,3]]
1241  null
1242  {"f1":1,"f2":[7,8,9]}
1243  false
1244  "stringy"
1245 (7 rows)
1246
1247 select * from json_array_elements('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q;
1248          value         
1249 -----------------------
1250  1
1251  true
1252  [1,[2,3]]
1253  null
1254  {"f1":1,"f2":[7,8,9]}
1255  false
1256  "stringy"
1257 (7 rows)
1258
1259 select json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]');
1260  json_array_elements_text 
1261 --------------------------
1262  1
1263  true
1264  [1,[2,3]]
1265  
1266  {"f1":1,"f2":[7,8,9]}
1267  false
1268  stringy
1269 (7 rows)
1270
1271 select * from json_array_elements_text('[1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"]') q;
1272          value         
1273 -----------------------
1274  1
1275  true
1276  [1,[2,3]]
1277  
1278  {"f1":1,"f2":[7,8,9]}
1279  false
1280  stringy
1281 (7 rows)
1282
1283 -- populate_record
1284 create type jpop as (a text, b int, c timestamp);
1285 select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q;
1286    a    | b | c 
1287 --------+---+---
1288  blurfl |   | 
1289 (1 row)
1290
1291 select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q;
1292    a    | b |            c             
1293 --------+---+--------------------------
1294  blurfl | 3 | Mon Dec 31 15:30:56 2012
1295 (1 row)
1296
1297 select * from json_populate_record(null::jpop,'{"a":"blurfl","x":43.2}') q;
1298    a    | b | c 
1299 --------+---+---
1300  blurfl |   | 
1301 (1 row)
1302
1303 select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":"blurfl","x":43.2}') q;
1304    a    | b |            c             
1305 --------+---+--------------------------
1306  blurfl | 3 | Mon Dec 31 15:30:56 2012
1307 (1 row)
1308
1309 select * from json_populate_record(null::jpop,'{"a":[100,200,false],"x":43.2}') q;
1310         a        | b | c 
1311 -----------------+---+---
1312  [100,200,false] |   | 
1313 (1 row)
1314
1315 select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"a":[100,200,false],"x":43.2}') q;
1316         a        | b |            c             
1317 -----------------+---+--------------------------
1318  [100,200,false] | 3 | Mon Dec 31 15:30:56 2012
1319 (1 row)
1320
1321 select * from json_populate_record(row('x',3,'2012-12-31 15:30:56')::jpop,'{"c":[100,200,false],"x":43.2}') q;
1322 ERROR:  invalid input syntax for type timestamp: "[100,200,false]"
1323 -- populate_recordset
1324 select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1325    a    | b |            c             
1326 --------+---+--------------------------
1327  blurfl |   | 
1328         | 3 | Fri Jan 20 10:42:53 2012
1329 (2 rows)
1330
1331 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1332    a    | b  |            c             
1333 --------+----+--------------------------
1334  blurfl | 99 | 
1335  def    |  3 | Fri Jan 20 10:42:53 2012
1336 (2 rows)
1337
1338 select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1339    a    | b |            c             
1340 --------+---+--------------------------
1341  blurfl |   | 
1342         | 3 | Fri Jan 20 10:42:53 2012
1343 (2 rows)
1344
1345 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1346    a    | b  |            c             
1347 --------+----+--------------------------
1348  blurfl | 99 | 
1349  def    |  3 | Fri Jan 20 10:42:53 2012
1350 (2 rows)
1351
1352 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q;
1353        a       | b  |            c             
1354 ---------------+----+--------------------------
1355  [100,200,300] | 99 | 
1356  {"z":true}    |  3 | Fri Jan 20 10:42:53 2012
1357 (2 rows)
1358
1359 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q;
1360 ERROR:  invalid input syntax for type timestamp: "[100,200,300]"
1361 create type jpop2 as (a int, b json, c int, d int);
1362 select * from json_populate_recordset(null::jpop2, '[{"a":2,"c":3,"b":{"z":4},"d":6}]') q;
1363  a |    b    | c | d 
1364 ---+---------+---+---
1365  2 | {"z":4} | 3 | 6
1366 (1 row)
1367
1368 select * from json_populate_recordset(null::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1369    a    | b |            c             
1370 --------+---+--------------------------
1371  blurfl |   | 
1372         | 3 | Fri Jan 20 10:42:53 2012
1373 (2 rows)
1374
1375 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}]') q;
1376    a    | b  |            c             
1377 --------+----+--------------------------
1378  blurfl | 99 | 
1379  def    |  3 | Fri Jan 20 10:42:53 2012
1380 (2 rows)
1381
1382 select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}]') q;
1383        a       | b  |            c             
1384 ---------------+----+--------------------------
1385  [100,200,300] | 99 | 
1386  {"z":true}    |  3 | Fri Jan 20 10:42:53 2012
1387 (2 rows)
1388
1389 -- handling of unicode surrogate pairs
1390 select json '{ "a":  "\ud83d\ude04\ud83d\udc36" }' -> 'a' as correct_in_utf8;
1391       correct_in_utf8       
1392 ----------------------------
1393  "\ud83d\ude04\ud83d\udc36"
1394 (1 row)
1395
1396 select json '{ "a":  "\ud83d\ud83d" }' -> 'a'; -- 2 high surrogates in a row
1397 ERROR:  invalid input syntax for type json
1398 DETAIL:  Unicode high surrogate must not follow a high surrogate.
1399 CONTEXT:  JSON data, line 1: { "a":...
1400 select json '{ "a":  "\ude04\ud83d" }' -> 'a'; -- surrogates in wrong order
1401 ERROR:  invalid input syntax for type json
1402 DETAIL:  Unicode low surrogate must follow a high surrogate.
1403 CONTEXT:  JSON data, line 1: { "a":...
1404 select json '{ "a":  "\ud83dX" }' -> 'a'; -- orphan high surrogate
1405 ERROR:  invalid input syntax for type json
1406 DETAIL:  Unicode low surrogate must follow a high surrogate.
1407 CONTEXT:  JSON data, line 1: { "a":...
1408 select json '{ "a":  "\ude04X" }' -> 'a'; -- orphan low surrogate
1409 ERROR:  invalid input syntax for type json
1410 DETAIL:  Unicode low surrogate must follow a high surrogate.
1411 CONTEXT:  JSON data, line 1: { "a":...
1412 --handling of simple unicode escapes
1413 select json '{ "a":  "the Copyright \u00a9 sign" }' as correct_in_utf8;
1414             correct_in_utf8            
1415 ---------------------------------------
1416  { "a":  "the Copyright \u00a9 sign" }
1417 (1 row)
1418
1419 select json '{ "a":  "dollar \u0024 character" }' as correct_everywhere;
1420          correct_everywhere          
1421 -------------------------------------
1422  { "a":  "dollar \u0024 character" }
1423 (1 row)
1424
1425 select json '{ "a":  "dollar \\u0024 character" }' as not_an_escape;
1426             not_an_escape             
1427 --------------------------------------
1428  { "a":  "dollar \\u0024 character" }
1429 (1 row)
1430
1431 select json '{ "a":  "null \u0000 escape" }' as not_unescaped;
1432          not_unescaped          
1433 --------------------------------
1434  { "a":  "null \u0000 escape" }
1435 (1 row)
1436
1437 select json '{ "a":  "null \\u0000 escape" }' as not_an_escape;
1438           not_an_escape          
1439 ---------------------------------
1440  { "a":  "null \\u0000 escape" }
1441 (1 row)
1442
1443 select json '{ "a":  "the Copyright \u00a9 sign" }' ->> 'a' as correct_in_utf8;
1444    correct_in_utf8    
1445 ----------------------
1446  the Copyright © sign
1447 (1 row)
1448
1449 select json '{ "a":  "dollar \u0024 character" }' ->> 'a' as correct_everywhere;
1450  correct_everywhere 
1451 --------------------
1452  dollar $ character
1453 (1 row)
1454
1455 select json '{ "a":  "dollar \\u0024 character" }' ->> 'a' as not_an_escape;
1456       not_an_escape      
1457 -------------------------
1458  dollar \u0024 character
1459 (1 row)
1460
1461 select json '{ "a":  "null \u0000 escape" }' ->> 'a' as fails;
1462 ERROR:  unsupported Unicode escape sequence
1463 DETAIL:  \u0000 cannot be converted to text.
1464 CONTEXT:  JSON data, line 1: { "a":...
1465 select json '{ "a":  "null \\u0000 escape" }' ->> 'a' as not_an_escape;
1466    not_an_escape    
1467 --------------------
1468  null \u0000 escape
1469 (1 row)
1470
1471 --json_typeof() function
1472 select value, json_typeof(value)
1473   from (values (json '123.4'),
1474                (json '-1'),
1475                (json '"foo"'),
1476                (json 'true'),
1477                (json 'false'),
1478                (json 'null'),
1479                (json '[1, 2, 3]'),
1480                (json '[]'),
1481                (json '{"x":"foo", "y":123}'),
1482                (json '{}'),
1483                (NULL::json))
1484       as data(value);
1485         value         | json_typeof 
1486 ----------------------+-------------
1487  123.4                | number
1488  -1                   | number
1489  "foo"                | string
1490  true                 | boolean
1491  false                | boolean
1492  null                 | null
1493  [1, 2, 3]            | array
1494  []                   | array
1495  {"x":"foo", "y":123} | object
1496  {}                   | object
1497                       | 
1498 (11 rows)
1499
1500 -- json_build_array, json_build_object, json_object_agg
1501 SELECT json_build_array('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
1502                            json_build_array                            
1503 -----------------------------------------------------------------------
1504  ["a", 1, "b", 1.2, "c", true, "d", null, "e", {"x": 3, "y": [1,2,3]}]
1505 (1 row)
1506
1507 SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e',json '{"x": 3, "y": [1,2,3]}');
1508                              json_build_object                              
1509 ----------------------------------------------------------------------------
1510  {"a" : 1, "b" : 1.2, "c" : true, "d" : null, "e" : {"x": 3, "y": [1,2,3]}}
1511 (1 row)
1512
1513 SELECT json_build_object(
1514        'a', json_build_object('b',false,'c',99),
1515        'd', json_build_object('e',array[9,8,7]::int[],
1516            'f', (select row_to_json(r) from ( select relkind, oid::regclass as name from pg_class where relname = 'pg_class') r)));
1517                                         json_build_object                                        
1518 -------------------------------------------------------------------------------------------------
1519  {"a" : {"b" : false, "c" : 99}, "d" : {"e" : [9,8,7], "f" : {"relkind":"r","name":"pg_class"}}}
1520 (1 row)
1521
1522 -- empty objects/arrays
1523 SELECT json_build_array();
1524  json_build_array 
1525 ------------------
1526  []
1527 (1 row)
1528
1529 SELECT json_build_object();
1530  json_build_object 
1531 -------------------
1532  {}
1533 (1 row)
1534
1535 -- make sure keys are quoted
1536 SELECT json_build_object(1,2);
1537  json_build_object 
1538 -------------------
1539  {"1" : 2}
1540 (1 row)
1541
1542 -- keys must be scalar and not null
1543 SELECT json_build_object(null,2);
1544 ERROR:  argument 1 cannot be null
1545 HINT:  Object keys should be text.
1546 SELECT json_build_object(r,2) FROM (SELECT 1 AS a, 2 AS b) r;
1547 ERROR:  key value must be scalar, not array, composite, or json
1548 SELECT json_build_object(json '{"a":1,"b":2}', 3);
1549 ERROR:  key value must be scalar, not array, composite, or json
1550 SELECT json_build_object('{1,2,3}'::int[], 3);
1551 ERROR:  key value must be scalar, not array, composite, or json
1552 CREATE TEMP TABLE foo (serial_num int, name text, type text);
1553 INSERT INTO foo VALUES (847001,'t15','GE1043');
1554 INSERT INTO foo VALUES (847002,'t16','GE1043');
1555 INSERT INTO foo VALUES (847003,'sub-alpha','GESS90');
1556 SELECT json_build_object('turbines',json_object_agg(serial_num,json_build_object('name',name,'type',type)))
1557 FROM foo;
1558                                                                             json_build_object                                                                            
1559 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1560  {"turbines" : { "847001" : {"name" : "t15", "type" : "GE1043"}, "847002" : {"name" : "t16", "type" : "GE1043"}, "847003" : {"name" : "sub-alpha", "type" : "GESS90"} }}
1561 (1 row)
1562
1563 -- json_object
1564 -- one dimension
1565 SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}');
1566                       json_object                      
1567 -------------------------------------------------------
1568  {"a" : "1", "b" : "2", "3" : null, "d e f" : "a b c"}
1569 (1 row)
1570
1571 -- same but with two dimensions
1572 SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}');
1573                       json_object                      
1574 -------------------------------------------------------
1575  {"a" : "1", "b" : "2", "3" : null, "d e f" : "a b c"}
1576 (1 row)
1577
1578 -- odd number error
1579 SELECT json_object('{a,b,c}');
1580 ERROR:  array must have even number of elements
1581 -- one column error
1582 SELECT json_object('{{a},{b}}');
1583 ERROR:  array must have two columns
1584 -- too many columns error
1585 SELECT json_object('{{a,b,c},{b,c,d}}');
1586 ERROR:  array must have two columns
1587 -- too many dimensions error
1588 SELECT json_object('{{{a,b},{c,d}},{{b,c},{d,e}}}');
1589 ERROR:  wrong number of array subscripts
1590 --two argument form of json_object
1591 select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c"}');
1592                      json_object                      
1593 ------------------------------------------------------
1594  {"a" : "1", "b" : "2", "c" : "3", "d e f" : "a b c"}
1595 (1 row)
1596
1597 -- too many dimensions
1598 SELECT json_object('{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}', '{{a,1},{b,2},{3,NULL},{"d e f","a b c"}}');
1599 ERROR:  wrong number of array subscripts
1600 -- mismatched dimensions
1601 select json_object('{a,b,c,"d e f",g}','{1,2,3,"a b c"}');
1602 ERROR:  mismatched array dimensions
1603 select json_object('{a,b,c,"d e f"}','{1,2,3,"a b c",g}');
1604 ERROR:  mismatched array dimensions
1605 -- null key error
1606 select json_object('{a,b,NULL,"d e f"}','{1,2,3,"a b c"}');
1607 ERROR:  null value not allowed for object key
1608 -- empty key is allowed
1609 select json_object('{a,b,"","d e f"}','{1,2,3,"a b c"}');
1610                      json_object                     
1611 -----------------------------------------------------
1612  {"a" : "1", "b" : "2", "" : "3", "d e f" : "a b c"}
1613 (1 row)
1614
1615 -- json_to_record and json_to_recordset
1616 select * from json_to_record('{"a":1,"b":"foo","c":"bar"}')
1617     as x(a int, b text, d text);
1618  a |  b  | d 
1619 ---+-----+---
1620  1 | foo | 
1621 (1 row)
1622
1623 select * from json_to_recordset('[{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}]')
1624     as x(a int, b text, c boolean);
1625  a |  b  | c 
1626 ---+-----+---
1627  1 | foo | 
1628  2 | bar | t
1629 (2 rows)
1630
1631 select * from json_to_recordset('[{"a":1,"b":{"d":"foo"},"c":true},{"a":2,"c":false,"b":{"d":"bar"}}]')
1632     as x(a int, b json, c boolean);
1633  a |      b      | c 
1634 ---+-------------+---
1635  1 | {"d":"foo"} | t
1636  2 | {"d":"bar"} | f
1637 (2 rows)
1638
1639 -- json_strip_nulls
1640 select json_strip_nulls(null);
1641  json_strip_nulls 
1642 ------------------
1643  
1644 (1 row)
1645
1646 select json_strip_nulls('1');
1647  json_strip_nulls 
1648 ------------------
1649  1
1650 (1 row)
1651
1652 select json_strip_nulls('"a string"');
1653  json_strip_nulls 
1654 ------------------
1655  "a string"
1656 (1 row)
1657
1658 select json_strip_nulls('null');
1659  json_strip_nulls 
1660 ------------------
1661  null
1662 (1 row)
1663
1664 select json_strip_nulls('[1,2,null,3,4]');
1665  json_strip_nulls 
1666 ------------------
1667  [1,2,null,3,4]
1668 (1 row)
1669
1670 select json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}');
1671           json_strip_nulls          
1672 ------------------------------------
1673  {"a":1,"c":[2,null,3],"d":{"e":4}}
1674 (1 row)
1675
1676 select json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]');
1677   json_strip_nulls   
1678 ---------------------
1679  [1,{"a":1,"c":2},3]
1680 (1 row)
1681
1682 -- an empty object is not null and should not be stripped
1683 select json_strip_nulls('{"a": {"b": null, "c": null}, "d": {} }');
1684  json_strip_nulls 
1685 ------------------
1686  {"a":{},"d":{}}
1687 (1 row)
1688