PostgreSQL Source Code  git master
json.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * json.c
4  * JSON data type support.
5  *
6  * Portions Copyright (c) 1996-2023, 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 "catalog/pg_proc.h"
17 #include "catalog/pg_type.h"
18 #include "common/hashfn.h"
19 #include "funcapi.h"
20 #include "libpq/pqformat.h"
21 #include "miscadmin.h"
22 #include "utils/array.h"
23 #include "utils/builtins.h"
24 #include "utils/date.h"
25 #include "utils/datetime.h"
26 #include "utils/json.h"
27 #include "utils/jsonfuncs.h"
28 #include "utils/lsyscache.h"
29 #include "utils/typcache.h"
30 
31 
32 /*
33  * Support for fast key uniqueness checking.
34  *
35  * We maintain a hash table of used keys in JSON objects for fast detection
36  * of duplicates.
37  */
38 /* Common context for key uniqueness check */
39 typedef struct HTAB *JsonUniqueCheckState; /* hash table for key names */
40 
41 /* Hash entry for JsonUniqueCheckState */
42 typedef struct JsonUniqueHashEntry
43 {
44  const char *key;
45  int key_len;
46  int object_id;
48 
49 /* Stack element for key uniqueness check during JSON parsing */
50 typedef struct JsonUniqueStackEntry
51 {
53  int object_id;
55 
56 /* Context struct for key uniqueness check during JSON parsing */
57 typedef struct JsonUniqueParsingState
58 {
63  bool unique;
65 
66 /* Context struct for key uniqueness check during JSON building */
67 typedef struct JsonUniqueBuilderState
68 {
69  JsonUniqueCheckState check; /* unique check */
70  StringInfoData skipped_keys; /* skipped keys with NULL values */
71  MemoryContext mcxt; /* context for saving skipped keys */
73 
74 
75 /* State struct for JSON aggregation */
76 typedef struct JsonAggState
77 {
85 
86 static void composite_to_json(Datum composite, StringInfo result,
87  bool use_line_feeds);
88 static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims,
89  Datum *vals, bool *nulls, int *valcount,
90  JsonTypeCategory tcategory, Oid outfuncoid,
91  bool use_line_feeds);
92 static void array_to_json_internal(Datum array, StringInfo result,
93  bool use_line_feeds);
94 static void datum_to_json_internal(Datum val, bool is_null, StringInfo result,
95  JsonTypeCategory tcategory, Oid outfuncoid,
96  bool key_scalar);
97 static void add_json(Datum val, bool is_null, StringInfo result,
98  Oid val_type, bool key_scalar);
99 static text *catenate_stringinfo_string(StringInfo buffer, const char *addon);
100 
101 /*
102  * Input.
103  */
104 Datum
106 {
107  char *json = PG_GETARG_CSTRING(0);
108  text *result = cstring_to_text(json);
109  JsonLexContext lex;
110 
111  /* validate it */
112  makeJsonLexContext(&lex, result, false);
113  if (!pg_parse_json_or_errsave(&lex, &nullSemAction, fcinfo->context))
114  PG_RETURN_NULL();
115 
116  /* Internal representation is the same as text */
117  PG_RETURN_TEXT_P(result);
118 }
119 
120 /*
121  * Output.
122  */
123 Datum
125 {
126  /* we needn't detoast because text_to_cstring will handle that */
127  Datum txt = PG_GETARG_DATUM(0);
128 
130 }
131 
132 /*
133  * Binary send.
134  */
135 Datum
137 {
138  text *t = PG_GETARG_TEXT_PP(0);
140 
144 }
145 
146 /*
147  * Binary receive.
148  */
149 Datum
151 {
153  char *str;
154  int nbytes;
155  JsonLexContext lex;
156 
157  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
158 
159  /* Validate it. */
161  false);
163 
165 }
166 
167 /*
168  * Turn a Datum into JSON text, appending the string to "result".
169  *
170  * tcategory and outfuncoid are from a previous call to json_categorize_type,
171  * except that if is_null is true then they can be invalid.
172  *
173  * If key_scalar is true, the value is being printed as a key, so insist
174  * it's of an acceptable type, and force it to be quoted.
175  */
176 static void
178  JsonTypeCategory tcategory, Oid outfuncoid,
179  bool key_scalar)
180 {
181  char *outputstr;
182  text *jsontext;
183 
185 
186  /* callers are expected to ensure that null keys are not passed in */
187  Assert(!(key_scalar && is_null));
188 
189  if (is_null)
190  {
191  appendStringInfoString(result, "null");
192  return;
193  }
194 
195  if (key_scalar &&
196  (tcategory == JSONTYPE_ARRAY ||
197  tcategory == JSONTYPE_COMPOSITE ||
198  tcategory == JSONTYPE_JSON ||
199  tcategory == JSONTYPE_CAST))
200  ereport(ERROR,
201  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
202  errmsg("key value must be scalar, not array, composite, or json")));
203 
204  switch (tcategory)
205  {
206  case JSONTYPE_ARRAY:
207  array_to_json_internal(val, result, false);
208  break;
209  case JSONTYPE_COMPOSITE:
210  composite_to_json(val, result, false);
211  break;
212  case JSONTYPE_BOOL:
213  outputstr = DatumGetBool(val) ? "true" : "false";
214  if (key_scalar)
215  escape_json(result, outputstr);
216  else
217  appendStringInfoString(result, outputstr);
218  break;
219  case JSONTYPE_NUMERIC:
220  outputstr = OidOutputFunctionCall(outfuncoid, val);
221 
222  /*
223  * Don't call escape_json for a non-key if it's a valid JSON
224  * number.
225  */
226  if (!key_scalar && IsValidJsonNumber(outputstr, strlen(outputstr)))
227  appendStringInfoString(result, outputstr);
228  else
229  escape_json(result, outputstr);
230  pfree(outputstr);
231  break;
232  case JSONTYPE_DATE:
233  {
234  char buf[MAXDATELEN + 1];
235 
236  JsonEncodeDateTime(buf, val, DATEOID, NULL);
237  appendStringInfo(result, "\"%s\"", buf);
238  }
239  break;
240  case JSONTYPE_TIMESTAMP:
241  {
242  char buf[MAXDATELEN + 1];
243 
244  JsonEncodeDateTime(buf, val, TIMESTAMPOID, NULL);
245  appendStringInfo(result, "\"%s\"", buf);
246  }
247  break;
249  {
250  char buf[MAXDATELEN + 1];
251 
252  JsonEncodeDateTime(buf, val, TIMESTAMPTZOID, NULL);
253  appendStringInfo(result, "\"%s\"", buf);
254  }
255  break;
256  case JSONTYPE_JSON:
257  /* JSON and JSONB output will already be escaped */
258  outputstr = OidOutputFunctionCall(outfuncoid, val);
259  appendStringInfoString(result, outputstr);
260  pfree(outputstr);
261  break;
262  case JSONTYPE_CAST:
263  /* outfuncoid refers to a cast function, not an output function */
264  jsontext = DatumGetTextPP(OidFunctionCall1(outfuncoid, val));
265  outputstr = text_to_cstring(jsontext);
266  appendStringInfoString(result, outputstr);
267  pfree(outputstr);
268  pfree(jsontext);
269  break;
270  default:
271  outputstr = OidOutputFunctionCall(outfuncoid, val);
272  escape_json(result, outputstr);
273  pfree(outputstr);
274  break;
275  }
276 }
277 
278 /*
279  * Encode 'value' of datetime type 'typid' into JSON string in ISO format using
280  * optionally preallocated buffer 'buf'. Optional 'tzp' determines time-zone
281  * offset (in seconds) in which we want to show timestamptz.
282  */
283 char *
284 JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
285 {
286  if (!buf)
287  buf = palloc(MAXDATELEN + 1);
288 
289  switch (typid)
290  {
291  case DATEOID:
292  {
293  DateADT date;
294  struct pg_tm tm;
295 
297 
298  /* Same as date_out(), but forcing DateStyle */
299  if (DATE_NOT_FINITE(date))
301  else
302  {
304  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
306  }
307  }
308  break;
309  case TIMEOID:
310  {
311  TimeADT time = DatumGetTimeADT(value);
312  struct pg_tm tt,
313  *tm = &tt;
314  fsec_t fsec;
315 
316  /* Same as time_out(), but forcing DateStyle */
317  time2tm(time, tm, &fsec);
318  EncodeTimeOnly(tm, fsec, false, 0, USE_XSD_DATES, buf);
319  }
320  break;
321  case TIMETZOID:
322  {
324  struct pg_tm tt,
325  *tm = &tt;
326  fsec_t fsec;
327  int tz;
328 
329  /* Same as timetz_out(), but forcing DateStyle */
330  timetz2tm(time, tm, &fsec, &tz);
331  EncodeTimeOnly(tm, fsec, true, tz, USE_XSD_DATES, buf);
332  }
333  break;
334  case TIMESTAMPOID:
335  {
337  struct pg_tm tm;
338  fsec_t fsec;
339 
341  /* Same as timestamp_out(), but forcing DateStyle */
344  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
345  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
346  else
347  ereport(ERROR,
348  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
349  errmsg("timestamp out of range")));
350  }
351  break;
352  case TIMESTAMPTZOID:
353  {
355  struct pg_tm tm;
356  int tz;
357  fsec_t fsec;
358  const char *tzn = NULL;
359 
361 
362  /*
363  * If a time zone is specified, we apply the time-zone shift,
364  * convert timestamptz to pg_tm as if it were without a time
365  * zone, and then use the specified time zone for converting
366  * the timestamp into a string.
367  */
368  if (tzp)
369  {
370  tz = *tzp;
372  }
373 
374  /* Same as timestamptz_out(), but forcing DateStyle */
377  else if (timestamp2tm(timestamp, tzp ? NULL : &tz, &tm, &fsec,
378  tzp ? NULL : &tzn, NULL) == 0)
379  {
380  if (tzp)
381  tm.tm_isdst = 1; /* set time-zone presence flag */
382 
383  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
384  }
385  else
386  ereport(ERROR,
387  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
388  errmsg("timestamp out of range")));
389  }
390  break;
391  default:
392  elog(ERROR, "unknown jsonb value datetime type oid %u", typid);
393  return NULL;
394  }
395 
396  return buf;
397 }
398 
399 /*
400  * Process a single dimension of an array.
401  * If it's the innermost dimension, output the values, otherwise call
402  * ourselves recursively to process the next dimension.
403  */
404 static void
405 array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals,
406  bool *nulls, int *valcount, JsonTypeCategory tcategory,
407  Oid outfuncoid, bool use_line_feeds)
408 {
409  int i;
410  const char *sep;
411 
412  Assert(dim < ndims);
413 
414  sep = use_line_feeds ? ",\n " : ",";
415 
416  appendStringInfoChar(result, '[');
417 
418  for (i = 1; i <= dims[dim]; i++)
419  {
420  if (i > 1)
421  appendStringInfoString(result, sep);
422 
423  if (dim + 1 == ndims)
424  {
425  datum_to_json_internal(vals[*valcount], nulls[*valcount],
426  result, tcategory,
427  outfuncoid, false);
428  (*valcount)++;
429  }
430  else
431  {
432  /*
433  * Do we want line feeds on inner dimensions of arrays? For now
434  * we'll say no.
435  */
436  array_dim_to_json(result, dim + 1, ndims, dims, vals, nulls,
437  valcount, tcategory, outfuncoid, false);
438  }
439  }
440 
441  appendStringInfoChar(result, ']');
442 }
443 
444 /*
445  * Turn an array into JSON.
446  */
447 static void
448 array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
449 {
450  ArrayType *v = DatumGetArrayTypeP(array);
451  Oid element_type = ARR_ELEMTYPE(v);
452  int *dim;
453  int ndim;
454  int nitems;
455  int count = 0;
456  Datum *elements;
457  bool *nulls;
458  int16 typlen;
459  bool typbyval;
460  char typalign;
461  JsonTypeCategory tcategory;
462  Oid outfuncoid;
463 
464  ndim = ARR_NDIM(v);
465  dim = ARR_DIMS(v);
466  nitems = ArrayGetNItems(ndim, dim);
467 
468  if (nitems <= 0)
469  {
470  appendStringInfoString(result, "[]");
471  return;
472  }
473 
474  get_typlenbyvalalign(element_type,
475  &typlen, &typbyval, &typalign);
476 
477  json_categorize_type(element_type, false,
478  &tcategory, &outfuncoid);
479 
480  deconstruct_array(v, element_type, typlen, typbyval,
481  typalign, &elements, &nulls,
482  &nitems);
483 
484  array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
485  outfuncoid, use_line_feeds);
486 
487  pfree(elements);
488  pfree(nulls);
489 }
490 
491 /*
492  * Turn a composite / record into JSON.
493  */
494 static void
495 composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
496 {
497  HeapTupleHeader td;
498  Oid tupType;
499  int32 tupTypmod;
500  TupleDesc tupdesc;
501  HeapTupleData tmptup,
502  *tuple;
503  int i;
504  bool needsep = false;
505  const char *sep;
506 
507  sep = use_line_feeds ? ",\n " : ",";
508 
509  td = DatumGetHeapTupleHeader(composite);
510 
511  /* Extract rowtype info and find a tupdesc */
512  tupType = HeapTupleHeaderGetTypeId(td);
513  tupTypmod = HeapTupleHeaderGetTypMod(td);
514  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
515 
516  /* Build a temporary HeapTuple control structure */
518  tmptup.t_data = td;
519  tuple = &tmptup;
520 
521  appendStringInfoChar(result, '{');
522 
523  for (i = 0; i < tupdesc->natts; i++)
524  {
525  Datum val;
526  bool isnull;
527  char *attname;
528  JsonTypeCategory tcategory;
529  Oid outfuncoid;
530  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
531 
532  if (att->attisdropped)
533  continue;
534 
535  if (needsep)
536  appendStringInfoString(result, sep);
537  needsep = true;
538 
539  attname = NameStr(att->attname);
540  escape_json(result, attname);
541  appendStringInfoChar(result, ':');
542 
543  val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
544 
545  if (isnull)
546  {
547  tcategory = JSONTYPE_NULL;
548  outfuncoid = InvalidOid;
549  }
550  else
551  json_categorize_type(att->atttypid, false, &tcategory,
552  &outfuncoid);
553 
554  datum_to_json_internal(val, isnull, result, tcategory, outfuncoid,
555  false);
556  }
557 
558  appendStringInfoChar(result, '}');
559  ReleaseTupleDesc(tupdesc);
560 }
561 
562 /*
563  * Append JSON text for "val" to "result".
564  *
565  * This is just a thin wrapper around datum_to_json. If the same type will be
566  * printed many times, avoid using this; better to do the json_categorize_type
567  * lookups only once.
568  */
569 static void
570 add_json(Datum val, bool is_null, StringInfo result,
571  Oid val_type, bool key_scalar)
572 {
573  JsonTypeCategory tcategory;
574  Oid outfuncoid;
575 
576  if (val_type == InvalidOid)
577  ereport(ERROR,
578  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
579  errmsg("could not determine input data type")));
580 
581  if (is_null)
582  {
583  tcategory = JSONTYPE_NULL;
584  outfuncoid = InvalidOid;
585  }
586  else
587  json_categorize_type(val_type, false,
588  &tcategory, &outfuncoid);
589 
590  datum_to_json_internal(val, is_null, result, tcategory, outfuncoid,
591  key_scalar);
592 }
593 
594 /*
595  * SQL function array_to_json(row)
596  */
597 Datum
599 {
600  Datum array = PG_GETARG_DATUM(0);
601  StringInfo result;
602 
603  result = makeStringInfo();
604 
605  array_to_json_internal(array, result, false);
606 
608 }
609 
610 /*
611  * SQL function array_to_json(row, prettybool)
612  */
613 Datum
615 {
616  Datum array = PG_GETARG_DATUM(0);
617  bool use_line_feeds = PG_GETARG_BOOL(1);
618  StringInfo result;
619 
620  result = makeStringInfo();
621 
622  array_to_json_internal(array, result, use_line_feeds);
623 
625 }
626 
627 /*
628  * SQL function row_to_json(row)
629  */
630 Datum
632 {
633  Datum array = PG_GETARG_DATUM(0);
634  StringInfo result;
635 
636  result = makeStringInfo();
637 
638  composite_to_json(array, result, false);
639 
641 }
642 
643 /*
644  * SQL function row_to_json(row, prettybool)
645  */
646 Datum
648 {
649  Datum array = PG_GETARG_DATUM(0);
650  bool use_line_feeds = PG_GETARG_BOOL(1);
651  StringInfo result;
652 
653  result = makeStringInfo();
654 
655  composite_to_json(array, result, use_line_feeds);
656 
658 }
659 
660 /*
661  * Is the given type immutable when coming out of a JSON context?
662  *
663  * At present, datetimes are all considered mutable, because they
664  * depend on timezone. XXX we should also drill down into objects
665  * and arrays, but do not.
666  */
667 bool
669 {
670  JsonTypeCategory tcategory;
671  Oid outfuncoid;
672 
673  json_categorize_type(typoid, false, &tcategory, &outfuncoid);
674 
675  switch (tcategory)
676  {
677  case JSONTYPE_BOOL:
678  case JSONTYPE_JSON:
679  case JSONTYPE_JSONB:
680  case JSONTYPE_NULL:
681  return true;
682 
683  case JSONTYPE_DATE:
684  case JSONTYPE_TIMESTAMP:
686  return false;
687 
688  case JSONTYPE_ARRAY:
689  return false; /* TODO recurse into elements */
690 
691  case JSONTYPE_COMPOSITE:
692  return false; /* TODO recurse into fields */
693 
694  case JSONTYPE_NUMERIC:
695  case JSONTYPE_CAST:
696  case JSONTYPE_OTHER:
697  return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
698  }
699 
700  return false; /* not reached */
701 }
702 
703 /*
704  * SQL function to_json(anyvalue)
705  */
706 Datum
708 {
710  Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
711  JsonTypeCategory tcategory;
712  Oid outfuncoid;
713 
714  if (val_type == InvalidOid)
715  ereport(ERROR,
716  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
717  errmsg("could not determine input data type")));
718 
719  json_categorize_type(val_type, false,
720  &tcategory, &outfuncoid);
721 
722  PG_RETURN_DATUM(datum_to_json(val, tcategory, outfuncoid));
723 }
724 
725 /*
726  * Turn a Datum into JSON text.
727  *
728  * tcategory and outfuncoid are from a previous call to json_categorize_type.
729  */
730 Datum
731 datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
732 {
733  StringInfo result = makeStringInfo();
734 
735  datum_to_json_internal(val, false, result, tcategory, outfuncoid,
736  false);
737 
738  return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
739 }
740 
741 /*
742  * json_agg transition function
743  *
744  * aggregate input column as a json array value.
745  */
746 static Datum
747 json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
748 {
749  MemoryContext aggcontext,
750  oldcontext;
752  Datum val;
753 
754  if (!AggCheckCallContext(fcinfo, &aggcontext))
755  {
756  /* cannot be called directly because of internal-type argument */
757  elog(ERROR, "json_agg_transfn called in non-aggregate context");
758  }
759 
760  if (PG_ARGISNULL(0))
761  {
762  Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
763 
764  if (arg_type == InvalidOid)
765  ereport(ERROR,
766  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
767  errmsg("could not determine input data type")));
768 
769  /*
770  * Make this state object in a context where it will persist for the
771  * duration of the aggregate call. MemoryContextSwitchTo is only
772  * needed the first time, as the StringInfo routines make sure they
773  * use the right context to enlarge the object if necessary.
774  */
775  oldcontext = MemoryContextSwitchTo(aggcontext);
776  state = (JsonAggState *) palloc(sizeof(JsonAggState));
777  state->str = makeStringInfo();
778  MemoryContextSwitchTo(oldcontext);
779 
780  appendStringInfoChar(state->str, '[');
781  json_categorize_type(arg_type, false, &state->val_category,
782  &state->val_output_func);
783  }
784  else
785  {
787  }
788 
789  if (absent_on_null && PG_ARGISNULL(1))
791 
792  if (state->str->len > 1)
793  appendStringInfoString(state->str, ", ");
794 
795  /* fast path for NULLs */
796  if (PG_ARGISNULL(1))
797  {
799  InvalidOid, false);
801  }
802 
803  val = PG_GETARG_DATUM(1);
804 
805  /* add some whitespace if structured type and not first item */
806  if (!PG_ARGISNULL(0) && state->str->len > 1 &&
807  (state->val_category == JSONTYPE_ARRAY ||
808  state->val_category == JSONTYPE_COMPOSITE))
809  {
810  appendStringInfoString(state->str, "\n ");
811  }
812 
813  datum_to_json_internal(val, false, state->str, state->val_category,
814  state->val_output_func, false);
815 
816  /*
817  * The transition type for json_agg() is declared to be "internal", which
818  * is a pass-by-value type the same size as a pointer. So we can safely
819  * pass the JsonAggState pointer through nodeAgg.c's machinations.
820  */
822 }
823 
824 
825 /*
826  * json_agg aggregate function
827  */
828 Datum
830 {
831  return json_agg_transfn_worker(fcinfo, false);
832 }
833 
834 /*
835  * json_agg_strict aggregate function
836  */
837 Datum
839 {
840  return json_agg_transfn_worker(fcinfo, true);
841 }
842 
843 /*
844  * json_agg final function
845  */
846 Datum
848 {
850 
851  /* cannot be called directly because of internal-type argument */
852  Assert(AggCheckCallContext(fcinfo, NULL));
853 
854  state = PG_ARGISNULL(0) ?
855  NULL :
857 
858  /* NULL result for no rows in, as is standard with aggregates */
859  if (state == NULL)
860  PG_RETURN_NULL();
861 
862  /* Else return state with appropriate array terminator added */
864 }
865 
866 /* Functions implementing hash table for key uniqueness check */
867 static uint32
868 json_unique_hash(const void *key, Size keysize)
869 {
870  const JsonUniqueHashEntry *entry = (JsonUniqueHashEntry *) key;
872 
873  hash ^= hash_bytes((const unsigned char *) entry->key, entry->key_len);
874 
875  return DatumGetUInt32(hash);
876 }
877 
878 static int
879 json_unique_hash_match(const void *key1, const void *key2, Size keysize)
880 {
881  const JsonUniqueHashEntry *entry1 = (const JsonUniqueHashEntry *) key1;
882  const JsonUniqueHashEntry *entry2 = (const JsonUniqueHashEntry *) key2;
883 
884  if (entry1->object_id != entry2->object_id)
885  return entry1->object_id > entry2->object_id ? 1 : -1;
886 
887  if (entry1->key_len != entry2->key_len)
888  return entry1->key_len > entry2->key_len ? 1 : -1;
889 
890  return strncmp(entry1->key, entry2->key, entry1->key_len);
891 }
892 
893 /*
894  * Uniqueness detection support.
895  *
896  * In order to detect uniqueness during building or parsing of a JSON
897  * object, we maintain a hash table of key names already seen.
898  */
899 static void
901 {
902  HASHCTL ctl;
903 
904  memset(&ctl, 0, sizeof(ctl));
905  ctl.keysize = sizeof(JsonUniqueHashEntry);
906  ctl.entrysize = sizeof(JsonUniqueHashEntry);
908  ctl.hash = json_unique_hash;
910 
911  *cxt = hash_create("json object hashtable",
912  32,
913  &ctl,
915 }
916 
917 static void
919 {
921  cxt->mcxt = CurrentMemoryContext;
922  cxt->skipped_keys.data = NULL;
923 }
924 
925 static bool
926 json_unique_check_key(JsonUniqueCheckState *cxt, const char *key, int object_id)
927 {
928  JsonUniqueHashEntry entry;
929  bool found;
930 
931  entry.key = key;
932  entry.key_len = strlen(key);
933  entry.object_id = object_id;
934 
935  (void) hash_search(*cxt, &entry, HASH_ENTER, &found);
936 
937  return !found;
938 }
939 
940 /*
941  * On-demand initialization of a throwaway StringInfo. This is used to
942  * read a key name that we don't need to store in the output object, for
943  * duplicate key detection when the value is NULL.
944  */
945 static StringInfo
947 {
948  StringInfo out = &cxt->skipped_keys;
949 
950  if (!out->data)
951  {
953 
954  initStringInfo(out);
955  MemoryContextSwitchTo(oldcxt);
956  }
957  else
958  /* Just reset the string to empty */
959  out->len = 0;
960 
961  return out;
962 }
963 
964 /*
965  * json_object_agg transition function.
966  *
967  * aggregate two input columns as a single json object value.
968  */
969 static Datum
971  bool absent_on_null, bool unique_keys)
972 {
973  MemoryContext aggcontext,
974  oldcontext;
976  StringInfo out;
977  Datum arg;
978  bool skip;
979  int key_offset;
980 
981  if (!AggCheckCallContext(fcinfo, &aggcontext))
982  {
983  /* cannot be called directly because of internal-type argument */
984  elog(ERROR, "json_object_agg_transfn called in non-aggregate context");
985  }
986 
987  if (PG_ARGISNULL(0))
988  {
989  Oid arg_type;
990 
991  /*
992  * Make the StringInfo in a context where it will persist for the
993  * duration of the aggregate call. Switching context is only needed
994  * for this initial step, as the StringInfo and dynahash routines make
995  * sure they use the right context to enlarge the object if necessary.
996  */
997  oldcontext = MemoryContextSwitchTo(aggcontext);
998  state = (JsonAggState *) palloc(sizeof(JsonAggState));
999  state->str = makeStringInfo();
1000  if (unique_keys)
1001  json_unique_builder_init(&state->unique_check);
1002  else
1003  memset(&state->unique_check, 0, sizeof(state->unique_check));
1004  MemoryContextSwitchTo(oldcontext);
1005 
1006  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1007 
1008  if (arg_type == InvalidOid)
1009  ereport(ERROR,
1010  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1011  errmsg("could not determine data type for argument %d", 1)));
1012 
1013  json_categorize_type(arg_type, false, &state->key_category,
1014  &state->key_output_func);
1015 
1016  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1017 
1018  if (arg_type == InvalidOid)
1019  ereport(ERROR,
1020  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1021  errmsg("could not determine data type for argument %d", 2)));
1022 
1023  json_categorize_type(arg_type, false, &state->val_category,
1024  &state->val_output_func);
1025 
1026  appendStringInfoString(state->str, "{ ");
1027  }
1028  else
1029  {
1031  }
1032 
1033  /*
1034  * Note: since json_object_agg() is declared as taking type "any", the
1035  * parser will not do any type conversion on unknown-type literals (that
1036  * is, undecorated strings or NULLs). Such values will arrive here as
1037  * type UNKNOWN, which fortunately does not matter to us, since
1038  * unknownout() works fine.
1039  */
1040 
1041  if (PG_ARGISNULL(1))
1042  ereport(ERROR,
1043  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1044  errmsg("null value not allowed for object key")));
1045 
1046  /* Skip null values if absent_on_null */
1047  skip = absent_on_null && PG_ARGISNULL(2);
1048 
1049  if (skip)
1050  {
1051  /*
1052  * We got a NULL value and we're not storing those; if we're not
1053  * testing key uniqueness, we're done. If we are, use the throwaway
1054  * buffer to store the key name so that we can check it.
1055  */
1056  if (!unique_keys)
1058 
1059  out = json_unique_builder_get_throwawaybuf(&state->unique_check);
1060  }
1061  else
1062  {
1063  out = state->str;
1064 
1065  /*
1066  * Append comma delimiter only if we have already output some fields
1067  * after the initial string "{ ".
1068  */
1069  if (out->len > 2)
1070  appendStringInfoString(out, ", ");
1071  }
1072 
1073  arg = PG_GETARG_DATUM(1);
1074 
1075  key_offset = out->len;
1076 
1077  datum_to_json_internal(arg, false, out, state->key_category,
1078  state->key_output_func, true);
1079 
1080  if (unique_keys)
1081  {
1082  const char *key = &out->data[key_offset];
1083 
1084  if (!json_unique_check_key(&state->unique_check.check, key, 0))
1085  ereport(ERROR,
1086  errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1087  errmsg("duplicate JSON object key value: %s", key));
1088 
1089  if (skip)
1091  }
1092 
1093  appendStringInfoString(state->str, " : ");
1094 
1095  if (PG_ARGISNULL(2))
1096  arg = (Datum) 0;
1097  else
1098  arg = PG_GETARG_DATUM(2);
1099 
1101  state->val_category,
1102  state->val_output_func, false);
1103 
1105 }
1106 
1107 /*
1108  * json_object_agg aggregate function
1109  */
1110 Datum
1112 {
1113  return json_object_agg_transfn_worker(fcinfo, false, false);
1114 }
1115 
1116 /*
1117  * json_object_agg_strict aggregate function
1118  */
1119 Datum
1121 {
1122  return json_object_agg_transfn_worker(fcinfo, true, false);
1123 }
1124 
1125 /*
1126  * json_object_agg_unique aggregate function
1127  */
1128 Datum
1130 {
1131  return json_object_agg_transfn_worker(fcinfo, false, true);
1132 }
1133 
1134 /*
1135  * json_object_agg_unique_strict aggregate function
1136  */
1137 Datum
1139 {
1140  return json_object_agg_transfn_worker(fcinfo, true, true);
1141 }
1142 
1143 /*
1144  * json_object_agg final function.
1145  */
1146 Datum
1148 {
1150 
1151  /* cannot be called directly because of internal-type argument */
1152  Assert(AggCheckCallContext(fcinfo, NULL));
1153 
1154  state = PG_ARGISNULL(0) ? NULL : (JsonAggState *) PG_GETARG_POINTER(0);
1155 
1156  /* NULL result for no rows in, as is standard with aggregates */
1157  if (state == NULL)
1158  PG_RETURN_NULL();
1159 
1160  /* Else return state with appropriate object terminator added */
1162 }
1163 
1164 /*
1165  * Helper function for aggregates: return given StringInfo's contents plus
1166  * specified trailing string, as a text datum. We need this because aggregate
1167  * final functions are not allowed to modify the aggregate state.
1168  */
1169 static text *
1170 catenate_stringinfo_string(StringInfo buffer, const char *addon)
1171 {
1172  /* custom version of cstring_to_text_with_len */
1173  int buflen = buffer->len;
1174  int addlen = strlen(addon);
1175  text *result = (text *) palloc(buflen + addlen + VARHDRSZ);
1176 
1177  SET_VARSIZE(result, buflen + addlen + VARHDRSZ);
1178  memcpy(VARDATA(result), buffer->data, buflen);
1179  memcpy(VARDATA(result) + buflen, addon, addlen);
1180 
1181  return result;
1182 }
1183 
1184 Datum
1185 json_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
1186  bool absent_on_null, bool unique_keys)
1187 {
1188  int i;
1189  const char *sep = "";
1190  StringInfo result;
1191  JsonUniqueBuilderState unique_check;
1192 
1193  if (nargs % 2 != 0)
1194  ereport(ERROR,
1195  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1196  errmsg("argument list must have even number of elements"),
1197  /* translator: %s is a SQL function name */
1198  errhint("The arguments of %s must consist of alternating keys and values.",
1199  "json_build_object()")));
1200 
1201  result = makeStringInfo();
1202 
1203  appendStringInfoChar(result, '{');
1204 
1205  if (unique_keys)
1206  json_unique_builder_init(&unique_check);
1207 
1208  for (i = 0; i < nargs; i += 2)
1209  {
1210  StringInfo out;
1211  bool skip;
1212  int key_offset;
1213 
1214  /* Skip null values if absent_on_null */
1215  skip = absent_on_null && nulls[i + 1];
1216 
1217  if (skip)
1218  {
1219  /* If key uniqueness check is needed we must save skipped keys */
1220  if (!unique_keys)
1221  continue;
1222 
1223  out = json_unique_builder_get_throwawaybuf(&unique_check);
1224  }
1225  else
1226  {
1227  appendStringInfoString(result, sep);
1228  sep = ", ";
1229  out = result;
1230  }
1231 
1232  /* process key */
1233  if (nulls[i])
1234  ereport(ERROR,
1235  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1236  errmsg("null value not allowed for object key")));
1237 
1238  /* save key offset before appending it */
1239  key_offset = out->len;
1240 
1241  add_json(args[i], false, out, types[i], true);
1242 
1243  if (unique_keys)
1244  {
1245  /* check key uniqueness after key appending */
1246  const char *key = &out->data[key_offset];
1247 
1248  if (!json_unique_check_key(&unique_check.check, key, 0))
1249  ereport(ERROR,
1250  errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1251  errmsg("duplicate JSON object key value: %s", key));
1252 
1253  if (skip)
1254  continue;
1255  }
1256 
1257  appendStringInfoString(result, " : ");
1258 
1259  /* process value */
1260  add_json(args[i + 1], nulls[i + 1], result, types[i + 1], false);
1261  }
1262 
1263  appendStringInfoChar(result, '}');
1264 
1265  return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
1266 }
1267 
1268 /*
1269  * SQL function json_build_object(variadic "any")
1270  */
1271 Datum
1273 {
1274  Datum *args;
1275  bool *nulls;
1276  Oid *types;
1277 
1278  /* build argument values to build the object */
1279  int nargs = extract_variadic_args(fcinfo, 0, true,
1280  &args, &types, &nulls);
1281 
1282  if (nargs < 0)
1283  PG_RETURN_NULL();
1284 
1285  PG_RETURN_DATUM(json_build_object_worker(nargs, args, nulls, types, false, false));
1286 }
1287 
1288 /*
1289  * degenerate case of json_build_object where it gets 0 arguments.
1290  */
1291 Datum
1293 {
1295 }
1296 
1297 Datum
1298 json_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
1299  bool absent_on_null)
1300 {
1301  int i;
1302  const char *sep = "";
1303  StringInfo result;
1304 
1305  result = makeStringInfo();
1306 
1307  appendStringInfoChar(result, '[');
1308 
1309  for (i = 0; i < nargs; i++)
1310  {
1311  if (absent_on_null && nulls[i])
1312  continue;
1313 
1314  appendStringInfoString(result, sep);
1315  sep = ", ";
1316  add_json(args[i], nulls[i], result, types[i], false);
1317  }
1318 
1319  appendStringInfoChar(result, ']');
1320 
1321  return PointerGetDatum(cstring_to_text_with_len(result->data, result->len));
1322 }
1323 
1324 /*
1325  * SQL function json_build_array(variadic "any")
1326  */
1327 Datum
1329 {
1330  Datum *args;
1331  bool *nulls;
1332  Oid *types;
1333 
1334  /* build argument values to build the object */
1335  int nargs = extract_variadic_args(fcinfo, 0, true,
1336  &args, &types, &nulls);
1337 
1338  if (nargs < 0)
1339  PG_RETURN_NULL();
1340 
1341  PG_RETURN_DATUM(json_build_array_worker(nargs, args, nulls, types, false));
1342 }
1343 
1344 /*
1345  * degenerate case of json_build_array where it gets 0 arguments.
1346  */
1347 Datum
1349 {
1351 }
1352 
1353 /*
1354  * SQL function json_object(text[])
1355  *
1356  * take a one or two dimensional array of text as key/value pairs
1357  * for a json object.
1358  */
1359 Datum
1361 {
1362  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
1363  int ndims = ARR_NDIM(in_array);
1364  StringInfoData result;
1365  Datum *in_datums;
1366  bool *in_nulls;
1367  int in_count,
1368  count,
1369  i;
1370  text *rval;
1371  char *v;
1372 
1373  switch (ndims)
1374  {
1375  case 0:
1377  break;
1378 
1379  case 1:
1380  if ((ARR_DIMS(in_array)[0]) % 2)
1381  ereport(ERROR,
1382  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1383  errmsg("array must have even number of elements")));
1384  break;
1385 
1386  case 2:
1387  if ((ARR_DIMS(in_array)[1]) != 2)
1388  ereport(ERROR,
1389  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1390  errmsg("array must have two columns")));
1391  break;
1392 
1393  default:
1394  ereport(ERROR,
1395  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1396  errmsg("wrong number of array subscripts")));
1397  }
1398 
1399  deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
1400 
1401  count = in_count / 2;
1402 
1403  initStringInfo(&result);
1404 
1405  appendStringInfoChar(&result, '{');
1406 
1407  for (i = 0; i < count; ++i)
1408  {
1409  if (in_nulls[i * 2])
1410  ereport(ERROR,
1411  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1412  errmsg("null value not allowed for object key")));
1413 
1414  v = TextDatumGetCString(in_datums[i * 2]);
1415  if (i > 0)
1416  appendStringInfoString(&result, ", ");
1417  escape_json(&result, v);
1418  appendStringInfoString(&result, " : ");
1419  pfree(v);
1420  if (in_nulls[i * 2 + 1])
1421  appendStringInfoString(&result, "null");
1422  else
1423  {
1424  v = TextDatumGetCString(in_datums[i * 2 + 1]);
1425  escape_json(&result, v);
1426  pfree(v);
1427  }
1428  }
1429 
1430  appendStringInfoChar(&result, '}');
1431 
1432  pfree(in_datums);
1433  pfree(in_nulls);
1434 
1435  rval = cstring_to_text_with_len(result.data, result.len);
1436  pfree(result.data);
1437 
1438  PG_RETURN_TEXT_P(rval);
1439 }
1440 
1441 /*
1442  * SQL function json_object(text[], text[])
1443  *
1444  * take separate key and value arrays of text to construct a json object
1445  * pairwise.
1446  */
1447 Datum
1449 {
1450  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(0);
1451  ArrayType *val_array = PG_GETARG_ARRAYTYPE_P(1);
1452  int nkdims = ARR_NDIM(key_array);
1453  int nvdims = ARR_NDIM(val_array);
1454  StringInfoData result;
1455  Datum *key_datums,
1456  *val_datums;
1457  bool *key_nulls,
1458  *val_nulls;
1459  int key_count,
1460  val_count,
1461  i;
1462  text *rval;
1463  char *v;
1464 
1465  if (nkdims > 1 || nkdims != nvdims)
1466  ereport(ERROR,
1467  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1468  errmsg("wrong number of array subscripts")));
1469 
1470  if (nkdims == 0)
1472 
1473  deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
1474  deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, &val_count);
1475 
1476  if (key_count != val_count)
1477  ereport(ERROR,
1478  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1479  errmsg("mismatched array dimensions")));
1480 
1481  initStringInfo(&result);
1482 
1483  appendStringInfoChar(&result, '{');
1484 
1485  for (i = 0; i < key_count; ++i)
1486  {
1487  if (key_nulls[i])
1488  ereport(ERROR,
1489  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1490  errmsg("null value not allowed for object key")));
1491 
1492  v = TextDatumGetCString(key_datums[i]);
1493  if (i > 0)
1494  appendStringInfoString(&result, ", ");
1495  escape_json(&result, v);
1496  appendStringInfoString(&result, " : ");
1497  pfree(v);
1498  if (val_nulls[i])
1499  appendStringInfoString(&result, "null");
1500  else
1501  {
1502  v = TextDatumGetCString(val_datums[i]);
1503  escape_json(&result, v);
1504  pfree(v);
1505  }
1506  }
1507 
1508  appendStringInfoChar(&result, '}');
1509 
1510  pfree(key_datums);
1511  pfree(key_nulls);
1512  pfree(val_datums);
1513  pfree(val_nulls);
1514 
1515  rval = cstring_to_text_with_len(result.data, result.len);
1516  pfree(result.data);
1517 
1518  PG_RETURN_TEXT_P(rval);
1519 }
1520 
1521 
1522 /*
1523  * Produce a JSON string literal, properly escaping characters in the text.
1524  */
1525 void
1527 {
1528  const char *p;
1529 
1531  for (p = str; *p; p++)
1532  {
1533  switch (*p)
1534  {
1535  case '\b':
1536  appendStringInfoString(buf, "\\b");
1537  break;
1538  case '\f':
1539  appendStringInfoString(buf, "\\f");
1540  break;
1541  case '\n':
1542  appendStringInfoString(buf, "\\n");
1543  break;
1544  case '\r':
1545  appendStringInfoString(buf, "\\r");
1546  break;
1547  case '\t':
1548  appendStringInfoString(buf, "\\t");
1549  break;
1550  case '"':
1551  appendStringInfoString(buf, "\\\"");
1552  break;
1553  case '\\':
1554  appendStringInfoString(buf, "\\\\");
1555  break;
1556  default:
1557  if ((unsigned char) *p < ' ')
1558  appendStringInfo(buf, "\\u%04x", (int) *p);
1559  else
1561  break;
1562  }
1563  }
1565 }
1566 
1567 /* Semantic actions for key uniqueness check */
1568 static JsonParseErrorType
1570 {
1571  JsonUniqueParsingState *state = _state;
1572  JsonUniqueStackEntry *entry;
1573 
1574  if (!state->unique)
1575  return JSON_SUCCESS;
1576 
1577  /* push object entry to stack */
1578  entry = palloc(sizeof(*entry));
1579  entry->object_id = state->id_counter++;
1580  entry->parent = state->stack;
1581  state->stack = entry;
1582 
1583  return JSON_SUCCESS;
1584 }
1585 
1586 static JsonParseErrorType
1588 {
1589  JsonUniqueParsingState *state = _state;
1590  JsonUniqueStackEntry *entry;
1591 
1592  if (!state->unique)
1593  return JSON_SUCCESS;
1594 
1595  entry = state->stack;
1596  state->stack = entry->parent; /* pop object from stack */
1597  pfree(entry);
1598  return JSON_SUCCESS;
1599 }
1600 
1601 static JsonParseErrorType
1602 json_unique_object_field_start(void *_state, char *field, bool isnull)
1603 {
1604  JsonUniqueParsingState *state = _state;
1605  JsonUniqueStackEntry *entry;
1606 
1607  if (!state->unique)
1608  return JSON_SUCCESS;
1609 
1610  /* find key collision in the current object */
1611  if (json_unique_check_key(&state->check, field, state->stack->object_id))
1612  return JSON_SUCCESS;
1613 
1614  state->unique = false;
1615 
1616  /* pop all objects entries */
1617  while ((entry = state->stack))
1618  {
1619  state->stack = entry->parent;
1620  pfree(entry);
1621  }
1622  return JSON_SUCCESS;
1623 }
1624 
1625 /* Validate JSON text and additionally check key uniqueness */
1626 bool
1627 json_validate(text *json, bool check_unique_keys, bool throw_error)
1628 {
1629  JsonLexContext lex;
1630  JsonSemAction uniqueSemAction = {0};
1632  JsonParseErrorType result;
1633 
1634  makeJsonLexContext(&lex, json, check_unique_keys);
1635 
1636  if (check_unique_keys)
1637  {
1638  state.lex = &lex;
1639  state.stack = NULL;
1640  state.id_counter = 0;
1641  state.unique = true;
1642  json_unique_check_init(&state.check);
1643 
1644  uniqueSemAction.semstate = &state;
1645  uniqueSemAction.object_start = json_unique_object_start;
1647  uniqueSemAction.object_end = json_unique_object_end;
1648  }
1649 
1650  result = pg_parse_json(&lex, check_unique_keys ? &uniqueSemAction : &nullSemAction);
1651 
1652  if (result != JSON_SUCCESS)
1653  {
1654  if (throw_error)
1655  json_errsave_error(result, &lex, NULL);
1656 
1657  return false; /* invalid json */
1658  }
1659 
1660  if (check_unique_keys && !state.unique)
1661  {
1662  if (throw_error)
1663  ereport(ERROR,
1664  (errcode(ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE),
1665  errmsg("duplicate JSON object key value")));
1666 
1667  return false; /* not unique keys */
1668  }
1669 
1670  if (check_unique_keys)
1671  freeJsonLexContext(&lex);
1672 
1673  return true; /* ok */
1674 }
1675 
1676 /*
1677  * SQL function json_typeof(json) -> text
1678  *
1679  * Returns the type of the outermost JSON value as TEXT. Possible types are
1680  * "object", "array", "string", "number", "boolean", and "null".
1681  *
1682  * Performs a single call to json_lex() to get the first token of the supplied
1683  * value. This initial token uniquely determines the value's type. As our
1684  * input must already have been validated by json_in() or json_recv(), the
1685  * initial token should never be JSON_TOKEN_OBJECT_END, JSON_TOKEN_ARRAY_END,
1686  * JSON_TOKEN_COLON, JSON_TOKEN_COMMA, or JSON_TOKEN_END.
1687  */
1688 Datum
1690 {
1691  text *json = PG_GETARG_TEXT_PP(0);
1692  JsonLexContext lex;
1693  char *type;
1694  JsonParseErrorType result;
1695 
1696  /* Lex exactly one token from the input and check its type. */
1697  makeJsonLexContext(&lex, json, false);
1698  result = json_lex(&lex);
1699  if (result != JSON_SUCCESS)
1700  json_errsave_error(result, &lex, NULL);
1701 
1702  switch (lex.token_type)
1703  {
1705  type = "object";
1706  break;
1708  type = "array";
1709  break;
1710  case JSON_TOKEN_STRING:
1711  type = "string";
1712  break;
1713  case JSON_TOKEN_NUMBER:
1714  type = "number";
1715  break;
1716  case JSON_TOKEN_TRUE:
1717  case JSON_TOKEN_FALSE:
1718  type = "boolean";
1719  break;
1720  case JSON_TOKEN_NULL:
1721  type = "null";
1722  break;
1723  default:
1724  elog(ERROR, "unexpected json token: %d", lex.token_type);
1725  }
1726 
1728 }
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3613
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3679
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition: datetime.c:4227
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:313
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4257
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:4142
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1591
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1896
#define CStringGetTextDatum(s)
Definition: builtins.h:94
#define TextDatumGetCString(d)
Definition: builtins.h:95
#define NameStr(name)
Definition: c.h:735
unsigned int uint32
Definition: c.h:495
signed short int16
Definition: c.h:482
signed int int32
Definition: c.h:483
#define VARHDRSZ
Definition: c.h:681
size_t Size
Definition: c.h:594
int64 Timestamp
Definition: timestamp.h:38
int64 TimestampTz
Definition: timestamp.h:39
int32 fsec_t
Definition: timestamp.h:41
#define USECS_PER_SEC
Definition: timestamp.h:134
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:169
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: date.c:2403
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition: date.c:1488
void EncodeSpecialDate(DateADT dt, char *str)
Definition: date.c:294
#define DATE_NOT_FINITE(j)
Definition: date.h:43
int32 DateADT
Definition: date.h:23
static DateADT DatumGetDateADT(Datum X)
Definition: date.h:54
static TimeADT DatumGetTimeADT(Datum X)
Definition: date.h:60
static TimeTzADT * DatumGetTimeTzADTP(Datum X)
Definition: date.h:66
int64 TimeADT
Definition: date.h:25
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:953
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:350
struct typedefs * types
Definition: ecpg.c:29
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1746
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1893
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:680
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
#define DatumGetTextPP(X)
Definition: fmgr.h:292
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1997
uint32 hash_bytes_uint32(uint32 k)
Definition: hashfn.c:610
uint32 hash_bytes(const unsigned char *k, int keylen)
Definition: hashfn.c:146
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_CONTEXT
Definition: hsearch.h:102
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_COMPARE
Definition: hsearch.h:99
#define HASH_FUNCTION
Definition: hsearch.h:98
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:466
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
#define MAXDATELEN
Definition: datetime.h:200
#define nitems(x)
Definition: indent.h:31
long val
Definition: informix.c:664
static struct @148 value
int i
Definition: isn.c:73
Datum row_to_json(PG_FUNCTION_ARGS)
Definition: json.c:631
struct JsonUniqueStackEntry JsonUniqueStackEntry
static JsonParseErrorType json_unique_object_start(void *_state)
Definition: json.c:1569
static uint32 json_unique_hash(const void *key, Size keysize)
Definition: json.c:868
Datum json_build_object_noargs(PG_FUNCTION_ARGS)
Definition: json.c:1292
static int json_unique_hash_match(const void *key1, const void *key2, Size keysize)
Definition: json.c:879
static void json_unique_check_init(JsonUniqueCheckState *cxt)
Definition: json.c:900
static text * catenate_stringinfo_string(StringInfo buffer, const char *addon)
Definition: json.c:1170
struct HTAB * JsonUniqueCheckState
Definition: json.c:39
Datum json_agg_strict_transfn(PG_FUNCTION_ARGS)
Definition: json.c:838
struct JsonUniqueBuilderState JsonUniqueBuilderState
Datum json_in(PG_FUNCTION_ARGS)
Definition: json.c:105
static StringInfo json_unique_builder_get_throwawaybuf(JsonUniqueBuilderState *cxt)
Definition: json.c:946
static bool json_unique_check_key(JsonUniqueCheckState *cxt, const char *key, int object_id)
Definition: json.c:926
struct JsonUniqueParsingState JsonUniqueParsingState
Datum json_out(PG_FUNCTION_ARGS)
Definition: json.c:124
Datum json_agg_transfn(PG_FUNCTION_ARGS)
Definition: json.c:829
Datum to_json(PG_FUNCTION_ARGS)
Definition: json.c:707
Datum json_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: json.c:1298
Datum json_object_agg_finalfn(PG_FUNCTION_ARGS)
Definition: json.c:1147
Datum row_to_json_pretty(PG_FUNCTION_ARGS)
Definition: json.c:647
struct JsonUniqueHashEntry JsonUniqueHashEntry
Datum json_send(PG_FUNCTION_ARGS)
Definition: json.c:136
static Datum json_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
Definition: json.c:747
static void datum_to_json_internal(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:177
Datum array_to_json_pretty(PG_FUNCTION_ARGS)
Definition: json.c:614
Datum json_object_agg_unique_transfn(PG_FUNCTION_ARGS)
Definition: json.c:1129
Datum json_object_two_arg(PG_FUNCTION_ARGS)
Definition: json.c:1448
Datum json_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS)
Definition: json.c:1138
Datum json_build_array_noargs(PG_FUNCTION_ARGS)
Definition: json.c:1348
Datum json_object_agg_transfn(PG_FUNCTION_ARGS)
Definition: json.c:1111
Datum array_to_json(PG_FUNCTION_ARGS)
Definition: json.c:598
Datum json_object_agg_strict_transfn(PG_FUNCTION_ARGS)
Definition: json.c:1120
Datum json_build_array(PG_FUNCTION_ARGS)
Definition: json.c:1328
static void json_unique_builder_init(JsonUniqueBuilderState *cxt)
Definition: json.c:918
Datum json_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Definition: json.c:1185
static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
Definition: json.c:570
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Definition: json.c:284
Datum json_agg_finalfn(PG_FUNCTION_ARGS)
Definition: json.c:847
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
Definition: json.c:405
Datum json_recv(PG_FUNCTION_ARGS)
Definition: json.c:150
Datum datum_to_json(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: json.c:731
bool json_validate(text *json, bool check_unique_keys, bool throw_error)
Definition: json.c:1627
Datum json_typeof(PG_FUNCTION_ARGS)
Definition: json.c:1689
struct JsonAggState JsonAggState
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition: json.c:495
static Datum json_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Definition: json.c:970
Datum json_object(PG_FUNCTION_ARGS)
Definition: json.c:1360
Datum json_build_object(PG_FUNCTION_ARGS)
Definition: json.c:1272
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1526
bool to_json_is_immutable(Oid typoid)
Definition: json.c:668
static JsonParseErrorType json_unique_object_field_start(void *_state, char *field, bool isnull)
Definition: json.c:1602
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
Definition: json.c:448
static JsonParseErrorType json_unique_object_end(void *_state)
Definition: json.c:1587
bool IsValidJsonNumber(const char *str, int len)
Definition: jsonapi.c:105
JsonSemAction nullSemAction
Definition: jsonapi.c:57
JsonParseErrorType pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonapi.c:205
JsonParseErrorType json_lex(JsonLexContext *lex)
Definition: jsonapi.c:588
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:153
void freeJsonLexContext(JsonLexContext *lex)
Definition: jsonapi.c:183
JsonParseErrorType
Definition: jsonapi.h:37
@ JSON_SUCCESS
Definition: jsonapi.h:38
@ JSON_TOKEN_FALSE
Definition: jsonapi.h:31
@ JSON_TOKEN_TRUE
Definition: jsonapi.h:30
@ JSON_TOKEN_NULL
Definition: jsonapi.h:32
@ JSON_TOKEN_OBJECT_START
Definition: jsonapi.h:24
@ JSON_TOKEN_NUMBER
Definition: jsonapi.h:23
@ JSON_TOKEN_STRING
Definition: jsonapi.h:22
@ JSON_TOKEN_ARRAY_START
Definition: jsonapi.h:26
JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)
Definition: jsonfuncs.c:529
bool pg_parse_json_or_errsave(JsonLexContext *lex, JsonSemAction *sem, Node *escontext)
Definition: jsonfuncs.c:508
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonfuncs.c:5705
void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, Node *escontext)
Definition: jsonfuncs.c:630
#define pg_parse_json_or_ereport(lex, sem)
Definition: jsonfuncs.h:46
JsonTypeCategory
Definition: jsonfuncs.h:68
@ JSONTYPE_JSON
Definition: jsonfuncs.h:75
@ JSONTYPE_NULL
Definition: jsonfuncs.h:69
@ JSONTYPE_TIMESTAMP
Definition: jsonfuncs.h:73
@ JSONTYPE_NUMERIC
Definition: jsonfuncs.h:71
@ JSONTYPE_DATE
Definition: jsonfuncs.h:72
@ JSONTYPE_BOOL
Definition: jsonfuncs.h:70
@ JSONTYPE_OTHER
Definition: jsonfuncs.h:80
@ JSONTYPE_CAST
Definition: jsonfuncs.h:79
@ JSONTYPE_COMPOSITE
Definition: jsonfuncs.h:78
@ JSONTYPE_ARRAY
Definition: jsonfuncs.h:77
@ JSONTYPE_TIMESTAMPTZ
Definition: jsonfuncs.h:74
@ JSONTYPE_JSONB
Definition: jsonfuncs.h:76
Assert(fmt[strlen(fmt) - 1] !='\n')
static struct pg_tm tm
Definition: localtime.c:104
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2253
char func_volatile(Oid funcid)
Definition: lsyscache.c:1784
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
void pfree(void *pointer)
Definition: mcxt.c:1456
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
void * palloc(Size size)
Definition: mcxt.c:1226
#define USE_XSD_DATES
Definition: miscadmin.h:235
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4512
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
NameData attname
Definition: pg_attribute.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
void * arg
static const struct exclude_list_item skip[]
Definition: pg_checksums.c:108
static char * buf
Definition: pg_test_fsync.c:73
char typalign
Definition: pg_type.h:176
long date
Definition: pgtypes_date.h:9
int64 timestamp
void check_stack_depth(void)
Definition: postgres.c:3520
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:222
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:175
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:549
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
StringInfoData * StringInfo
Definition: stringinfo.h:54
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:203
FmgrInfo * flinfo
Definition: fmgr.h:87
Size keysize
Definition: hsearch.h:75
HashValueFunc hash
Definition: hsearch.h:78
Size entrysize
Definition: hsearch.h:76
HashCompareFunc match
Definition: hsearch.h:80
MemoryContext hcxt
Definition: hsearch.h:86
Definition: dynahash.c:220
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
JsonUniqueBuilderState unique_check
Definition: json.c:83
JsonTypeCategory key_category
Definition: json.c:79
Oid val_output_func
Definition: json.c:82
StringInfo str
Definition: json.c:78
Oid key_output_func
Definition: json.c:80
JsonTypeCategory val_category
Definition: json.c:81
JsonTokenType token_type
Definition: jsonapi.h:86
json_struct_action object_start
Definition: jsonapi.h:120
json_ofield_action object_field_start
Definition: jsonapi.h:124
void * semstate
Definition: jsonapi.h:119
json_struct_action object_end
Definition: jsonapi.h:121
JsonUniqueCheckState check
Definition: json.c:69
StringInfoData skipped_keys
Definition: json.c:70
MemoryContext mcxt
Definition: json.c:71
const char * key
Definition: json.c:44
JsonUniqueCheckState check
Definition: json.c:60
JsonUniqueStackEntry * stack
Definition: json.c:61
JsonLexContext * lex
Definition: json.c:59
struct JsonUniqueStackEntry * parent
Definition: json.c:52
Definition: date.h:28
Definition: pgtime.h:35
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_isdst
Definition: pgtime.h:44
int tm_year
Definition: pgtime.h:41
Definition: regguts.h:323
Definition: c.h:676
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1830
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28
static TimestampTz DatumGetTimestampTz(Datum X)
Definition: timestamp.h:34
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
char * text_to_cstring(const text *t)
Definition: varlena.c:217
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196
text * cstring_to_text(const char *s)
Definition: varlena.c:184
const char * type