PostgreSQL Source Code git master
Loading...
Searching...
No Matches
jsonb.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/json.h"
#include "utils/jsonb.h"
#include "utils/jsonfuncs.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
Include dependency graph for jsonb.c:

Go to the source code of this file.

Data Structures

struct  JsonbAggState
 

Typedefs

typedef struct JsonbAggState JsonbAggState
 

Functions

static Datum jsonb_from_cstring (char *json, int len, bool unique_keys, Node *escontext)
 
static bool checkStringLen (size_t len, Node *escontext)
 
static JsonParseErrorType jsonb_in_object_start (void *pstate)
 
static JsonParseErrorType jsonb_in_object_end (void *pstate)
 
static JsonParseErrorType jsonb_in_array_start (void *pstate)
 
static JsonParseErrorType jsonb_in_array_end (void *pstate)
 
static JsonParseErrorType jsonb_in_object_field_start (void *pstate, char *fname, bool isnull)
 
static void jsonb_put_escaped_value (StringInfo out, JsonbValue *scalarVal)
 
static JsonParseErrorType jsonb_in_scalar (void *pstate, char *token, JsonTokenType tokentype)
 
static void composite_to_jsonb (Datum composite, JsonbInState *result)
 
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)
 
static void array_to_jsonb_internal (Datum array, JsonbInState *result)
 
static void datum_to_jsonb_internal (Datum val, bool is_null, JsonbInState *result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
 
static void add_jsonb (Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
 
static charJsonbToCStringWorker (StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
 
static void add_indent (StringInfo out, bool indent, int level)
 
Datum jsonb_in (PG_FUNCTION_ARGS)
 
Datum jsonb_recv (PG_FUNCTION_ARGS)
 
Datum jsonb_out (PG_FUNCTION_ARGS)
 
Datum jsonb_send (PG_FUNCTION_ARGS)
 
Datum jsonb_from_text (text *js, bool unique_keys)
 
static const charJsonbContainerTypeName (JsonbContainer *jbc)
 
const charJsonbTypeName (JsonbValue *val)
 
Datum jsonb_typeof (PG_FUNCTION_ARGS)
 
charJsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
charJsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
bool to_jsonb_is_immutable (Oid typoid)
 
Datum to_jsonb (PG_FUNCTION_ARGS)
 
Datum datum_to_jsonb (Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
 
Datum jsonb_build_object_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
 
Datum jsonb_build_object (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
 
Datum jsonb_build_array (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_object (PG_FUNCTION_ARGS)
 
Datum jsonb_object_two_arg (PG_FUNCTION_ARGS)
 
static Datum jsonb_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null)
 
Datum jsonb_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_finalfn (PG_FUNCTION_ARGS)
 
static Datum jsonb_object_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
 
Datum jsonb_object_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_unique_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_unique_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_finalfn (PG_FUNCTION_ARGS)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
static void cannotCastJsonbValue (enum jbvType type, const char *sqltype)
 
Datum jsonb_bool (PG_FUNCTION_ARGS)
 
Datum jsonb_numeric (PG_FUNCTION_ARGS)
 
Datum jsonb_int2 (PG_FUNCTION_ARGS)
 
Datum jsonb_int4 (PG_FUNCTION_ARGS)
 
Datum jsonb_int8 (PG_FUNCTION_ARGS)
 
Datum jsonb_float4 (PG_FUNCTION_ARGS)
 
Datum jsonb_float8 (PG_FUNCTION_ARGS)
 
charJsonbUnquote (Jsonb *jb)
 

Typedef Documentation

◆ JsonbAggState

Function Documentation

◆ add_indent()

static void add_indent ( StringInfo  out,
bool  indent,
int  level 
)
static

Definition at line 607 of file jsonb.c.

608{
609 if (indent)
610 {
611 appendStringInfoCharMacro(out, '\n');
612 appendStringInfoSpaces(out, level * 4);
613 }
614}
void appendStringInfoSpaces(StringInfo str, int count)
Definition stringinfo.c:260
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231

References appendStringInfoCharMacro, and appendStringInfoSpaces().

Referenced by JsonbToCStringWorker().

◆ add_jsonb()

static void add_jsonb ( Datum  val,
bool  is_null,
JsonbInState result,
Oid  val_type,
bool  key_scalar 
)
static

Definition at line 1052 of file jsonb.c.

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}
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
long val
Definition informix.c:689
static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition jsonb.c:630
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition jsonfuncs.c:5967
JsonTypeCategory
Definition jsonfuncs.h:69
@ JSONTYPE_NULL
Definition jsonfuncs.h:70
static char * errmsg
#define InvalidOid
unsigned int Oid
static int fb(int x)

References datum_to_jsonb_internal(), ereport, errcode(), errmsg, ERROR, fb(), InvalidOid, json_categorize_type(), JSONTYPE_NULL, and val.

Referenced by jsonb_build_array_worker(), and jsonb_build_object_worker().

◆ array_dim_to_jsonb()

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 
)
static

Definition at line 898 of file jsonb.c.

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}
#define Assert(condition)
Definition c.h:945
int i
Definition isn.c:77
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
@ WJB_END_ARRAY
Definition jsonb.h:27
@ WJB_BEGIN_ARRAY
Definition jsonb.h:26
void pushJsonbValue(JsonbInState *pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition jsonb_util.c:583

References array_dim_to_jsonb(), Assert, datum_to_jsonb_internal(), fb(), i, pushJsonbValue(), WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by array_dim_to_jsonb(), and array_to_jsonb_internal().

◆ array_to_jsonb_internal()

static void array_to_jsonb_internal ( Datum  array,
JsonbInState result 
)
static

Definition at line 930 of file jsonb.c.

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}
#define ARR_NDIM(a)
Definition array.h:290
#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(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
int16_t int16
Definition c.h:613
#define nitems(x)
Definition indent.h:31
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition lsyscache.c:2491
void pfree(void *pointer)
Definition mcxt.c:1616
char typalign
Definition pg_type.h:178
uint64_t Datum
Definition postgres.h:70

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_dim_to_jsonb(), ArrayGetNItems(), DatumGetArrayTypeP, deconstruct_array(), fb(), get_typlenbyvalalign(), json_categorize_type(), nitems, pfree(), pushJsonbValue(), typalign, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by datum_to_jsonb_internal().

◆ cannotCastJsonbValue()

static void cannotCastJsonbValue ( enum jbvType  type,
const char sqltype 
)
static

Definition at line 1789 of file jsonb.c.

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}
#define gettext_noop(x)
Definition c.h:1287
#define lengthof(array)
Definition c.h:875
#define elog(elevel,...)
Definition elog.h:226
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
@ jbvString
Definition jsonb.h:231
const char * type

References elog, ereport, errcode(), errmsg, ERROR, fb(), gettext_noop, i, jbvArray, jbvBinary, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, lengthof, and type.

Referenced by jsonb_bool(), jsonb_float4(), jsonb_float8(), jsonb_int2(), jsonb_int4(), jsonb_int8(), and jsonb_numeric().

◆ checkStringLen()

static bool checkStringLen ( size_t  len,
Node escontext 
)
static

Definition at line 269 of file jsonb.c.

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}
#define ereturn(context, dummy_value,...)
Definition elog.h:278
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define JENTRY_OFFLENMASK
Definition jsonb.h:140
const void size_t len

