PostgreSQL Source Code  git master
jsonb.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/transam.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "parser/parse_coerce.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/json.h"
#include "utils/jsonb.h"
#include "utils/jsonfuncs.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "utils/typcache.h"
Include dependency graph for jsonb.c:

Go to the source code of this file.

Data Structures

struct  JsonbInState
 
struct  JsonbAggState
 

Typedefs

typedef struct JsonbInState JsonbInState
 
typedef struct JsonbAggState JsonbAggState
 

Enumerations

enum  JsonbTypeCategory {
  JSONBTYPE_NULL , JSONBTYPE_BOOL , JSONBTYPE_NUMERIC , JSONBTYPE_DATE ,
  JSONBTYPE_TIMESTAMP , JSONBTYPE_TIMESTAMPTZ , JSONBTYPE_JSON , JSONBTYPE_JSONB ,
  JSONBTYPE_ARRAY , JSONBTYPE_COMPOSITE , JSONBTYPE_JSONCAST , JSONBTYPE_OTHER
}
 

Functions

static Datum jsonb_from_cstring (char *json, int len)
 
static size_t checkStringLen (size_t len)
 
static void jsonb_in_object_start (void *pstate)
 
static void jsonb_in_object_end (void *pstate)
 
static void jsonb_in_array_start (void *pstate)
 
static void jsonb_in_array_end (void *pstate)
 
static void jsonb_in_object_field_start (void *pstate, char *fname, bool isnull)
 
static void jsonb_put_escaped_value (StringInfo out, JsonbValue *scalarVal)
 
static void jsonb_in_scalar (void *pstate, char *token, JsonTokenType tokentype)
 
static void jsonb_categorize_type (Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
 
static void composite_to_jsonb (Datum composite, JsonbInState *result)
 
static void array_dim_to_jsonb (JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonbTypeCategory tcategory, Oid outfuncoid)
 
static void array_to_jsonb_internal (Datum array, JsonbInState *result)
 
static void datum_to_jsonb (Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
 
static void add_jsonb (Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
 
static JsonbParseStateclone_parse_state (JsonbParseState *state)
 
static char * JsonbToCStringWorker (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)
 
static const char * JsonbContainerTypeName (JsonbContainer *jbc)
 
const char * JsonbTypeName (JsonbValue *val)
 
Datum jsonb_typeof (PG_FUNCTION_ARGS)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
Datum to_jsonb (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object_noargs (PG_FUNCTION_ARGS)
 
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)
 
Datum jsonb_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_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)
 

Typedef Documentation

◆ JsonbAggState

typedef struct JsonbAggState JsonbAggState

◆ JsonbInState

typedef struct JsonbInState JsonbInState

Enumeration Type Documentation

◆ JsonbTypeCategory

Enumerator
JSONBTYPE_NULL 
JSONBTYPE_BOOL 
JSONBTYPE_NUMERIC 
JSONBTYPE_DATE 
JSONBTYPE_TIMESTAMP 
JSONBTYPE_TIMESTAMPTZ 
JSONBTYPE_JSON 
JSONBTYPE_JSONB 
JSONBTYPE_ARRAY 
JSONBTYPE_COMPOSITE 
JSONBTYPE_JSONCAST 
JSONBTYPE_OTHER 

Definition at line 39 of file jsonb.c.

40 {
41  JSONBTYPE_NULL, /* null, so we didn't bother to identify */
42  JSONBTYPE_BOOL, /* boolean (built-in types only) */
43  JSONBTYPE_NUMERIC, /* numeric (ditto) */
44  JSONBTYPE_DATE, /* we use special formatting for datetimes */
45  JSONBTYPE_TIMESTAMP, /* we use special formatting for timestamp */
46  JSONBTYPE_TIMESTAMPTZ, /* ... and timestamptz */
47  JSONBTYPE_JSON, /* JSON */
48  JSONBTYPE_JSONB, /* JSONB */
49  JSONBTYPE_ARRAY, /* array */
50  JSONBTYPE_COMPOSITE, /* composite */
51  JSONBTYPE_JSONCAST, /* something with an explicit cast to JSON */
52  JSONBTYPE_OTHER /* all else */
JsonbTypeCategory
Definition: jsonb.c:40
@ JSONBTYPE_OTHER
Definition: jsonb.c:52
@ JSONBTYPE_TIMESTAMPTZ
Definition: jsonb.c:46
@ JSONBTYPE_JSONB
Definition: jsonb.c:48
@ JSONBTYPE_DATE
Definition: jsonb.c:44
@ JSONBTYPE_NUMERIC
Definition: jsonb.c:43
@ JSONBTYPE_ARRAY
Definition: jsonb.c:49
@ JSONBTYPE_COMPOSITE
Definition: jsonb.c:50
@ JSONBTYPE_JSON
Definition: jsonb.c:47
@ JSONBTYPE_BOOL
Definition: jsonb.c:42
@ JSONBTYPE_NULL
Definition: jsonb.c:41
@ JSONBTYPE_TIMESTAMP
Definition: jsonb.c:45
@ JSONBTYPE_JSONCAST
Definition: jsonb.c:51

Function Documentation

◆ add_indent()

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

Definition at line 602 of file jsonb.c.

603 {
604  if (indent)
605  {
606  int i;
607 
608  appendStringInfoCharMacro(out, '\n');
609  for (i = 0; i < level; i++)
610  appendBinaryStringInfo(out, " ", 4);
611  }
612 }
int i
Definition: isn.c:73
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128

References appendBinaryStringInfo(), appendStringInfoCharMacro, and i.

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 1105 of file jsonb.c.

1107 {
1108  JsonbTypeCategory tcategory;
1109  Oid outfuncoid;
1110 
1111  if (val_type == InvalidOid)
1112  ereport(ERROR,
1113  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1114  errmsg("could not determine input data type")));
1115 
1116  if (is_null)
1117  {
1118  tcategory = JSONBTYPE_NULL;
1119  outfuncoid = InvalidOid;
1120  }
1121  else
1122  jsonb_categorize_type(val_type,
1123  &tcategory, &outfuncoid);
1124 
1125  datum_to_jsonb(val, is_null, result, tcategory, outfuncoid, key_scalar);
1126 }
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
long val
Definition: informix.c:664
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31

References datum_to_jsonb(), ereport, errcode(), errmsg(), ERROR, InvalidOid, jsonb_categorize_type(), JSONBTYPE_NULL, and val.

Referenced by jsonb_build_array(), and jsonb_build_object().

◆ array_dim_to_jsonb()

static void array_dim_to_jsonb ( JsonbInState result,
int  dim,
int  ndims,
int *  dims,
Datum vals,
bool nulls,
int *  valcount,
JsonbTypeCategory  tcategory,
Oid  outfuncoid 
)
static

Definition at line 953 of file jsonb.c.

956 {
957  int i;
958 
959  Assert(dim < ndims);
960 
961  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
962 
963  for (i = 1; i <= dims[dim]; i++)
964  {
965  if (dim + 1 == ndims)
966  {
967  datum_to_jsonb(vals[*valcount], nulls[*valcount], result, tcategory,
968  outfuncoid, false);
969  (*valcount)++;
970  }
971  else
972  {
973  array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
974  valcount, tcategory, outfuncoid);
975  }
976  }
977 
978  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
979 }
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonbTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:953
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:567
Assert(fmt[strlen(fmt) - 1] !='\n')
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35

References Assert(), datum_to_jsonb(), i, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by array_to_jsonb_internal().

◆ array_to_jsonb_internal()

static void array_to_jsonb_internal ( Datum  array,
JsonbInState result 
)
static

Definition at line 985 of file jsonb.c.

986 {
987  ArrayType *v = DatumGetArrayTypeP(array);
988  Oid element_type = ARR_ELEMTYPE(v);
989  int *dim;
990  int ndim;
991  int nitems;
992  int count = 0;
993  Datum *elements;
994  bool *nulls;
995  int16 typlen;
996  bool typbyval;
997  char typalign;
998  JsonbTypeCategory tcategory;
999  Oid outfuncoid;
1000 
1001  ndim = ARR_NDIM(v);
1002  dim = ARR_DIMS(v);
1003  nitems = ArrayGetNItems(ndim, dim);
1004 
1005  if (nitems <= 0)
1006  {
1007  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
1008  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
1009  return;
1010  }
1011 
1012  get_typlenbyvalalign(element_type,
1013  &typlen, &typbyval, &typalign);
1014 
1015  jsonb_categorize_type(element_type,
1016  &tcategory, &outfuncoid);
1017 
1018  deconstruct_array(v, element_type, typlen, typbyval,
1019  typalign, &elements, &nulls,
1020  &nitems);
1021 
1022  array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
1023  outfuncoid);
1024 
1025  pfree(elements);
1026  pfree(nulls);
1027 }
#define ARR_NDIM(a)
Definition: array.h:283
#define DatumGetArrayTypeP(X)
Definition: array.h:254
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_DIMS(a)
Definition: array.h:287
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3576
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
signed short int16
Definition: c.h:429
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2229
void pfree(void *pointer)
Definition: mcxt.c:1306
char typalign
Definition: pg_type.h:176
uintptr_t Datum
Definition: postgres.h:412

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_dim_to_jsonb(), ArrayGetNItems(), DatumGetArrayTypeP, deconstruct_array(), get_typlenbyvalalign(), jsonb_categorize_type(), JsonbInState::parseState, pfree(), pushJsonbValue(), JsonbInState::res, typalign, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

