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