References ereturn, errcode(), errdetail(), errmsg, fb(), JENTRY_OFFLENMASK, and len.

Referenced by datum_to_jsonb_internal(), jsonb_in_object_field_start(), and jsonb_in_scalar().

◆ composite_to_jsonb()

static void composite_to_jsonb ( Datum  composite,
JsonbInState result 
)
static

Definition at line 978 of file jsonb.c.

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}
#define NameStr(name)
Definition c.h:837
int32_t int32
Definition c.h:614
#define DatumGetHeapTupleHeader(X)
Definition fmgr.h:296
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)
@ WJB_KEY
Definition jsonb.h:23
@ WJB_END_OBJECT
Definition jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition jsonb.h:28
NameData attname
FormData_pg_attribute * Form_pg_attribute
enum jbvType type
Definition jsonb.h:257
char * val
Definition jsonb.h:266
#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

References attname, datum_to_jsonb_internal(), DatumGetHeapTupleHeader, fb(), heap_getattr(), HeapTupleHeaderGetDatumLength(), HeapTupleHeaderGetTypeId(), HeapTupleHeaderGetTypMod(), i, InvalidOid, jbvString, json_categorize_type(), JSONTYPE_NULL, lookup_rowtype_tupdesc(), NameStr, TupleDescData::natts, pushJsonbValue(), ReleaseTupleDesc, TupleDescAttr(), JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, and WJB_KEY.

Referenced by datum_to_jsonb_internal().

◆ datum_to_jsonb()

Datum datum_to_jsonb ( Datum  val,
JsonTypeCategory  tcategory,
Oid  outfuncoid 
)

Definition at line 1117 of file jsonb.c.

