PostgreSQL Source Code git master
Loading...
Searching...
No Matches
jsonb.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * jsonb.c
4 * I/O routines for jsonb type
5 *
6 * Copyright (c) 2014-2026, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/backend/utils/adt/jsonb.c
10 *
11 *-------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "access/htup_details.h"
16#include "catalog/pg_type.h"
17#include "funcapi.h"
18#include "libpq/pqformat.h"
19#include "miscadmin.h"
20#include "utils/builtins.h"
21#include "utils/fmgroids.h"
22#include "utils/json.h"
23#include "utils/jsonb.h"
24#include "utils/jsonfuncs.h"
25#include "utils/lsyscache.h"
26#include "utils/typcache.h"
27
36
37static inline Datum jsonb_from_cstring(char *json, int len, bool unique_keys,
38 Node *escontext);
39static bool checkStringLen(size_t len, Node *escontext);
40static JsonParseErrorType jsonb_in_object_start(void *pstate);
41static JsonParseErrorType jsonb_in_object_end(void *pstate);
42static JsonParseErrorType jsonb_in_array_start(void *pstate);
43static JsonParseErrorType jsonb_in_array_end(void *pstate);
44static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
46static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
47static void composite_to_jsonb(Datum composite, JsonbInState *result);
48static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims,
49 const Datum *vals, const bool *nulls, int *valcount,
51static void array_to_jsonb_internal(Datum array, JsonbInState *result);
52static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result,
54 bool key_scalar);
55static void add_jsonb(Datum val, bool is_null, JsonbInState *result,
56 Oid val_type, bool key_scalar);
57static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent);
58static void add_indent(StringInfo out, bool indent, int level);
59
60/*
61 * jsonb type input function
62 */
65{
66 char *json = PG_GETARG_CSTRING(0);
67
68 return jsonb_from_cstring(json, strlen(json), false, fcinfo->context);
69}
70
71/*
72 * jsonb type recv function
73 *
74 * The type is sent as text in binary mode, so this is almost the same
75 * as the input function, but it's prefixed with a version number so we
76 * can change the binary format sent in future if necessary. For now,
77 * only version 1 is supported.
78 */
81{
83 int version = pq_getmsgint(buf, 1);
84 char *str;
85 int nbytes;
86
87 if (version == 1)
88 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
89 else
90 elog(ERROR, "unsupported jsonb version number %d", version);
91
92 return jsonb_from_cstring(str, nbytes, false, NULL);
93}
94
95/*
96 * jsonb type output function
97 */
100{
102 char *out;
103
104 out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
105
107}
108
109/*
110 * jsonb type send function
111 *
112 * Just send jsonb as a version number, then a string of text
113 */
114Datum
116{
120 int version = 1;
121
123 (void) JsonbToCString(&jtext, &jb->root, VARSIZE(jb));
124
126 pq_sendint8(&buf, version);
127 pq_sendtext(&buf, jtext.data, jtext.len);
128 pfree(jtext.data);
129
131}
132
133/*
134 * jsonb_from_text
135 *
136 * Turns json text string into a jsonb Datum.
137 */
138Datum
139jsonb_from_text(text *js, bool unique_keys)
140{
143 unique_keys,
144 NULL);
145}
146
147/*
148 * Get the type name of a jsonb container.
149 */
150static const char *
152{
153 JsonbValue scalar;
154
155 if (JsonbExtractScalar(jbc, &scalar))
156 return JsonbTypeName(&scalar);
157 else if (JsonContainerIsArray(jbc))
158 return "array";
159 else if (JsonContainerIsObject(jbc))
160 return "object";
161 else
162 {
163 elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
164 return "unknown";
165 }
166}
167
168/*
169 * Get the type name of a jsonb value.
170 */
171const char *
173{
174 switch (val->type)
175 {
176 case jbvBinary:
177 return JsonbContainerTypeName(val->val.binary.data);
178 case jbvObject:
179 return "object";
180 case jbvArray:
181 return "array";
182 case jbvNumeric:
183 return "number";
184 case jbvString:
185 return "string";
186 case jbvBool:
187 return "boolean";
188 case jbvNull:
189 return "null";
190 case jbvDatetime:
191 switch (val->val.datetime.typid)
192 {
193 case DATEOID:
194 return "date";
195 case TIMEOID:
196 return "time without time zone";
197 case TIMETZOID:
198 return "time with time zone";
199 case TIMESTAMPOID:
200 return "timestamp without time zone";
201 case TIMESTAMPTZOID:
202 return "timestamp with time zone";
203 default:
204 elog(ERROR, "unrecognized jsonb value datetime type: %d",
205 val->val.datetime.typid);
206 }
207 return "unknown";
208 default:
209 elog(ERROR, "unrecognized jsonb value type: %d", val->type);
210 return "unknown";
211 }
212}
213
214/*
215 * SQL function jsonb_typeof(jsonb) -> text
216 *
217 * This function is here because the analog json function is in json.c, since
218 * it uses the json parser internals not exposed elsewhere.
219 */
220Datum
222{
223 Jsonb *in = PG_GETARG_JSONB_P(0);
224 const char *result = JsonbContainerTypeName(&in->root);
225
227}
228
229/*
230 * jsonb_from_cstring
231 *
232 * Turns json string into a jsonb Datum.
233 *
234 * Uses the json parser (with hooks) to construct a jsonb.
235 *
236 * If escontext points to an ErrorSaveContext, errors are reported there
237 * instead of being thrown.
238 */
239static inline Datum
240jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
241{
242 JsonLexContext lex;
245
246 memset(&state, 0, sizeof(state));
247 memset(&sem, 0, sizeof(sem));
249
250 state.unique_keys = unique_keys;
251 state.escontext = escontext;
252 sem.semstate = &state;
253
260
261 if (!pg_parse_json_or_errsave(&lex, &sem, escontext))
262 return (Datum) 0;
263
264 /* after parsing, the result field has the composed jsonb structure */
266}
267
268static bool
269checkStringLen(size_t len, Node *escontext)
270{
272 ereturn(escontext, false,
274 errmsg("string too long to represent as jsonb string"),
275 errdetail("Due to an implementation restriction, jsonb strings cannot exceed %d bytes.",
277
278 return true;
279}
280
283{
284 JsonbInState *_state = (JsonbInState *) pstate;
285
287 _state->parseState->unique_keys = _state->unique_keys;
288
289 return JSON_SUCCESS;
290}
291
294{
295 JsonbInState *_state = (JsonbInState *) pstate;
296
298
299 return JSON_SUCCESS;
300}
301
304{
305 JsonbInState *_state = (JsonbInState *) pstate;
306
308
309 return JSON_SUCCESS;
310}
311
314{
315 JsonbInState *_state = (JsonbInState *) pstate;
316
318
319 return JSON_SUCCESS;
320}
321
323jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
324{
325 JsonbInState *_state = (JsonbInState *) pstate;
326 JsonbValue v;
327
328 Assert(fname != NULL);
329 v.type = jbvString;
330 v.val.string.len = strlen(fname);
331 if (!checkStringLen(v.val.string.len, _state->escontext))
333 v.val.string.val = fname;
334
336
337 return JSON_SUCCESS;
338}
339
340static void
342{
343 switch (scalarVal->type)
344 {
345 case jbvNull:
346 appendBinaryStringInfo(out, "null", 4);
347 break;
348 case jbvString:
349 escape_json_with_len(out, scalarVal->val.string.val, scalarVal->val.string.len);
350 break;
351 case jbvNumeric:
354 PointerGetDatum(scalarVal->val.numeric))));
355 break;
356 case jbvBool:
357 if (scalarVal->val.boolean)
358 appendBinaryStringInfo(out, "true", 4);
359 else
360 appendBinaryStringInfo(out, "false", 5);
361 break;
362 default:
363 elog(ERROR, "unknown jsonb scalar type");
364 }
365}
366
367/*
368 * For jsonb we always want the de-escaped value - that's what's in token
369 */
371jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
372{
373 JsonbInState *_state = (JsonbInState *) pstate;
374 JsonbValue v;
375 Datum numd;
376
377 switch (tokentype)
378 {
379
381 Assert(token != NULL);
382 v.type = jbvString;
383 v.val.string.len = strlen(token);
384 if (!checkStringLen(v.val.string.len, _state->escontext))
386 v.val.string.val = token;
387 break;
389
390 /*
391 * No need to check size of numeric values, because maximum
392 * numeric size is well below the JsonbValue restriction
393 */
394 Assert(token != NULL);
395 v.type = jbvNumeric;
397 InvalidOid, -1,
398 _state->escontext,
399 &numd))
401 v.val.numeric = DatumGetNumeric(numd);
402 break;
403 case JSON_TOKEN_TRUE:
404 v.type = jbvBool;
405 v.val.boolean = true;
406 break;
407 case JSON_TOKEN_FALSE:
408 v.type = jbvBool;
409 v.val.boolean = false;
410 break;
411 case JSON_TOKEN_NULL:
412 v.type = jbvNull;
413 break;
414 default:
415 /* should not be possible */
416 elog(ERROR, "invalid json token type");
417 break;
418 }
419
420 if (_state->parseState == NULL)
421 {
422 /* single scalar */
424
425 va.type = jbvArray;
426 va.val.array.rawScalar = true;
427 va.val.array.nElems = 1;
428
432 }
433 else
434 {
435 JsonbValue *o = &_state->parseState->contVal;
436
437 switch (o->type)
438 {
439 case jbvArray:
441 break;
442 case jbvObject:
444 break;
445 default:
446 elog(ERROR, "unexpected parent of nested structure");
447 }
448 }
449
450 return JSON_SUCCESS;
451}
452
453/*
454 * JsonbToCString
455 * Converts jsonb value to a C-string.
456 *
457 * If 'out' argument is non-null, the resulting C-string is stored inside the
458 * StringBuffer. The resulting string is always returned.
459 *
460 * A typical case for passing the StringInfo in rather than NULL is where the
461 * caller wants access to the len attribute without having to call strlen, e.g.
462 * if they are converting it to a text* object.
463 */
464char *
466{
467 return JsonbToCStringWorker(out, in, estimated_len, false);
468}
469
470/*
471 * same thing but with indentation turned on
472 */
473char *
478
479/*
480 * common worker for above two functions
481 */
482static char *
484{
485 bool first = true;
487 JsonbValue v;
489 int level = 0;
490 bool redo_switch = false;
491
492 /* If we are indenting, don't add a space after a comma */
493 int ispaces = indent ? 1 : 2;
494
495 /*
496 * Don't indent the very first item. This gets set to the indent flag at
497 * the bottom of the loop.
498 */
499 bool use_indent = false;
500 bool raw_scalar = false;
501 bool last_was_key = false;
502
503 if (out == NULL)
504 out = makeStringInfo();
505
507
508 it = JsonbIteratorInit(in);
509
510 while (redo_switch ||
511 ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE))
512 {
513 redo_switch = false;
514 switch (type)
515 {
516 case WJB_BEGIN_ARRAY:
517 if (!first)
519
520 if (!v.val.array.rawScalar)
521 {
522 add_indent(out, use_indent && !last_was_key, level);
524 }
525 else
526 raw_scalar = true;
527
528 first = true;
529 level++;
530 break;
531 case WJB_BEGIN_OBJECT:
532 if (!first)
534
535 add_indent(out, use_indent && !last_was_key, level);
537
538 first = true;
539 level++;
540 break;
541 case WJB_KEY:
542 if (!first)
544 first = true;
545
546 add_indent(out, use_indent, level);
547
548 /* json rules guarantee this is a string */
550 appendBinaryStringInfo(out, ": ", 2);
551
552 type = JsonbIteratorNext(&it, &v, false);
553 if (type == WJB_VALUE)
554 {
555 first = false;
557 }
558 else
559 {
561
562 /*
563 * We need to rerun the current switch() since we need to
564 * output the object which we just got from the iterator
565 * before calling the iterator again.
566 */
567 redo_switch = true;
568 }
569 break;
570 case WJB_ELEM:
571 if (!first)
573 first = false;
574
575 if (!raw_scalar)
576 add_indent(out, use_indent, level);
578 break;
579 case WJB_END_ARRAY:
580 level--;
581 if (!raw_scalar)
582 {
583 add_indent(out, use_indent, level);
585 }
586 first = false;
587 break;
588 case WJB_END_OBJECT:
589 level--;
590 add_indent(out, use_indent, level);
592 first = false;
593 break;
594 default:
595 elog(ERROR, "unknown jsonb iterator token type");
596 }
597 use_indent = indent;
599 }
600
601 Assert(level == 0);
602
603 return out->data;
604}
605
606static void
607add_indent(StringInfo out, bool indent, int level)
608{
609 if (indent)
610 {
611 appendStringInfoCharMacro(out, '\n');
612 appendStringInfoSpaces(out, level * 4);
613 }
614}
615
616
617/*
618 * Turn a Datum into jsonb, adding it to the result JsonbInState.
619 *
620 * tcategory and outfuncoid are from a previous call to json_categorize_type,
621 * except that if is_null is true then they can be invalid.
622 *
623 * If key_scalar is true, the value is stored as a key, so insist
624 * it's of an acceptable type, and force it to be a jbvString.
625 *
626 * Note: currently, we assume that result->escontext is NULL and errors
627 * will be thrown.
628 */
629static void
632 bool key_scalar)
633{
634 char *outputstr;
638 bool scalar_jsonb = false;
639
641
642 /* Convert val to a JsonbValue in jb (in most cases) */
643 if (is_null)
644 {
646 jb.type = jbvNull;
647 }
648 else if (key_scalar &&
654 {
657 errmsg("key value must be scalar, not array, composite, or json")));
658 }
659 else
660 {
661 switch (tcategory)
662 {
663 case JSONTYPE_ARRAY:
665 break;
667 composite_to_jsonb(val, result);
668 break;
669 case JSONTYPE_BOOL:
670 if (key_scalar)
671 {
672 outputstr = DatumGetBool(val) ? "true" : "false";
673 jb.type = jbvString;
674 jb.val.string.len = strlen(outputstr);
675 jb.val.string.val = outputstr;
676 }
677 else
678 {
679 jb.type = jbvBool;
680 jb.val.boolean = DatumGetBool(val);
681 }
682 break;
683 case JSONTYPE_NUMERIC:
684 if (key_scalar)
685 {
686 /* always stringify keys */
687 numeric_to_string = true;
688 numeric_val = NULL; /* pacify stupider compilers */
689 }
690 else
691 {
692 Datum numd;
693
694 switch (outfuncoid)
695 {
696 case F_NUMERIC_OUT:
698 break;
699 case F_INT2OUT:
701 break;
702 case F_INT4OUT:
704 break;
705 case F_INT8OUT:
707 break;
708#ifdef NOT_USED
709
710 /*
711 * Ideally we'd short-circuit these two cases
712 * using float[48]_numeric. However, those
713 * functions are currently slower than the generic
714 * coerce-via-I/O approach. And they may round
715 * off differently. Until/unless that gets fixed,
716 * continue to use coerce-via-I/O for floats.
717 */
718 case F_FLOAT4OUT:
721 break;
722 case F_FLOAT8OUT:
725 break;
726#endif
727 default:
732 Int32GetDatum(-1));
734 break;
735 }
736 /* Must convert to string if it's Inf or NaN */
739 }
741 {
743 jb.type = jbvString;
744 jb.val.string.len = strlen(outputstr);
745 jb.val.string.val = outputstr;
746 }
747 else
748 {
749 jb.type = jbvNumeric;
750 jb.val.numeric = numeric_val;
751 }
752 break;
753 case JSONTYPE_DATE:
754 jb.type = jbvString;
755 jb.val.string.val = JsonEncodeDateTime(NULL, val,
756 DATEOID, NULL);
757 jb.val.string.len = strlen(jb.val.string.val);
758 break;
760 jb.type = jbvString;
761 jb.val.string.val = JsonEncodeDateTime(NULL, val,
763 jb.val.string.len = strlen(jb.val.string.val);
764 break;
766 jb.type = jbvString;
767 jb.val.string.val = JsonEncodeDateTime(NULL, val,
769 jb.val.string.len = strlen(jb.val.string.val);
770 break;
771 case JSONTYPE_CAST:
772 /* cast to JSON, and then process as JSON */
775 case JSONTYPE_JSON:
776 {
777 /* parse the json right into the existing result object */
778 JsonLexContext lex;
780 text *json = DatumGetTextPP(val);
781
782 makeJsonLexContext(&lex, json, true);
783
784 memset(&sem, 0, sizeof(sem));
785
786 sem.semstate = result;
787
794
796 freeJsonLexContext(&lex);
797 }
798 break;
799 case JSONTYPE_JSONB:
800 {
801 Jsonb *jsonb = DatumGetJsonbP(val);
803
804 it = JsonbIteratorInit(&jsonb->root);
805
806 if (JB_ROOT_IS_SCALAR(jsonb))
807 {
808 (void) JsonbIteratorNext(&it, &jb, true);
809 Assert(jb.type == jbvArray);
810 (void) JsonbIteratorNext(&it, &jb, true);
811 scalar_jsonb = true;
812 }
813 else
814 {
816
817 while ((type = JsonbIteratorNext(&it, &jb, false))
818 != WJB_DONE)
819 {
820 if (type == WJB_END_ARRAY || type == WJB_END_OBJECT ||
822 pushJsonbValue(result, type, NULL);
823 else
824 pushJsonbValue(result, type, &jb);
825 }
826 }
827 }
828 break;
829 default:
830 /* special-case text types to save useless palloc/memcpy ops */
831 if (outfuncoid == F_TEXTOUT ||
834 {
836
837 jb.val.string.len = VARSIZE_ANY_EXHDR(txt);
838 jb.val.string.val = VARDATA_ANY(txt);
839 }
840 else
841 {
843 jb.val.string.len = strlen(outputstr);
844 jb.val.string.val = outputstr;
845 }
846 jb.type = jbvString;
847 (void) checkStringLen(jb.val.string.len, NULL);
848 break;
849 }
850 }
851
852 /* Now insert jb into result, unless we did it recursively */
853 if (!is_null && !scalar_jsonb &&
855 {
856 /* work has been done recursively */
857 return;
858 }
859 else if (result->parseState == NULL)
860 {
861 /* single root scalar */
863
864 va.type = jbvArray;
865 va.val.array.rawScalar = true;
866 va.val.array.nElems = 1;
867
869 pushJsonbValue(result, WJB_ELEM, &jb);
871 }
872 else
873 {
874 JsonbValue *o = &result->parseState->contVal;
875
876 switch (o->type)
877 {
878 case jbvArray:
879 pushJsonbValue(result, WJB_ELEM, &jb);
880 break;
881 case jbvObject:
882 pushJsonbValue(result,
884 &jb);
885 break;
886 default:
887 elog(ERROR, "unexpected parent of nested structure");
888 }
889 }
890}
891
892/*
893 * Process a single dimension of an array.
894 * If it's the innermost dimension, output the values, otherwise call
895 * ourselves recursively to process the next dimension.
896 */
897static void
898array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, const Datum *vals,
899 const bool *nulls, int *valcount, JsonTypeCategory tcategory,
901{
902 int i;
903
904 Assert(dim < ndims);
905
907
908 for (i = 1; i <= dims[dim]; i++)
909 {
910 if (dim + 1 == ndims)
911 {
912 datum_to_jsonb_internal(vals[*valcount], nulls[*valcount], result, tcategory,
913 outfuncoid, false);
914 (*valcount)++;
915 }
916 else
917 {
918 array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
920 }
921 }
922
924}
925
926/*
927 * Turn an array into JSON.
928 */
929static void
931{
932 ArrayType *v = DatumGetArrayTypeP(array);
933 Oid element_type = ARR_ELEMTYPE(v);
934 int *dim;
935 int ndim;
936 int nitems;
937 int count = 0;
938 Datum *elements;
939 bool *nulls;
940 int16 typlen;
941 bool typbyval;
942 char typalign;
945
946 ndim = ARR_NDIM(v);
947 dim = ARR_DIMS(v);
948 nitems = ArrayGetNItems(ndim, dim);
949
950 if (nitems <= 0)
951 {
954 return;
955 }
956
957 get_typlenbyvalalign(element_type,
958 &typlen, &typbyval, &typalign);
959
960 json_categorize_type(element_type, true,
962
963 deconstruct_array(v, element_type, typlen, typbyval,
964 typalign, &elements, &nulls,
965 &nitems);
966
967 array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
968 outfuncoid);
969
970 pfree(elements);
971 pfree(nulls);
972}
973
974/*
975 * Turn a composite / record into JSON.
976 */
977static void
979{
981 Oid tupType;
983 TupleDesc tupdesc;
985 *tuple;
986 int i;
987
988 td = DatumGetHeapTupleHeader(composite);
989
990 /* Extract rowtype info and find a tupdesc */
994
995 /* Build a temporary HeapTuple control structure */
997 tmptup.t_data = td;
998 tuple = &tmptup;
999
1001
1002 for (i = 0; i < tupdesc->natts; i++)
1003 {
1004 Datum val;
1005 bool isnull;
1006 char *attname;
1009 JsonbValue v;
1011
1012 if (att->attisdropped)
1013 continue;
1014
1015 attname = NameStr(att->attname);
1016
1017 v.type = jbvString;
1018 /* don't need checkStringLen here - can't exceed maximum name length */
1019 v.val.string.len = strlen(attname);
1020 v.val.string.val = attname;
1021
1022 pushJsonbValue(result, WJB_KEY, &v);
1023
1024 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1025
1026 if (isnull)
1027 {
1030 }
1031 else
1032 json_categorize_type(att->atttypid, true, &tcategory,
1033 &outfuncoid);
1034
1036 false);
1037 }
1038
1040 ReleaseTupleDesc(tupdesc);
1041}
1042
1043/*
1044 * Append JSON text for "val" to "result".
1045 *
1046 * This is just a thin wrapper around datum_to_jsonb. If the same type will be
1047 * printed many times, avoid using this; better to do the json_categorize_type
1048 * lookups only once.
1049 */
1050
1051static void
1053 Oid val_type, bool key_scalar)
1054{
1057
1058 if (val_type == InvalidOid)
1059 ereport(ERROR,
1061 errmsg("could not determine input data type")));
1062
1063 if (is_null)
1064 {
1067 }
1068 else
1071
1073 key_scalar);
1074}
1075
1076
1077/*
1078 * Is the given type immutable when coming out of a JSONB context?
1079 */
1080bool
1082{
1083 bool has_mutable = false;
1084
1085 json_check_mutability(typoid, true, &has_mutable);
1086 return !has_mutable;
1087}
1088
1089/*
1090 * SQL function to_jsonb(anyvalue)
1091 */
1092Datum
1094{
1096 Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1099
1100 if (val_type == InvalidOid)
1101 ereport(ERROR,
1103 errmsg("could not determine input data type")));
1104
1107
1109}
1110
1111/*
1112 * Turn a Datum into jsonb.
1113 *
1114 * tcategory and outfuncoid are from a previous call to json_categorize_type.
1115 */
1116Datum
1118{
1119 JsonbInState result;
1120
1121 memset(&result, 0, sizeof(JsonbInState));
1122
1124 false);
1125
1126 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1127}
1128
1129Datum
1130jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
1131 bool absent_on_null, bool unique_keys)
1132{
1133 int i;
1134 JsonbInState result;
1135
1136 if (nargs % 2 != 0)
1137 ereport(ERROR,
1139 errmsg("argument list must have even number of elements"),
1140 /* translator: %s is a SQL function name */
1141 errhint("The arguments of %s must consist of alternating keys and values.",
1142 "jsonb_build_object()")));
1143
1144 memset(&result, 0, sizeof(JsonbInState));
1145
1147 result.parseState->unique_keys = unique_keys;
1148 result.parseState->skip_nulls = absent_on_null;
1149
1150 for (i = 0; i < nargs; i += 2)
1151 {
1152 /* process key */
1153 bool skip;
1154
1155 if (nulls[i])
1156 ereport(ERROR,
1158 errmsg("argument %d: key must not be null", i + 1)));
1159
1160 /* skip null values if absent_on_null */
1161 skip = absent_on_null && nulls[i + 1];
1162
1163 /* we need to save skipped keys for the key uniqueness check */
1164 if (skip && !unique_keys)
1165 continue;
1166
1167 add_jsonb(args[i], false, &result, types[i], true);
1168
1169 /* process value */
1170 add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1171 }
1172
1174
1175 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1176}
1177
1178/*
1179 * SQL function jsonb_build_object(variadic "any")
1180 */
1181Datum
1183{
1184 Datum *args;
1185 bool *nulls;
1186 Oid *types;
1187
1188 /* build argument values to build the object */
1189 int nargs = extract_variadic_args(fcinfo, 0, true,
1190 &args, &types, &nulls);
1191
1192 if (nargs < 0)
1194
1195 PG_RETURN_DATUM(jsonb_build_object_worker(nargs, args, nulls, types, false, false));
1196}
1197
1198/*
1199 * degenerate case of jsonb_build_object where it gets 0 arguments.
1200 */
1201Datum
1203{
1204 JsonbInState result;
1205
1206 memset(&result, 0, sizeof(JsonbInState));
1207
1210
1212}
1213
1214Datum
1215jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types,
1216 bool absent_on_null)
1217{
1218 int i;
1219 JsonbInState result;
1220
1221 memset(&result, 0, sizeof(JsonbInState));
1222
1224
1225 for (i = 0; i < nargs; i++)
1226 {
1227 if (absent_on_null && nulls[i])
1228 continue;
1229
1230 add_jsonb(args[i], nulls[i], &result, types[i], false);
1231 }
1232
1234
1235 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1236}
1237
1238/*
1239 * SQL function jsonb_build_array(variadic "any")
1240 */
1241Datum
1243{
1244 Datum *args;
1245 bool *nulls;
1246 Oid *types;
1247
1248 /* build argument values to build the object */
1249 int nargs = extract_variadic_args(fcinfo, 0, true,
1250 &args, &types, &nulls);
1251
1252 if (nargs < 0)
1254
1255 PG_RETURN_DATUM(jsonb_build_array_worker(nargs, args, nulls, types, false));
1256}
1257
1258
1259/*
1260 * degenerate case of jsonb_build_array where it gets 0 arguments.
1261 */
1262Datum
1264{
1265 JsonbInState result;
1266
1267 memset(&result, 0, sizeof(JsonbInState));
1268
1271
1273}
1274
1275
1276/*
1277 * SQL function jsonb_object(text[])
1278 *
1279 * take a one or two dimensional array of text as name value pairs
1280 * for a jsonb object.
1281 *
1282 */
1283Datum
1285{
1287 int ndims = ARR_NDIM(in_array);
1289 bool *in_nulls;
1290 int in_count,
1291 count,
1292 i;
1293 JsonbInState result;
1294
1295 memset(&result, 0, sizeof(JsonbInState));
1296
1298
1299 switch (ndims)
1300 {
1301 case 0:
1302 goto close_object;
1303 break;
1304
1305 case 1:
1306 if ((ARR_DIMS(in_array)[0]) % 2)
1307 ereport(ERROR,
1309 errmsg("array must have even number of elements")));
1310 break;
1311
1312 case 2:
1313 if ((ARR_DIMS(in_array)[1]) != 2)
1314 ereport(ERROR,
1316 errmsg("array must have two columns")));
1317 break;
1318
1319 default:
1320 ereport(ERROR,
1322 errmsg("wrong number of array subscripts")));
1323 }
1324
1326
1327 count = in_count / 2;
1328
1329 for (i = 0; i < count; ++i)
1330 {
1331 JsonbValue v;
1332 char *str;
1333 int len;
1334
1335 if (in_nulls[i * 2])
1336 ereport(ERROR,
1338 errmsg("null value not allowed for object key")));
1339
1341 len = strlen(str);
1342
1343 v.type = jbvString;
1344
1345 v.val.string.len = len;
1346 v.val.string.val = str;
1347
1348 pushJsonbValue(&result, WJB_KEY, &v);
1349
1350 if (in_nulls[i * 2 + 1])
1351 {
1352 v.type = jbvNull;
1353 }
1354 else
1355 {
1356 str = TextDatumGetCString(in_datums[i * 2 + 1]);
1357 len = strlen(str);
1358
1359 v.type = jbvString;
1360
1361 v.val.string.len = len;
1362 v.val.string.val = str;
1363 }
1364
1365 pushJsonbValue(&result, WJB_VALUE, &v);
1366 }
1367
1369 pfree(in_nulls);
1370
1373
1375}
1376
1377/*
1378 * SQL function jsonb_object(text[], text[])
1379 *
1380 * take separate name and value arrays of text to construct a jsonb object
1381 * pairwise.
1382 */
1383Datum
1385{
1388 int nkdims = ARR_NDIM(key_array);
1389 int nvdims = ARR_NDIM(val_array);
1391 *val_datums;
1392 bool *key_nulls,
1393 *val_nulls;
1394 int key_count,
1395 val_count,
1396 i;
1397 JsonbInState result;
1398
1399 memset(&result, 0, sizeof(JsonbInState));
1400
1402
1403 if (nkdims > 1 || nkdims != nvdims)
1404 ereport(ERROR,
1406 errmsg("wrong number of array subscripts")));
1407
1408 if (nkdims == 0)
1409 goto close_object;
1410
1413
1414 if (key_count != val_count)
1415 ereport(ERROR,
1417 errmsg("mismatched array dimensions")));
1418
1419 for (i = 0; i < key_count; ++i)
1420 {
1421 JsonbValue v;
1422 char *str;
1423 int len;
1424
1425 if (key_nulls[i])
1426 ereport(ERROR,
1428 errmsg("null value not allowed for object key")));
1429
1431 len = strlen(str);
1432
1433 v.type = jbvString;
1434
1435 v.val.string.len = len;
1436 v.val.string.val = str;
1437
1438 pushJsonbValue(&result, WJB_KEY, &v);
1439
1440 if (val_nulls[i])
1441 {
1442 v.type = jbvNull;
1443 }
1444 else
1445 {
1447 len = strlen(str);
1448
1449 v.type = jbvString;
1450
1451 v.val.string.len = len;
1452 v.val.string.val = str;
1453 }
1454
1455 pushJsonbValue(&result, WJB_VALUE, &v);
1456 }
1457
1462
1465
1467}
1468
1469
1470/*
1471 * Functions for jsonb_agg, jsonb_object_agg, and variants
1472 */
1473
1474static Datum
1475jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
1476{
1477 MemoryContext aggcontext;
1479 Datum val;
1480 JsonbInState *result;
1481
1482 if (!AggCheckCallContext(fcinfo, &aggcontext))
1483 {
1484 /* cannot be called directly because of internal-type argument */
1485 elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
1486 }
1487
1488 /* set up the accumulator on the first go round */
1489
1490 if (PG_ARGISNULL(0))
1491 {
1492 Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1493
1494 if (arg_type == InvalidOid)
1495 ereport(ERROR,
1497 errmsg("could not determine input data type")));
1498
1499 state = MemoryContextAllocZero(aggcontext, sizeof(JsonbAggState));
1500 result = &state->pstate;
1501 result->outcontext = aggcontext;
1503
1504 json_categorize_type(arg_type, true, &state->val_category,
1505 &state->val_output_func);
1506 }
1507 else
1508 {
1510 result = &state->pstate;
1511 }
1512
1513 if (absent_on_null && PG_ARGISNULL(1))
1515
1516 /*
1517 * We run this code in the normal function context, so that we don't leak
1518 * any cruft from datatype output functions and such into the aggcontext.
1519 * But the "result" JsonbValue will be constructed in aggcontext, so that
1520 * it remains available across calls.
1521 */
1522 val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
1523
1524 datum_to_jsonb_internal(val, PG_ARGISNULL(1), result, state->val_category,
1525 state->val_output_func, false);
1526
1528}
1529
1530/*
1531 * jsonb_agg aggregate function
1532 */
1533Datum
1535{
1536 return jsonb_agg_transfn_worker(fcinfo, false);
1537}
1538
1539/*
1540 * jsonb_agg_strict aggregate function
1541 */
1542Datum
1547
1548Datum
1550{
1552 JsonbInState result;
1553 Jsonb *out;
1554
1555 /* cannot be called directly because of internal-type argument */
1557
1558 if (PG_ARGISNULL(0))
1559 PG_RETURN_NULL(); /* returns null iff no input values */
1560
1562
1563 /*
1564 * The final function can be called more than once, so we must not change
1565 * the stored JsonbValue data structure. Fortunately, the WJB_END_ARRAY
1566 * action will only change fields in the JsonbInState struct itself, so we
1567 * can simply invoke pushJsonbValue on a local copy of that.
1568 */
1569 result = arg->pstate;
1570
1572
1573 /* We expect result.parseState == NULL after closing the array */
1574 Assert(result.parseState == NULL);
1575
1576 out = JsonbValueToJsonb(result.result);
1577
1578 PG_RETURN_POINTER(out);
1579}
1580
1581static Datum
1583 bool absent_on_null, bool unique_keys)
1584{
1585 MemoryContext aggcontext;
1587 Datum val;
1588 JsonbInState *result;
1589 bool skip;
1590
1591 if (!AggCheckCallContext(fcinfo, &aggcontext))
1592 {
1593 /* cannot be called directly because of internal-type argument */
1594 elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
1595 }
1596
1597 /* set up the accumulator on the first go round */
1598
1599 if (PG_ARGISNULL(0))
1600 {
1601 Oid arg_type;
1602
1603 state = MemoryContextAllocZero(aggcontext, sizeof(JsonbAggState));
1604 result = &state->pstate;
1605 result->outcontext = aggcontext;
1607 result->parseState->unique_keys = unique_keys;
1608 result->parseState->skip_nulls = absent_on_null;
1609
1610 arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1611
1612 if (arg_type == InvalidOid)
1613 ereport(ERROR,
1615 errmsg("could not determine input data type")));
1616
1617 json_categorize_type(arg_type, true, &state->key_category,
1618 &state->key_output_func);
1619
1620 arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1621
1622 if (arg_type == InvalidOid)
1623 ereport(ERROR,
1625 errmsg("could not determine input data type")));
1626
1627 json_categorize_type(arg_type, true, &state->val_category,
1628 &state->val_output_func);
1629 }
1630 else
1631 {
1633 result = &state->pstate;
1634 }
1635
1636 if (PG_ARGISNULL(1))
1637 ereport(ERROR,
1639 errmsg("field name must not be null")));
1640
1641 /*
1642 * Skip null values if absent_on_null unless key uniqueness check is
1643 * needed (because we must save keys in this case).
1644 */
1645 skip = absent_on_null && PG_ARGISNULL(2);
1646
1647 if (skip && !unique_keys)
1649
1650 /*
1651 * We run this code in the normal function context, so that we don't leak
1652 * any cruft from datatype output functions and such into the aggcontext.
1653 * But the "result" JsonbValue will be constructed in aggcontext, so that
1654 * it remains available across calls.
1655 */
1656 val = PG_GETARG_DATUM(1);
1657
1658 datum_to_jsonb_internal(val, false, result, state->key_category,
1659 state->key_output_func, true);
1660
1661 val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
1662
1663 datum_to_jsonb_internal(val, PG_ARGISNULL(2), result, state->val_category,
1664 state->val_output_func, false);
1665
1667}
1668
1669/*
1670 * jsonb_object_agg aggregate function
1671 */
1672Datum
1674{
1675 return jsonb_object_agg_transfn_worker(fcinfo, false, false);
1676}
1677
1678
1679/*
1680 * jsonb_object_agg_strict aggregate function
1681 */
1682Datum
1687
1688/*
1689 * jsonb_object_agg_unique aggregate function
1690 */
1691Datum
1696
1697/*
1698 * jsonb_object_agg_unique_strict aggregate function
1699 */
1700Datum
1705
1706Datum
1708{
1710 JsonbInState result;
1711 Jsonb *out;
1712
1713 /* cannot be called directly because of internal-type argument */
1715
1716 if (PG_ARGISNULL(0))
1717 PG_RETURN_NULL(); /* returns null iff no input values */
1718
1720
1721 /*
1722 * The final function can be called more than once, so we must not change
1723 * the stored JsonbValue data structure. Fortunately, the WJB_END_OBJECT
1724 * action will only destructively change fields in the JsonbInState struct
1725 * itself, so we can simply invoke pushJsonbValue on a local copy of that.
1726 * Note that this will run uniqueifyJsonbObject each time; that's hard to
1727 * avoid, since duplicate pairs may have been added since the previous
1728 * finalization. We assume uniqueifyJsonbObject can be applied repeatedly
1729 * (with the same unique_keys/skip_nulls options) without damaging the
1730 * data structure.
1731 */
1732 result = arg->pstate;
1733
1735
1736 /* We expect result.parseState == NULL after closing the object */
1737 Assert(result.parseState == NULL);
1738
1739 out = JsonbValueToJsonb(result.result);
1740
1741 PG_RETURN_POINTER(out);
1742}
1743
1744
1745/*
1746 * Extract scalar value from raw-scalar pseudo-array jsonb.
1747 */
1748bool
1750{
1753 JsonbValue tmp;
1754
1756 {
1757 /* inform caller about actual type of container */
1758 res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1759 return false;
1760 }
1761
1762 /*
1763 * A root scalar is stored as an array of one element, so we get the array
1764 * and then its first (and only) member.
1765 */
1766 it = JsonbIteratorInit(jbc);
1767
1768 tok = JsonbIteratorNext(&it, &tmp, true);
1770 Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1771
1772 tok = JsonbIteratorNext(&it, res, true);
1773 Assert(tok == WJB_ELEM);
1774 Assert(IsAJsonbScalar(res));
1775
1776 tok = JsonbIteratorNext(&it, &tmp, true);
1778
1779 tok = JsonbIteratorNext(&it, &tmp, true);
1780 Assert(tok == WJB_DONE);
1781
1782 return true;
1783}
1784
1785/*
1786 * Emit correct, translatable cast error message
1787 */
1788static void
1789cannotCastJsonbValue(enum jbvType type, const char *sqltype)
1790{
1791 static const struct
1792 {
1793 enum jbvType type;
1794 const char *msg;
1795 }
1796 messages[] =
1797 {
1798 {jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
1799 {jbvString, gettext_noop("cannot cast jsonb string to type %s")},
1800 {jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
1801 {jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
1802 {jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
1803 {jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
1804 {jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
1805 };
1806 int i;
1807
1808 for (i = 0; i < lengthof(messages); i++)
1809 if (messages[i].type == type)
1810 ereport(ERROR,
1812 errmsg(messages[i].msg, sqltype)));
1813
1814 /* should be unreachable */
1815 elog(ERROR, "unknown jsonb type: %d", (int) type);
1816}
1817
1818Datum
1820{
1821 Jsonb *in = PG_GETARG_JSONB_P(0);
1822 JsonbValue v;
1823
1824 if (!JsonbExtractScalar(&in->root, &v))
1825 cannotCastJsonbValue(v.type, "boolean");
1826
1827 if (v.type == jbvNull)
1828 {
1829 PG_FREE_IF_COPY(in, 0);
1831 }
1832
1833 if (v.type != jbvBool)
1834 cannotCastJsonbValue(v.type, "boolean");
1835
1836 PG_FREE_IF_COPY(in, 0);
1837
1838 PG_RETURN_BOOL(v.val.boolean);
1839}
1840
1841Datum
1843{
1844 Jsonb *in = PG_GETARG_JSONB_P(0);
1845 JsonbValue v;
1847
1848 if (!JsonbExtractScalar(&in->root, &v))
1849 cannotCastJsonbValue(v.type, "numeric");
1850
1851 if (v.type == jbvNull)
1852 {
1853 PG_FREE_IF_COPY(in, 0);
1855 }
1856
1857 if (v.type != jbvNumeric)
1858 cannotCastJsonbValue(v.type, "numeric");
1859
1860 /*
1861 * v.val.numeric points into jsonb body, so we need to make a copy to
1862 * return
1863 */
1865
1866 PG_FREE_IF_COPY(in, 0);
1867
1869}
1870
1871Datum
1873{
1874 Jsonb *in = PG_GETARG_JSONB_P(0);
1875 JsonbValue v;
1877
1878 if (!JsonbExtractScalar(&in->root, &v))
1879 cannotCastJsonbValue(v.type, "smallint");
1880
1881 if (v.type == jbvNull)
1882 {
1883 PG_FREE_IF_COPY(in, 0);
1885 }
1886
1887 if (v.type != jbvNumeric)
1888 cannotCastJsonbValue(v.type, "smallint");
1889
1891 NumericGetDatum(v.val.numeric));
1892
1893 PG_FREE_IF_COPY(in, 0);
1894
1896}
1897
1898Datum
1900{
1901 Jsonb *in = PG_GETARG_JSONB_P(0);
1902 JsonbValue v;
1904
1905 if (!JsonbExtractScalar(&in->root, &v))
1906 cannotCastJsonbValue(v.type, "integer");
1907
1908 if (v.type == jbvNull)
1909 {
1910 PG_FREE_IF_COPY(in, 0);
1912 }
1913
1914 if (v.type != jbvNumeric)
1915 cannotCastJsonbValue(v.type, "integer");
1916
1918 NumericGetDatum(v.val.numeric));
1919
1920 PG_FREE_IF_COPY(in, 0);
1921
1923}
1924
1925Datum
1927{
1928 Jsonb *in = PG_GETARG_JSONB_P(0);
1929 JsonbValue v;
1931
1932 if (!JsonbExtractScalar(&in->root, &v))
1933 cannotCastJsonbValue(v.type, "bigint");
1934
1935 if (v.type == jbvNull)
1936 {
1937 PG_FREE_IF_COPY(in, 0);
1939 }
1940
1941 if (v.type != jbvNumeric)
1942 cannotCastJsonbValue(v.type, "bigint");
1943
1945 NumericGetDatum(v.val.numeric));
1946
1947 PG_FREE_IF_COPY(in, 0);
1948
1950}
1951
1952Datum
1954{
1955 Jsonb *in = PG_GETARG_JSONB_P(0);
1956 JsonbValue v;
1958
1959 if (!JsonbExtractScalar(&in->root, &v))
1960 cannotCastJsonbValue(v.type, "real");
1961
1962 if (v.type == jbvNull)
1963 {
1964 PG_FREE_IF_COPY(in, 0);
1966 }
1967
1968 if (v.type != jbvNumeric)
1969 cannotCastJsonbValue(v.type, "real");
1970
1972 NumericGetDatum(v.val.numeric));
1973
1974 PG_FREE_IF_COPY(in, 0);
1975
1977}
1978
1979Datum
1981{
1982 Jsonb *in = PG_GETARG_JSONB_P(0);
1983 JsonbValue v;
1985
1986 if (!JsonbExtractScalar(&in->root, &v))
1987 cannotCastJsonbValue(v.type, "double precision");
1988
1989 if (v.type == jbvNull)
1990 {
1991 PG_FREE_IF_COPY(in, 0);
1993 }
1994
1995 if (v.type != jbvNumeric)
1996 cannotCastJsonbValue(v.type, "double precision");
1997
1999 NumericGetDatum(v.val.numeric));
2000
2001 PG_FREE_IF_COPY(in, 0);
2002
2004}
2005
2006/*
2007 * Convert jsonb to a C-string stripping quotes from scalar strings.
2008 */
2009char *
2011{
2012 if (JB_ROOT_IS_SCALAR(jb))
2013 {
2014 JsonbValue v;
2015
2016 (void) JsonbExtractScalar(&jb->root, &v);
2017
2018 if (v.type == jbvString)
2019 return pnstrdup(v.val.string.val, v.val.string.len);
2020 else if (v.type == jbvBool)
2021 return pstrdup(v.val.boolean ? "true" : "false");
2022 else if (v.type == jbvNumeric)
2024 PointerGetDatum(v.val.numeric)));
2025 else if (v.type == jbvNull)
2026 return pstrdup("null");
2027 else
2028 {
2029 elog(ERROR, "unrecognized jsonb value type %d", v.type);
2030 return NULL;
2031 }
2032 }
2033 else
2034 return JsonbToCString(NULL, &jb->root, VARSIZE(jb));
2035}
#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_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
void deconstruct_array(const ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int ArrayGetNItems(int ndim, const int *dims)
Definition arrayutils.c:57
Datum float8_numeric(PG_FUNCTION_ARGS)
Definition numeric.c:4521
Numeric int64_to_numeric(int64 val)
Definition numeric.c:4259
Datum float4_numeric(PG_FUNCTION_ARGS)
Definition numeric.c:4615
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition numeric.c:4463
Datum numeric_int4(PG_FUNCTION_ARGS)
Definition numeric.c:4393
Datum numeric_out(PG_FUNCTION_ARGS)
Definition numeric.c:799
Datum numeric_int2(PG_FUNCTION_ARGS)
Definition numeric.c:4481
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition numeric.c:4556
Datum numeric_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
bool numeric_is_nan(Numeric num)
Definition numeric.c:834
Datum numeric_float4(PG_FUNCTION_ARGS)
Definition numeric.c:4650
bool numeric_is_inf(Numeric num)
Definition numeric.c:845
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:837
#define gettext_noop(x)
Definition c.h:1287
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243
#define Assert(condition)
Definition c.h:945
int16_t int16
Definition c.h:613
int32_t int32
Definition c.h:614
#define lengthof(array)
Definition c.h:875
#define pg_fallthrough
Definition c.h:152
struct typedefs * types
Definition ecpg.c:30
Datum arg
Definition elog.c:1322
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereturn(context, dummy_value,...)
Definition elog.h:278
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
Definition fmgr.c:1641
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition fmgr.c:1764
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1876
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:722
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define DatumGetHeapTupleHeader(X)
Definition fmgr.h:296
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition funcapi.c:2011
const char * str
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static int32 HeapTupleHeaderGetTypMod(const HeapTupleHeaderData *tup)
static uint32 HeapTupleHeaderGetDatumLength(const HeapTupleHeaderData *tup)
static Oid HeapTupleHeaderGetTypeId(const HeapTupleHeaderData *tup)
#define nitems(x)
Definition indent.h:31
#define token
long val
Definition informix.c:689
int i
Definition isn.c:77
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Definition json.c:311
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition json.c:1602
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
Definition jsonapi.c:392
void freeJsonLexContext(JsonLexContext *lex)
Definition jsonapi.c:687
JsonParseErrorType
Definition jsonapi.h:35
@ JSON_SEM_ACTION_FAILED
Definition jsonapi.h:59
@ JSON_SUCCESS
Definition jsonapi.h:36
JsonTokenType
Definition jsonapi.h:18
@ JSON_TOKEN_FALSE
Definition jsonapi.h:29
@ JSON_TOKEN_TRUE
Definition jsonapi.h:28
@ JSON_TOKEN_NULL
Definition jsonapi.h:30
@ JSON_TOKEN_NUMBER
Definition jsonapi.h:21
@ JSON_TOKEN_STRING
Definition jsonapi.h:20
Datum jsonb_from_text(text *js, bool unique_keys)
Definition jsonb.c:139
static Datum jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
Definition jsonb.c:1475
static JsonParseErrorType jsonb_in_object_start(void *pstate)
Definition jsonb.c:282
Datum jsonb_int4(PG_FUNCTION_ARGS)
Definition jsonb.c:1899
Datum jsonb_recv(PG_FUNCTION_ARGS)
Definition jsonb.c:80
Datum jsonb_object_agg_strict_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1683
Datum to_jsonb(PG_FUNCTION_ARGS)
Definition jsonb.c:1093
char * JsonbUnquote(Jsonb *jb)
Definition jsonb.c:2010
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition jsonb.c:1215
static Datum jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
Definition jsonb.c:240
static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition jsonb.c:630
Datum jsonb_build_array_noargs(PG_FUNCTION_ARGS)
Definition jsonb.c:1263
Datum jsonb_object_agg_unique_strict_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1701
Datum jsonb_in(PG_FUNCTION_ARGS)
Definition jsonb.c:64
Datum jsonb_build_object_noargs(PG_FUNCTION_ARGS)
Definition jsonb.c:1202
Datum jsonb_agg_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1534
Datum jsonb_object_two_arg(PG_FUNCTION_ARGS)
Definition jsonb.c:1384
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition jsonb.c:151
Datum jsonb_object_agg_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1673
static JsonParseErrorType jsonb_in_array_end(void *pstate)
Definition jsonb.c:313
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition jsonb.c:483
Datum jsonb_build_array(PG_FUNCTION_ARGS)
Definition jsonb.c:1242
Datum jsonb_int8(PG_FUNCTION_ARGS)
Definition jsonb.c:1926
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
Definition jsonb.c:341
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition jsonb.c:1789
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition jsonb.c:1052
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
Definition jsonb.c:323
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:465
Datum jsonb_object_agg_unique_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1692
Datum jsonb_out(PG_FUNCTION_ARGS)
Definition jsonb.c:99
Datum jsonb_numeric(PG_FUNCTION_ARGS)
Definition jsonb.c:1842
static void array_to_jsonb_internal(Datum array, JsonbInState *result)
Definition jsonb.c:930
const char * JsonbTypeName(JsonbValue *val)
Definition jsonb.c:172
Datum jsonb_object(PG_FUNCTION_ARGS)
Definition jsonb.c:1284
Datum jsonb_build_object_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
Definition jsonb.c:1130
Datum jsonb_int2(PG_FUNCTION_ARGS)
Definition jsonb.c:1872
static void composite_to_jsonb(Datum composite, JsonbInState *result)
Definition jsonb.c:978
Datum jsonb_float4(PG_FUNCTION_ARGS)
Definition jsonb.c:1953
Datum jsonb_agg_strict_transfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1543
static void add_indent(StringInfo out, bool indent, int level)
Definition jsonb.c:607
Datum jsonb_object_agg_finalfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1707
static JsonParseErrorType jsonb_in_array_start(void *pstate)
Definition jsonb.c:303
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition jsonb.c:1749
Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition jsonb.c:1117
Datum jsonb_build_object(PG_FUNCTION_ARGS)
Definition jsonb.c:1182
static Datum jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Definition jsonb.c:1582
Datum jsonb_typeof(PG_FUNCTION_ARGS)
Definition jsonb.c:221
Datum jsonb_bool(PG_FUNCTION_ARGS)
Definition jsonb.c:1819
char * JsonbToCStringIndent(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:474
static JsonParseErrorType jsonb_in_object_end(void *pstate)
Definition jsonb.c:293
static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
Definition jsonb.c:371
Datum jsonb_agg_finalfn(PG_FUNCTION_ARGS)
Definition jsonb.c:1549
Datum jsonb_float8(PG_FUNCTION_ARGS)
Definition jsonb.c:1980
bool to_jsonb_is_immutable(Oid typoid)
Definition jsonb.c:1081
static bool checkStringLen(size_t len, Node *escontext)
Definition jsonb.c:269
Datum jsonb_send(PG_FUNCTION_ARGS)
Definition jsonb.c:115
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, const Datum *vals, const bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid)
Definition jsonb.c:898
jbvType
Definition jsonb.h:228
@ jbvObject
Definition jsonb.h:236
@ jbvNumeric
Definition jsonb.h:232
@ jbvBool
Definition jsonb.h:233
@ jbvArray
Definition jsonb.h:235
@ jbvBinary
Definition jsonb.h:238
@ jbvNull
Definition jsonb.h:230
@ jbvDatetime
Definition jsonb.h:246
@ jbvString
Definition jsonb.h:231
#define JsonContainerIsScalar(jc)
Definition jsonb.h:209
#define JsonContainerIsArray(jc)
Definition jsonb.h:211
static Datum JsonbPGetDatum(const Jsonb *p)
Definition jsonb.h:413
#define IsAJsonbScalar(jsonbval)
Definition jsonb.h:299
#define JENTRY_OFFLENMASK
Definition jsonb.h:140
#define PG_GETARG_JSONB_P(x)
Definition jsonb.h:418
#define JsonContainerIsObject(jc)
Definition jsonb.h:210
static Jsonb * DatumGetJsonbP(Datum d)
Definition jsonb.h:401
#define JB_ROOT_IS_SCALAR(jbp_)
Definition jsonb.h:222
JsonbIteratorToken
Definition jsonb.h:21
@ WJB_KEY
Definition jsonb.h:23
@ WJB_DONE
Definition jsonb.h:22
@ WJB_END_ARRAY
Definition jsonb.h:27
@ WJB_VALUE
Definition jsonb.h:24
@ WJB_END_OBJECT
Definition jsonb.h:29
@ WJB_ELEM
Definition jsonb.h:25
@ WJB_BEGIN_OBJECT
Definition jsonb.h:28
@ WJB_BEGIN_ARRAY
Definition jsonb.h:26
void pushJsonbValue(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition jsonb_util.c:583
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition jsonb_util.c:935
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition jsonb_util.c:973
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition jsonb_util.c:96
JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)
Definition jsonfuncs.c:543
void json_check_mutability(Oid typoid, bool is_jsonb, bool *has_mutable)
Definition jsonfuncs.c:6078
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition jsonfuncs.c:5967
bool pg_parse_json_or_errsave(JsonLexContext *lex, const JsonSemAction *sem, Node *escontext)
Definition jsonfuncs.c:522
#define pg_parse_json_or_ereport(lex, sem)
Definition jsonfuncs.h:47
JsonTypeCategory
Definition jsonfuncs.h:69
@ JSONTYPE_JSON
Definition jsonfuncs.h:76
@ JSONTYPE_NULL
Definition jsonfuncs.h:70
@ JSONTYPE_TIMESTAMP
Definition jsonfuncs.h:74
@ JSONTYPE_NUMERIC
Definition jsonfuncs.h:72
@ JSONTYPE_DATE
Definition jsonfuncs.h:73
@ JSONTYPE_BOOL
Definition jsonfuncs.h:71
@ JSONTYPE_CAST
Definition jsonfuncs.h:80
@ JSONTYPE_COMPOSITE
Definition jsonfuncs.h:79
@ JSONTYPE_ARRAY
Definition jsonfuncs.h:78
@ JSONTYPE_TIMESTAMPTZ
Definition jsonfuncs.h:75
@ JSONTYPE_JSONB
Definition jsonfuncs.h:77
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2491
int GetDatabaseEncoding(void)
Definition mbutils.c:1389
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
char * pnstrdup(const char *in, Size len)
Definition mcxt.c:1792
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609
static Numeric DatumGetNumericCopy(Datum X)
Definition numeric.h:70
static Numeric DatumGetNumeric(Datum X)
Definition numeric.h:64
#define PG_RETURN_NUMERIC(x)
Definition numeric.h:83
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76
static char * errmsg
NameData attname
FormData_pg_attribute * Form_pg_attribute
static const struct exclude_list_item skip[]
const void size_t len
static char buf[DEFAULT_XLOG_SEG_SIZE]
char typalign
Definition pg_type.h:178
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static int64 DatumGetInt64(Datum X)
Definition postgres.h:403
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static char * DatumGetCString(Datum X)
Definition postgres.h:355
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int16 DatumGetInt16(Datum X)
Definition postgres.h:162
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define InvalidOid
unsigned int Oid
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition pqformat.c:172
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition pqformat.c:545
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendint8(StringInfo buf, uint8 i)
Definition pqformat.h:128
static int fb(int x)
void check_stack_depth(void)
Definition stack_depth.c:95
struct StringInfoData * StringInfo
Definition string.h:15
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
void enlargeStringInfo(StringInfo str, int needed)
Definition stringinfo.c:337
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281
void appendStringInfoSpaces(StringInfo str, int count)
Definition stringinfo.c:260
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231
FmgrInfo * flinfo
Definition fmgr.h:87
json_struct_action array_end
Definition jsonapi.h:157
json_struct_action object_start
Definition jsonapi.h:154
json_ofield_action object_field_start
Definition jsonapi.h:158
json_scalar_action scalar
Definition jsonapi.h:162
void * semstate
Definition jsonapi.h:153
json_struct_action array_start
Definition jsonapi.h:156
json_struct_action object_end
Definition jsonapi.h:155
JsonTypeCategory val_category
Definition jsonb.c:33
JsonTypeCategory key_category
Definition jsonb.c:31
Oid key_output_func
Definition jsonb.c:32
JsonbInState pstate
Definition jsonb.c:30
Oid val_output_func
Definition jsonb.c:34
uint32 header
Definition jsonb.h:194
MemoryContext outcontext
Definition jsonb.h:334
JsonbValue * result
Definition jsonb.h:333
JsonbParseState * parseState
Definition jsonb.h:337
bool unique_keys
Definition jsonb.h:351
bool skip_nulls
Definition jsonb.h:352
JsonbValue contVal
Definition jsonb.h:348
enum jbvType type
Definition jsonb.h:257
char * val
Definition jsonb.h:266
Definition jsonb.h:215
JsonbContainer root
Definition jsonb.h:217
Definition nodes.h:135
Definition c.h:778
static JsonSemAction sem
#define ReleaseTupleDesc(tupdesc)
Definition tupdesc.h:238
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition typcache.c:1947
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static Size VARSIZE(const void *PTR)
Definition varatt.h:298
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
text * cstring_to_text(const char *s)
Definition varlena.c:184
const char * type