Referenced by datum_to_jsonb().

◆ cannotCastJsonbValue()

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

Definition at line 1927 of file jsonb.c.

1928 {
1929  static const struct
1930  {
1931  enum jbvType type;
1932  const char *msg;
1933  }
1934  messages[] =
1935  {
1936  {jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
1937  {jbvString, gettext_noop("cannot cast jsonb string to type %s")},
1938  {jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
1939  {jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
1940  {jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
1941  {jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
1942  {jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
1943  };
1944  int i;
1945 
1946  for (i = 0; i < lengthof(messages); i++)
1947  if (messages[i].type == type)
1948  ereport(ERROR,
1949  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1950  errmsg(messages[i].msg, sqltype)));
1951 
1952  /* should be unreachable */
1953  elog(ERROR, "unknown jsonb type: %d", (int) type);
1954 }
#define gettext_noop(x)
Definition: c.h:1135
#define lengthof(array)
Definition: c.h:724
jbvType
Definition: jsonb.h:226
@ jbvObject
Definition: jsonb.h:234
@ jbvNumeric
Definition: jsonb.h:230
@ jbvBool
Definition: jsonb.h:231
@ jbvArray
Definition: jsonb.h:233
@ jbvBinary
Definition: jsonb.h:236
@ jbvNull
Definition: jsonb.h:228
@ jbvString
Definition: jsonb.h:229

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

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

◆ checkStringLen()

static size_t checkStringLen ( size_t  len)
static

Definition at line 282 of file jsonb.c.

283 {
284  if (len > JENTRY_OFFLENMASK)
285  ereport(ERROR,
286  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
287  errmsg("string too long to represent as jsonb string"),
288  errdetail("Due to an implementation restriction, jsonb strings cannot exceed %d bytes.",
290 
291  return len;
292 }
int errdetail(const char *fmt,...)
Definition: elog.c:1039
#define JENTRY_OFFLENMASK
Definition: jsonb.h:138
const void size_t len

References ereport, errcode(), errdetail(), errmsg(), ERROR, JENTRY_OFFLENMASK, and len.

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

◆ clone_parse_state()

static JsonbParseState * clone_parse_state ( JsonbParseState state)
static

Definition at line 1469 of file jsonb.c.

1470 {
1471  JsonbParseState *result,
1472  *icursor,
1473  *ocursor;
1474 
1475  if (state == NULL)
1476  return NULL;
1477 
1478  result = palloc(sizeof(JsonbParseState));
1479  icursor = state;
1480  ocursor = result;
1481  for (;;)
1482  {
1483  ocursor->contVal = icursor->contVal;
1484  ocursor->size = icursor->size;
1485  icursor = icursor->next;
1486  if (icursor == NULL)
1487  break;
1488  ocursor->next = palloc(sizeof(JsonbParseState));
1489  ocursor = ocursor->next;
1490  }
1491  ocursor->next = NULL;
1492 
1493  return result;
1494 }
void * palloc(Size size)
Definition: mcxt.c:1199
struct JsonbParseState * next
Definition: jsonb.h:323
JsonbValue contVal
Definition: jsonb.h:321
Definition: regguts.h:318

References JsonbParseState::contVal, JsonbParseState::next, palloc(), and JsonbParseState::size.

Referenced by jsonb_agg_finalfn(), and jsonb_object_agg_finalfn().

◆ composite_to_jsonb()

static void composite_to_jsonb ( Datum  composite,
JsonbInState result 
)
static

Definition at line 1033 of file jsonb.c.

1034 {
1035  HeapTupleHeader td;
1036  Oid tupType;
1037  int32 tupTypmod;
1038  TupleDesc tupdesc;
1039  HeapTupleData tmptup,
1040  *tuple;
1041  int i;
1042 
1043  td = DatumGetHeapTupleHeader(composite);
1044 
1045  /* Extract rowtype info and find a tupdesc */
1046  tupType = HeapTupleHeaderGetTypeId(td);
1047  tupTypmod = HeapTupleHeaderGetTypMod(td);
1048  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1049 
1050  /* Build a temporary HeapTuple control structure */
1051  tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1052  tmptup.t_data = td;
1053  tuple = &tmptup;
1054 
1055  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_OBJECT, NULL);
1056 
1057  for (i = 0; i < tupdesc->natts; i++)
1058  {
1059  Datum val;
1060  bool isnull;
1061  char *attname;
1062  JsonbTypeCategory tcategory;
1063  Oid outfuncoid;
1064  JsonbValue v;
1065  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1066 
1067  if (att->attisdropped)
1068  continue;
1069 
1070  attname = NameStr(att->attname);
1071 
1072  v.type = jbvString;
1073  /* don't need checkStringLen here - can't exceed maximum name length */
1074  v.val.string.len = strlen(attname);
1075  v.val.string.val = attname;
1076 
1077  result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
1078 
1079  val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1080 
1081  if (isnull)
1082  {
1083  tcategory = JSONBTYPE_NULL;
1084  outfuncoid = InvalidOid;
1085  }
1086  else
1087  jsonb_categorize_type(att->atttypid, &tcategory, &outfuncoid);
1088 
1089  datum_to_jsonb(val, isnull, result, tcategory, outfuncoid, false);
1090  }
1091 
1092  result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
1093  ReleaseTupleDesc(tupdesc);
1094 }
#define NameStr(name)
Definition: c.h:682
signed int int32
Definition: c.h:430
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:788
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:462
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:452
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:446
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
NameData attname
Definition: pg_attribute.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
enum jbvType type
Definition: jsonb.h:255
char * val
Definition: jsonb.h:264
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1824

References attname, datum_to_jsonb(), DatumGetHeapTupleHeader, heap_getattr(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, i, InvalidOid, jbvString, jsonb_categorize_type(), JSONBTYPE_NULL, lookup_rowtype_tupdesc(), NameStr, TupleDescData::natts, JsonbInState::parseState, pushJsonbValue(), ReleaseTupleDesc, JsonbInState::res, HeapTupleData::t_data, HeapTupleData::t_len, TupleDescAttr, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, and WJB_KEY.

Referenced by datum_to_jsonb().

◆ datum_to_jsonb()

static void datum_to_jsonb ( Datum  val,
bool  is_null,
JsonbInState result,
JsonbTypeCategory  tcategory,
Oid  outfuncoid,
bool  key_scalar 
)
static

Definition at line 731 of file jsonb.c.

734 {
735  char *outputstr;
736  bool numeric_error;
737  JsonbValue jb;
738  bool scalar_jsonb = false;
739 
741 
742  /* Convert val to a JsonbValue in jb (in most cases) */
743  if (is_null)
744  {
745  Assert(!key_scalar);
746  jb.type = jbvNull;
747  }
748  else if (key_scalar &&
749  (tcategory == JSONBTYPE_ARRAY ||
750  tcategory == JSONBTYPE_COMPOSITE ||
751  tcategory == JSONBTYPE_JSON ||
752  tcategory == JSONBTYPE_JSONB ||
753  tcategory == JSONBTYPE_JSONCAST))
754  {
755  ereport(ERROR,
756  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
757  errmsg("key value must be scalar, not array, composite, or json")));
758  }
759  else
760  {
761  if (tcategory == JSONBTYPE_JSONCAST)
762  val = OidFunctionCall1(outfuncoid, val);
763 
764  switch (tcategory)
765  {
766  case JSONBTYPE_ARRAY:
767  array_to_jsonb_internal(val, result);
768  break;
769  case JSONBTYPE_COMPOSITE:
770  composite_to_jsonb(val, result);
771  break;
772  case JSONBTYPE_BOOL:
773  if (key_scalar)
774  {
775  outputstr = DatumGetBool(val) ? "true" : "false";
776  jb.type = jbvString;
777  jb.val.string.len = strlen(outputstr);
778  jb.val.string.val = outputstr;
779  }
780  else
781  {
782  jb.type = jbvBool;
783  jb.val.boolean = DatumGetBool(val);
784  }
785  break;
786  case JSONBTYPE_NUMERIC:
787  outputstr = OidOutputFunctionCall(outfuncoid, val);
788  if (key_scalar)
789  {
790  /* always quote keys */
791  jb.type = jbvString;
792  jb.val.string.len = strlen(outputstr);
793  jb.val.string.val = outputstr;
794  }
795  else
796  {
797  /*
798  * Make it numeric if it's a valid JSON number, otherwise
799  * a string. Invalid numeric output will always have an
800  * 'N' or 'n' in it (I think).
801  */
802  numeric_error = (strchr(outputstr, 'N') != NULL ||
803  strchr(outputstr, 'n') != NULL);
804  if (!numeric_error)
805  {
806  Datum numd;
807 
808  jb.type = jbvNumeric;
810  CStringGetDatum(outputstr),
812  Int32GetDatum(-1));
813  jb.val.numeric = DatumGetNumeric(numd);
814  pfree(outputstr);
815  }
816  else
817  {
818  jb.type = jbvString;
819  jb.val.string.len = strlen(outputstr);
820  jb.val.string.val = outputstr;
821  }
822  }
823  break;
824  case JSONBTYPE_DATE:
825  jb.type = jbvString;
826  jb.val.string.val = JsonEncodeDateTime(NULL, val,
827  DATEOID, NULL);
828  jb.val.string.len = strlen(jb.val.string.val);
829  break;
830  case JSONBTYPE_TIMESTAMP:
831  jb.type = jbvString;
832  jb.val.string.val = JsonEncodeDateTime(NULL, val,
833  TIMESTAMPOID, NULL);
834  jb.val.string.len = strlen(jb.val.string.val);
835  break;
837  jb.type = jbvString;
838  jb.val.string.val = JsonEncodeDateTime(NULL, val,
839  TIMESTAMPTZOID, NULL);
840  jb.val.string.len = strlen(jb.val.string.val);
841  break;
842  case JSONBTYPE_JSONCAST:
843  case JSONBTYPE_JSON:
844  {
845  /* parse the json right into the existing result object */
846  JsonLexContext *lex;
847  JsonSemAction sem;
848  text *json = DatumGetTextPP(val);
849 
850  lex = makeJsonLexContext(json, true);
851 
852  memset(&sem, 0, sizeof(sem));
853 
854  sem.semstate = (void *) result;
855 
860  sem.scalar = jsonb_in_scalar;
862 
863  pg_parse_json_or_ereport(lex, &sem);
864  }
865  break;
866  case JSONBTYPE_JSONB:
867  {
868  Jsonb *jsonb = DatumGetJsonbP(val);
869  JsonbIterator *it;
870 
871  it = JsonbIteratorInit(&jsonb->root);
872 
873  if (JB_ROOT_IS_SCALAR(jsonb))
874  {
875  (void) JsonbIteratorNext(&it, &jb, true);
876  Assert(jb.type == jbvArray);
877  (void) JsonbIteratorNext(&it, &jb, true);
878  scalar_jsonb = true;
879  }
880  else
881  {
883 
884  while ((type = JsonbIteratorNext(&it, &jb, false))
885  != WJB_DONE)
886  {
887  if (type == WJB_END_ARRAY || type == WJB_END_OBJECT ||
889  result->res = pushJsonbValue(&result->parseState,
890  type, NULL);
891  else
892  result->res = pushJsonbValue(&result->parseState,
893  type, &jb);
894  }
895  }
896  }
897  break;
898  default:
899  outputstr = OidOutputFunctionCall(outfuncoid, val);
900  jb.type = jbvString;
901  jb.val.string.len = checkStringLen(strlen(outputstr));
902  jb.val.string.val = outputstr;
903  break;
904  }
905  }
906 
907  /* Now insert jb into result, unless we did it recursively */
908  if (!is_null && !scalar_jsonb &&
909  tcategory >= JSONBTYPE_JSON && tcategory <= JSONBTYPE_JSONCAST)
910  {
911  /* work has been done recursively */
912  return;
913  }
914  else if (result->parseState == NULL)
915  {
916  /* single root scalar */
917  JsonbValue va;
918 
919  va.type = jbvArray;
920  va.val.array.rawScalar = true;
921  va.val.array.nElems = 1;
922 
923  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, &va);
924  result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
925  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
926  }
927  else
928  {
929  JsonbValue *o = &result->parseState->contVal;
930 
931  switch (o->type)
932  {
933  case jbvArray:
934  result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
935  break;
936  case jbvObject:
937  result->res = pushJsonbValue(&result->parseState,
938  key_scalar ? WJB_KEY : WJB_VALUE,
939  &jb);
940  break;
941  default:
942  elog(ERROR, "unexpected parent of nested structure");
943  }
944  }
945 }
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:617
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1639
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:680
#define DatumGetTextPP(X)
Definition: fmgr.h:292
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:646
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Definition: json.c:353
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
Definition: jsonb.c:371
static void jsonb_in_object_end(void *pstate)
Definition: jsonb.c:303
static void array_to_jsonb_internal(Datum array, JsonbInState *result)
Definition: jsonb.c:985
static void jsonb_in_array_start(void *pstate)
Definition: jsonb.c:311
static void composite_to_jsonb(Datum composite, JsonbInState *result)
Definition: jsonb.c:1033
static void jsonb_in_object_start(void *pstate)
Definition: jsonb.c:295
static size_t checkStringLen(size_t len)
Definition: jsonb.c:282
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
Definition: jsonb.c:327
static void jsonb_in_array_end(void *pstate)
Definition: jsonb.c:319
static Jsonb * DatumGetJsonbP(Datum d)
Definition: jsonb.h:372
#define JB_ROOT_IS_SCALAR(jbp_)
Definition: jsonb.h:220
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:813
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:849
void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonfuncs.c:501
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:517
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:60
void check_stack_depth(void)
Definition: postgres.c:3440
static bool DatumGetBool(Datum X)
Definition: postgres.h:438
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:698
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:560
json_struct_action array_end
Definition: jsonapi.h:110
json_struct_action object_start
Definition: jsonapi.h:107
json_ofield_action object_field_start
Definition: jsonapi.h:111
json_scalar_action scalar
Definition: jsonapi.h:115
void * semstate
Definition: jsonapi.h:106
json_struct_action array_start
Definition: jsonapi.h:109
json_struct_action object_end
Definition: jsonapi.h:108
Definition: jsonb.h:213
JsonbContainer root
Definition: jsonb.h:215
Definition: c.h:623

References JsonSemAction::array_end, JsonSemAction::array_start, array_to_jsonb_internal(), Assert(), check_stack_depth(), checkStringLen(), composite_to_jsonb(), JsonbParseState::contVal, CStringGetDatum(), DatumGetBool(), DatumGetJsonbP(), DatumGetNumeric(), DatumGetTextPP, DirectFunctionCall3, elog(), ereport, errcode(), errmsg(), ERROR, Int32GetDatum(), 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(), JSONBTYPE_ARRAY, JSONBTYPE_BOOL, JSONBTYPE_COMPOSITE, JSONBTYPE_DATE, JSONBTYPE_JSON, JSONBTYPE_JSONB, JSONBTYPE_JSONCAST, JSONBTYPE_NUMERIC, JSONBTYPE_TIMESTAMP, JSONBTYPE_TIMESTAMPTZ, JsonEncodeDateTime(), makeJsonLexContext(), numeric_in(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, ObjectIdGetDatum(), OidFunctionCall1, OidOutputFunctionCall(), JsonbInState::parseState, pfree(), pg_parse_json_or_ereport(), pushJsonbValue(), JsonbInState::res, Jsonb::root, JsonSemAction::scalar, JsonSemAction::semstate, generate_unaccent_rules::type, JsonbValue::type, JsonbValue::val, val, 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(), jsonb_agg_transfn(), jsonb_object_agg_transfn(), and to_jsonb().

◆ jsonb_agg_finalfn()

Datum jsonb_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1619 of file jsonb.c.

1620 {
1621  JsonbAggState *arg;
1622  JsonbInState result;
1623  Jsonb *out;
1624 
1625  /* cannot be called directly because of internal-type argument */
1626  Assert(AggCheckCallContext(fcinfo, NULL));
1627 
1628  if (PG_ARGISNULL(0))
1629  PG_RETURN_NULL(); /* returns null iff no input values */
1630 
1632 
1633  /*
1634  * We need to do a shallow clone of the argument in case the final
1635  * function is called more than once, so we avoid changing the argument. A
1636  * shallow clone is sufficient as we aren't going to change any of the
1637  * values, just add the final array end marker.
1638  */
1639 
1640  result.parseState = clone_parse_state(arg->res->parseState);
1641 
1642  result.res = pushJsonbValue(&result.parseState,
1643  WJB_END_ARRAY, NULL);
1644 
1645  out = JsonbValueToJsonb(result.res);
1646 
1647  PG_RETURN_POINTER(out);
1648 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static JsonbParseState * clone_parse_state(JsonbParseState *state)
Definition: jsonb.c:1469
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:93
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4509
void * arg

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

◆ jsonb_agg_transfn()

Datum jsonb_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1501 of file jsonb.c.

1502 {
1503  MemoryContext oldcontext,
1504  aggcontext;
1506  JsonbInState elem;
1507  Datum val;
1508  JsonbInState *result;
1509  bool single_scalar = false;
1510  JsonbIterator *it;
1511  Jsonb *jbelem;
1512  JsonbValue v;
1514 
1515  if (!AggCheckCallContext(fcinfo, &aggcontext))
1516  {
1517  /* cannot be called directly because of internal-type argument */
1518  elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
1519  }
1520 
1521  /* set up the accumulator on the first go round */
1522 
1523  if (PG_ARGISNULL(0))
1524  {
1525  Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1526 
1527  if (arg_type == InvalidOid)
1528  ereport(ERROR,
1529  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1530  errmsg("could not determine input data type")));
1531 
1532  oldcontext = MemoryContextSwitchTo(aggcontext);
1533  state = palloc(sizeof(JsonbAggState));
1534  result = palloc0(sizeof(JsonbInState));
1535  state->res = result;
1536  result->res = pushJsonbValue(&result->parseState,
1537  WJB_BEGIN_ARRAY, NULL);
1538  MemoryContextSwitchTo(oldcontext);
1539 
1540  jsonb_categorize_type(arg_type, &state->val_category,
1541  &state->val_output_func);
1542  }
1543  else
1544  {
1546  result = state->res;
1547  }
1548 
1549  /* turn the argument into jsonb in the normal function context */
1550 
1551  val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
1552 
1553  memset(&elem, 0, sizeof(JsonbInState));
1554 
1555  datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category,
1556  state->val_output_func, false);
1557 
1558  jbelem = JsonbValueToJsonb(elem.res);
1559 
1560  /* switch to the aggregate context for accumulation operations */
1561 
1562  oldcontext = MemoryContextSwitchTo(aggcontext);
1563 
1564  it = JsonbIteratorInit(&jbelem->root);
1565 
1566  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1567  {
1568  switch (type)
1569  {
1570  case WJB_BEGIN_ARRAY:
1571  if (v.val.array.rawScalar)
1572  single_scalar = true;
1573  else
1574  result->res = pushJsonbValue(&result->parseState,
1575  type, NULL);
1576  break;
1577  case WJB_END_ARRAY:
1578  if (!single_scalar)
1579  result->res = pushJsonbValue(&result->parseState,
1580  type, NULL);
1581  break;
1582  case WJB_BEGIN_OBJECT:
1583  case WJB_END_OBJECT:
1584  result->res = pushJsonbValue(&result->parseState,
1585  type, NULL);
1586  break;
1587  case WJB_ELEM:
1588  case WJB_KEY:
1589  case WJB_VALUE:
1590  if (v.type == jbvString)
1591  {
1592  /* copy string values in the aggregate context */
1593  char *buf = palloc(v.val.string.len + 1);
1594 
1595  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1596  v.val.string.val = buf;
1597  }
1598  else if (v.type == jbvNumeric)
1599  {
1600  /* same for numeric */
1601  v.val.numeric =
1603  NumericGetDatum(v.val.numeric)));
1604  }
1605  result->res = pushJsonbValue(&result->parseState,
1606  type, &v);
1607  break;
1608  default:
1609  elog(ERROR, "unknown jsonb iterator token type");
1610  }
1611  }
1612 
1613  MemoryContextSwitchTo(oldcontext);
1614 
1616 }
Datum numeric_uplus(PG_FUNCTION_ARGS)
Definition: numeric.c:1381
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1786
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
void * palloc0(Size size)
Definition: mcxt.c:1230
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:72
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:135
static char * buf
Definition: pg_test_fsync.c:67
#define snprintf
Definition: port.h:238

References AggCheckCallContext(), buf, datum_to_jsonb(), DatumGetNumeric(), DirectFunctionCall1, elog(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, jbvNumeric, jbvString, jsonb_categorize_type(), JsonbIteratorInit(), JsonbIteratorNext(), JsonbValueToJsonb(), MemoryContextSwitchTo(), numeric_uplus(), NumericGetDatum(), palloc(), palloc0(), JsonbInState::parseState, PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, Jsonb::root, snprintf, generate_unaccent_rules::type, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ jsonb_bool()

Datum jsonb_bool ( PG_FUNCTION_ARGS  )

Definition at line 1957 of file jsonb.c.

1958 {
1959  Jsonb *in = PG_GETARG_JSONB_P(0);
1960  JsonbValue v;
1961 
1962  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
1963  cannotCastJsonbValue(v.type, "boolean");
1964 
1965  PG_FREE_IF_COPY(in, 0);
1966 
1967  PG_RETURN_BOOL(v.val.boolean);
1968 }
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1927
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1887
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:389

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

◆ jsonb_build_array()

Datum jsonb_build_array ( PG_FUNCTION_ARGS  )

Definition at line 1225 of file jsonb.c.

1226 {
1227  int nargs;
1228  int i;
1229  JsonbInState result;
1230  Datum *args;
1231  bool *nulls;
1232  Oid *types;
1233 
1234  /* build argument values to build the array */
1235  nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1236 
1237  if (nargs < 0)
1238  PG_RETURN_NULL();
1239 
1240  memset(&result, 0, sizeof(JsonbInState));
1241 
1242  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1243 
1244  for (i = 0; i < nargs; i++)
1245  add_jsonb(args[i], nulls[i], &result, types[i], false);
1246 
1247  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1248 
1250 }
struct typedefs * types
Definition: ecpg.c:29
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:2006
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1105

References add_jsonb(), generate_unaccent_rules::args, extract_variadic_args(), i, JsonbValueToJsonb(), JsonbInState::parseState, PG_RETURN_NULL, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, types, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

◆ jsonb_build_array_noargs()

Datum jsonb_build_array_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1256 of file jsonb.c.

1257 {
1258  JsonbInState result;
1259 
1260  memset(&result, 0, sizeof(JsonbInState));
1261 
1262  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1263  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1264 
1266 }

References JsonbValueToJsonb(), JsonbInState::parseState, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, WJB_BEGIN_ARRAY, and WJB_END_ARRAY.

◆ jsonb_build_object()

Datum jsonb_build_object ( PG_FUNCTION_ARGS  )

Definition at line 1159 of file jsonb.c.

1160 {
1161  int nargs;
1162  int i;
1163  JsonbInState result;
1164  Datum *args;
1165  bool *nulls;
1166  Oid *types;
1167 
1168  /* build argument values to build the object */
1169  nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1170 
1171  if (nargs < 0)
1172  PG_RETURN_NULL();
1173 
1174  if (nargs % 2 != 0)
1175  ereport(ERROR,
1176  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1177  errmsg("argument list must have even number of elements"),
1178  /* translator: %s is a SQL function name */
1179  errhint("The arguments of %s must consist of alternating keys and values.",
1180  "jsonb_build_object()")));
1181 
1182  memset(&result, 0, sizeof(JsonbInState));
1183 
1184  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1185 
1186  for (i = 0; i < nargs; i += 2)
1187  {
1188  /* process key */
1189  if (nulls[i])
1190  ereport(ERROR,
1191  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1192  errmsg("argument %d: key must not be null", i + 1)));
1193 
1194  add_jsonb(args[i], false, &result, types[i], true);
1195 
1196  /* process value */
1197  add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1198  }
1199 
1200  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1201 
1203 }
int errhint(const char *fmt,...)
Definition: elog.c:1153

References add_jsonb(), generate_unaccent_rules::args, ereport, errcode(), errhint(), errmsg(), ERROR, extract_variadic_args(), i, JsonbValueToJsonb(), JsonbInState::parseState, PG_RETURN_NULL, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, types, WJB_BEGIN_OBJECT, and WJB_END_OBJECT.

◆ jsonb_build_object_noargs()

Datum jsonb_build_object_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1209 of file jsonb.c.

1210 {
1211  JsonbInState result;
1212 
1213  memset(&result, 0, sizeof(JsonbInState));
1214 
1215  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1216  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1217 
1219 }

References JsonbValueToJsonb(), JsonbInState::parseState, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, WJB_BEGIN_OBJECT, and WJB_END_OBJECT.

◆ jsonb_categorize_type()

static void jsonb_categorize_type ( Oid  typoid,
JsonbTypeCategory tcategory,
Oid outfuncoid 
)
static

Definition at line 623 of file jsonb.c.

626 {
627  bool typisvarlena;
628 
629  /* Look through any domain */
630  typoid = getBaseType(typoid);
631 
632  *outfuncoid = InvalidOid;
633 
634  /*
635  * We need to get the output function for everything except date and
636  * timestamp types, booleans, array and composite types, json and jsonb,
637  * and non-builtin types where there's a cast to json. In this last case
638  * we return the oid of the cast function instead.
639  */
640 
641  switch (typoid)
642  {
643  case BOOLOID:
644  *tcategory = JSONBTYPE_BOOL;
645  break;
646 
647  case INT2OID:
648  case INT4OID:
649  case INT8OID:
650  case FLOAT4OID:
651  case FLOAT8OID:
652  case NUMERICOID:
653  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
654  *tcategory = JSONBTYPE_NUMERIC;
655  break;
656 
657  case DATEOID:
658  *tcategory = JSONBTYPE_DATE;
659  break;
660 
661  case TIMESTAMPOID:
662  *tcategory = JSONBTYPE_TIMESTAMP;
663  break;
664 
665  case TIMESTAMPTZOID:
666  *tcategory = JSONBTYPE_TIMESTAMPTZ;
667  break;
668 
669  case JSONBOID:
670  *tcategory = JSONBTYPE_JSONB;
671  break;
672 
673  case JSONOID:
674  *tcategory = JSONBTYPE_JSON;
675  break;
676 
677  default:
678  /* Check for arrays and composites */
679  if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
680  || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)
681  *tcategory = JSONBTYPE_ARRAY;
682  else if (type_is_rowtype(typoid)) /* includes RECORDOID */
683  *tcategory = JSONBTYPE_COMPOSITE;
684  else
685  {
686  /* It's probably the general case ... */
687  *tcategory = JSONBTYPE_OTHER;
688 
689  /*
690  * but first let's look for a cast to json (note: not to
691  * jsonb) if it's not built-in.
692  */
693  if (typoid >= FirstNormalObjectId)
694  {
695  Oid castfunc;
696  CoercionPathType ctype;
697 
698  ctype = find_coercion_pathway(JSONOID, typoid,
699  COERCION_EXPLICIT, &castfunc);
700  if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
701  {
702  *tcategory = JSONBTYPE_JSONCAST;
703  *outfuncoid = castfunc;
704  }
705  else
706  {
707  /* not a cast type, so just get the usual output func */
708  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
709  }
710  }
711  else
712  {
713  /* any other builtin type */
714  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
715  }
716  break;
717  }
718  }
719 }
#define OidIsValid(objectId)
Definition: c.h:711
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2717
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2613
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2865
Oid getBaseType(Oid typid)
Definition: lsyscache.c:2479
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
CoercionPathType
Definition: parse_coerce.h:25
@ COERCION_PATH_FUNC
Definition: parse_coerce.h:27
@ COERCION_EXPLICIT
Definition: primnodes.h:569
#define FirstNormalObjectId
Definition: transam.h:197

References COERCION_EXPLICIT, COERCION_PATH_FUNC, find_coercion_pathway(), FirstNormalObjectId, get_element_type(), getBaseType(), getTypeOutputInfo(), InvalidOid, JSONBTYPE_ARRAY, JSONBTYPE_BOOL, JSONBTYPE_COMPOSITE, JSONBTYPE_DATE, JSONBTYPE_JSON, JSONBTYPE_JSONB, JSONBTYPE_JSONCAST, JSONBTYPE_NUMERIC, JSONBTYPE_OTHER, JSONBTYPE_TIMESTAMP, JSONBTYPE_TIMESTAMPTZ, OidIsValid, and type_is_rowtype().

Referenced by add_jsonb(), array_to_jsonb_internal(), composite_to_jsonb(), jsonb_agg_transfn(), jsonb_object_agg_transfn(), and to_jsonb().

◆ jsonb_float4()

Datum jsonb_float4 ( PG_FUNCTION_ARGS  )

Definition at line 2046 of file jsonb.c.

2047 {
2048  Jsonb *in = PG_GETARG_JSONB_P(0);
2049  JsonbValue v;
2050  Datum retValue;
2051 
2052  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2053  cannotCastJsonbValue(v.type, "real");
2054 
2056  NumericGetDatum(v.val.numeric));
2057 
2058  PG_FREE_IF_COPY(in, 0);
2059 
2060  PG_RETURN_DATUM(retValue);
2061 }
Datum numeric_float4(PG_FUNCTION_ARGS)
Definition: numeric.c:4519
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353

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