1118{
1119 JsonbInState result;
1120
1121 memset(&result, 0, sizeof(JsonbInState));
1122
1124 false);
1125
1126 return JsonbPGetDatum(JsonbValueToJsonb(result.result));
1127}
static Datum JsonbPGetDatum(const Jsonb *p)
Definition jsonb.h:413
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition jsonb_util.c:96
JsonbValue * result
Definition jsonb.h:333

References datum_to_jsonb_internal(), fb(), JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::result, and val.

Referenced by ExecEvalJsonConstructor(), and to_jsonb().

◆ datum_to_jsonb_internal()

static void datum_to_jsonb_internal ( Datum  val,
bool  is_null,
JsonbInState result,
JsonTypeCategory  tcategory,
Oid  outfuncoid,
bool  key_scalar 
)
static

Definition at line 630 of file jsonb.c.

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}
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_in(PG_FUNCTION_ARGS)
Definition numeric.c:626
bool numeric_is_nan(Numeric num)
Definition numeric.c:834
bool numeric_is_inf(Numeric num)
Definition numeric.c:845
#define pg_fallthrough
Definition c.h:152
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition fmgr.c:1764
#define OidFunctionCall1(functionId, arg1)
Definition fmgr.h:722
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition fmgr.h:688
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Definition json.c:309
void freeJsonLexContext(JsonLexContext *lex)
Definition jsonapi.c:687
static JsonParseErrorType jsonb_in_object_start(void *pstate)
Definition jsonb.c:282
static JsonParseErrorType jsonb_in_array_end(void *pstate)
Definition jsonb.c:313
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
Definition jsonb.c:323
static void array_to_jsonb_internal(Datum array, JsonbInState *result)
Definition jsonb.c:930
static void composite_to_jsonb(Datum composite, JsonbInState *result)
Definition jsonb.c:978
static JsonParseErrorType jsonb_in_array_start(void *pstate)
Definition jsonb.c:303
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
static bool checkStringLen(size_t len, Node *escontext)
Definition jsonb.c:269
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_DONE
Definition jsonb.h:22
@ WJB_VALUE
Definition jsonb.h:24
@ WJB_ELEM
Definition jsonb.h:25
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition jsonb_util.c:935
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition jsonb_util.c:973
JsonLexContext * makeJsonLexContext(JsonLexContext *lex, text *json, bool need_escapes)
Definition jsonfuncs.c:543
#define pg_parse_json_or_ereport(lex, sem)
Definition jsonfuncs.h:47
@ JSONTYPE_JSON
Definition jsonfuncs.h:76
@ 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
static Numeric DatumGetNumeric(Datum X)
Definition numeric.h:64
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static int64 DatumGetInt64(Datum X)
Definition postgres.h:403
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
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
void check_stack_depth(void)
Definition stack_depth.c:95
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
JsonbParseState * parseState
Definition jsonb.h:337
JsonbValue contVal
Definition jsonb.h:348
Definition jsonb.h:215
JsonbContainer root
Definition jsonb.h:217
Definition c.h:778
static JsonSemAction sem
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486

