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