◆ jsonb_float8()

Datum jsonb_float8 ( PG_FUNCTION_ARGS  )

Definition at line 2064 of file jsonb.c.

2065 {
2066  Jsonb *in = PG_GETARG_JSONB_P(0);
2067  JsonbValue v;
2068  Datum retValue;
2069 
2070  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2071  cannotCastJsonbValue(v.type, "double precision");
2072 
2074  NumericGetDatum(v.val.numeric));
2075 
2076  PG_FREE_IF_COPY(in, 0);
2077 
2078  PG_RETURN_DATUM(retValue);
2079 }
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:4426

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

◆ jsonb_from_cstring()

static Datum jsonb_from_cstring ( char *  json,
int  len 
)
inlinestatic

Definition at line 256 of file jsonb.c.

257 {
258  JsonLexContext *lex;
260  JsonSemAction sem;
261 
262  memset(&state, 0, sizeof(state));
263  memset(&sem, 0, sizeof(sem));
265 
266  sem.semstate = (void *) &state;
267 
272  sem.scalar = jsonb_in_scalar;
274 
275  pg_parse_json_or_ereport(lex, &sem);
276 
277  /* after parsing, the item member has the composed jsonb structure */
279 }
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:145
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210

References JsonSemAction::array_end, JsonSemAction::array_start, 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_ereport(), PG_RETURN_POINTER, JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by jsonb_in(), and jsonb_recv().