References JsonSemAction::array_end, JsonSemAction::array_start, array_to_jsonb_internal(), Assert, check_stack_depth(), checkStringLen(), composite_to_jsonb(), JsonbParseState::contVal, CStringGetDatum(), DatumGetBool(), DatumGetInt16(), DatumGetInt32(), DatumGetInt64(), DatumGetJsonbP(), DatumGetNumeric(), DatumGetTextPP, DirectFunctionCall1, DirectFunctionCall3, elog, ereport, errcode(), errmsg, ERROR, fb(), float4_numeric(), float8_numeric(), freeJsonLexContext(), Int32GetDatum(), int64_to_numeric(), InvalidOid, JB_ROOT_IS_SCALAR, jbvArray, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, jsonb_in_array_end(), jsonb_in_array_start(), jsonb_in_object_end(), jsonb_in_object_field_start(), jsonb_in_object_start(), jsonb_in_scalar(), JsonbIteratorInit(), JsonbIteratorNext(), JsonEncodeDateTime(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_JSONB, JSONTYPE_NUMERIC, JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, makeJsonLexContext(), numeric_in(), numeric_is_inf(), numeric_is_nan(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, ObjectIdGetDatum(), OidFunctionCall1, OidOutputFunctionCall(), JsonbInState::parseState, pg_fallthrough, pg_parse_json_or_ereport, pushJsonbValue(), Jsonb::root, JsonSemAction::scalar, sem, JsonSemAction::semstate, type, JsonbValue::type, val, VARDATA_ANY(), VARSIZE_ANY_EXHDR(), WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by add_jsonb(), array_dim_to_jsonb(), composite_to_jsonb(), datum_to_jsonb(), jsonb_agg_transfn_worker(), and jsonb_object_agg_transfn_worker().

◆ jsonb_agg_finalfn()

Datum jsonb_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1549 of file jsonb.c.

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}
Datum arg
Definition elog.c:1322
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition nodeAgg.c:4609

References AggCheckCallContext(), arg, Assert, fb(), JsonbValueToJsonb(), JsonbInState::parseState, PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, and WJB_END_ARRAY.

◆ jsonb_agg_strict_transfn()

Datum jsonb_agg_strict_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1543 of file jsonb.c.

1544{
1545 return jsonb_agg_transfn_worker(fcinfo, true);
1546}
static Datum jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
Definition jsonb.c:1475

References jsonb_agg_transfn_worker().

◆ jsonb_agg_transfn()

Datum jsonb_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1534 of file jsonb.c.

1535{
1536 return jsonb_agg_transfn_worker(fcinfo, false);
1537}

References jsonb_agg_transfn_worker().

◆ jsonb_agg_transfn_worker()

static Datum jsonb_agg_transfn_worker ( FunctionCallInfo  fcinfo,
bool  absent_on_null 
)
static

Definition at line 1475 of file jsonb.c.

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}
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition fmgr.c:1876
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition mcxt.c:1266
FmgrInfo * flinfo
Definition fmgr.h:87
MemoryContext outcontext
Definition jsonb.h:334

References AggCheckCallContext(), datum_to_jsonb_internal(), elog, ereport, errcode(), errmsg, ERROR, fb(), FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), MemoryContextAllocZero(), JsonbInState::outcontext, PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, pushJsonbValue(), val, and WJB_BEGIN_ARRAY.

Referenced by jsonb_agg_strict_transfn(), and jsonb_agg_transfn().

◆ jsonb_bool()

Datum jsonb_bool ( PG_FUNCTION_ARGS  )

Definition at line 1819 of file jsonb.c.

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}
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition jsonb.c:1789
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition jsonb.c:1749
#define PG_GETARG_JSONB_P(x)
Definition jsonb.h:418

References cannotCastJsonbValue(), jbvBool, jbvNull, JsonbExtractScalar(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_BOOL, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_build_array()

Datum jsonb_build_array ( PG_FUNCTION_ARGS  )

Definition at line 1242 of file jsonb.c.

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}
struct typedefs * types
Definition ecpg.c:30
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition funcapi.c:2011
Datum jsonb_build_array_worker(int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition jsonb.c:1215

References extract_variadic_args(), jsonb_build_array_worker(), PG_RETURN_DATUM, PG_RETURN_NULL, and types.

◆ jsonb_build_array_noargs()

Datum jsonb_build_array_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1263 of file jsonb.c.

1264{
1265 JsonbInState result;
1266
1267 memset(&result, 0, sizeof(JsonbInState));
1268
1271
1273}

References fb(), JsonbValueToJsonb(), PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

◆ jsonb_build_array_worker()

Datum jsonb_build_array_worker ( int  nargs,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null 
)

Definition at line 1215 of file jsonb.c.

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}
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition jsonb.c:1052

References add_jsonb(), fb(), i, JsonbPGetDatum(), JsonbValueToJsonb(), pushJsonbValue(), JsonbInState::result, types, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by ExecEvalJsonConstructor(), and jsonb_build_array().

◆ jsonb_build_object()

Datum jsonb_build_object ( PG_FUNCTION_ARGS  )

Definition at line 1182 of file jsonb.c.

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}
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

References extract_variadic_args(), jsonb_build_object_worker(), PG_RETURN_DATUM, PG_RETURN_NULL, and types.

◆ jsonb_build_object_noargs()

Datum jsonb_build_object_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1202 of file jsonb.c.

1203{
1204 JsonbInState result;
1205
1206 memset(&result, 0, sizeof(JsonbInState));
1207
1210
1212}

References fb(), JsonbValueToJsonb(), PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, WJB_BEGIN_OBJECT, and WJB_END_OBJECT.

◆ jsonb_build_object_worker()

Datum jsonb_build_object_worker ( int  nargs,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null,
bool  unique_keys 
)

