]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/json.c
Do not escape a unicode sequence when escaping JSON text.
[postgresql] / src / backend / utils / adt / json.c
1 /*-------------------------------------------------------------------------
2  *
3  * json.c
4  *              JSON data type support.
5  *
6  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        src/backend/utils/adt/json.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include "access/htup_details.h"
17 #include "access/transam.h"
18 #include "catalog/pg_cast.h"
19 #include "catalog/pg_type.h"
20 #include "executor/spi.h"
21 #include "lib/stringinfo.h"
22 #include "libpq/pqformat.h"
23 #include "mb/pg_wchar.h"
24 #include "parser/parse_coerce.h"
25 #include "utils/array.h"
26 #include "utils/builtins.h"
27 #include "utils/formatting.h"
28 #include "utils/lsyscache.h"
29 #include "utils/json.h"
30 #include "utils/jsonapi.h"
31 #include "utils/typcache.h"
32 #include "utils/syscache.h"
33
34 /*
35  * The context of the parser is maintained by the recursive descent
36  * mechanism, but is passed explicitly to the error reporting routine
37  * for better diagnostics.
38  */
39 typedef enum                                    /* contexts of JSON parser */
40 {
41         JSON_PARSE_VALUE,                       /* expecting a value */
42         JSON_PARSE_STRING,                      /* expecting a string (for a field name) */
43         JSON_PARSE_ARRAY_START,         /* saw '[', expecting value or ']' */
44         JSON_PARSE_ARRAY_NEXT,          /* saw array element, expecting ',' or ']' */
45         JSON_PARSE_OBJECT_START,        /* saw '{', expecting label or '}' */
46         JSON_PARSE_OBJECT_LABEL,        /* saw object label, expecting ':' */
47         JSON_PARSE_OBJECT_NEXT,         /* saw object value, expecting ',' or '}' */
48         JSON_PARSE_OBJECT_COMMA,        /* saw object ',', expecting next label */
49         JSON_PARSE_END                          /* saw the end of a document, expect nothing */
50 } JsonParseContext;
51
52 typedef enum                                    /* type categories for datum_to_json */
53 {
54         JSONTYPE_NULL,                          /* null, so we didn't bother to identify */
55         JSONTYPE_BOOL,                          /* boolean (built-in types only) */
56         JSONTYPE_NUMERIC,                       /* numeric (ditto) */
57         JSONTYPE_TIMESTAMP,         /* we use special formatting for timestamp */
58         JSONTYPE_TIMESTAMPTZ,       /* ... and timestamptz */
59         JSONTYPE_JSON,                          /* JSON itself (and JSONB) */
60         JSONTYPE_ARRAY,                         /* array */
61         JSONTYPE_COMPOSITE,                     /* composite */
62         JSONTYPE_CAST,                          /* something with an explicit cast to JSON */
63         JSONTYPE_OTHER                          /* all else */
64 } JsonTypeCategory;
65
66 /*
67  * to_char formats to turn timestamps and timpstamptzs into json strings
68  * that are ISO 8601 compliant
69  */
70 #define TS_ISO8601_FMT "\\\"YYYY-MM-DD\"T\"HH24:MI:SS.US\\\""
71 #define TSTZ_ISO8601_FMT "\\\"YYYY-MM-DD\"T\"HH24:MI:SS.USOF\\\""
72
73 static inline void json_lex(JsonLexContext *lex);
74 static inline void json_lex_string(JsonLexContext *lex);
75 static inline void json_lex_number(JsonLexContext *lex, char *s, bool *num_err);
76 static inline void parse_scalar(JsonLexContext *lex, JsonSemAction *sem);
77 static void parse_object_field(JsonLexContext *lex, JsonSemAction *sem);
78 static void parse_object(JsonLexContext *lex, JsonSemAction *sem);
79 static void parse_array_element(JsonLexContext *lex, JsonSemAction *sem);
80 static void parse_array(JsonLexContext *lex, JsonSemAction *sem);
81 static void report_parse_error(JsonParseContext ctx, JsonLexContext *lex);
82 static void report_invalid_token(JsonLexContext *lex);
83 static int      report_json_context(JsonLexContext *lex);
84 static char *extract_mb_char(char *s);
85 static void composite_to_json(Datum composite, StringInfo result,
86                                   bool use_line_feeds);
87 static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
88                                   Datum *vals, bool *nulls, int *valcount,
89                                   JsonTypeCategory tcategory, Oid outfuncoid,
90                                   bool use_line_feeds);
91 static void array_to_json_internal(Datum array, StringInfo result,
92                                            bool use_line_feeds);
93 static void json_categorize_type(Oid typoid,
94                                          JsonTypeCategory *tcategory,
95                                          Oid *outfuncoid);
96 static void datum_to_json(Datum val, bool is_null, StringInfo result,
97                           JsonTypeCategory tcategory, Oid outfuncoid,
98                           bool key_scalar);
99 static void add_json(Datum val, bool is_null, StringInfo result,
100                  Oid val_type, bool key_scalar);
101
102 /* the null action object used for pure validation */
103 static JsonSemAction nullSemAction =
104 {
105         NULL, NULL, NULL, NULL, NULL,
106         NULL, NULL, NULL, NULL, NULL
107 };
108
109 /* Recursive Descent parser support routines */
110
111 /*
112  * lex_peek
113  *
114  * what is the current look_ahead token?
115 */
116 static inline JsonTokenType
117 lex_peek(JsonLexContext *lex)
118 {
119         return lex->token_type;
120 }
121
122 /*
123  * lex_accept
124  *
125  * accept the look_ahead token and move the lexer to the next token if the
126  * look_ahead token matches the token parameter. In that case, and if required,
127  * also hand back the de-escaped lexeme.
128  *
129  * returns true if the token matched, false otherwise.
130  */
131 static inline bool
132 lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
133 {
134         if (lex->token_type == token)
135         {
136                 if (lexeme != NULL)
137                 {
138                         if (lex->token_type == JSON_TOKEN_STRING)
139                         {
140                                 if (lex->strval != NULL)
141                                         *lexeme = pstrdup(lex->strval->data);
142                         }
143                         else
144                         {
145                                 int                     len = (lex->token_terminator - lex->token_start);
146                                 char       *tokstr = palloc(len + 1);
147
148                                 memcpy(tokstr, lex->token_start, len);
149                                 tokstr[len] = '\0';
150                                 *lexeme = tokstr;
151                         }
152                 }
153                 json_lex(lex);
154                 return true;
155         }
156         return false;
157 }
158
159 /*
160  * lex_accept
161  *
162  * move the lexer to the next token if the current look_ahead token matches
163  * the parameter token. Otherwise, report an error.
164  */
165 static inline void
166 lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
167 {
168         if (!lex_accept(lex, token, NULL))
169                 report_parse_error(ctx, lex);;
170 }
171
172 /* chars to consider as part of an alphanumeric token */
173 #define JSON_ALPHANUMERIC_CHAR(c)  \
174         (((c) >= 'a' && (c) <= 'z') || \
175          ((c) >= 'A' && (c) <= 'Z') || \
176          ((c) >= '0' && (c) <= '9') || \
177          (c) == '_' || \
178          IS_HIGHBIT_SET(c))
179
180 /*
181  * Input.
182  */
183 Datum
184 json_in(PG_FUNCTION_ARGS)
185 {
186         char       *json = PG_GETARG_CSTRING(0);
187         text       *result = cstring_to_text(json);
188         JsonLexContext *lex;
189
190         /* validate it */
191         lex = makeJsonLexContext(result, false);
192         pg_parse_json(lex, &nullSemAction);
193
194         /* Internal representation is the same as text, for now */
195         PG_RETURN_TEXT_P(result);
196 }
197
198 /*
199  * Output.
200  */
201 Datum
202 json_out(PG_FUNCTION_ARGS)
203 {
204         /* we needn't detoast because text_to_cstring will handle that */
205         Datum           txt = PG_GETARG_DATUM(0);
206
207         PG_RETURN_CSTRING(TextDatumGetCString(txt));
208 }
209
210 /*
211  * Binary send.
212  */
213 Datum
214 json_send(PG_FUNCTION_ARGS)
215 {
216         text       *t = PG_GETARG_TEXT_PP(0);
217         StringInfoData buf;
218
219         pq_begintypsend(&buf);
220         pq_sendtext(&buf, VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t));
221         PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
222 }
223
224 /*
225  * Binary receive.
226  */
227 Datum
228 json_recv(PG_FUNCTION_ARGS)
229 {
230         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
231         char       *str;
232         int                     nbytes;
233         JsonLexContext *lex;
234
235         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
236
237         /* Validate it. */
238         lex = makeJsonLexContextCstringLen(str, nbytes, false);
239         pg_parse_json(lex, &nullSemAction);
240
241         PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
242 }
243
244 /*
245  * makeJsonLexContext
246  *
247  * lex constructor, with or without StringInfo object
248  * for de-escaped lexemes.
249  *
250  * Without is better as it makes the processing faster, so only make one
251  * if really required.
252  *
253  * If you already have the json as a text* value, use the first of these
254  * functions, otherwise use  makeJsonLexContextCstringLen().
255  */
256 JsonLexContext *
257 makeJsonLexContext(text *json, bool need_escapes)
258 {
259         return makeJsonLexContextCstringLen(VARDATA(json),
260                                                                                 VARSIZE(json) - VARHDRSZ,
261                                                                                 need_escapes);
262 }
263
264 JsonLexContext *
265 makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
266 {
267         JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
268
269         lex->input = lex->token_terminator = lex->line_start = json;
270         lex->line_number = 1;
271         lex->input_length = len;
272         if (need_escapes)
273                 lex->strval = makeStringInfo();
274         return lex;
275 }
276
277 /*
278  * pg_parse_json
279  *
280  * Publicly visible entry point for the JSON parser.
281  *
282  * lex is a lexing context, set up for the json to be processed by calling
283  * makeJsonLexContext(). sem is a strucure of function pointers to semantic
284  * action routines to be called at appropriate spots during parsing, and a
285  * pointer to a state object to be passed to those routines.
286  */
287 void
288 pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
289 {
290         JsonTokenType tok;
291
292         /* get the initial token */
293         json_lex(lex);
294
295         tok = lex_peek(lex);
296
297         /* parse by recursive descent */
298         switch (tok)
299         {
300                 case JSON_TOKEN_OBJECT_START:
301                         parse_object(lex, sem);
302                         break;
303                 case JSON_TOKEN_ARRAY_START:
304                         parse_array(lex, sem);
305                         break;
306                 default:
307                         parse_scalar(lex, sem);         /* json can be a bare scalar */
308         }
309
310         lex_expect(JSON_PARSE_END, lex, JSON_TOKEN_END);
311
312 }
313
314 /*
315  *      Recursive Descent parse routines. There is one for each structural
316  *      element in a json document:
317  *        - scalar (string, number, true, false, null)
318  *        - array  ( [ ] )
319  *        - array element
320  *        - object ( { } )
321  *        - object field
322  */
323 static inline void
324 parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
325 {
326         char       *val = NULL;
327         json_scalar_action sfunc = sem->scalar;
328         char      **valaddr;
329         JsonTokenType tok = lex_peek(lex);
330
331         valaddr = sfunc == NULL ? NULL : &val;
332
333         /* a scalar must be a string, a number, true, false, or null */
334         switch (tok)
335         {
336                 case JSON_TOKEN_TRUE:
337                         lex_accept(lex, JSON_TOKEN_TRUE, valaddr);
338                         break;
339                 case JSON_TOKEN_FALSE:
340                         lex_accept(lex, JSON_TOKEN_FALSE, valaddr);
341                         break;
342                 case JSON_TOKEN_NULL:
343                         lex_accept(lex, JSON_TOKEN_NULL, valaddr);
344                         break;
345                 case JSON_TOKEN_NUMBER:
346                         lex_accept(lex, JSON_TOKEN_NUMBER, valaddr);
347                         break;
348                 case JSON_TOKEN_STRING:
349                         lex_accept(lex, JSON_TOKEN_STRING, valaddr);
350                         break;
351                 default:
352                         report_parse_error(JSON_PARSE_VALUE, lex);
353         }
354
355         if (sfunc != NULL)
356                 (*sfunc) (sem->semstate, val, tok);
357 }
358
359 static void
360 parse_object_field(JsonLexContext *lex, JsonSemAction *sem)
361 {
362         /*
363          * an object field is "fieldname" : value where value can be a scalar,
364          * object or array
365          */
366
367         char       *fname = NULL;       /* keep compiler quiet */
368         json_ofield_action ostart = sem->object_field_start;
369         json_ofield_action oend = sem->object_field_end;
370         bool            isnull;
371         char      **fnameaddr = NULL;
372         JsonTokenType tok;
373
374         if (ostart != NULL || oend != NULL)
375                 fnameaddr = &fname;
376
377         if (!lex_accept(lex, JSON_TOKEN_STRING, fnameaddr))
378                 report_parse_error(JSON_PARSE_STRING, lex);
379
380         lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON);
381
382         tok = lex_peek(lex);
383         isnull = tok == JSON_TOKEN_NULL;
384
385         if (ostart != NULL)
386                 (*ostart) (sem->semstate, fname, isnull);
387
388         switch (tok)
389         {
390                 case JSON_TOKEN_OBJECT_START:
391                         parse_object(lex, sem);
392                         break;
393                 case JSON_TOKEN_ARRAY_START:
394                         parse_array(lex, sem);
395                         break;
396                 default:
397                         parse_scalar(lex, sem);
398         }
399
400         if (oend != NULL)
401                 (*oend) (sem->semstate, fname, isnull);
402 }
403
404 static void
405 parse_object(JsonLexContext *lex, JsonSemAction *sem)
406 {
407         /*
408          * an object is a possibly empty sequence of object fields, separated by
409          * commas and surrounde by curly braces.
410          */
411         json_struct_action ostart = sem->object_start;
412         json_struct_action oend = sem->object_end;
413         JsonTokenType tok;
414
415         if (ostart != NULL)
416                 (*ostart) (sem->semstate);
417
418         /*
419          * Data inside an object is at a higher nesting level than the object
420          * itself. Note that we increment this after we call the semantic routine
421          * for the object start and restore it before we call the routine for the
422          * object end.
423          */
424         lex->lex_level++;
425
426         /* we know this will succeeed, just clearing the token */
427         lex_expect(JSON_PARSE_OBJECT_START, lex, JSON_TOKEN_OBJECT_START);
428
429         tok = lex_peek(lex);
430         switch (tok)
431         {
432                 case JSON_TOKEN_STRING:
433                         parse_object_field(lex, sem);
434                         while (lex_accept(lex, JSON_TOKEN_COMMA, NULL))
435                                 parse_object_field(lex, sem);
436                         break;
437                 case JSON_TOKEN_OBJECT_END:
438                         break;
439                 default:
440                         /* case of an invalid initial token inside the object */
441                         report_parse_error(JSON_PARSE_OBJECT_START, lex);
442         }
443
444         lex_expect(JSON_PARSE_OBJECT_NEXT, lex, JSON_TOKEN_OBJECT_END);
445
446         lex->lex_level--;
447
448         if (oend != NULL)
449                 (*oend) (sem->semstate);
450 }
451
452 static void
453 parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
454 {
455         json_aelem_action astart = sem->array_element_start;
456         json_aelem_action aend = sem->array_element_end;
457         JsonTokenType tok = lex_peek(lex);
458
459         bool            isnull;
460
461         isnull = tok == JSON_TOKEN_NULL;
462
463         if (astart != NULL)
464                 (*astart) (sem->semstate, isnull);
465
466         /* an array element is any object, array or scalar */
467         switch (tok)
468         {
469                 case JSON_TOKEN_OBJECT_START:
470                         parse_object(lex, sem);
471                         break;
472                 case JSON_TOKEN_ARRAY_START:
473                         parse_array(lex, sem);
474                         break;
475                 default:
476                         parse_scalar(lex, sem);
477         }
478
479         if (aend != NULL)
480                 (*aend) (sem->semstate, isnull);
481 }
482
483 static void
484 parse_array(JsonLexContext *lex, JsonSemAction *sem)
485 {
486         /*
487          * an array is a possibly empty sequence of array elements, separated by
488          * commas and surrounded by square brackets.
489          */
490         json_struct_action astart = sem->array_start;
491         json_struct_action aend = sem->array_end;
492
493         if (astart != NULL)
494                 (*astart) (sem->semstate);
495
496         /*
497          * Data inside an array is at a higher nesting level than the array
498          * itself. Note that we increment this after we call the semantic routine
499          * for the array start and restore it before we call the routine for the
500          * array end.
501          */
502         lex->lex_level++;
503
504         lex_expect(JSON_PARSE_ARRAY_START, lex, JSON_TOKEN_ARRAY_START);
505         if (lex_peek(lex) != JSON_TOKEN_ARRAY_END)
506         {
507
508                 parse_array_element(lex, sem);
509
510                 while (lex_accept(lex, JSON_TOKEN_COMMA, NULL))
511                         parse_array_element(lex, sem);
512         }
513
514         lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END);
515
516         lex->lex_level--;
517
518         if (aend != NULL)
519                 (*aend) (sem->semstate);
520 }
521
522 /*
523  * Lex one token from the input stream.
524  */
525 static inline void
526 json_lex(JsonLexContext *lex)
527 {
528         char       *s;
529         int                     len;
530
531         /* Skip leading whitespace. */
532         s = lex->token_terminator;
533         len = s - lex->input;
534         while (len < lex->input_length &&
535                    (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
536         {
537                 if (*s == '\n')
538                         ++lex->line_number;
539                 ++s;
540                 ++len;
541         }
542         lex->token_start = s;
543
544         /* Determine token type. */
545         if (len >= lex->input_length)
546         {
547                 lex->token_start = NULL;
548                 lex->prev_token_terminator = lex->token_terminator;
549                 lex->token_terminator = s;
550                 lex->token_type = JSON_TOKEN_END;
551         }
552         else
553                 switch (*s)
554                 {
555                                 /* Single-character token, some kind of punctuation mark. */
556                         case '{':
557                                 lex->prev_token_terminator = lex->token_terminator;
558                                 lex->token_terminator = s + 1;
559                                 lex->token_type = JSON_TOKEN_OBJECT_START;
560                                 break;
561                         case '}':
562                                 lex->prev_token_terminator = lex->token_terminator;
563                                 lex->token_terminator = s + 1;
564                                 lex->token_type = JSON_TOKEN_OBJECT_END;
565                                 break;
566                         case '[':
567                                 lex->prev_token_terminator = lex->token_terminator;
568                                 lex->token_terminator = s + 1;
569                                 lex->token_type = JSON_TOKEN_ARRAY_START;
570                                 break;
571                         case ']':
572                                 lex->prev_token_terminator = lex->token_terminator;
573                                 lex->token_terminator = s + 1;
574                                 lex->token_type = JSON_TOKEN_ARRAY_END;
575                                 break;
576                         case ',':
577                                 lex->prev_token_terminator = lex->token_terminator;
578                                 lex->token_terminator = s + 1;
579                                 lex->token_type = JSON_TOKEN_COMMA;
580                                 break;
581                         case ':':
582                                 lex->prev_token_terminator = lex->token_terminator;
583                                 lex->token_terminator = s + 1;
584                                 lex->token_type = JSON_TOKEN_COLON;
585                                 break;
586                         case '"':
587                                 /* string */
588                                 json_lex_string(lex);
589                                 lex->token_type = JSON_TOKEN_STRING;
590                                 break;
591                         case '-':
592                                 /* Negative number. */
593                                 json_lex_number(lex, s + 1, NULL);
594                                 lex->token_type = JSON_TOKEN_NUMBER;
595                                 break;
596                         case '0':
597                         case '1':
598                         case '2':
599                         case '3':
600                         case '4':
601                         case '5':
602                         case '6':
603                         case '7':
604                         case '8':
605                         case '9':
606                                 /* Positive number. */
607                                 json_lex_number(lex, s, NULL);
608                                 lex->token_type = JSON_TOKEN_NUMBER;
609                                 break;
610                         default:
611                                 {
612                                         char       *p;
613
614                                         /*
615                                          * We're not dealing with a string, number, legal
616                                          * punctuation mark, or end of string.  The only legal
617                                          * tokens we might find here are true, false, and null,
618                                          * but for error reporting purposes we scan until we see a
619                                          * non-alphanumeric character.  That way, we can report
620                                          * the whole word as an unexpected token, rather than just
621                                          * some unintuitive prefix thereof.
622                                          */
623                                         for (p = s; p - s < lex->input_length - len && JSON_ALPHANUMERIC_CHAR(*p); p++)
624                                                  /* skip */ ;
625
626                                         /*
627                                          * We got some sort of unexpected punctuation or an
628                                          * otherwise unexpected character, so just complain about
629                                          * that one character.
630                                          */
631                                         if (p == s)
632                                         {
633                                                 lex->prev_token_terminator = lex->token_terminator;
634                                                 lex->token_terminator = s + 1;
635                                                 report_invalid_token(lex);
636                                         }
637
638                                         /*
639                                          * We've got a real alphanumeric token here.  If it
640                                          * happens to be true, false, or null, all is well.  If
641                                          * not, error out.
642                                          */
643                                         lex->prev_token_terminator = lex->token_terminator;
644                                         lex->token_terminator = p;
645                                         if (p - s == 4)
646                                         {
647                                                 if (memcmp(s, "true", 4) == 0)
648                                                         lex->token_type = JSON_TOKEN_TRUE;
649                                                 else if (memcmp(s, "null", 4) == 0)
650                                                         lex->token_type = JSON_TOKEN_NULL;
651                                                 else
652                                                         report_invalid_token(lex);
653                                         }
654                                         else if (p - s == 5 && memcmp(s, "false", 5) == 0)
655                                                 lex->token_type = JSON_TOKEN_FALSE;
656                                         else
657                                                 report_invalid_token(lex);
658
659                                 }
660                 }                                               /* end of switch */
661 }
662
663 /*
664  * The next token in the input stream is known to be a string; lex it.
665  */
666 static inline void
667 json_lex_string(JsonLexContext *lex)
668 {
669         char       *s;
670         int                     len;
671         int                     hi_surrogate = -1;
672
673         if (lex->strval != NULL)
674                 resetStringInfo(lex->strval);
675
676         Assert(lex->input_length > 0);
677         s = lex->token_start;
678         len = lex->token_start - lex->input;
679         for (;;)
680         {
681                 s++;
682                 len++;
683                 /* Premature end of the string. */
684                 if (len >= lex->input_length)
685                 {
686                         lex->token_terminator = s;
687                         report_invalid_token(lex);
688                 }
689                 else if (*s == '"')
690                         break;
691                 else if ((unsigned char) *s < 32)
692                 {
693                         /* Per RFC4627, these characters MUST be escaped. */
694                         /* Since *s isn't printable, exclude it from the context string */
695                         lex->token_terminator = s;
696                         ereport(ERROR,
697                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
698                                          errmsg("invalid input syntax for type json"),
699                                          errdetail("Character with value 0x%02x must be escaped.",
700                                                            (unsigned char) *s),
701                                          report_json_context(lex)));
702                 }
703                 else if (*s == '\\')
704                 {
705                         /* OK, we have an escape character. */
706                         s++;
707                         len++;
708                         if (len >= lex->input_length)
709                         {
710                                 lex->token_terminator = s;
711                                 report_invalid_token(lex);
712                         }
713                         else if (*s == 'u')
714                         {
715                                 int                     i;
716                                 int                     ch = 0;
717
718                                 for (i = 1; i <= 4; i++)
719                                 {
720                                         s++;
721                                         len++;
722                                         if (len >= lex->input_length)
723                                         {
724                                                 lex->token_terminator = s;
725                                                 report_invalid_token(lex);
726                                         }
727                                         else if (*s >= '0' && *s <= '9')
728                                                 ch = (ch * 16) + (*s - '0');
729                                         else if (*s >= 'a' && *s <= 'f')
730                                                 ch = (ch * 16) + (*s - 'a') + 10;
731                                         else if (*s >= 'A' && *s <= 'F')
732                                                 ch = (ch * 16) + (*s - 'A') + 10;
733                                         else
734                                         {
735                                                 lex->token_terminator = s + pg_mblen(s);
736                                                 ereport(ERROR,
737                                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
738                                                                  errmsg("invalid input syntax for type json"),
739                                                                  errdetail("\"\\u\" must be followed by four hexadecimal digits."),
740                                                                  report_json_context(lex)));
741                                         }
742                                 }
743                                 if (lex->strval != NULL)
744                                 {
745                                         char            utf8str[5];
746                                         int                     utf8len;
747
748                                         if (ch >= 0xd800 && ch <= 0xdbff)
749                                         {
750                                                 if (hi_surrogate != -1)
751                                                         ereport(ERROR,
752                                                            (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
753                                                                 errmsg("invalid input syntax for type json"),
754                                                                 errdetail("Unicode high surrogate must not follow a high surrogate."),
755                                                                 report_json_context(lex)));
756                                                 hi_surrogate = (ch & 0x3ff) << 10;
757                                                 continue;
758                                         }
759                                         else if (ch >= 0xdc00 && ch <= 0xdfff)
760                                         {
761                                                 if (hi_surrogate == -1)
762                                                         ereport(ERROR,
763                                                            (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
764                                                                 errmsg("invalid input syntax for type json"),
765                                                                 errdetail("Unicode low surrogate must follow a high surrogate."),
766                                                                 report_json_context(lex)));
767                                                 ch = 0x10000 + hi_surrogate + (ch & 0x3ff);
768                                                 hi_surrogate = -1;
769                                         }
770
771                                         if (hi_surrogate != -1)
772                                                 ereport(ERROR,
773                                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
774                                                                  errmsg("invalid input syntax for type json"),
775                                                                  errdetail("Unicode low surrogate must follow a high surrogate."),
776                                                                  report_json_context(lex)));
777
778                                         /*
779                                          * For UTF8, replace the escape sequence by the actual
780                                          * utf8 character in lex->strval. Do this also for other
781                                          * encodings if the escape designates an ASCII character,
782                                          * otherwise raise an error. We don't ever unescape a
783                                          * \u0000, since that would result in an impermissible nul
784                                          * byte.
785                                          */
786
787                                         if (ch == 0)
788                                         {
789                                                 appendStringInfoString(lex->strval, "\\u0000");
790                                         }
791                                         else if (GetDatabaseEncoding() == PG_UTF8)
792                                         {
793                                                 unicode_to_utf8(ch, (unsigned char *) utf8str);
794                                                 utf8len = pg_utf_mblen((unsigned char *) utf8str);
795                                                 appendBinaryStringInfo(lex->strval, utf8str, utf8len);
796                                         }
797                                         else if (ch <= 0x007f)
798                                         {
799                                                 /*
800                                                  * This is the only way to designate things like a
801                                                  * form feed character in JSON, so it's useful in all
802                                                  * encodings.
803                                                  */
804                                                 appendStringInfoChar(lex->strval, (char) ch);
805                                         }
806                                         else
807                                         {
808                                                 ereport(ERROR,
809                                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
810                                                                  errmsg("invalid input syntax for type json"),
811                                                                  errdetail("Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8."),
812                                                                  report_json_context(lex)));
813                                         }
814
815                                 }
816                         }
817                         else if (lex->strval != NULL)
818                         {
819                                 if (hi_surrogate != -1)
820                                         ereport(ERROR,
821                                                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
822                                                          errmsg("invalid input syntax for type json"),
823                                                          errdetail("Unicode low surrogate must follow a high surrogate."),
824                                                          report_json_context(lex)));
825
826                                 switch (*s)
827                                 {
828                                         case '"':
829                                         case '\\':
830                                         case '/':
831                                                 appendStringInfoChar(lex->strval, *s);
832                                                 break;
833                                         case 'b':
834                                                 appendStringInfoChar(lex->strval, '\b');
835                                                 break;
836                                         case 'f':
837                                                 appendStringInfoChar(lex->strval, '\f');
838                                                 break;
839                                         case 'n':
840                                                 appendStringInfoChar(lex->strval, '\n');
841                                                 break;
842                                         case 'r':
843                                                 appendStringInfoChar(lex->strval, '\r');
844                                                 break;
845                                         case 't':
846                                                 appendStringInfoChar(lex->strval, '\t');
847                                                 break;
848                                         default:
849                                                 /* Not a valid string escape, so error out. */
850                                                 lex->token_terminator = s + pg_mblen(s);
851                                                 ereport(ERROR,
852                                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
853                                                                  errmsg("invalid input syntax for type json"),
854                                                         errdetail("Escape sequence \"\\%s\" is invalid.",
855                                                                           extract_mb_char(s)),
856                                                                  report_json_context(lex)));
857                                 }
858                         }
859                         else if (strchr("\"\\/bfnrt", *s) == NULL)
860                         {
861                                 /*
862                                  * Simpler processing if we're not bothered about de-escaping
863                                  *
864                                  * It's very tempting to remove the strchr() call here and
865                                  * replace it with a switch statement, but testing so far has
866                                  * shown it's not a performance win.
867                                  */
868                                 lex->token_terminator = s + pg_mblen(s);
869                                 ereport(ERROR,
870                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
871                                                  errmsg("invalid input syntax for type json"),
872                                                  errdetail("Escape sequence \"\\%s\" is invalid.",
873                                                                    extract_mb_char(s)),
874                                                  report_json_context(lex)));
875                         }
876
877                 }
878                 else if (lex->strval != NULL)
879                 {
880                         if (hi_surrogate != -1)
881                                 ereport(ERROR,
882                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
883                                                  errmsg("invalid input syntax for type json"),
884                                                  errdetail("Unicode low surrogate must follow a high surrogate."),
885                                                  report_json_context(lex)));
886
887                         appendStringInfoChar(lex->strval, *s);
888                 }
889
890         }
891
892         if (hi_surrogate != -1)
893                 ereport(ERROR,
894                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
895                                  errmsg("invalid input syntax for type json"),
896                         errdetail("Unicode low surrogate must follow a high surrogate."),
897                                  report_json_context(lex)));
898
899         /* Hooray, we found the end of the string! */
900         lex->prev_token_terminator = lex->token_terminator;
901         lex->token_terminator = s + 1;
902 }
903
904 /*-------------------------------------------------------------------------
905  * The next token in the input stream is known to be a number; lex it.
906  *
907  * In JSON, a number consists of four parts:
908  *
909  * (1) An optional minus sign ('-').
910  *
911  * (2) Either a single '0', or a string of one or more digits that does not
912  *         begin with a '0'.
913  *
914  * (3) An optional decimal part, consisting of a period ('.') followed by
915  *         one or more digits.  (Note: While this part can be omitted
916  *         completely, it's not OK to have only the decimal point without
917  *         any digits afterwards.)
918  *
919  * (4) An optional exponent part, consisting of 'e' or 'E', optionally
920  *         followed by '+' or '-', followed by one or more digits.  (Note:
921  *         As with the decimal part, if 'e' or 'E' is present, it must be
922  *         followed by at least one digit.)
923  *
924  * The 's' argument to this function points to the ostensible beginning
925  * of part 2 - i.e. the character after any optional minus sign, and the
926  * first character of the string if there is none.
927  *
928  *-------------------------------------------------------------------------
929  */
930 static inline void
931 json_lex_number(JsonLexContext *lex, char *s, bool *num_err)
932 {
933         bool            error = false;
934         char       *p;
935         int                     len;
936
937         len = s - lex->input;
938         /* Part (1): leading sign indicator. */
939         /* Caller already did this for us; so do nothing. */
940
941         /* Part (2): parse main digit string. */
942         if (*s == '0')
943         {
944                 s++;
945                 len++;
946         }
947         else if (*s >= '1' && *s <= '9')
948         {
949                 do
950                 {
951                         s++;
952                         len++;
953                 } while (len < lex->input_length && *s >= '0' && *s <= '9');
954         }
955         else
956                 error = true;
957
958         /* Part (3): parse optional decimal portion. */
959         if (len < lex->input_length && *s == '.')
960         {
961                 s++;
962                 len++;
963                 if (len == lex->input_length || *s < '0' || *s > '9')
964                         error = true;
965                 else
966                 {
967                         do
968                         {
969                                 s++;
970                                 len++;
971                         } while (len < lex->input_length && *s >= '0' && *s <= '9');
972                 }
973         }
974
975         /* Part (4): parse optional exponent. */
976         if (len < lex->input_length && (*s == 'e' || *s == 'E'))
977         {
978                 s++;
979                 len++;
980                 if (len < lex->input_length && (*s == '+' || *s == '-'))
981                 {
982                         s++;
983                         len++;
984                 }
985                 if (len == lex->input_length || *s < '0' || *s > '9')
986                         error = true;
987                 else
988                 {
989                         do
990                         {
991                                 s++;
992                                 len++;
993                         } while (len < lex->input_length && *s >= '0' && *s <= '9');
994                 }
995         }
996
997         /*
998          * Check for trailing garbage.  As in json_lex(), any alphanumeric stuff
999          * here should be considered part of the token for error-reporting
1000          * purposes.
1001          */
1002         for (p = s; len < lex->input_length && JSON_ALPHANUMERIC_CHAR(*p); p++, len++)
1003                 error = true;
1004
1005         if (num_err != NULL)
1006         {
1007                 /* let the caller handle the error */
1008                 *num_err = error;
1009         }
1010         else
1011         {
1012                 lex->prev_token_terminator = lex->token_terminator;
1013                 lex->token_terminator = p;
1014                 if (error)
1015                         report_invalid_token(lex);
1016         }
1017 }
1018
1019 /*
1020  * Report a parse error.
1021  *
1022  * lex->token_start and lex->token_terminator must identify the current token.
1023  */
1024 static void
1025 report_parse_error(JsonParseContext ctx, JsonLexContext *lex)
1026 {
1027         char       *token;
1028         int                     toklen;
1029
1030         /* Handle case where the input ended prematurely. */
1031         if (lex->token_start == NULL || lex->token_type == JSON_TOKEN_END)
1032                 ereport(ERROR,
1033                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1034                                  errmsg("invalid input syntax for type json"),
1035                                  errdetail("The input string ended unexpectedly."),
1036                                  report_json_context(lex)));
1037
1038         /* Separate out the current token. */
1039         toklen = lex->token_terminator - lex->token_start;
1040         token = palloc(toklen + 1);
1041         memcpy(token, lex->token_start, toklen);
1042         token[toklen] = '\0';
1043
1044         /* Complain, with the appropriate detail message. */
1045         if (ctx == JSON_PARSE_END)
1046                 ereport(ERROR,
1047                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1048                                  errmsg("invalid input syntax for type json"),
1049                                  errdetail("Expected end of input, but found \"%s\".",
1050                                                    token),
1051                                  report_json_context(lex)));
1052         else
1053         {
1054                 switch (ctx)
1055                 {
1056                         case JSON_PARSE_VALUE:
1057                                 ereport(ERROR,
1058                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1059                                                  errmsg("invalid input syntax for type json"),
1060                                                  errdetail("Expected JSON value, but found \"%s\".",
1061                                                                    token),
1062                                                  report_json_context(lex)));
1063                                 break;
1064                         case JSON_PARSE_STRING:
1065                                 ereport(ERROR,
1066                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1067                                                  errmsg("invalid input syntax for type json"),
1068                                                  errdetail("Expected string, but found \"%s\".",
1069                                                                    token),
1070                                                  report_json_context(lex)));
1071                                 break;
1072                         case JSON_PARSE_ARRAY_START:
1073                                 ereport(ERROR,
1074                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1075                                                  errmsg("invalid input syntax for type json"),
1076                                                  errdetail("Expected array element or \"]\", but found \"%s\".",
1077                                                                    token),
1078                                                  report_json_context(lex)));
1079                                 break;
1080                         case JSON_PARSE_ARRAY_NEXT:
1081                                 ereport(ERROR,
1082                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1083                                                  errmsg("invalid input syntax for type json"),
1084                                           errdetail("Expected \",\" or \"]\", but found \"%s\".",
1085                                                                 token),
1086                                                  report_json_context(lex)));
1087                                 break;
1088                         case JSON_PARSE_OBJECT_START:
1089                                 ereport(ERROR,
1090                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1091                                                  errmsg("invalid input syntax for type json"),
1092                                          errdetail("Expected string or \"}\", but found \"%s\".",
1093                                                            token),
1094                                                  report_json_context(lex)));
1095                                 break;
1096                         case JSON_PARSE_OBJECT_LABEL:
1097                                 ereport(ERROR,
1098                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1099                                                  errmsg("invalid input syntax for type json"),
1100                                                  errdetail("Expected \":\", but found \"%s\".",
1101                                                                    token),
1102                                                  report_json_context(lex)));
1103                                 break;
1104                         case JSON_PARSE_OBJECT_NEXT:
1105                                 ereport(ERROR,
1106                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1107                                                  errmsg("invalid input syntax for type json"),
1108                                           errdetail("Expected \",\" or \"}\", but found \"%s\".",
1109                                                                 token),
1110                                                  report_json_context(lex)));
1111                                 break;
1112                         case JSON_PARSE_OBJECT_COMMA:
1113                                 ereport(ERROR,
1114                                                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1115                                                  errmsg("invalid input syntax for type json"),
1116                                                  errdetail("Expected string, but found \"%s\".",
1117                                                                    token),
1118                                                  report_json_context(lex)));
1119                                 break;
1120                         default:
1121                                 elog(ERROR, "unexpected json parse state: %d", ctx);
1122                 }
1123         }
1124 }
1125
1126 /*
1127  * Report an invalid input token.
1128  *
1129  * lex->token_start and lex->token_terminator must identify the token.
1130  */
1131 static void
1132 report_invalid_token(JsonLexContext *lex)
1133 {
1134         char       *token;
1135         int                     toklen;
1136
1137         /* Separate out the offending token. */
1138         toklen = lex->token_terminator - lex->token_start;
1139         token = palloc(toklen + 1);
1140         memcpy(token, lex->token_start, toklen);
1141         token[toklen] = '\0';
1142
1143         ereport(ERROR,
1144                         (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1145                          errmsg("invalid input syntax for type json"),
1146                          errdetail("Token \"%s\" is invalid.", token),
1147                          report_json_context(lex)));
1148 }
1149
1150 /*
1151  * Report a CONTEXT line for bogus JSON input.
1152  *
1153  * lex->token_terminator must be set to identify the spot where we detected
1154  * the error.  Note that lex->token_start might be NULL, in case we recognized
1155  * error at EOF.
1156  *
1157  * The return value isn't meaningful, but we make it non-void so that this
1158  * can be invoked inside ereport().
1159  */
1160 static int
1161 report_json_context(JsonLexContext *lex)
1162 {
1163         const char *context_start;
1164         const char *context_end;
1165         const char *line_start;
1166         int                     line_number;
1167         char       *ctxt;
1168         int                     ctxtlen;
1169         const char *prefix;
1170         const char *suffix;
1171
1172         /* Choose boundaries for the part of the input we will display */
1173         context_start = lex->input;
1174         context_end = lex->token_terminator;
1175         line_start = context_start;
1176         line_number = 1;
1177         for (;;)
1178         {
1179                 /* Always advance over newlines */
1180                 if (context_start < context_end && *context_start == '\n')
1181                 {
1182                         context_start++;
1183                         line_start = context_start;
1184                         line_number++;
1185                         continue;
1186                 }
1187                 /* Otherwise, done as soon as we are close enough to context_end */
1188                 if (context_end - context_start < 50)
1189                         break;
1190                 /* Advance to next multibyte character */
1191                 if (IS_HIGHBIT_SET(*context_start))
1192                         context_start += pg_mblen(context_start);
1193                 else
1194                         context_start++;
1195         }
1196
1197         /*
1198          * We add "..." to indicate that the excerpt doesn't start at the
1199          * beginning of the line ... but if we're within 3 characters of the
1200          * beginning of the line, we might as well just show the whole line.
1201          */
1202         if (context_start - line_start <= 3)
1203                 context_start = line_start;
1204
1205         /* Get a null-terminated copy of the data to present */
1206         ctxtlen = context_end - context_start;
1207         ctxt = palloc(ctxtlen + 1);
1208         memcpy(ctxt, context_start, ctxtlen);
1209         ctxt[ctxtlen] = '\0';
1210
1211         /*
1212          * Show the context, prefixing "..." if not starting at start of line, and
1213          * suffixing "..." if not ending at end of line.
1214          */
1215         prefix = (context_start > line_start) ? "..." : "";
1216         suffix = (lex->token_type != JSON_TOKEN_END && context_end - lex->input < lex->input_length && *context_end != '\n' && *context_end != '\r') ? "..." : "";
1217
1218         return errcontext("JSON data, line %d: %s%s%s",
1219                                           line_number, prefix, ctxt, suffix);
1220 }
1221
1222 /*
1223  * Extract a single, possibly multi-byte char from the input string.
1224  */
1225 static char *
1226 extract_mb_char(char *s)
1227 {
1228         char       *res;
1229         int                     len;
1230
1231         len = pg_mblen(s);
1232         res = palloc(len + 1);
1233         memcpy(res, s, len);
1234         res[len] = '\0';
1235
1236         return res;
1237 }
1238
1239 /*
1240  * Determine how we want to print values of a given type in datum_to_json.
1241  *
1242  * Given the datatype OID, return its JsonTypeCategory, as well as the type's
1243  * output function OID.  If the returned category is JSONTYPE_CAST, we
1244  * return the OID of the type->JSON cast function instead.
1245  */
1246 static void
1247 json_categorize_type(Oid typoid,
1248                                          JsonTypeCategory *tcategory,
1249                                          Oid *outfuncoid)
1250 {
1251         bool            typisvarlena;
1252
1253         /* Look through any domain */
1254         typoid = getBaseType(typoid);
1255
1256         /* We'll usually need to return the type output function */
1257         getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
1258
1259         /* Check for known types */
1260         switch (typoid)
1261         {
1262                 case BOOLOID:
1263                         *tcategory = JSONTYPE_BOOL;
1264                         break;
1265
1266                 case INT2OID:
1267                 case INT4OID:
1268                 case INT8OID:
1269                 case FLOAT4OID:
1270                 case FLOAT8OID:
1271                 case NUMERICOID:
1272                         *tcategory = JSONTYPE_NUMERIC;
1273                         break;
1274
1275                 case TIMESTAMPOID:
1276                         *tcategory = JSONTYPE_TIMESTAMP;
1277                         break;
1278
1279                 case TIMESTAMPTZOID:
1280                         *tcategory = JSONTYPE_TIMESTAMPTZ;
1281                         break;
1282
1283                 case JSONOID:
1284                 case JSONBOID:
1285                         *tcategory = JSONTYPE_JSON;
1286                         break;
1287
1288                 default:
1289                         /* Check for arrays and composites */
1290                         if (OidIsValid(get_element_type(typoid)))
1291                                 *tcategory = JSONTYPE_ARRAY;
1292                         else if (type_is_rowtype(typoid))
1293                                 *tcategory = JSONTYPE_COMPOSITE;
1294                         else
1295                         {
1296                                 /* It's probably the general case ... */
1297                                 *tcategory = JSONTYPE_OTHER;
1298                                 /* but let's look for a cast to json, if it's not built-in */
1299                                 if (typoid >= FirstNormalObjectId)
1300                                 {
1301                                         HeapTuple       tuple;
1302
1303                                         tuple = SearchSysCache2(CASTSOURCETARGET,
1304                                                                                         ObjectIdGetDatum(typoid),
1305                                                                                         ObjectIdGetDatum(JSONOID));
1306                                         if (HeapTupleIsValid(tuple))
1307                                         {
1308                                                 Form_pg_cast castForm = (Form_pg_cast) GETSTRUCT(tuple);
1309
1310                                                 if (castForm->castmethod == COERCION_METHOD_FUNCTION)
1311                                                 {
1312                                                         *tcategory = JSONTYPE_CAST;
1313                                                         *outfuncoid = castForm->castfunc;
1314                                                 }
1315
1316                                                 ReleaseSysCache(tuple);
1317                                         }
1318                                 }
1319                         }
1320                         break;
1321         }
1322 }
1323
1324 /*
1325  * Turn a Datum into JSON text, appending the string to "result".
1326  *
1327  * tcategory and outfuncoid are from a previous call to json_categorize_type,
1328  * except that if is_null is true then they can be invalid.
1329  *
1330  * If key_scalar is true, the value is being printed as a key, so insist
1331  * it's of an acceptable type, and force it to be quoted.
1332  */
1333 static void
1334 datum_to_json(Datum val, bool is_null, StringInfo result,
1335                           JsonTypeCategory tcategory, Oid outfuncoid,
1336                           bool key_scalar)
1337 {
1338         char       *outputstr;
1339         text       *jsontext;
1340         bool            numeric_error;
1341         JsonLexContext dummy_lex;
1342
1343         if (is_null)
1344         {
1345                 appendStringInfoString(result, "null");
1346                 return;
1347         }
1348
1349         if (key_scalar &&
1350                 (tcategory == JSONTYPE_ARRAY ||
1351                  tcategory == JSONTYPE_COMPOSITE ||
1352                  tcategory == JSONTYPE_JSON ||
1353                  tcategory == JSONTYPE_CAST))
1354                 ereport(ERROR,
1355                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1356                   errmsg("key value must be scalar, not array, composite or json")));
1357
1358         switch (tcategory)
1359         {
1360                 case JSONTYPE_ARRAY:
1361                         array_to_json_internal(val, result, false);
1362                         break;
1363                 case JSONTYPE_COMPOSITE:
1364                         composite_to_json(val, result, false);
1365                         break;
1366                 case JSONTYPE_BOOL:
1367                         outputstr = DatumGetBool(val) ? "true" : "false";
1368                         if (key_scalar)
1369                                 escape_json(result, outputstr);
1370                         else
1371                                 appendStringInfoString(result, outputstr);
1372                         break;
1373                 case JSONTYPE_NUMERIC:
1374                         outputstr = OidOutputFunctionCall(outfuncoid, val);
1375                         if (key_scalar)
1376                         {
1377                                 /* always quote keys */
1378                                 escape_json(result, outputstr);
1379                         }
1380                         else
1381                         {
1382                                 /*
1383                                  * Don't call escape_json for a non-key if it's a valid JSON
1384                                  * number.
1385                                  */
1386                                 dummy_lex.input = *outputstr == '-' ? outputstr + 1 : outputstr;
1387                                 dummy_lex.input_length = strlen(dummy_lex.input);
1388                                 json_lex_number(&dummy_lex, dummy_lex.input, &numeric_error);
1389                                 if (!numeric_error)
1390                                         appendStringInfoString(result, outputstr);
1391                                 else
1392                                         escape_json(result, outputstr);
1393                         }
1394                         pfree(outputstr);
1395                         break;
1396                 case JSONTYPE_TIMESTAMP:
1397                         /*
1398                          * The timestamp format used here provides for quoting the string,
1399                          * so no escaping is required.
1400                          */
1401                         jsontext = DatumGetTextP(
1402                                 DirectFunctionCall2(timestamp_to_char, val,
1403                                                                         CStringGetTextDatum(TS_ISO8601_FMT)));
1404                         outputstr = text_to_cstring(jsontext);
1405                         appendStringInfoString(result, outputstr);
1406                         pfree(outputstr);
1407                         pfree(jsontext);
1408                         break;
1409                 case JSONTYPE_TIMESTAMPTZ:
1410                         /* same comment as for timestamp above */
1411                         jsontext = DatumGetTextP(
1412                                 DirectFunctionCall2(timestamptz_to_char, val,
1413                                                                         CStringGetTextDatum(TSTZ_ISO8601_FMT)));
1414                         outputstr = text_to_cstring(jsontext);
1415                         appendStringInfoString(result, outputstr);
1416                         pfree(outputstr);
1417                         pfree(jsontext);
1418                         break;
1419                 case JSONTYPE_JSON:
1420                         /* JSON and JSONB output will already be escaped */
1421                         outputstr = OidOutputFunctionCall(outfuncoid, val);
1422                         appendStringInfoString(result, outputstr);
1423                         pfree(outputstr);
1424                         break;
1425                 case JSONTYPE_CAST:
1426                         /* outfuncoid refers to a cast function, not an output function */
1427                         jsontext = DatumGetTextP(OidFunctionCall1(outfuncoid, val));
1428                         outputstr = text_to_cstring(jsontext);
1429                         appendStringInfoString(result, outputstr);
1430                         pfree(outputstr);
1431                         pfree(jsontext);
1432                         break;
1433                 default:
1434                         outputstr = OidOutputFunctionCall(outfuncoid, val);
1435                         if (key_scalar && *outputstr == '\0')
1436                                 ereport(ERROR,
1437                                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1438                                                  errmsg("key value must not be empty")));
1439                         escape_json(result, outputstr);
1440                         pfree(outputstr);
1441                         break;
1442         }
1443 }
1444
1445 /*
1446  * Process a single dimension of an array.
1447  * If it's the innermost dimension, output the values, otherwise call
1448  * ourselves recursively to process the next dimension.
1449  */
1450 static void
1451 array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals,
1452                                   bool *nulls, int *valcount, JsonTypeCategory tcategory,
1453                                   Oid outfuncoid, bool use_line_feeds)
1454 {
1455         int                     i;
1456         const char *sep;
1457
1458         Assert(dim < ndims);
1459
1460         sep = use_line_feeds ? ",\n " : ",";
1461
1462         appendStringInfoChar(result, '[');
1463
1464         for (i = 1; i <= dims[dim]; i++)
1465         {
1466                 if (i > 1)
1467                         appendStringInfoString(result, sep);
1468
1469                 if (dim + 1 == ndims)
1470                 {
1471                         datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
1472                                                   outfuncoid, false);
1473                         (*valcount)++;
1474                 }
1475                 else
1476                 {
1477                         /*
1478                          * Do we want line feeds on inner dimensions of arrays? For now
1479                          * we'll say no.
1480                          */
1481                         array_dim_to_json(result, dim + 1, ndims, dims, vals, nulls,
1482                                                           valcount, tcategory, outfuncoid, false);
1483                 }
1484         }
1485
1486         appendStringInfoChar(result, ']');
1487 }
1488
1489 /*
1490  * Turn an array into JSON.
1491  */
1492 static void
1493 array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
1494 {
1495         ArrayType  *v = DatumGetArrayTypeP(array);
1496         Oid                     element_type = ARR_ELEMTYPE(v);
1497         int                *dim;
1498         int                     ndim;
1499         int                     nitems;
1500         int                     count = 0;
1501         Datum      *elements;
1502         bool       *nulls;
1503         int16           typlen;
1504         bool            typbyval;
1505         char            typalign;
1506         JsonTypeCategory tcategory;
1507         Oid                     outfuncoid;
1508
1509         ndim = ARR_NDIM(v);
1510         dim = ARR_DIMS(v);
1511         nitems = ArrayGetNItems(ndim, dim);
1512
1513         if (nitems <= 0)
1514         {
1515                 appendStringInfoString(result, "[]");
1516                 return;
1517         }
1518
1519         get_typlenbyvalalign(element_type,
1520                                                  &typlen, &typbyval, &typalign);
1521
1522         json_categorize_type(element_type,
1523                                                  &tcategory, &outfuncoid);
1524
1525         deconstruct_array(v, element_type, typlen, typbyval,
1526                                           typalign, &elements, &nulls,
1527                                           &nitems);
1528
1529         array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
1530                                           outfuncoid, use_line_feeds);
1531
1532         pfree(elements);
1533         pfree(nulls);
1534 }
1535
1536 /*
1537  * Turn a composite / record into JSON.
1538  */
1539 static void
1540 composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
1541 {
1542         HeapTupleHeader td;
1543         Oid                     tupType;
1544         int32           tupTypmod;
1545         TupleDesc       tupdesc;
1546         HeapTupleData tmptup,
1547                            *tuple;
1548         int                     i;
1549         bool            needsep = false;
1550         const char *sep;
1551
1552         sep = use_line_feeds ? ",\n " : ",";
1553
1554         td = DatumGetHeapTupleHeader(composite);
1555
1556         /* Extract rowtype info and find a tupdesc */
1557         tupType = HeapTupleHeaderGetTypeId(td);
1558         tupTypmod = HeapTupleHeaderGetTypMod(td);
1559         tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1560
1561         /* Build a temporary HeapTuple control structure */
1562         tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1563         tmptup.t_data = td;
1564         tuple = &tmptup;
1565
1566         appendStringInfoChar(result, '{');
1567
1568         for (i = 0; i < tupdesc->natts; i++)
1569         {
1570                 Datum           val;
1571                 bool            isnull;
1572                 char       *attname;
1573                 JsonTypeCategory tcategory;
1574                 Oid                     outfuncoid;
1575
1576                 if (tupdesc->attrs[i]->attisdropped)
1577                         continue;
1578
1579                 if (needsep)
1580                         appendStringInfoString(result, sep);
1581                 needsep = true;
1582
1583                 attname = NameStr(tupdesc->attrs[i]->attname);
1584                 escape_json(result, attname);
1585                 appendStringInfoChar(result, ':');
1586
1587                 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1588
1589                 if (isnull)
1590                 {
1591                         tcategory = JSONTYPE_NULL;
1592                         outfuncoid = InvalidOid;
1593                 }
1594                 else
1595                         json_categorize_type(tupdesc->attrs[i]->atttypid,
1596                                                                  &tcategory, &outfuncoid);
1597
1598                 datum_to_json(val, isnull, result, tcategory, outfuncoid, false);
1599         }
1600
1601         appendStringInfoChar(result, '}');
1602         ReleaseTupleDesc(tupdesc);
1603 }
1604
1605 /*
1606  * Append JSON text for "val" to "result".
1607  *
1608  * This is just a thin wrapper around datum_to_json.  If the same type will be
1609  * printed many times, avoid using this; better to do the json_categorize_type
1610  * lookups only once.
1611  */
1612 static void
1613 add_json(Datum val, bool is_null, StringInfo result,
1614                  Oid val_type, bool key_scalar)
1615 {
1616         JsonTypeCategory tcategory;
1617         Oid                     outfuncoid;
1618
1619         if (val_type == InvalidOid)
1620                 ereport(ERROR,
1621                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1622                                  errmsg("could not determine input data type")));
1623
1624         if (is_null)
1625         {
1626                 tcategory = JSONTYPE_NULL;
1627                 outfuncoid = InvalidOid;
1628         }
1629         else
1630                 json_categorize_type(val_type,
1631                                                          &tcategory, &outfuncoid);
1632
1633         datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
1634 }
1635
1636 /*
1637  * SQL function array_to_json(row)
1638  */
1639 extern Datum
1640 array_to_json(PG_FUNCTION_ARGS)
1641 {
1642         Datum           array = PG_GETARG_DATUM(0);
1643         StringInfo      result;
1644
1645         result = makeStringInfo();
1646
1647         array_to_json_internal(array, result, false);
1648
1649         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1650 }
1651
1652 /*
1653  * SQL function array_to_json(row, prettybool)
1654  */
1655 extern Datum
1656 array_to_json_pretty(PG_FUNCTION_ARGS)
1657 {
1658         Datum           array = PG_GETARG_DATUM(0);
1659         bool            use_line_feeds = PG_GETARG_BOOL(1);
1660         StringInfo      result;
1661
1662         result = makeStringInfo();
1663
1664         array_to_json_internal(array, result, use_line_feeds);
1665
1666         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1667 }
1668
1669 /*
1670  * SQL function row_to_json(row)
1671  */
1672 extern Datum
1673 row_to_json(PG_FUNCTION_ARGS)
1674 {
1675         Datum           array = PG_GETARG_DATUM(0);
1676         StringInfo      result;
1677
1678         result = makeStringInfo();
1679
1680         composite_to_json(array, result, false);
1681
1682         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1683 }
1684
1685 /*
1686  * SQL function row_to_json(row, prettybool)
1687  */
1688 extern Datum
1689 row_to_json_pretty(PG_FUNCTION_ARGS)
1690 {
1691         Datum           array = PG_GETARG_DATUM(0);
1692         bool            use_line_feeds = PG_GETARG_BOOL(1);
1693         StringInfo      result;
1694
1695         result = makeStringInfo();
1696
1697         composite_to_json(array, result, use_line_feeds);
1698
1699         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1700 }
1701
1702 /*
1703  * SQL function to_json(anyvalue)
1704  */
1705 Datum
1706 to_json(PG_FUNCTION_ARGS)
1707 {
1708         Datum           val = PG_GETARG_DATUM(0);
1709         Oid                     val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1710         StringInfo      result;
1711         JsonTypeCategory tcategory;
1712         Oid                     outfuncoid;
1713
1714         if (val_type == InvalidOid)
1715                 ereport(ERROR,
1716                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1717                                  errmsg("could not determine input data type")));
1718
1719         json_categorize_type(val_type,
1720                                                  &tcategory, &outfuncoid);
1721
1722         result = makeStringInfo();
1723
1724         datum_to_json(val, false, result, tcategory, outfuncoid, false);
1725
1726         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
1727 }
1728
1729 /*
1730  * json_agg transition function
1731  */
1732 Datum
1733 json_agg_transfn(PG_FUNCTION_ARGS)
1734 {
1735         Oid                     val_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1736         MemoryContext aggcontext,
1737                                 oldcontext;
1738         StringInfo      state;
1739         Datum           val;
1740         JsonTypeCategory tcategory;
1741         Oid                     outfuncoid;
1742
1743         if (val_type == InvalidOid)
1744                 ereport(ERROR,
1745                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1746                                  errmsg("could not determine input data type")));
1747
1748         if (!AggCheckCallContext(fcinfo, &aggcontext))
1749         {
1750                 /* cannot be called directly because of internal-type argument */
1751                 elog(ERROR, "json_agg_transfn called in non-aggregate context");
1752         }
1753
1754         if (PG_ARGISNULL(0))
1755         {
1756                 /*
1757                  * Make this StringInfo in a context where it will persist for the
1758                  * duration of the aggregate call.  MemoryContextSwitchTo is only
1759                  * needed the first time, as the StringInfo routines make sure they
1760                  * use the right context to enlarge the object if necessary.
1761                  */
1762                 oldcontext = MemoryContextSwitchTo(aggcontext);
1763                 state = makeStringInfo();
1764                 MemoryContextSwitchTo(oldcontext);
1765
1766                 appendStringInfoChar(state, '[');
1767         }
1768         else
1769         {
1770                 state = (StringInfo) PG_GETARG_POINTER(0);
1771                 appendStringInfoString(state, ", ");
1772         }
1773
1774         /* fast path for NULLs */
1775         if (PG_ARGISNULL(1))
1776         {
1777                 datum_to_json((Datum) 0, true, state, JSONTYPE_NULL, InvalidOid, false);
1778                 PG_RETURN_POINTER(state);
1779         }
1780
1781         val = PG_GETARG_DATUM(1);
1782
1783         /* XXX we do this every time?? */
1784         json_categorize_type(val_type,
1785                                                  &tcategory, &outfuncoid);
1786
1787         /* add some whitespace if structured type and not first item */
1788         if (!PG_ARGISNULL(0) &&
1789                 (tcategory == JSONTYPE_ARRAY || tcategory == JSONTYPE_COMPOSITE))
1790         {
1791                 appendStringInfoString(state, "\n ");
1792         }
1793
1794         datum_to_json(val, false, state, tcategory, outfuncoid, false);
1795
1796         /*
1797          * The transition type for array_agg() is declared to be "internal", which
1798          * is a pass-by-value type the same size as a pointer.  So we can safely
1799          * pass the ArrayBuildState pointer through nodeAgg.c's machinations.
1800          */
1801         PG_RETURN_POINTER(state);
1802 }
1803
1804 /*
1805  * json_agg final function
1806  */
1807 Datum
1808 json_agg_finalfn(PG_FUNCTION_ARGS)
1809 {
1810         StringInfo      state;
1811
1812         /* cannot be called directly because of internal-type argument */
1813         Assert(AggCheckCallContext(fcinfo, NULL));
1814
1815         state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
1816
1817         if (state == NULL)
1818                 PG_RETURN_NULL();
1819
1820         appendStringInfoChar(state, ']');
1821
1822         PG_RETURN_TEXT_P(cstring_to_text_with_len(state->data, state->len));
1823 }
1824
1825 /*
1826  * json_object_agg transition function.
1827  *
1828  * aggregate two input columns as a single json value.
1829  */
1830 Datum
1831 json_object_agg_transfn(PG_FUNCTION_ARGS)
1832 {
1833         Oid                     val_type;
1834         MemoryContext aggcontext,
1835                                 oldcontext;
1836         StringInfo      state;
1837         Datum           arg;
1838
1839         if (!AggCheckCallContext(fcinfo, &aggcontext))
1840         {
1841                 /* cannot be called directly because of internal-type argument */
1842                 elog(ERROR, "json_agg_transfn called in non-aggregate context");
1843         }
1844
1845         if (PG_ARGISNULL(0))
1846         {
1847                 /*
1848                  * Make this StringInfo in a context where it will persist for the
1849                  * duration off the aggregate call. It's only needed for this initial
1850                  * piece, as the StringInfo routines make sure they use the right
1851                  * context to enlarge the object if necessary.
1852                  */
1853                 oldcontext = MemoryContextSwitchTo(aggcontext);
1854                 state = makeStringInfo();
1855                 MemoryContextSwitchTo(oldcontext);
1856
1857                 appendStringInfoString(state, "{ ");
1858         }
1859         else
1860         {
1861                 state = (StringInfo) PG_GETARG_POINTER(0);
1862                 appendStringInfoString(state, ", ");
1863         }
1864
1865         if (PG_ARGISNULL(1))
1866                 ereport(ERROR,
1867                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1868                                  errmsg("field name must not be null")));
1869
1870
1871         val_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1872
1873         /*
1874          * turn a constant (more or less literal) value that's of unknown type
1875          * into text. Unknowns come in as a cstring pointer.
1876          */
1877         if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, 1))
1878         {
1879                 val_type = TEXTOID;
1880                 arg = CStringGetTextDatum(PG_GETARG_POINTER(1));
1881         }
1882         else
1883         {
1884                 arg = PG_GETARG_DATUM(1);
1885         }
1886
1887         if (val_type == InvalidOid || val_type == UNKNOWNOID)
1888                 ereport(ERROR,
1889                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1890                                  errmsg("arg 1: could not determine data type")));
1891
1892         add_json(arg, false, state, val_type, true);
1893
1894         appendStringInfoString(state, " : ");
1895
1896         val_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1897         /* see comments above */
1898         if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, 2))
1899         {
1900                 val_type = TEXTOID;
1901                 if (PG_ARGISNULL(2))
1902                         arg = (Datum) 0;
1903                 else
1904                         arg = CStringGetTextDatum(PG_GETARG_POINTER(2));
1905         }
1906         else
1907         {
1908                 arg = PG_GETARG_DATUM(2);
1909         }
1910
1911         if (val_type == InvalidOid || val_type == UNKNOWNOID)
1912                 ereport(ERROR,
1913                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1914                                  errmsg("arg 2: could not determine data type")));
1915
1916         add_json(arg, PG_ARGISNULL(2), state, val_type, false);
1917
1918         PG_RETURN_POINTER(state);
1919 }
1920
1921 /*
1922  * json_object_agg final function.
1923  *
1924  */
1925 Datum
1926 json_object_agg_finalfn(PG_FUNCTION_ARGS)
1927 {
1928         StringInfo      state;
1929
1930         /* cannot be called directly because of internal-type argument */
1931         Assert(AggCheckCallContext(fcinfo, NULL));
1932
1933         state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
1934
1935         if (state == NULL)
1936                 PG_RETURN_TEXT_P(cstring_to_text("{}"));
1937
1938         appendStringInfoString(state, " }");
1939
1940         PG_RETURN_TEXT_P(cstring_to_text_with_len(state->data, state->len));
1941 }
1942
1943 /*
1944  * SQL function json_build_object(variadic "any")
1945  */
1946 Datum
1947 json_build_object(PG_FUNCTION_ARGS)
1948 {
1949         int                     nargs = PG_NARGS();
1950         int                     i;
1951         Datum           arg;
1952         char       *sep = "";
1953         StringInfo      result;
1954         Oid                     val_type;
1955
1956
1957         if (nargs % 2 != 0)
1958                 ereport(ERROR,
1959                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1960                                  errmsg("invalid number or arguments: object must be matched key value pairs")));
1961
1962         result = makeStringInfo();
1963
1964         appendStringInfoChar(result, '{');
1965
1966         for (i = 0; i < nargs; i += 2)
1967         {
1968
1969                 /* process key */
1970
1971                 if (PG_ARGISNULL(i))
1972                         ereport(ERROR,
1973                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1974                                          errmsg("arg %d: key cannot be null", i + 1)));
1975                 val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
1976
1977                 /*
1978                  * turn a constant (more or less literal) value that's of unknown type
1979                  * into text. Unknowns come in as a cstring pointer.
1980                  */
1981                 if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
1982                 {
1983                         val_type = TEXTOID;
1984                         if (PG_ARGISNULL(i))
1985                                 arg = (Datum) 0;
1986                         else
1987                                 arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
1988                 }
1989                 else
1990                 {
1991                         arg = PG_GETARG_DATUM(i);
1992                 }
1993                 if (val_type == InvalidOid || val_type == UNKNOWNOID)
1994                         ereport(ERROR,
1995                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1996                                          errmsg("arg %d: could not determine data type", i + 1)));
1997                 appendStringInfoString(result, sep);
1998                 sep = ", ";
1999                 add_json(arg, false, result, val_type, true);
2000
2001                 appendStringInfoString(result, " : ");
2002
2003                 /* process value */
2004
2005                 val_type = get_fn_expr_argtype(fcinfo->flinfo, i + 1);
2006                 /* see comments above */
2007                 if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i + 1))
2008                 {
2009                         val_type = TEXTOID;
2010                         if (PG_ARGISNULL(i + 1))
2011                                 arg = (Datum) 0;
2012                         else
2013                                 arg = CStringGetTextDatum(PG_GETARG_POINTER(i + 1));
2014                 }
2015                 else
2016                 {
2017                         arg = PG_GETARG_DATUM(i + 1);
2018                 }
2019                 if (val_type == InvalidOid || val_type == UNKNOWNOID)
2020                         ereport(ERROR,
2021                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2022                                          errmsg("arg %d: could not determine data type", i + 2)));
2023                 add_json(arg, PG_ARGISNULL(i + 1), result, val_type, false);
2024
2025         }
2026         appendStringInfoChar(result, '}');
2027
2028         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
2029
2030 }
2031
2032 /*
2033  * degenerate case of json_build_object where it gets 0 arguments.
2034  */
2035 Datum
2036 json_build_object_noargs(PG_FUNCTION_ARGS)
2037 {
2038         PG_RETURN_TEXT_P(cstring_to_text_with_len("{}", 2));
2039 }
2040
2041 /*
2042  * SQL function json_build_array(variadic "any")
2043  */
2044 Datum
2045 json_build_array(PG_FUNCTION_ARGS)
2046 {
2047         int                     nargs = PG_NARGS();
2048         int                     i;
2049         Datum           arg;
2050         char       *sep = "";
2051         StringInfo      result;
2052         Oid                     val_type;
2053
2054
2055         result = makeStringInfo();
2056
2057         appendStringInfoChar(result, '[');
2058
2059         for (i = 0; i < nargs; i++)
2060         {
2061                 val_type = get_fn_expr_argtype(fcinfo->flinfo, i);
2062                 arg = PG_GETARG_DATUM(i + 1);
2063                 /* see comments in json_build_object above */
2064                 if (val_type == UNKNOWNOID && get_fn_expr_arg_stable(fcinfo->flinfo, i))
2065                 {
2066                         val_type = TEXTOID;
2067                         if (PG_ARGISNULL(i))
2068                                 arg = (Datum) 0;
2069                         else
2070                                 arg = CStringGetTextDatum(PG_GETARG_POINTER(i));
2071                 }
2072                 else
2073                 {
2074                         arg = PG_GETARG_DATUM(i);
2075                 }
2076                 if (val_type == InvalidOid || val_type == UNKNOWNOID)
2077                         ereport(ERROR,
2078                                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2079                                          errmsg("arg %d: could not determine data type", i + 1)));
2080                 appendStringInfoString(result, sep);
2081                 sep = ", ";
2082                 add_json(arg, PG_ARGISNULL(i), result, val_type, false);
2083         }
2084         appendStringInfoChar(result, ']');
2085
2086         PG_RETURN_TEXT_P(cstring_to_text_with_len(result->data, result->len));
2087
2088 }
2089
2090 /*
2091  * degenerate case of json_build_array where it gets 0 arguments.
2092  */
2093 Datum
2094 json_build_array_noargs(PG_FUNCTION_ARGS)
2095 {
2096         PG_RETURN_TEXT_P(cstring_to_text_with_len("[]", 2));
2097 }
2098
2099 /*
2100  * SQL function json_object(text[])
2101  *
2102  * take a one or two dimensional array of text as name vale pairs
2103  * for a json object.
2104  *
2105  */
2106 Datum
2107 json_object(PG_FUNCTION_ARGS)
2108 {
2109         ArrayType  *in_array = PG_GETARG_ARRAYTYPE_P(0);
2110         int                     ndims = ARR_NDIM(in_array);
2111         StringInfoData result;
2112         Datum      *in_datums;
2113         bool       *in_nulls;
2114         int                     in_count,
2115                                 count,
2116                                 i;
2117         text       *rval;
2118         char       *v;
2119
2120         switch (ndims)
2121         {
2122                 case 0:
2123                         PG_RETURN_DATUM(CStringGetTextDatum("{}"));
2124                         break;
2125
2126                 case 1:
2127                         if ((ARR_DIMS(in_array)[0]) % 2)
2128                                 ereport(ERROR,
2129                                                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2130                                                  errmsg("array must have even number of elements")));
2131                         break;
2132
2133                 case 2:
2134                         if ((ARR_DIMS(in_array)[1]) != 2)
2135                                 ereport(ERROR,
2136                                                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2137                                                  errmsg("array must have two columns")));
2138                         break;
2139
2140                 default:
2141                         ereport(ERROR,
2142                                         (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2143                                          errmsg("wrong number of array subscripts")));
2144         }
2145
2146         deconstruct_array(in_array,
2147                                           TEXTOID, -1, false, 'i',
2148                                           &in_datums, &in_nulls, &in_count);
2149
2150         count = in_count / 2;
2151
2152         initStringInfo(&result);
2153
2154         appendStringInfoChar(&result, '{');
2155
2156         for (i = 0; i < count; ++i)
2157         {
2158                 if (in_nulls[i * 2])
2159                         ereport(ERROR,
2160                                         (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2161                                          errmsg("null value not allowed for object key")));
2162
2163                 v = TextDatumGetCString(in_datums[i * 2]);
2164                 if (v[0] == '\0')
2165                         ereport(ERROR,
2166                                         (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2167                                          errmsg("empty value not allowed for object key")));
2168                 if (i > 0)
2169                         appendStringInfoString(&result, ", ");
2170                 escape_json(&result, v);
2171                 appendStringInfoString(&result, " : ");
2172                 pfree(v);
2173                 if (in_nulls[i * 2 + 1])
2174                         appendStringInfoString(&result, "null");
2175                 else
2176                 {
2177                         v = TextDatumGetCString(in_datums[i * 2 + 1]);
2178                         escape_json(&result, v);
2179                         pfree(v);
2180                 }
2181         }
2182
2183         appendStringInfoChar(&result, '}');
2184
2185         pfree(in_datums);
2186         pfree(in_nulls);
2187
2188         rval = cstring_to_text_with_len(result.data, result.len);
2189         pfree(result.data);
2190
2191         PG_RETURN_TEXT_P(rval);
2192
2193 }
2194
2195 /*
2196  * SQL function json_object(text[], text[])
2197  *
2198  * take separate name and value arrays of text to construct a json object
2199  * pairwise.
2200  */
2201 Datum
2202 json_object_two_arg(PG_FUNCTION_ARGS)
2203 {
2204         ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(0);
2205         ArrayType  *val_array = PG_GETARG_ARRAYTYPE_P(1);
2206         int                     nkdims = ARR_NDIM(key_array);
2207         int                     nvdims = ARR_NDIM(val_array);
2208         StringInfoData result;
2209         Datum      *key_datums,
2210                            *val_datums;
2211         bool       *key_nulls,
2212                            *val_nulls;
2213         int                     key_count,
2214                                 val_count,
2215                                 i;
2216         text       *rval;
2217         char       *v;
2218
2219         if (nkdims > 1 || nkdims != nvdims)
2220                 ereport(ERROR,
2221                                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2222                                  errmsg("wrong number of array subscripts")));
2223
2224         if (nkdims == 0)
2225                 PG_RETURN_DATUM(CStringGetTextDatum("{}"));
2226
2227         deconstruct_array(key_array,
2228                                           TEXTOID, -1, false, 'i',
2229                                           &key_datums, &key_nulls, &key_count);
2230
2231         deconstruct_array(val_array,
2232                                           TEXTOID, -1, false, 'i',
2233                                           &val_datums, &val_nulls, &val_count);
2234
2235         if (key_count != val_count)
2236                 ereport(ERROR,
2237                                 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
2238                                  errmsg("mismatched array dimensions")));
2239
2240         initStringInfo(&result);
2241
2242         appendStringInfoChar(&result, '{');
2243
2244         for (i = 0; i < key_count; ++i)
2245         {
2246                 if (key_nulls[i])
2247                         ereport(ERROR,
2248                                         (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2249                                          errmsg("null value not allowed for object key")));
2250
2251                 v = TextDatumGetCString(key_datums[i]);
2252                 if (v[0] == '\0')
2253                         ereport(ERROR,
2254                                         (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
2255                                          errmsg("empty value not allowed for object key")));
2256                 if (i > 0)
2257                         appendStringInfoString(&result, ", ");
2258                 escape_json(&result, v);
2259                 appendStringInfoString(&result, " : ");
2260                 pfree(v);
2261                 if (val_nulls[i])
2262                         appendStringInfoString(&result, "null");
2263                 else
2264                 {
2265                         v = TextDatumGetCString(val_datums[i]);
2266                         escape_json(&result, v);
2267                         pfree(v);
2268                 }
2269         }
2270
2271         appendStringInfoChar(&result, '}');
2272
2273         pfree(key_datums);
2274         pfree(key_nulls);
2275         pfree(val_datums);
2276         pfree(val_nulls);
2277
2278         rval = cstring_to_text_with_len(result.data, result.len);
2279         pfree(result.data);
2280
2281         PG_RETURN_TEXT_P(rval);
2282
2283 }
2284
2285
2286 /*
2287  * Produce a JSON string literal, properly escaping characters in the text.
2288  */
2289 void
2290 escape_json(StringInfo buf, const char *str)
2291 {
2292         const char *p;
2293
2294         appendStringInfoCharMacro(buf, '\"');
2295         for (p = str; *p; p++)
2296         {
2297                 switch (*p)
2298                 {
2299                         case '\b':
2300                                 appendStringInfoString(buf, "\\b");
2301                                 break;
2302                         case '\f':
2303                                 appendStringInfoString(buf, "\\f");
2304                                 break;
2305                         case '\n':
2306                                 appendStringInfoString(buf, "\\n");
2307                                 break;
2308                         case '\r':
2309                                 appendStringInfoString(buf, "\\r");
2310                                 break;
2311                         case '\t':
2312                                 appendStringInfoString(buf, "\\t");
2313                                 break;
2314                         case '"':
2315                                 appendStringInfoString(buf, "\\\"");
2316                                 break;
2317                         case '\\':
2318                                 /*
2319                                  * Unicode escapes are passed through as is. There is no
2320                                  * requirement that they denote a valid character in the
2321                                  * server encoding - indeed that is a big part of their
2322                                  * usefulness.
2323                                  *
2324                                  * All we require is that they consist of \uXXXX where
2325                                  * the Xs are hexadecimal digits. It is the responsibility
2326                                  * of the caller of, say, to_json() to make sure that the
2327                                  * unicode escape is valid.
2328                                  *
2329                                  * In the case of a jsonb string value being escaped, the
2330                                  * only unicode escape that should be present is \u0000,
2331                                  * all the other unicode escapes will have been resolved.
2332                                  */
2333                                 if (p[1] == 'u' && isxdigit(p[2]) && isxdigit(p[3])
2334                                         && isxdigit(p[4]) && isxdigit(p[5]))
2335                                         appendStringInfoCharMacro(buf, *p);
2336                                 else
2337                                         appendStringInfoString(buf, "\\\\");
2338                                 break;
2339                         default:
2340                                 if ((unsigned char) *p < ' ')
2341                                         appendStringInfo(buf, "\\u%04x", (int) *p);
2342                                 else
2343                                         appendStringInfoCharMacro(buf, *p);
2344                                 break;
2345                 }
2346         }
2347         appendStringInfoCharMacro(buf, '\"');
2348 }
2349
2350 /*
2351  * SQL function json_typeof(json) -> text
2352  *
2353  * Returns the type of the outermost JSON value as TEXT.  Possible types are
2354  * "object", "array", "string", "number", "boolean", and "null".
2355  *
2356  * Performs a single call to json_lex() to get the first token of the supplied
2357  * value.  This initial token uniquely determines the value's type.  As our
2358  * input must already have been validated by json_in() or json_recv(), the
2359  * initial token should never be JSON_TOKEN_OBJECT_END, JSON_TOKEN_ARRAY_END,
2360  * JSON_TOKEN_COLON, JSON_TOKEN_COMMA, or JSON_TOKEN_END.
2361  */
2362 Datum
2363 json_typeof(PG_FUNCTION_ARGS)
2364 {
2365         text       *json;
2366
2367         JsonLexContext *lex;
2368         JsonTokenType tok;
2369         char       *type;
2370
2371         json = PG_GETARG_TEXT_P(0);
2372         lex = makeJsonLexContext(json, false);
2373
2374         /* Lex exactly one token from the input and check its type. */
2375         json_lex(lex);
2376         tok = lex_peek(lex);
2377         switch (tok)
2378         {
2379                 case JSON_TOKEN_OBJECT_START:
2380                         type = "object";
2381                         break;
2382                 case JSON_TOKEN_ARRAY_START:
2383                         type = "array";
2384                         break;
2385                 case JSON_TOKEN_STRING:
2386                         type = "string";
2387                         break;
2388                 case JSON_TOKEN_NUMBER:
2389                         type = "number";
2390                         break;
2391                 case JSON_TOKEN_TRUE:
2392                 case JSON_TOKEN_FALSE:
2393                         type = "boolean";
2394                         break;
2395                 case JSON_TOKEN_NULL:
2396                         type = "null";
2397                         break;
2398                 default:
2399                         elog(ERROR, "unexpected json token: %d", tok);
2400         }
2401
2402         PG_RETURN_TEXT_P(cstring_to_text(type));
2403 }