◆ jsonb_in()

Datum jsonb_in ( PG_FUNCTION_ARGS  )

Definition at line 97 of file jsonb.c.

98 {
99  char *json = PG_GETARG_CSTRING(0);
100 
101  return jsonb_from_cstring(json, strlen(json));
102 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
static Datum jsonb_from_cstring(char *json, int len)
Definition: jsonb.c:256

References jsonb_from_cstring(), and PG_GETARG_CSTRING.

Referenced by jsonb_set_lax().

◆ jsonb_in_array_end()

static void jsonb_in_array_end ( void *  pstate)
static

Definition at line 319 of file jsonb.c.

320 {
321  JsonbInState *_state = (JsonbInState *) pstate;
322 
323  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
324 }

References JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, and WJB_END_ARRAY.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_in_array_start()

static void jsonb_in_array_start ( void *  pstate)
static

Definition at line 311 of file jsonb.c.

312 {
313  JsonbInState *_state = (JsonbInState *) pstate;
314 
315  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
316 }

References JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, and WJB_BEGIN_ARRAY.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_in_object_end()

static void jsonb_in_object_end ( void *  pstate)
static

Definition at line 303 of file jsonb.c.

304 {
305  JsonbInState *_state = (JsonbInState *) pstate;
306 
307  _state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
308 }

References JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, and WJB_END_OBJECT.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_in_object_field_start()

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

Definition at line 327 of file jsonb.c.

328 {
329  JsonbInState *_state = (JsonbInState *) pstate;
330  JsonbValue v;
331 
332  Assert(fname != NULL);
333  v.type = jbvString;
334  v.val.string.len = checkStringLen(strlen(fname));
335  v.val.string.val = fname;
336 
337  _state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
338 }

References Assert(), checkStringLen(), jbvString, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, JsonbValue::type, JsonbValue::val, and WJB_KEY.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_in_object_start()

static void jsonb_in_object_start ( void *  pstate)
static

Definition at line 295 of file jsonb.c.

296 {
297  JsonbInState *_state = (JsonbInState *) pstate;
298 
299  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
300 }

References JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, and WJB_BEGIN_OBJECT.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_in_scalar()

static void 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 
380  case JSON_TOKEN_STRING:
381  Assert(token != NULL);
382  v.type = jbvString;
383  v.val.string.len = checkStringLen(strlen(token));
384  v.val.string.val = token;
385  break;
386  case JSON_TOKEN_NUMBER:
387 
388  /*
389  * No need to check size of numeric values, because maximum
390  * numeric size is well below the JsonbValue restriction
391  */
392  Assert(token != NULL);
393  v.type = jbvNumeric;
395  CStringGetDatum(token),
397  Int32GetDatum(-1));
398  v.val.numeric = DatumGetNumeric(numd);
399  break;
400  case JSON_TOKEN_TRUE:
401  v.type = jbvBool;
402  v.val.boolean = true;
403  break;
404  case JSON_TOKEN_FALSE:
405  v.type = jbvBool;
406  v.val.boolean = false;
407  break;
408  case JSON_TOKEN_NULL:
409  v.type = jbvNull;
410  break;
411  default:
412  /* should not be possible */
413  elog(ERROR, "invalid json token type");
414  break;
415  }
416 
417  if (_state->parseState == NULL)
418  {
419  /* single scalar */
420  JsonbValue va;
421 
422  va.type = jbvArray;
423  va.val.array.rawScalar = true;
424  va.val.array.nElems = 1;
425 
426  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
427  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
428  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
429  }
430  else
431  {
432  JsonbValue *o = &_state->parseState->contVal;
433 
434  switch (o->type)
435  {
436  case jbvArray:
437  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
438  break;
439  case jbvObject:
440  _state->res = pushJsonbValue(&_state->parseState, WJB_VALUE, &v);
441  break;
442  default:
443  elog(ERROR, "unexpected parent of nested structure");
444  }
445  }
446 }
@ JSON_TOKEN_FALSE
Definition: jsonapi.h:31
@ JSON_TOKEN_TRUE
Definition: jsonapi.h:30
@ JSON_TOKEN_NULL
Definition: jsonapi.h:32
@ JSON_TOKEN_NUMBER
Definition: jsonapi.h:23
@ JSON_TOKEN_STRING
Definition: jsonapi.h:22