Definition at line 1130 of file jsonb.c.

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}
int errhint(const char *fmt,...) pg_attribute_printf(1
static const struct exclude_list_item skip[]
bool unique_keys
Definition jsonb.h:351
bool skip_nulls
Definition jsonb.h:352

References add_jsonb(), ereport, errcode(), errhint(), errmsg, ERROR, fb(), i, JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::result, skip, JsonbParseState::skip_nulls, types, JsonbParseState::unique_keys, WJB_BEGIN_OBJECT, and WJB_END_OBJECT.

Referenced by ExecEvalJsonConstructor(), and jsonb_build_object().

◆ jsonb_float4()

Datum jsonb_float4 ( PG_FUNCTION_ARGS  )

Definition at line 1953 of file jsonb.c.

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}
Datum numeric_float4(PG_FUNCTION_ARGS)
Definition numeric.c:4650
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76

References cannotCastJsonbValue(), DirectFunctionCall1, fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), numeric_float4(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_DATUM, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_float8()

Datum jsonb_float8 ( PG_FUNCTION_ARGS  )

Definition at line 1980 of file jsonb.c.

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}
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition numeric.c:4556

References cannotCastJsonbValue(), DirectFunctionCall1, fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), numeric_float8(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_DATUM, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_from_cstring()

static Datum jsonb_from_cstring ( char json,
int  len,
bool  unique_keys,
Node escontext 
)
inlinestatic

Definition at line 240 of file jsonb.c.

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}
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
Definition jsonapi.c:392
bool pg_parse_json_or_errsave(JsonLexContext *lex, const JsonSemAction *sem, Node *escontext)
Definition jsonfuncs.c:522
int GetDatabaseEncoding(void)
Definition mbutils.c:1389

References JsonSemAction::array_end, JsonSemAction::array_start, fb(), GetDatabaseEncoding(), jsonb_in_array_end(), jsonb_in_array_start(), jsonb_in_object_end(), jsonb_in_object_field_start(), jsonb_in_object_start(), jsonb_in_scalar(), JsonbValueToJsonb(), len, makeJsonLexContextCstringLen(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, pg_parse_json_or_errsave(), PG_RETURN_POINTER, JsonSemAction::scalar, sem, and JsonSemAction::semstate.

Referenced by jsonb_from_text(), jsonb_in(), and jsonb_recv().

◆ jsonb_from_text()

Datum jsonb_from_text ( text js,
bool  unique_keys 
)

Definition at line 139 of file jsonb.c.

140{
143 unique_keys,
144 NULL);
145}
static Datum jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
Definition jsonb.c:240

References fb(), jsonb_from_cstring(), VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by ExecEvalJsonConstructor().

◆ jsonb_in()

Datum jsonb_in ( PG_FUNCTION_ARGS  )

Definition at line 64 of file jsonb.c.

65{
66 char *json = PG_GETARG_CSTRING(0);
67
68 return jsonb_from_cstring(json, strlen(json), false, fcinfo->context);
69}
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278

References fb(), jsonb_from_cstring(), and PG_GETARG_CSTRING.

Referenced by ExecEvalJsonCoercion(), GetJsonBehaviorConst(), jsonb_set_lax(), JsonItemFromDatum(), and transformJsonBehavior().

◆ jsonb_in_array_end()

static JsonParseErrorType jsonb_in_array_end ( void pstate)
static

Definition at line 313 of file jsonb.c.

314{
315 JsonbInState *_state = (JsonbInState *) pstate;
316
318
319 return JSON_SUCCESS;
320}
@ JSON_SUCCESS
Definition jsonapi.h:36

References fb(), JSON_SUCCESS, pushJsonbValue(), and WJB_END_ARRAY.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_in_array_start()

static JsonParseErrorType jsonb_in_array_start ( void pstate)
static

Definition at line 303 of file jsonb.c.

304{
305 JsonbInState *_state = (JsonbInState *) pstate;
306
308
309 return JSON_SUCCESS;
310}

References fb(), JSON_SUCCESS, pushJsonbValue(), and WJB_BEGIN_ARRAY.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_in_object_end()

static JsonParseErrorType jsonb_in_object_end ( void pstate)
static

Definition at line 293 of file jsonb.c.

294{
295 JsonbInState *_state = (JsonbInState *) pstate;
296
298
299 return JSON_SUCCESS;
300}

References fb(), JSON_SUCCESS, pushJsonbValue(), and WJB_END_OBJECT.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_in_object_field_start()

static JsonParseErrorType jsonb_in_object_field_start ( void pstate,
char fname,
bool  isnull 
)
static

Definition at line 323 of file jsonb.c.

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}
@ JSON_SEM_ACTION_FAILED
Definition jsonapi.h:59

References Assert, checkStringLen(), fb(), jbvString, JSON_SEM_ACTION_FAILED, JSON_SUCCESS, pushJsonbValue(), JsonbValue::type, JsonbValue::val, and WJB_KEY.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_in_object_start()

static JsonParseErrorType jsonb_in_object_start ( void pstate)
static

Definition at line 282 of file jsonb.c.

283{
284 JsonbInState *_state = (JsonbInState *) pstate;
285
287 _state->parseState->unique_keys = _state->unique_keys;
288
289 return JSON_SUCCESS;
290}

References fb(), JSON_SUCCESS, pushJsonbValue(), and WJB_BEGIN_OBJECT.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_in_scalar()

static JsonParseErrorType jsonb_in_scalar ( void pstate,
char token,
JsonTokenType  tokentype 
)
static

Definition at line 371 of file jsonb.c.

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}
bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, Node *escontext, Datum *result)
Definition fmgr.c:1641
#define token
@ 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

References Assert, checkStringLen(), DatumGetNumeric(), DirectInputFunctionCallSafe(), elog, ERROR, fb(), InvalidOid, jbvArray, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, JSON_SEM_ACTION_FAILED, JSON_SUCCESS, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, numeric_in(), pushJsonbValue(), token, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_ELEM, WJB_END_ARRAY, and WJB_VALUE.

Referenced by datum_to_jsonb_internal(), and jsonb_from_cstring().

◆ jsonb_int2()

Datum jsonb_int2 ( PG_FUNCTION_ARGS  )

Definition at line 1872 of file jsonb.c.

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}
Datum numeric_int2(PG_FUNCTION_ARGS)
Definition numeric.c:4481

References cannotCastJsonbValue(), DirectFunctionCall1, fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), numeric_int2(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_DATUM, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_int4()

Datum jsonb_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1899 of file jsonb.c.

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}
Datum numeric_int4(PG_FUNCTION_ARGS)
Definition numeric.c:4393

References cannotCastJsonbValue(), DirectFunctionCall1, fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), numeric_int4(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_DATUM, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_int8()

Datum jsonb_int8 ( PG_FUNCTION_ARGS  )

Definition at line 1926 of file jsonb.c.

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}
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition numeric.c:4463

References cannotCastJsonbValue(), DirectFunctionCall1, fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), numeric_int8(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_DATUM, PG_RETURN_NULL, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_numeric()

Datum jsonb_numeric ( PG_FUNCTION_ARGS  )

Definition at line 1842 of file jsonb.c.

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}
static Numeric DatumGetNumericCopy(Datum X)
Definition numeric.h:70
#define PG_RETURN_NUMERIC(x)
Definition numeric.h:83

References cannotCastJsonbValue(), DatumGetNumericCopy(), fb(), jbvNull, jbvNumeric, JsonbExtractScalar(), NumericGetDatum(), PG_FREE_IF_COPY, PG_GETARG_JSONB_P, PG_RETURN_NULL, PG_RETURN_NUMERIC, Jsonb::root, JsonbValue::type, and JsonbValue::val.

◆ jsonb_object()

Datum jsonb_object ( PG_FUNCTION_ARGS  )

Definition at line 1284 of file jsonb.c.

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}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition array.h:263
void deconstruct_array_builtin(const ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
#define TextDatumGetCString(d)
Definition builtins.h:99
const char * str

References ARR_DIMS, ARR_NDIM, deconstruct_array_builtin(), ereport, errcode(), errmsg, ERROR, fb(), i, jbvNull, jbvString, JsonbValueToJsonb(), len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, str, TextDatumGetCString, JsonbValue::type, JsonbValue::val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ jsonb_object_agg_finalfn()

Datum jsonb_object_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1707 of file jsonb.c.

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}

References AggCheckCallContext(), arg, Assert, fb(), JsonbValueToJsonb(), JsonbInState::parseState, PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, and WJB_END_OBJECT.

◆ jsonb_object_agg_strict_transfn()

Datum jsonb_object_agg_strict_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1683 of file jsonb.c.

1684{
1685 return jsonb_object_agg_transfn_worker(fcinfo, true, false);
1686}
static Datum jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Definition jsonb.c:1582

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_transfn()

Datum jsonb_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1673 of file jsonb.c.

1674{
1675 return jsonb_object_agg_transfn_worker(fcinfo, false, false);
1676}

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_transfn_worker()

static Datum jsonb_object_agg_transfn_worker ( FunctionCallInfo  fcinfo,
bool  absent_on_null,
bool  unique_keys 
)
static