References Assert(), checkStringLen(), JsonbParseState::contVal, CStringGetDatum(), DatumGetNumeric(), DirectFunctionCall3, elog(), ERROR, Int32GetDatum(), InvalidOid, jbvArray, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, numeric_in(), ObjectIdGetDatum(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, JsonbValue::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_ELEM, WJB_END_ARRAY, and WJB_VALUE.

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

◆ jsonb_int2()

Datum jsonb_int2 ( PG_FUNCTION_ARGS  )

Definition at line 1992 of file jsonb.c.

1993 {
1994  Jsonb *in = PG_GETARG_JSONB_P(0);
1995  JsonbValue v;
1996  Datum retValue;
1997 
1998  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
1999  cannotCastJsonbValue(v.type, "smallint");
2000 
2001  retValue = DirectFunctionCall1(numeric_int2,
2002  NumericGetDatum(v.val.numeric));
2003 
2004  PG_FREE_IF_COPY(in, 0);
2005 
2006  PG_RETURN_DATUM(retValue);
2007 }
Datum numeric_int2(PG_FUNCTION_ARGS)
Definition: numeric.c:4352

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

◆ jsonb_int4()

Datum jsonb_int4 ( PG_FUNCTION_ARGS  )

Definition at line 2010 of file jsonb.c.

2011 {
2012  Jsonb *in = PG_GETARG_JSONB_P(0);
2013  JsonbValue v;
2014  Datum retValue;
2015 
2016  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2017  cannotCastJsonbValue(v.type, "integer");
2018 
2019  retValue = DirectFunctionCall1(numeric_int4,
2020  NumericGetDatum(v.val.numeric));
2021 
2022  PG_FREE_IF_COPY(in, 0);
2023 
2024  PG_RETURN_DATUM(retValue);
2025 }
Datum numeric_int4(PG_FUNCTION_ARGS)
Definition: numeric.c:4273

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

◆ jsonb_int8()

Datum jsonb_int8 ( PG_FUNCTION_ARGS  )

Definition at line 2028 of file jsonb.c.

2029 {
2030  Jsonb *in = PG_GETARG_JSONB_P(0);
2031  JsonbValue v;
2032  Datum retValue;
2033 
2034  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2035  cannotCastJsonbValue(v.type, "bigint");
2036 
2037  retValue = DirectFunctionCall1(numeric_int8,
2038  NumericGetDatum(v.val.numeric));
2039 
2040  PG_FREE_IF_COPY(in, 0);
2041 
2042  PG_RETURN_DATUM(retValue);
2043 }
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:4312

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

◆ jsonb_numeric()

Datum jsonb_numeric ( PG_FUNCTION_ARGS  )

Definition at line 1971 of file jsonb.c.

1972 {
1973  Jsonb *in = PG_GETARG_JSONB_P(0);
1974  JsonbValue v;
1975  Numeric retValue;
1976 
1977  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
1978  cannotCastJsonbValue(v.type, "numeric");
1979 
1980  /*
1981  * v.val.numeric points into jsonb body, so we need to make a copy to
1982  * return
1983  */
1984  retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
1985 
1986  PG_FREE_IF_COPY(in, 0);
1987 
1988  PG_RETURN_NUMERIC(retValue);
1989 }
static Numeric DatumGetNumericCopy(Datum X)
Definition: numeric.h:66
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:79

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

◆ jsonb_object()

Datum jsonb_object ( PG_FUNCTION_ARGS  )

Definition at line 1277 of file jsonb.c.

1278 {
1279  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
1280  int ndims = ARR_NDIM(in_array);
1281  Datum *in_datums;
1282  bool *in_nulls;
1283  int in_count,
1284  count,
1285  i;
1286  JsonbInState result;
1287 
1288  memset(&result, 0, sizeof(JsonbInState));
1289 
1290  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1291 
1292  switch (ndims)
1293  {
1294  case 0:
1295  goto close_object;
1296  break;
1297 
1298  case 1:
1299  if ((ARR_DIMS(in_array)[0]) % 2)
1300  ereport(ERROR,
1301  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1302  errmsg("array must have even number of elements")));
1303  break;
1304 
1305  case 2:
1306  if ((ARR_DIMS(in_array)[1]) != 2)
1307  ereport(ERROR,
1308  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1309  errmsg("array must have two columns")));
1310  break;
1311 
1312  default:
1313  ereport(ERROR,
1314  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1315  errmsg("wrong number of array subscripts")));
1316  }
1317 
1318  deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
1319 
1320  count = in_count / 2;
1321 
1322  for (i = 0; i < count; ++i)
1323  {
1324  JsonbValue v;
1325  char *str;
1326  int len;
1327 
1328  if (in_nulls[i * 2])
1329  ereport(ERROR,
1330  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1331  errmsg("null value not allowed for object key")));
1332 
1333  str = TextDatumGetCString(in_datums[i * 2]);
1334  len = strlen(str);
1335 
1336  v.type = jbvString;
1337 
1338  v.val.string.len = len;
1339  v.val.string.val = str;
1340 
1341  (void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
1342 
1343  if (in_nulls[i * 2 + 1])
1344  {
1345  v.type = jbvNull;
1346  }
1347  else
1348  {
1349  str = TextDatumGetCString(in_datums[i * 2 + 1]);
1350  len = strlen(str);
1351 
1352  v.type = jbvString;
1353 
1354  v.val.string.len = len;
1355  v.val.string.val = str;
1356  }
1357 
1358  (void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
1359  }
1360 
1361  pfree(in_datums);
1362  pfree(in_nulls);
1363 
1364 close_object:
1365  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1366 
1368 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3642
#define TextDatumGetCString(d)
Definition: builtins.h:86

References ARR_DIMS, ARR_NDIM, deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, i, jbvNull, jbvString, JsonbValueToJsonb(), len, JsonbInState::parseState, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, generate_unaccent_rules::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 1850 of file jsonb.c.

1851 {
1852  JsonbAggState *arg;
1853  JsonbInState result;
1854  Jsonb *out;
1855 
1856  /* cannot be called directly because of internal-type argument */
1857  Assert(AggCheckCallContext(fcinfo, NULL));
1858 
1859  if (PG_ARGISNULL(0))
1860  PG_RETURN_NULL(); /* returns null iff no input values */
1861 
1863 
1864  /*
1865  * We need to do a shallow clone of the argument's res field in case the
1866  * final function is called more than once, so we avoid changing the
1867  * aggregate state value. A shallow clone is sufficient as we aren't
1868  * going to change any of the values, just add the final object end
1869  * marker.
1870  */
1871 
1872  result.parseState = clone_parse_state(arg->res->parseState);
1873 
1874  result.res = pushJsonbValue(&result.parseState,
1875  WJB_END_OBJECT, NULL);
1876 
1877  out = JsonbValueToJsonb(result.res);
1878 
1879  PG_RETURN_POINTER(out);
1880 }

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

◆ jsonb_object_agg_transfn()

Datum jsonb_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1654 of file jsonb.c.

1655 {
1656  MemoryContext oldcontext,
1657  aggcontext;
1658  JsonbInState elem;
1660  Datum val;
1661  JsonbInState *result;
1662  bool single_scalar;
1663  JsonbIterator *it;
1664  Jsonb *jbkey,
1665  *jbval;
1666  JsonbValue v;
1668 
1669  if (!AggCheckCallContext(fcinfo, &aggcontext))
1670  {
1671  /* cannot be called directly because of internal-type argument */
1672  elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
1673  }
1674 
1675  /* set up the accumulator on the first go round */
1676 
1677  if (PG_ARGISNULL(0))
1678  {
1679  Oid arg_type;
1680 
1681  oldcontext = MemoryContextSwitchTo(aggcontext);
1682  state = palloc(sizeof(JsonbAggState));
1683  result = palloc0(sizeof(JsonbInState));
1684  state->res = result;
1685  result->res = pushJsonbValue(&result->parseState,
1686  WJB_BEGIN_OBJECT, NULL);
1687  MemoryContextSwitchTo(oldcontext);
1688 
1689  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1690 
1691  if (arg_type == InvalidOid)
1692  ereport(ERROR,
1693  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1694  errmsg("could not determine input data type")));
1695 
1696  jsonb_categorize_type(arg_type, &state->key_category,
1697  &state->key_output_func);
1698 
1699  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1700 
1701  if (arg_type == InvalidOid)
1702  ereport(ERROR,
1703  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1704  errmsg("could not determine input data type")));
1705 
1706  jsonb_categorize_type(arg_type, &state->val_category,
1707  &state->val_output_func);
1708  }
1709  else
1710  {
1712  result = state->res;
1713  }
1714 
1715  /* turn the argument into jsonb in the normal function context */
1716 
1717  if (PG_ARGISNULL(1))
1718  ereport(ERROR,
1719  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1720  errmsg("field name must not be null")));
1721 
1722  val = PG_GETARG_DATUM(1);
1723 
1724  memset(&elem, 0, sizeof(JsonbInState));
1725 
1726  datum_to_jsonb(val, false, &elem, state->key_category,
1727  state->key_output_func, true);
1728 
1729  jbkey = JsonbValueToJsonb(elem.res);
1730 
1731  val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
1732 
1733  memset(&elem, 0, sizeof(JsonbInState));
1734 
1735  datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category,
1736  state->val_output_func, false);
1737 
1738  jbval = JsonbValueToJsonb(elem.res);
1739 
1740  it = JsonbIteratorInit(&jbkey->root);
1741 
1742  /* switch to the aggregate context for accumulation operations */
1743 
1744  oldcontext = MemoryContextSwitchTo(aggcontext);
1745 
1746  /*
1747  * keys should be scalar, and we should have already checked for that
1748  * above when calling datum_to_jsonb, so we only need to look for these
1749  * things.
1750  */
1751 
1752  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1753  {
1754  switch (type)
1755  {
1756  case WJB_BEGIN_ARRAY:
1757  if (!v.val.array.rawScalar)
1758  elog(ERROR, "unexpected structure for key");
1759  break;
1760  case WJB_ELEM:
1761  if (v.type == jbvString)
1762  {
1763  /* copy string values in the aggregate context */
1764  char *buf = palloc(v.val.string.len + 1);
1765 
1766  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1767  v.val.string.val = buf;
1768  }
1769  else
1770  {
1771  ereport(ERROR,
1772  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1773  errmsg("object keys must be strings")));
1774  }
1775  result->res = pushJsonbValue(&result->parseState,
1776  WJB_KEY, &v);
1777  break;
1778  case WJB_END_ARRAY:
1779  break;
1780  default:
1781  elog(ERROR, "unexpected structure for key");
1782  break;
1783  }
1784  }
1785 
1786  it = JsonbIteratorInit(&jbval->root);
1787 
1788  single_scalar = false;
1789 
1790  /*
1791  * values can be anything, including structured and null, so we treat them
1792  * as in json_agg_transfn, except that single scalars are always pushed as
1793  * WJB_VALUE items.
1794  */
1795 
1796  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1797  {
1798  switch (type)
1799  {
1800  case WJB_BEGIN_ARRAY:
1801  if (v.val.array.rawScalar)
1802  single_scalar = true;
1803  else
1804  result->res = pushJsonbValue(&result->parseState,
1805  type, NULL);
1806  break;
1807  case WJB_END_ARRAY:
1808  if (!single_scalar)
1809  result->res = pushJsonbValue(&result->parseState,
1810  type, NULL);
1811  break;
1812  case WJB_BEGIN_OBJECT:
1813  case WJB_END_OBJECT:
1814  result->res = pushJsonbValue(&result->parseState,
1815  type, NULL);
1816  break;
1817  case WJB_ELEM:
1818  case WJB_KEY:
1819  case WJB_VALUE:
1820  if (v.type == jbvString)
1821  {
1822  /* copy string values in the aggregate context */
1823  char *buf = palloc(v.val.string.len + 1);
1824 
1825  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1826  v.val.string.val = buf;
1827  }
1828  else if (v.type == jbvNumeric)
1829  {
1830  /* same for numeric */
1831  v.val.numeric =
1833  NumericGetDatum(v.val.numeric)));
1834  }
1835  result->res = pushJsonbValue(&result->parseState,
1836  single_scalar ? WJB_VALUE : type,
1837  &v);
1838  break;
1839  default:
1840  elog(ERROR, "unknown jsonb iterator token type");
1841  }
1842  }
1843 
1844  MemoryContextSwitchTo(oldcontext);
1845 
1847 }

References AggCheckCallContext(), buf, datum_to_jsonb(), DatumGetNumeric(), DirectFunctionCall1, elog(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, jbvNumeric, jbvString, jsonb_categorize_type(), JsonbIteratorInit(), JsonbIteratorNext(), JsonbValueToJsonb(), MemoryContextSwitchTo(), numeric_uplus(), NumericGetDatum(), palloc(), palloc0(), JsonbInState::parseState, PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, Jsonb::root, snprintf, generate_unaccent_rules::type, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ jsonb_object_two_arg()

Datum jsonb_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1377 of file jsonb.c.

1378 {
1379  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(0);
1380  ArrayType *val_array = PG_GETARG_ARRAYTYPE_P(1);
1381  int nkdims = ARR_NDIM(key_array);
1382  int nvdims = ARR_NDIM(val_array);
1383  Datum *key_datums,
1384  *val_datums;
1385  bool *key_nulls,
1386  *val_nulls;
1387  int key_count,
1388  val_count,
1389  i;
1390  JsonbInState result;
1391 
1392  memset(&result, 0, sizeof(JsonbInState));
1393 
1394  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1395 
1396  if (nkdims > 1 || nkdims != nvdims)
1397  ereport(ERROR,
1398  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1399  errmsg("wrong number of array subscripts")));
1400 
1401  if (nkdims == 0)
1402  goto close_object;
1403 
1404  deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
1405  deconstruct_array_builtin(val_array, TEXTOID, &val_datums, &val_nulls, &val_count);
1406 
1407  if (key_count != val_count)
1408  ereport(ERROR,
1409  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1410  errmsg("mismatched array dimensions")));
1411 
1412  for (i = 0; i < key_count; ++i)
1413  {
1414  JsonbValue v;
1415  char *str;
1416  int len;
1417 
1418  if (key_nulls[i])
1419  ereport(ERROR,
1420  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1421  errmsg("null value not allowed for object key")));
1422 
1423  str = TextDatumGetCString(key_datums[i]);
1424  len = strlen(str);
1425 
1426  v.type = jbvString;
1427 
1428  v.val.string.len = len;
1429  v.val.string.val = str;
1430 
1431  (void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
1432 
1433  if (val_nulls[i])
1434  {
1435  v.type = jbvNull;
1436  }
1437  else
1438  {
1439  str = TextDatumGetCString(val_datums[i]);
1440  len = strlen(str);
1441 
1442  v.type = jbvString;
1443 
1444  v.val.string.len = len;
1445  v.val.string.val = str;
1446  }
1447 
1448  (void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
1449  }
1450 
1451  pfree(key_datums);
1452  pfree(key_nulls);
1453  pfree(val_datums);
1454  pfree(val_nulls);
1455 
1456 close_object:
1457  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1458 
1460 }