Definition at line 1582 of file jsonb.c.

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}

References AggCheckCallContext(), datum_to_jsonb_internal(), elog, ereport, errcode(), errmsg, ERROR, fb(), FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), MemoryContextAllocZero(), JsonbInState::outcontext, JsonbInState::parseState, PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, pushJsonbValue(), skip, JsonbParseState::skip_nulls, JsonbParseState::unique_keys, val, and WJB_BEGIN_OBJECT.

Referenced by jsonb_object_agg_strict_transfn(), jsonb_object_agg_transfn(), jsonb_object_agg_unique_strict_transfn(), and jsonb_object_agg_unique_transfn().

◆ jsonb_object_agg_unique_strict_transfn()

Datum jsonb_object_agg_unique_strict_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1701 of file jsonb.c.

1702{
1703 return jsonb_object_agg_transfn_worker(fcinfo, true, true);
1704}

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_unique_transfn()

Datum jsonb_object_agg_unique_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1692 of file jsonb.c.

1693{
1694 return jsonb_object_agg_transfn_worker(fcinfo, false, true);
1695}

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_two_arg()

Datum jsonb_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1384 of file jsonb.c.

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}

References ARR_NDIM, deconstruct_array_builtin(), ereport, errcode(), errmsg, ERROR, fb(), i, jbvNull, jbvString, JsonbValueToJsonb(), len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::result, str, TextDatumGetCString, JsonbValue::type, JsonbValue::val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ jsonb_out()

Datum jsonb_out ( PG_FUNCTION_ARGS  )

Definition at line 99 of file jsonb.c.

100{
102 char *out;
103
104 out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
105
107}
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition jsonb.c:465
static Size VARSIZE(const void *PTR)
Definition varatt.h:298

References fb(), JsonbToCString(), PG_GETARG_JSONB_P, PG_RETURN_CSTRING, and VARSIZE().

Referenced by ExecEvalJsonExprPath(), and ExecGetJsonValueItemString().

◆ jsonb_put_escaped_value()

static void jsonb_put_escaped_value ( StringInfo  out,
JsonbValue scalarVal 
)
static

Definition at line 341 of file jsonb.c.

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}
Datum numeric_out(PG_FUNCTION_ARGS)
Definition numeric.c:799
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition json.c:1601
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
static char * DatumGetCString(Datum X)
Definition postgres.h:355
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230

References appendBinaryStringInfo(), appendStringInfoString(), DatumGetCString(), DirectFunctionCall1, elog, ERROR, escape_json_with_len(), fb(), jbvBool, jbvNull, jbvNumeric, jbvString, StringInfoData::len, numeric_out(), and PointerGetDatum().

Referenced by JsonbToCStringWorker().

◆ jsonb_recv()

Datum jsonb_recv ( PG_FUNCTION_ARGS  )

Definition at line 80 of file jsonb.c.

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}
static char buf[DEFAULT_XLOG_SEG_SIZE]
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition pqformat.c:545
struct StringInfoData * StringInfo
Definition string.h:15

References buf, elog, ERROR, fb(), jsonb_from_cstring(), PG_GETARG_POINTER, pq_getmsgint(), pq_getmsgtext(), and str.

◆ jsonb_send()

Datum jsonb_send ( PG_FUNCTION_ARGS  )

Definition at line 115 of file jsonb.c.

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}
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition pqformat.c:172
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
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References buf, fb(), initStringInfo(), JsonbToCString(), pfree(), PG_GETARG_JSONB_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint8(), pq_sendtext(), and VARSIZE().

◆ jsonb_typeof()

Datum jsonb_typeof ( PG_FUNCTION_ARGS  )

Definition at line 221 of file jsonb.c.

222{
223 Jsonb *in = PG_GETARG_JSONB_P(0);
224 const char *result = JsonbContainerTypeName(&in->root);
225
227}
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition jsonb.c:151
text * cstring_to_text(const char *s)
Definition varlena.c:184

References cstring_to_text(), JsonbContainerTypeName(), PG_GETARG_JSONB_P, PG_RETURN_TEXT_P, and Jsonb::root.

◆ JsonbContainerTypeName()

static const char * JsonbContainerTypeName ( JsonbContainer jbc)
static

Definition at line 151 of file jsonb.c.

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}
const char * JsonbTypeName(JsonbValue *val)
Definition jsonb.c:172
#define JsonContainerIsArray(jc)
Definition jsonb.h:211
#define JsonContainerIsObject(jc)
Definition jsonb.h:210
uint32 header
Definition jsonb.h:194