References ARR_NDIM, deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, i, jbvNull, jbvString, JsonbValueToJsonb(), len, JsonbInState::parseState, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, pushJsonbValue(), JsonbInState::res, generate_unaccent_rules::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 132 of file jsonb.c.

133 {
134  Jsonb *jb = PG_GETARG_JSONB_P(0);
135  char *out;
136 
137  out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
138 
139  PG_RETURN_CSTRING(out);
140 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:460
#define VARSIZE(PTR)
Definition: postgres.h:317

References JsonbToCString(), PG_GETARG_JSONB_P, PG_RETURN_CSTRING, Jsonb::root, and VARSIZE.

◆ 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(out, pnstrdup(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:735
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1271
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1494
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:670
static char * DatumGetCString(Datum X)
Definition: postgres.h:683
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176

References appendBinaryStringInfo(), appendStringInfoString(), DatumGetCString(), DirectFunctionCall1, elog(), ERROR, escape_json(), jbvBool, jbvNull, jbvNumeric, jbvString, numeric_out(), pnstrdup(), PointerGetDatum(), JsonbValue::type, and JsonbValue::val.

Referenced by JsonbToCStringWorker().

◆ jsonb_recv()

Datum jsonb_recv ( PG_FUNCTION_ARGS  )

Definition at line 113 of file jsonb.c.

114 {
116  int version = pq_getmsgint(buf, 1);
117  char *str;
118  int nbytes;
119 
120  if (version == 1)
121  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
122  else
123  elog(ERROR, "unsupported jsonb version number %d", version);
124 
125  return jsonb_from_cstring(str, nbytes);
126 }
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
StringInfoData * StringInfo
Definition: stringinfo.h:44

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

◆ jsonb_send()

Datum jsonb_send ( PG_FUNCTION_ARGS  )

Definition at line 148 of file jsonb.c.

149 {
150  Jsonb *jb = PG_GETARG_JSONB_P(0);
152  StringInfo jtext = makeStringInfo();
153  int version = 1;
154 
155  (void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
156 
158  pq_sendint8(&buf, version);
159  pq_sendtext(&buf, jtext->data, jtext->len);
160  pfree(jtext->data);
161  pfree(jtext);
162 
164 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:129
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41

References buf, StringInfoData::data, JsonbToCString(), StringInfoData::len, makeStringInfo(), pfree(), PG_GETARG_JSONB_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint8(), pq_sendtext(), Jsonb::root, and VARSIZE.

◆ jsonb_typeof()

Datum jsonb_typeof ( PG_FUNCTION_ARGS  )

Definition at line 240 of file jsonb.c.

241 {
242  Jsonb *in = PG_GETARG_JSONB_P(0);
243  const char *result = JsonbContainerTypeName(&in->root);
244 
246 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:170
text * cstring_to_text(const char *s)
Definition: varlena.c:189

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 170 of file jsonb.c.

171 {
172  JsonbValue scalar;
173 
174  if (JsonbExtractScalar(jbc, &scalar))
175  return JsonbTypeName(&scalar);
176  else if (JsonContainerIsArray(jbc))
177  return "array";
178  else if (JsonContainerIsObject(jbc))
179  return "object";
180  else
181  {
182  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
183  return "unknown";
184  }
185 }
const char * JsonbTypeName(JsonbValue *val)
Definition: jsonb.c:191
#define JsonContainerIsArray(jc)
Definition: jsonb.h:209
#define JsonContainerIsObject(jc)
Definition: jsonb.h:208
uint32 header
Definition: jsonb.h:192

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 1887 of file jsonb.c.

1888 {
1889  JsonbIterator *it;
1891  JsonbValue tmp;
1892 
1893  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1894  {
1895  /* inform caller about actual type of container */
1896  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1897  return false;
1898  }
1899 
1900  /*
1901  * A root scalar is stored as an array of one element, so we get the array
1902  * and then its first (and only) member.
1903  */
1904  it = JsonbIteratorInit(jbc);
1905 
1906  tok = JsonbIteratorNext(&it, &tmp, true);
1907  Assert(tok == WJB_BEGIN_ARRAY);
1908  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1909 
1910  tok = JsonbIteratorNext(&it, res, true);
1911  Assert(tok == WJB_ELEM);
1913 
1914  tok = JsonbIteratorNext(&it, &tmp, true);
1915  Assert(tok == WJB_END_ARRAY);
1916 
1917  tok = JsonbIteratorNext(&it, &tmp, true);
1918  Assert(tok == WJB_DONE);
1919 
1920  return true;
1921 }
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:166
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:207
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:297

References Assert(), IsAJsonbScalar, jbvArray, jbvObject, JsonbIteratorInit(), JsonbIteratorNext(), JsonContainerIsArray, JsonContainerIsScalar, PG_USED_FOR_ASSERTS_ONLY, res, 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(), and JsonbContainerTypeName().

◆ JsonbToCString()

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

Definition at line 460 of file jsonb.c.

461 {
462  return JsonbToCStringWorker(out, in, estimated_len, false);
463 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:478

References JsonbToCStringWorker().

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

◆ JsonbToCStringIndent()

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

Definition at line 469 of file jsonb.c.

470 {
471  return JsonbToCStringWorker(out, in, estimated_len, true);
472 }

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToCStringWorker()

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

Definition at line 478 of file jsonb.c.

479 {
480  bool first = true;
481  JsonbIterator *it;
482  JsonbValue v;
484  int level = 0;
485  bool redo_switch = false;
486 
487  /* If we are indenting, don't add a space after a comma */
488  int ispaces = indent ? 1 : 2;
489 
490  /*
491  * Don't indent the very first item. This gets set to the indent flag at
492  * the bottom of the loop.
493  */
494  bool use_indent = false;
495  bool raw_scalar = false;
496  bool last_was_key = false;
497 
498  if (out == NULL)
499  out = makeStringInfo();
500 
501  enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
502 
503  it = JsonbIteratorInit(in);
504 
505  while (redo_switch ||
506  ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE))
507  {
508  redo_switch = false;
509  switch (type)
510  {
511  case WJB_BEGIN_ARRAY:
512  if (!first)
513  appendBinaryStringInfo(out, ", ", ispaces);
514 
515  if (!v.val.array.rawScalar)
516  {
517  add_indent(out, use_indent && !last_was_key, level);
518  appendStringInfoCharMacro(out, '[');
519  }
520  else
521  raw_scalar = true;
522 
523  first = true;
524  level++;
525  break;
526  case WJB_BEGIN_OBJECT:
527  if (!first)
528  appendBinaryStringInfo(out, ", ", ispaces);
529 
530  add_indent(out, use_indent && !last_was_key, level);
531  appendStringInfoCharMacro(out, '{');
532 
533  first = true;
534  level++;
535  break;
536  case WJB_KEY:
537  if (!first)
538  appendBinaryStringInfo(out, ", ", ispaces);
539  first = true;
540 
541  add_indent(out, use_indent, level);
542 
543  /* json rules guarantee this is a string */
544  jsonb_put_escaped_value(out, &v);
545  appendBinaryStringInfo(out, ": ", 2);
546 
547  type = JsonbIteratorNext(&it, &v, false);
548  if (type == WJB_VALUE)
549  {
550  first = false;
551  jsonb_put_escaped_value(out, &v);
552  }
553  else
554  {
556 
557  /*
558  * We need to rerun the current switch() since we need to
559  * output the object which we just got from the iterator
560  * before calling the iterator again.
561  */
562  redo_switch = true;
563  }
564  break;
565  case WJB_ELEM:
566  if (!first)
567  appendBinaryStringInfo(out, ", ", ispaces);
568  first = false;
569 
570  if (!raw_scalar)
571  add_indent(out, use_indent, level);
572  jsonb_put_escaped_value(out, &v);
573  break;
574  case WJB_END_ARRAY:
575  level--;
576  if (!raw_scalar)
577  {
578  add_indent(out, use_indent, level);
579  appendStringInfoCharMacro(out, ']');
580  }
581  first = false;
582  break;
583  case WJB_END_OBJECT:
584  level--;
585  add_indent(out, use_indent, level);
586  appendStringInfoCharMacro(out, '}');
587  first = false;
588  break;
589  default:
590  elog(ERROR, "unknown jsonb iterator token type");
591  }
592  use_indent = indent;
593  last_was_key = redo_switch;
594  }
595 
596  Assert(level == 0);
597 
598  return out->data;
599 }
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:602
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:283

References add_indent(), appendBinaryStringInfo(), appendStringInfoCharMacro, Assert(), StringInfoData::data, elog(), enlargeStringInfo(), ERROR, jsonb_put_escaped_value(), JsonbIteratorInit(), JsonbIteratorNext(), makeStringInfo(), generate_unaccent_rules::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 191 of file jsonb.c.

192 {
193  switch (val->type)
194  {
195  case jbvBinary:
196  return JsonbContainerTypeName(val->val.binary.data);
197  case jbvObject:
198  return "object";
199  case jbvArray:
200  return "array";
201  case jbvNumeric:
202  return "number";
203  case jbvString:
204  return "string";
205  case jbvBool:
206  return "boolean";
207  case jbvNull:
208  return "null";
209  case jbvDatetime:
210  switch (val->val.datetime.typid)
211  {
212  case DATEOID:
213  return "date";
214  case TIMEOID:
215  return "time without time zone";
216  case TIMETZOID:
217  return "time with time zone";
218  case TIMESTAMPOID:
219  return "timestamp without time zone";
220  case TIMESTAMPTZOID:
221  return "timestamp with time zone";
222  default:
223  elog(ERROR, "unrecognized jsonb value datetime type: %d",
224  val->val.datetime.typid);
225  }
226  return "unknown";
227  default:
228  elog(ERROR, "unrecognized jsonb value type: %d", val->type);
229  return "unknown";
230  }
231 }
@ jbvDatetime
Definition: jsonb.h:244

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

◆ to_jsonb()

Datum to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1132 of file jsonb.c.

1133 {
1134  Datum val = PG_GETARG_DATUM(0);
1135  Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1136  JsonbInState result;
1137  JsonbTypeCategory tcategory;
1138  Oid outfuncoid;
1139 
1140  if (val_type == InvalidOid)
1141  ereport(ERROR,
1142  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1143  errmsg("could not determine input data type")));
1144 
1145  jsonb_categorize_type(val_type,
1146  &tcategory, &outfuncoid);
1147 
1148  memset(&result, 0, sizeof(JsonbInState));
1149 
1150  datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false);
1151 
1153 }

References datum_to_jsonb(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, jsonb_categorize_type(), JsonbValueToJsonb(), PG_GETARG_DATUM, PG_RETURN_POINTER, JsonbInState::res, and val.