References elog, ERROR, JsonbContainer::header, JsonbExtractScalar(), JsonbTypeName(), JsonContainerIsArray, and JsonContainerIsObject.

Referenced by jsonb_typeof(), and JsonbTypeName().

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1749 of file jsonb.c.

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}
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:243
#define JsonContainerIsScalar(jc)
Definition jsonb.h:209
#define IsAJsonbScalar(jsonbval)
Definition jsonb.h:299

References Assert, fb(), IsAJsonbScalar, jbvArray, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), JsonContainerIsArray, JsonContainerIsScalar, PG_USED_FOR_ASSERTS_ONLY, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, and WJB_END_ARRAY.

Referenced by executeJsonPath(), jsonb_bool(), jsonb_float4(), jsonb_float8(), jsonb_int2(), jsonb_int4(), jsonb_int8(), jsonb_numeric(), JsonbContainerTypeName(), JsonbUnquote(), JsonItemFromDatum(), and JsonPathValue().

◆ JsonbToCString()

char * JsonbToCString ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 465 of file jsonb.c.

466{
467 return JsonbToCStringWorker(out, in, estimated_len, false);
468}
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition jsonb.c:483

References fb(), and JsonbToCStringWorker().

Referenced by jsonb_get_element(), jsonb_out(), jsonb_send(), JsonbUnquote(), JsonbValueAsText(), and populate_scalar().

◆ JsonbToCStringIndent()

char * JsonbToCStringIndent ( StringInfo  out,
JsonbContainer in,
int  estimated_len 
)

Definition at line 474 of file jsonb.c.

475{
476 return JsonbToCStringWorker(out, in, estimated_len, true);
477}

References fb(), and JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToCStringWorker()

static char * JsonbToCStringWorker ( StringInfo  out,
JsonbContainer in,
int  estimated_len,
bool  indent 
)
static

Definition at line 483 of file jsonb.c.

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}
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal)
Definition jsonb.c:341
static void add_indent(StringInfo out, bool indent, int level)
Definition jsonb.c:607
StringInfo makeStringInfo(void)
Definition stringinfo.c:72
void enlargeStringInfo(StringInfo str, int needed)
Definition stringinfo.c:337

References add_indent(), appendBinaryStringInfo(), appendStringInfoCharMacro, Assert, StringInfoData::data, elog, enlargeStringInfo(), ERROR, fb(), jsonb_put_escaped_value(), JsonbIteratorInit(), JsonbIteratorNext(), makeStringInfo(), type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by JsonbToCString(), and JsonbToCStringIndent().

◆ JsonbTypeName()

const char * JsonbTypeName ( JsonbValue val)

Definition at line 172 of file jsonb.c.

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}
@ jbvDatetime
Definition jsonb.h:246

References elog, ERROR, fb(), jbvArray, jbvBinary, jbvBool, jbvDatetime, jbvNull, jbvNumeric, jbvObject, jbvString, JsonbContainerTypeName(), and val.

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ JsonbUnquote()

char * JsonbUnquote ( Jsonb jb)

Definition at line 2010 of file jsonb.c.

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}
char * pstrdup(const char *in)
Definition mcxt.c:1781
char * pnstrdup(const char *in, Size len)
Definition mcxt.c:1792

References DatumGetCString(), DirectFunctionCall1, elog, ERROR, fb(), JB_ROOT_IS_SCALAR, jbvBool, jbvNull, jbvNumeric, jbvString, JsonbExtractScalar(), JsonbToCString(), numeric_out(), pnstrdup(), PointerGetDatum(), pstrdup(), JsonbValue::type, JsonbValue::val, and VARSIZE().

Referenced by json_populate_type().

◆ to_jsonb()

Datum to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1093 of file jsonb.c.

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}
Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition jsonb.c:1117

References datum_to_jsonb(), ereport, errcode(), errmsg, ERROR, fb(), get_fn_expr_argtype(), InvalidOid, json_categorize_type(), PG_GETARG_DATUM, PG_RETURN_DATUM, and val.

◆ to_jsonb_is_immutable()

bool to_jsonb_is_immutable ( Oid  typoid)

Definition at line 1081 of file jsonb.c.

1082{
1083 bool has_mutable = false;
1084
1085 json_check_mutability(typoid, true, &has_mutable);
1086 return !has_mutable;
1087}
void json_check_mutability(Oid typoid, bool is_jsonb, bool *has_mutable)
Definition jsonfuncs.c:6078

References fb(), and json_check_mutability().

Referenced by contain_mutable_functions_walker().