PostgreSQL Source Code  git master
jsonb.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/transam.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.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
 

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, Datum *vals, 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 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)
 
Datum jsonb_from_text (text *js, bool unique_keys)
 
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)
 
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, Datum *args, bool *nulls, 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, Datum *args, bool *nulls, 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)
 

Typedef Documentation

◆ JsonbAggState

typedef struct JsonbAggState JsonbAggState

◆ JsonbInState

typedef struct JsonbInState JsonbInState

Function Documentation

◆ add_indent()

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

Definition at line 620 of file jsonb.c.

621 {
622  if (indent)
623  {
624  appendStringInfoCharMacro(out, '\n');
625  appendStringInfoSpaces(out, level * 4);
626  }
627 }
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:206
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128

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

1022 {
1023  JsonTypeCategory tcategory;
1024  Oid outfuncoid;
1025 
1026  if (val_type == InvalidOid)
1027  ereport(ERROR,
1028  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1029  errmsg("could not determine input data type")));
1030 
1031  if (is_null)
1032  {
1033  tcategory = JSONTYPE_NULL;
1034  outfuncoid = InvalidOid;
1035  }
1036  else
1037  json_categorize_type(val_type, true,
1038  &tcategory, &outfuncoid);
1039 
1040  datum_to_jsonb_internal(val, is_null, result, tcategory, outfuncoid,
1041  key_scalar);
1042 }
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
long val
Definition: informix.c:664
static void datum_to_jsonb_internal(Datum val, bool is_null, JsonbInState *result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:643
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonfuncs.c:5698
JsonTypeCategory
Definition: jsonfuncs.h:68
@ JSONTYPE_NULL
Definition: jsonfuncs.h:69
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31

References datum_to_jsonb_internal(), ereport, errcode(), errmsg(), ERROR, 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,
Datum vals,
bool nulls,
int *  valcount,
JsonTypeCategory  tcategory,
Oid  outfuncoid 
)
static

Definition at line 866 of file jsonb.c.

869 {
870  int i;
871 
872  Assert(dim < ndims);
873 
874  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
875 
876  for (i = 1; i <= dims[dim]; i++)
877  {
878  if (dim + 1 == ndims)
879  {
880  datum_to_jsonb_internal(vals[*valcount], nulls[*valcount], result, tcategory,
881  outfuncoid, false);
882  (*valcount)++;
883  }
884  else
885  {
886  array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
887  valcount, tcategory, outfuncoid);
888  }
889  }
890 
891  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
892 }
int i
Definition: isn.c:73
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:866
@ 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:568
Assert(fmt[strlen(fmt) - 1] !='\n')
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35

References Assert(), datum_to_jsonb_internal(), 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 898 of file jsonb.c.

899 {
900  ArrayType *v = DatumGetArrayTypeP(array);
901  Oid element_type = ARR_ELEMTYPE(v);
902  int *dim;
903  int ndim;
904  int nitems;
905  int count = 0;
906  Datum *elements;
907  bool *nulls;
908  int16 typlen;
909  bool typbyval;
910  char typalign;
911  JsonTypeCategory tcategory;
912  Oid outfuncoid;
913 
914  ndim = ARR_NDIM(v);
915  dim = ARR_DIMS(v);
916  nitems = ArrayGetNItems(ndim, dim);
917 
918  if (nitems <= 0)
919  {
920  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
921  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
922  return;
923  }
924 
925  get_typlenbyvalalign(element_type,
926  &typlen, &typbyval, &typalign);
927 
928  json_categorize_type(element_type, true,
929  &tcategory, &outfuncoid);
930 
931  deconstruct_array(v, element_type, typlen, typbyval,
932  typalign, &elements, &nulls,
933  &nitems);
934 
935  array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
936  outfuncoid);
937 
938  pfree(elements);
939  pfree(nulls);
940 }
#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:3578
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
signed short int16
Definition: c.h:482
#define nitems(x)
Definition: indent.h:31
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2253
void pfree(void *pointer)
Definition: mcxt.c:1456
char typalign
Definition: pg_type.h:176
uintptr_t Datum
Definition: postgres.h:64

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_dim_to_jsonb(), ArrayGetNItems(), DatumGetArrayTypeP, deconstruct_array(), get_typlenbyvalalign(), json_categorize_type(), nitems, JsonbInState::parseState, pfree(), pushJsonbValue(), JsonbInState::res, 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 2012 of file jsonb.c.

2013 {
2014  static const struct
2015  {
2016  enum jbvType type;
2017  const char *msg;
2018  }
2019  messages[] =
2020  {
2021  {jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
2022  {jbvString, gettext_noop("cannot cast jsonb string to type %s")},
2023  {jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
2024  {jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
2025  {jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
2026  {jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
2027  {jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
2028  };
2029  int i;
2030 
2031  for (i = 0; i < lengthof(messages); i++)
2032  if (messages[i].type == type)
2033  ereport(ERROR,
2034  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2035  errmsg(messages[i].msg, sqltype)));
2036 
2037  /* should be unreachable */
2038  elog(ERROR, "unknown jsonb type: %d", (int) type);
2039 }
#define gettext_noop(x)
Definition: c.h:1209
#define lengthof(array)
Definition: c.h:777
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
const char * type

References elog(), ereport, errcode(), errmsg(), ERROR, 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 282 of file jsonb.c.

283 {
284  if (len > JENTRY_OFFLENMASK)
285  ereturn(escontext, false,
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 true;
292 }
int errdetail(const char *fmt,...)
Definition: elog.c:1202
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define JENTRY_OFFLENMASK
Definition: jsonb.h:138
const void size_t len

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

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

◆ clone_parse_state()

static JsonbParseState * clone_parse_state ( JsonbParseState state)
static

Definition at line 1475 of file jsonb.c.

1476 {
1477  JsonbParseState *result,
1478  *icursor,
1479  *ocursor;
1480 
1481  if (state == NULL)
1482  return NULL;
1483 
1484  result = palloc(sizeof(JsonbParseState));
1485  icursor = state;
1486  ocursor = result;
1487  for (;;)
1488  {
1489  ocursor->contVal = icursor->contVal;
1490  ocursor->size = icursor->size;
1491  ocursor->unique_keys = icursor->unique_keys;
1492  ocursor->skip_nulls = icursor->skip_nulls;
1493  icursor = icursor->next;
1494  if (icursor == NULL)
1495  break;
1496  ocursor->next = palloc(sizeof(JsonbParseState));
1497  ocursor = ocursor->next;
1498  }
1499  ocursor->next = NULL;
1500 
1501  return result;
1502 }
void * palloc(Size size)
Definition: mcxt.c:1226
bool unique_keys
Definition: jsonb.h:324
struct JsonbParseState * next
Definition: jsonb.h:323
bool skip_nulls
Definition: jsonb.h:325
JsonbValue contVal
Definition: jsonb.h:321
Definition: regguts.h:323

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

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

947 {
948  HeapTupleHeader td;
949  Oid tupType;
950  int32 tupTypmod;
951  TupleDesc tupdesc;
952  HeapTupleData tmptup,
953  *tuple;
954  int i;
955 
956  td = DatumGetHeapTupleHeader(composite);
957 
958  /* Extract rowtype info and find a tupdesc */
959  tupType = HeapTupleHeaderGetTypeId(td);
960  tupTypmod = HeapTupleHeaderGetTypMod(td);
961  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
962 
963  /* Build a temporary HeapTuple control structure */
965  tmptup.t_data = td;
966  tuple = &tmptup;
967 
968  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_OBJECT, NULL);
969 
970  for (i = 0; i < tupdesc->natts; i++)
971  {
972  Datum val;
973  bool isnull;
974  char *attname;
975  JsonTypeCategory tcategory;
976  Oid outfuncoid;
977  JsonbValue v;
978  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
979 
980  if (att->attisdropped)
981  continue;
982 
983  attname = NameStr(att->attname);
984 
985  v.type = jbvString;
986  /* don't need checkStringLen here - can't exceed maximum name length */
987  v.val.string.len = strlen(attname);
988  v.val.string.val = attname;
989 
990  result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
991 
992  val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
993 
994  if (isnull)
995  {
996  tcategory = JSONTYPE_NULL;
997  outfuncoid = InvalidOid;
998  }
999  else
1000  json_categorize_type(att->atttypid, true, &tcategory,
1001  &outfuncoid);
1002 
1003  datum_to_jsonb_internal(val, isnull, result, tcategory, outfuncoid,
1004  false);
1005  }
1006 
1007  result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
1008  ReleaseTupleDesc(tupdesc);
1009 }
#define NameStr(name)
Definition: c.h:735
signed int int32
Definition: c.h:483
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:295
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:466
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
@ 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:209
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:1830

References attname, datum_to_jsonb_internal(), DatumGetHeapTupleHeader, heap_getattr(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, i, InvalidOid, jbvString, json_categorize_type(), JSONTYPE_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_internal().

◆ datum_to_jsonb()

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

Definition at line 1116 of file jsonb.c.

1117 {
1118  JsonbInState result;
1119 
1120  memset(&result, 0, sizeof(JsonbInState));
1121 
1122  datum_to_jsonb_internal(val, false, &result, tcategory, outfuncoid,
1123  false);
1124 
1125  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1126 }
static Datum JsonbPGetDatum(const Jsonb *p)
Definition: jsonb.h:386
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94

References datum_to_jsonb_internal(), JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::res, 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 643 of file jsonb.c.

646 {
647  char *outputstr;
648  bool numeric_error;
649  JsonbValue jb;
650  bool scalar_jsonb = false;
651 
653 
654  /* Convert val to a JsonbValue in jb (in most cases) */
655  if (is_null)
656  {
657  Assert(!key_scalar);
658  jb.type = jbvNull;
659  }
660  else if (key_scalar &&
661  (tcategory == JSONTYPE_ARRAY ||
662  tcategory == JSONTYPE_COMPOSITE ||
663  tcategory == JSONTYPE_JSON ||
664  tcategory == JSONTYPE_JSONB ||
665  tcategory == JSONTYPE_JSON))
666  {
667  ereport(ERROR,
668  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
669  errmsg("key value must be scalar, not array, composite, or json")));
670  }
671  else
672  {
673  if (tcategory == JSONTYPE_CAST)
674  val = OidFunctionCall1(outfuncoid, val);
675 
676  switch (tcategory)
677  {
678  case JSONTYPE_ARRAY:
679  array_to_jsonb_internal(val, result);
680  break;
681  case JSONTYPE_COMPOSITE:
682  composite_to_jsonb(val, result);
683  break;
684  case JSONTYPE_BOOL:
685  if (key_scalar)
686  {
687  outputstr = DatumGetBool(val) ? "true" : "false";
688  jb.type = jbvString;
689  jb.val.string.len = strlen(outputstr);
690  jb.val.string.val = outputstr;
691  }
692  else
693  {
694  jb.type = jbvBool;
695  jb.val.boolean = DatumGetBool(val);
696  }
697  break;
698  case JSONTYPE_NUMERIC:
699  outputstr = OidOutputFunctionCall(outfuncoid, val);
700  if (key_scalar)
701  {
702  /* always quote keys */
703  jb.type = jbvString;
704  jb.val.string.len = strlen(outputstr);
705  jb.val.string.val = outputstr;
706  }
707  else
708  {
709  /*
710  * Make it numeric if it's a valid JSON number, otherwise
711  * a string. Invalid numeric output will always have an
712  * 'N' or 'n' in it (I think).
713  */
714  numeric_error = (strchr(outputstr, 'N') != NULL ||
715  strchr(outputstr, 'n') != NULL);
716  if (!numeric_error)
717  {
718  Datum numd;
719 
720  jb.type = jbvNumeric;
722  CStringGetDatum(outputstr),
724  Int32GetDatum(-1));
725  jb.val.numeric = DatumGetNumeric(numd);
726  pfree(outputstr);
727  }
728  else
729  {
730  jb.type = jbvString;
731  jb.val.string.len = strlen(outputstr);
732  jb.val.string.val = outputstr;
733  }
734  }
735  break;
736  case JSONTYPE_DATE:
737  jb.type = jbvString;
738  jb.val.string.val = JsonEncodeDateTime(NULL, val,
739  DATEOID, NULL);
740  jb.val.string.len = strlen(jb.val.string.val);
741  break;
742  case JSONTYPE_TIMESTAMP:
743  jb.type = jbvString;
744  jb.val.string.val = JsonEncodeDateTime(NULL, val,
745  TIMESTAMPOID, NULL);
746  jb.val.string.len = strlen(jb.val.string.val);
747  break;
749  jb.type = jbvString;
750  jb.val.string.val = JsonEncodeDateTime(NULL, val,
751  TIMESTAMPTZOID, NULL);
752  jb.val.string.len = strlen(jb.val.string.val);
753  break;
754  case JSONTYPE_CAST:
755  case JSONTYPE_JSON:
756  {
757  /* parse the json right into the existing result object */
758  JsonLexContext *lex;
759  JsonSemAction sem;
760  text *json = DatumGetTextPP(val);
761 
762  lex = makeJsonLexContext(json, true);
763 
764  memset(&sem, 0, sizeof(sem));
765 
766  sem.semstate = (void *) result;
767 
772  sem.scalar = jsonb_in_scalar;
774 
775  pg_parse_json_or_ereport(lex, &sem);
776  }
777  break;
778  case JSONTYPE_JSONB:
779  {
780  Jsonb *jsonb = DatumGetJsonbP(val);
781  JsonbIterator *it;
782 
783  it = JsonbIteratorInit(&jsonb->root);
784 
785  if (JB_ROOT_IS_SCALAR(jsonb))
786  {
787  (void) JsonbIteratorNext(&it, &jb, true);
788  Assert(jb.type == jbvArray);
789  (void) JsonbIteratorNext(&it, &jb, true);
790  scalar_jsonb = true;
791  }
792  else
793  {
795 
796  while ((type = JsonbIteratorNext(&it, &jb, false))
797  != WJB_DONE)
798  {
799  if (type == WJB_END_ARRAY || type == WJB_END_OBJECT ||
801  result->res = pushJsonbValue(&result->parseState,
802  type, NULL);
803  else
804  result->res = pushJsonbValue(&result->parseState,
805  type, &jb);
806  }
807  }
808  }
809  break;
810  default:
811  outputstr = OidOutputFunctionCall(outfuncoid, val);
812  jb.type = jbvString;
813  jb.val.string.len = strlen(outputstr);
814  (void) checkStringLen(jb.val.string.len, NULL);
815  jb.val.string.val = outputstr;
816  break;
817  }
818  }
819 
820  /* Now insert jb into result, unless we did it recursively */
821  if (!is_null && !scalar_jsonb &&
822  tcategory >= JSONTYPE_JSON && tcategory <= JSONTYPE_CAST)
823  {
824  /* work has been done recursively */
825  return;
826  }
827  else if (result->parseState == NULL)
828  {
829  /* single root scalar */
830  JsonbValue va;
831 
832  va.type = jbvArray;
833  va.val.array.rawScalar = true;
834  va.val.array.nElems = 1;
835 
836  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, &va);
837  result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
838  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
839  }
840  else
841  {
842  JsonbValue *o = &result->parseState->contVal;
843 
844  switch (o->type)
845  {
846  case jbvArray:
847  result->res = pushJsonbValue(&result->parseState, WJB_ELEM, &jb);
848  break;
849  case jbvObject:
850  result->res = pushJsonbValue(&result->parseState,
851  key_scalar ? WJB_KEY : WJB_VALUE,
852  &jb);
853  break;
854  default:
855  elog(ERROR, "unexpected parent of nested structure");
856  }
857  }
858 }
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:627
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1746
#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:283
static JsonParseErrorType jsonb_in_object_start(void *pstate)
Definition: jsonb.c:295
static JsonParseErrorType jsonb_in_array_end(void *pstate)
Definition: jsonb.c:326
static JsonParseErrorType jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
Definition: jsonb.c:336
static void array_to_jsonb_internal(Datum array, JsonbInState *result)
Definition: jsonb.c:898
static void composite_to_jsonb(Datum composite, JsonbInState *result)
Definition: jsonb.c:946
static JsonParseErrorType jsonb_in_array_start(void *pstate)
Definition: jsonb.c:316
static JsonParseErrorType jsonb_in_object_end(void *pstate)
Definition: jsonb.c:306
static JsonParseErrorType jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
Definition: jsonb.c:384
static bool checkStringLen(size_t len, Node *escontext)
Definition: jsonb.c:282
static Jsonb * DatumGetJsonbP(Datum d)
Definition: jsonb.h:374
#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:819
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:855
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:529
#define pg_parse_json_or_ereport(lex, sem)
Definition: jsonfuncs.h:46
@ JSONTYPE_JSON
Definition: jsonfuncs.h:75
@ JSONTYPE_TIMESTAMP
Definition: jsonfuncs.h:73
@ JSONTYPE_NUMERIC
Definition: jsonfuncs.h:71
@ JSONTYPE_DATE
Definition: jsonfuncs.h:72
@ JSONTYPE_BOOL
Definition: jsonfuncs.h:70
@ JSONTYPE_CAST
Definition: jsonfuncs.h:79
@ JSONTYPE_COMPOSITE
Definition: jsonfuncs.h:78
@ JSONTYPE_ARRAY
Definition: jsonfuncs.h:77
@ JSONTYPE_TIMESTAMPTZ
Definition: jsonfuncs.h:74
@ JSONTYPE_JSONB
Definition: jsonfuncs.h:76
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:60
void check_stack_depth(void)
Definition: postgres.c:3523
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
json_struct_action array_end
Definition: jsonapi.h:118
json_struct_action object_start
Definition: jsonapi.h:115
json_ofield_action object_field_start
Definition: jsonapi.h:119
json_scalar_action scalar
Definition: jsonapi.h:123
void * semstate
Definition: jsonapi.h:114
json_struct_action array_start
Definition: jsonapi.h:117
json_struct_action object_end
Definition: jsonapi.h:116
Definition: jsonb.h:213
JsonbContainer root
Definition: jsonb.h:215
Definition: c.h:676

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(), JsonEncodeDateTime(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_JSONB, JSONTYPE_NUMERIC, JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, 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, 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(), 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 1644 of file jsonb.c.

1645 {
1646  JsonbAggState *arg;
1647  JsonbInState result;
1648  Jsonb *out;
1649 
1650  /* cannot be called directly because of internal-type argument */
1651  Assert(AggCheckCallContext(fcinfo, NULL));
1652 
1653  if (PG_ARGISNULL(0))
1654  PG_RETURN_NULL(); /* returns null iff no input values */
1655 
1657 
1658  /*
1659  * We need to do a shallow clone of the argument in case the final
1660  * function is called more than once, so we avoid changing the argument. A
1661  * shallow clone is sufficient as we aren't going to change any of the
1662  * values, just add the final array end marker.
1663  */
1664  memset(&result, 0, sizeof(JsonbInState));
1665 
1666  result.parseState = clone_parse_state(arg->res->parseState);
1667 
1668  result.res = pushJsonbValue(&result.parseState,
1669  WJB_END_ARRAY, NULL);
1670 
1671  out = JsonbValueToJsonb(result.res);
1672 
1673  PG_RETURN_POINTER(out);
1674 }
#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:1475
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4512
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_strict_transfn()

Datum jsonb_agg_strict_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1638 of file jsonb.c.

1639 {
1640  return jsonb_agg_transfn_worker(fcinfo, true);
1641 }
static Datum jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
Definition: jsonb.c:1505

References jsonb_agg_transfn_worker().

◆ jsonb_agg_transfn()

Datum jsonb_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1629 of file jsonb.c.

1630 {
1631  return jsonb_agg_transfn_worker(fcinfo, false);
1632 }

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

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

References AggCheckCallContext(), buf, datum_to_jsonb_internal(), DatumGetNumeric(), DirectFunctionCall1, elog(), ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, jbvNumeric, jbvString, json_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, 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 jsonb_agg_strict_transfn(), and jsonb_agg_transfn().

◆ jsonb_bool()

Datum jsonb_bool ( PG_FUNCTION_ARGS  )

Definition at line 2042 of file jsonb.c.

2043 {
2044  Jsonb *in = PG_GETARG_JSONB_P(0);
2045  JsonbValue v;
2046 
2047  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
2048  cannotCastJsonbValue(v.type, "boolean");
2049 
2050  PG_FREE_IF_COPY(in, 0);
2051 
2052  PG_RETURN_BOOL(v.val.boolean);
2053 }
#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:2012
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1972
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:391

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

1242 {
1243  Datum *args;
1244  bool *nulls;
1245  Oid *types;
1246 
1247  /* build argument values to build the object */
1248  int nargs = extract_variadic_args(fcinfo, 0, true,
1249  &args, &types, &nulls);
1250 
1251  if (nargs < 0)
1252  PG_RETURN_NULL();
1253 
1254  PG_RETURN_DATUM(jsonb_build_array_worker(nargs, args, nulls, types, false));
1255 }
struct typedefs * types
Definition: ecpg.c:29
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1997
Datum jsonb_build_array_worker(int nargs, Datum *args, bool *nulls, Oid *types, bool absent_on_null)
Definition: jsonb.c:1214

References generate_unaccent_rules::args, 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 1262 of file jsonb.c.

1263 {
1264  JsonbInState result;
1265 
1266  memset(&result, 0, sizeof(JsonbInState));
1267 
1268  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1269  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1270 
1272 }

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

◆ jsonb_build_array_worker()

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

Definition at line 1214 of file jsonb.c.

1216 {
1217  int i;
1218  JsonbInState result;
1219 
1220  memset(&result, 0, sizeof(JsonbInState));
1221 
1222  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1223 
1224  for (i = 0; i < nargs; i++)
1225  {
1226  if (absent_on_null && nulls[i])
1227  continue;
1228 
1229  add_jsonb(args[i], nulls[i], &result, types[i], false);
1230  }
1231 
1232  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1233 
1234  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1235 }
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1020

References add_jsonb(), generate_unaccent_rules::args, i, JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 1181 of file jsonb.c.

1182 {
1183  Datum *args;
1184  bool *nulls;
1185  Oid *types;
1186 
1187  /* build argument values to build the object */
1188  int nargs = extract_variadic_args(fcinfo, 0, true,
1189  &args, &types, &nulls);
1190 
1191  if (nargs < 0)
1192  PG_RETURN_NULL();
1193 
1194  PG_RETURN_DATUM(jsonb_build_object_worker(nargs, args, nulls, types, false, false));
1195 }
Datum jsonb_build_object_worker(int nargs, Datum *args, bool *nulls, Oid *types, bool absent_on_null, bool unique_keys)
Definition: jsonb.c:1129

References generate_unaccent_rules::args, 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 1201 of file jsonb.c.

1202 {
1203  JsonbInState result;
1204 
1205  memset(&result, 0, sizeof(JsonbInState));
1206 
1207  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1208  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1209 
1211 }

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

◆ jsonb_build_object_worker()

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

Definition at line 1129 of file jsonb.c.

1131 {
1132  int i;
1133  JsonbInState result;
1134 
1135  if (nargs % 2 != 0)
1136  ereport(ERROR,
1137  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1138  errmsg("argument list must have even number of elements"),
1139  /* translator: %s is a SQL function name */
1140  errhint("The arguments of %s must consist of alternating keys and values.",
1141  "jsonb_build_object()")));
1142 
1143  memset(&result, 0, sizeof(JsonbInState));
1144 
1145  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1146  result.parseState->unique_keys = unique_keys;
1147  result.parseState->skip_nulls = absent_on_null;
1148 
1149  for (i = 0; i < nargs; i += 2)
1150  {
1151  /* process key */
1152  bool skip;
1153 
1154  if (nulls[i])
1155  ereport(ERROR,
1156  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1157  errmsg("argument %d: key must not be null", i + 1)));
1158 
1159  /* skip null values if absent_on_null */
1160  skip = absent_on_null && nulls[i + 1];
1161 
1162  /* we need to save skipped keys for the key uniqueness check */
1163  if (skip && !unique_keys)
1164  continue;
1165 
1166  add_jsonb(args[i], false, &result, types[i], true);
1167 
1168  /* process value */
1169  add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1170  }
1171 
1172  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1173 
1174  return JsonbPGetDatum(JsonbValueToJsonb(result.res));
1175 }
int errhint(const char *fmt,...)
Definition: elog.c:1316
static const struct exclude_list_item skip[]
Definition: pg_checksums.c:108

References add_jsonb(), generate_unaccent_rules::args, ereport, errcode(), errhint(), errmsg(), ERROR, i, JsonbPGetDatum(), JsonbValueToJsonb(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 2131 of file jsonb.c.

2132 {
2133  Jsonb *in = PG_GETARG_JSONB_P(0);
2134  JsonbValue v;
2135  Datum retValue;
2136 
2137  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2138  cannotCastJsonbValue(v.type, "real");
2139 
2141  NumericGetDatum(v.val.numeric));
2142 
2143  PG_FREE_IF_COPY(in, 0);
2144 
2145  PG_RETURN_DATUM(retValue);
2146 }
Datum numeric_float4(PG_FUNCTION_ARGS)
Definition: numeric.c:4644

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

2150 {
2151  Jsonb *in = PG_GETARG_JSONB_P(0);
2152  JsonbValue v;
2153  Datum retValue;
2154 
2155  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2156  cannotCastJsonbValue(v.type, "double precision");
2157 
2159  NumericGetDatum(v.val.numeric));
2160 
2161  PG_FREE_IF_COPY(in, 0);
2162 
2163  PG_RETURN_DATUM(retValue);
2164 }
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:4550

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,
bool  unique_keys,
Node escontext 
)
inlinestatic

Definition at line 253 of file jsonb.c.

254 {
255  JsonLexContext *lex;
257  JsonSemAction sem;
258 
259  memset(&state, 0, sizeof(state));
260  memset(&sem, 0, sizeof(sem));
262 
263  state.unique_keys = unique_keys;
264  state.escontext = escontext;
265  sem.semstate = (void *) &state;
266 
271  sem.scalar = jsonb_in_scalar;
273 
274  if (!pg_parse_json_or_errsave(lex, &sem, escontext))
275  return (Datum) 0;
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
bool pg_parse_json_or_errsave(JsonLexContext *lex, JsonSemAction *sem, Node *escontext)
Definition: jsonfuncs.c:508
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268

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_errsave(), PG_RETURN_POINTER, JsonSemAction::scalar, 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 152 of file jsonb.c.

153 {
154  return jsonb_from_cstring(VARDATA_ANY(js),
155  VARSIZE_ANY_EXHDR(js),
156  unique_keys,
157  NULL);
158 }
static Datum jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
Definition: jsonb.c:253
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

References jsonb_from_cstring(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by ExecEvalJsonConstructor().

◆ jsonb_in()

Datum jsonb_in ( PG_FUNCTION_ARGS  )

Definition at line 77 of file jsonb.c.

78 {
79  char *json = PG_GETARG_CSTRING(0);
80 
81  return jsonb_from_cstring(json, strlen(json), false, fcinfo->context);
82 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

References jsonb_from_cstring(), and PG_GETARG_CSTRING.

Referenced by jsonb_set_lax().

◆ jsonb_in_array_end()

static JsonParseErrorType jsonb_in_array_end ( void *  pstate)
static

Definition at line 326 of file jsonb.c.

327 {
328  JsonbInState *_state = (JsonbInState *) pstate;
329 
330  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
331 
332  return JSON_SUCCESS;
333 }
@ JSON_SUCCESS
Definition: jsonapi.h:38

References JSON_SUCCESS, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 316 of file jsonb.c.

317 {
318  JsonbInState *_state = (JsonbInState *) pstate;
319 
320  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
321 
322  return JSON_SUCCESS;
323 }

References JSON_SUCCESS, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 306 of file jsonb.c.

307 {
308  JsonbInState *_state = (JsonbInState *) pstate;
309 
310  _state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
311 
312  return JSON_SUCCESS;
313 }

References JSON_SUCCESS, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 336 of file jsonb.c.

337 {
338  JsonbInState *_state = (JsonbInState *) pstate;
339  JsonbValue v;
340 
341  Assert(fname != NULL);
342  v.type = jbvString;
343  v.val.string.len = strlen(fname);
344  if (!checkStringLen(v.val.string.len, _state->escontext))
345  return JSON_SEM_ACTION_FAILED;
346  v.val.string.val = fname;
347 
348  _state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
349 
350  return JSON_SUCCESS;
351 }
@ JSON_SEM_ACTION_FAILED
Definition: jsonapi.h:57
Node * escontext
Definition: jsonb.c:37

References Assert(), checkStringLen(), JsonbInState::escontext, jbvString, JSON_SEM_ACTION_FAILED, JSON_SUCCESS, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 295 of file jsonb.c.

296 {
297  JsonbInState *_state = (JsonbInState *) pstate;
298 
299  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
300  _state->parseState->unique_keys = _state->unique_keys;
301 
302  return JSON_SUCCESS;
303 }
bool unique_keys
Definition: jsonb.c:36

References JSON_SUCCESS, JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, JsonbInState::unique_keys, JsonbParseState::unique_keys, 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 384 of file jsonb.c.

385 {
386  JsonbInState *_state = (JsonbInState *) pstate;
387  JsonbValue v;
388  Datum numd;
389 
390  switch (tokentype)
391  {
392 
393  case JSON_TOKEN_STRING:
394  Assert(token != NULL);
395  v.type = jbvString;
396  v.val.string.len = strlen(token);
397  if (!checkStringLen(v.val.string.len, _state->escontext))
398  return JSON_SEM_ACTION_FAILED;
399  v.val.string.val = token;
400  break;
401  case JSON_TOKEN_NUMBER:
402 
403  /*
404  * No need to check size of numeric values, because maximum
405  * numeric size is well below the JsonbValue restriction
406  */
407  Assert(token != NULL);
408  v.type = jbvNumeric;
410  InvalidOid, -1,
411  _state->escontext,
412  &numd))
413  return JSON_SEM_ACTION_FAILED;
414  v.val.numeric = DatumGetNumeric(numd);
415  break;
416  case JSON_TOKEN_TRUE:
417  v.type = jbvBool;
418  v.val.boolean = true;
419  break;
420  case JSON_TOKEN_FALSE:
421  v.type = jbvBool;
422  v.val.boolean = false;
423  break;
424  case JSON_TOKEN_NULL:
425  v.type = jbvNull;
426  break;
427  default:
428  /* should not be possible */
429  elog(ERROR, "invalid json token type");
430  break;
431  }
432 
433  if (_state->parseState == NULL)
434  {
435  /* single scalar */
436  JsonbValue va;
437 
438  va.type = jbvArray;
439  va.val.array.rawScalar = true;
440  va.val.array.nElems = 1;
441 
442  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
443  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
444  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
445  }
446  else
447  {
448  JsonbValue *o = &_state->parseState->contVal;
449 
450  switch (o->type)
451  {
452  case jbvArray:
453  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
454  break;
455  case jbvObject:
456  _state->res = pushJsonbValue(&_state->parseState, WJB_VALUE, &v);
457  break;
458  default:
459  elog(ERROR, "unexpected parent of nested structure");
460  }
461  }
462 
463  return JSON_SUCCESS;
464 }
bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, fmNodePtr escontext, Datum *result)
Definition: fmgr.c:1623
#define token
Definition: indent_globs.h:126
@ 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, DatumGetNumeric(), DirectInputFunctionCallSafe(), elog(), ERROR, JsonbInState::escontext, 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(), JsonbInState::parseState, pushJsonbValue(), JsonbInState::res, 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 2077 of file jsonb.c.

2078 {
2079  Jsonb *in = PG_GETARG_JSONB_P(0);
2080  JsonbValue v;
2081  Datum retValue;
2082 
2083  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2084  cannotCastJsonbValue(v.type, "smallint");
2085 
2086  retValue = DirectFunctionCall1(numeric_int2,
2087  NumericGetDatum(v.val.numeric));
2088 
2089  PG_FREE_IF_COPY(in, 0);
2090 
2091  PG_RETURN_DATUM(retValue);
2092 }
Datum numeric_int2(PG_FUNCTION_ARGS)
Definition: numeric.c:4475

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

2096 {
2097  Jsonb *in = PG_GETARG_JSONB_P(0);
2098  JsonbValue v;
2099  Datum retValue;
2100 
2101  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2102  cannotCastJsonbValue(v.type, "integer");
2103 
2104  retValue = DirectFunctionCall1(numeric_int4,
2105  NumericGetDatum(v.val.numeric));
2106 
2107  PG_FREE_IF_COPY(in, 0);
2108 
2109  PG_RETURN_DATUM(retValue);
2110 }
Datum numeric_int4(PG_FUNCTION_ARGS)
Definition: numeric.c:4396

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

2114 {
2115  Jsonb *in = PG_GETARG_JSONB_P(0);
2116  JsonbValue v;
2117  Datum retValue;
2118 
2119  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2120  cannotCastJsonbValue(v.type, "bigint");
2121 
2122  retValue = DirectFunctionCall1(numeric_int8,
2123  NumericGetDatum(v.val.numeric));
2124 
2125  PG_FREE_IF_COPY(in, 0);
2126 
2127  PG_RETURN_DATUM(retValue);
2128 }
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:4435

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

2057 {
2058  Jsonb *in = PG_GETARG_JSONB_P(0);
2059  JsonbValue v;
2060  Numeric retValue;
2061 
2062  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2063  cannotCastJsonbValue(v.type, "numeric");
2064 
2065  /*
2066  * v.val.numeric points into jsonb body, so we need to make a copy to
2067  * return
2068  */
2069  retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
2070 
2071  PG_FREE_IF_COPY(in, 0);
2072 
2073  PG_RETURN_NUMERIC(retValue);
2074 }
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 1283 of file jsonb.c.

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

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

1935 {
1936  JsonbAggState *arg;
1937  JsonbInState result;
1938  Jsonb *out;
1939 
1940  /* cannot be called directly because of internal-type argument */
1941  Assert(AggCheckCallContext(fcinfo, NULL));
1942 
1943  if (PG_ARGISNULL(0))
1944  PG_RETURN_NULL(); /* returns null iff no input values */
1945 
1947 
1948  /*
1949  * We need to do a shallow clone of the argument's res field in case the
1950  * final function is called more than once, so we avoid changing the
1951  * aggregate state value. A shallow clone is sufficient as we aren't
1952  * going to change any of the values, just add the final object end
1953  * marker.
1954  */
1955  memset(&result, 0, sizeof(JsonbInState));
1956 
1957  result.parseState = clone_parse_state(arg->res->parseState);
1958 
1959  result.res = pushJsonbValue(&result.parseState,
1960  WJB_END_OBJECT, NULL);
1961 
1962  out = JsonbValueToJsonb(result.res);
1963 
1964  PG_RETURN_POINTER(out);
1965 }

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_strict_transfn()

Datum jsonb_object_agg_strict_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1910 of file jsonb.c.

1911 {
1912  return jsonb_object_agg_transfn_worker(fcinfo, true, false);
1913 }
static Datum jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Definition: jsonb.c:1677

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_transfn()

Datum jsonb_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1900 of file jsonb.c.

1901 {
1902  return jsonb_object_agg_transfn_worker(fcinfo, false, false);
1903 }

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

1679 {
1680  MemoryContext oldcontext,
1681  aggcontext;
1682  JsonbInState elem;
1684  Datum val;
1685  JsonbInState *result;
1686  bool single_scalar;
1687  JsonbIterator *it;
1688  Jsonb *jbkey,
1689  *jbval;
1690  JsonbValue v;
1692  bool skip;
1693 
1694  if (!AggCheckCallContext(fcinfo, &aggcontext))
1695  {
1696  /* cannot be called directly because of internal-type argument */
1697  elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
1698  }
1699 
1700  /* set up the accumulator on the first go round */
1701 
1702  if (PG_ARGISNULL(0))
1703  {
1704  Oid arg_type;
1705 
1706  oldcontext = MemoryContextSwitchTo(aggcontext);
1707  state = palloc(sizeof(JsonbAggState));
1708  result = palloc0(sizeof(JsonbInState));
1709  state->res = result;
1710  result->res = pushJsonbValue(&result->parseState,
1711  WJB_BEGIN_OBJECT, NULL);
1712  result->parseState->unique_keys = unique_keys;
1713  result->parseState->skip_nulls = absent_on_null;
1714 
1715  MemoryContextSwitchTo(oldcontext);
1716 
1717  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1718 
1719  if (arg_type == InvalidOid)
1720  ereport(ERROR,
1721  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1722  errmsg("could not determine input data type")));
1723 
1724  json_categorize_type(arg_type, true, &state->key_category,
1725  &state->key_output_func);
1726 
1727  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1728 
1729  if (arg_type == InvalidOid)
1730  ereport(ERROR,
1731  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1732  errmsg("could not determine input data type")));
1733 
1734  json_categorize_type(arg_type, true, &state->val_category,
1735  &state->val_output_func);
1736  }
1737  else
1738  {
1740  result = state->res;
1741  }
1742 
1743  /* turn the argument into jsonb in the normal function context */
1744 
1745  if (PG_ARGISNULL(1))
1746  ereport(ERROR,
1747  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1748  errmsg("field name must not be null")));
1749 
1750  /*
1751  * Skip null values if absent_on_null unless key uniqueness check is
1752  * needed (because we must save keys in this case).
1753  */
1754  skip = absent_on_null && PG_ARGISNULL(2);
1755 
1756  if (skip && !unique_keys)
1758 
1759  val = PG_GETARG_DATUM(1);
1760 
1761  memset(&elem, 0, sizeof(JsonbInState));
1762 
1763  datum_to_jsonb_internal(val, false, &elem, state->key_category,
1764  state->key_output_func, true);
1765 
1766  jbkey = JsonbValueToJsonb(elem.res);
1767 
1768  val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
1769 
1770  memset(&elem, 0, sizeof(JsonbInState));
1771 
1772  datum_to_jsonb_internal(val, PG_ARGISNULL(2), &elem, state->val_category,
1773  state->val_output_func, false);
1774 
1775  jbval = JsonbValueToJsonb(elem.res);
1776 
1777  it = JsonbIteratorInit(&jbkey->root);
1778 
1779  /* switch to the aggregate context for accumulation operations */
1780 
1781  oldcontext = MemoryContextSwitchTo(aggcontext);
1782 
1783  /*
1784  * keys should be scalar, and we should have already checked for that
1785  * above when calling datum_to_jsonb, so we only need to look for these
1786  * things.
1787  */
1788 
1789  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1790  {
1791  switch (type)
1792  {
1793  case WJB_BEGIN_ARRAY:
1794  if (!v.val.array.rawScalar)
1795  elog(ERROR, "unexpected structure for key");
1796  break;
1797  case WJB_ELEM:
1798  if (v.type == jbvString)
1799  {
1800  /* copy string values in the aggregate context */
1801  char *buf = palloc(v.val.string.len + 1);
1802 
1803  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1804  v.val.string.val = buf;
1805  }
1806  else
1807  {
1808  ereport(ERROR,
1809  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1810  errmsg("object keys must be strings")));
1811  }
1812  result->res = pushJsonbValue(&result->parseState,
1813  WJB_KEY, &v);
1814 
1815  if (skip)
1816  {
1817  v.type = jbvNull;
1818  result->res = pushJsonbValue(&result->parseState,
1819  WJB_VALUE, &v);
1820  MemoryContextSwitchTo(oldcontext);
1822  }
1823 
1824  break;
1825  case WJB_END_ARRAY:
1826  break;
1827  default:
1828  elog(ERROR, "unexpected structure for key");
1829  break;
1830  }
1831  }
1832 
1833  it = JsonbIteratorInit(&jbval->root);
1834 
1835  single_scalar = false;
1836 
1837  /*
1838  * values can be anything, including structured and null, so we treat them
1839  * as in json_agg_transfn, except that single scalars are always pushed as
1840  * WJB_VALUE items.
1841  */
1842 
1843  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1844  {
1845  switch (type)
1846  {
1847  case WJB_BEGIN_ARRAY:
1848  if (v.val.array.rawScalar)
1849  single_scalar = true;
1850  else
1851  result->res = pushJsonbValue(&result->parseState,
1852  type, NULL);
1853  break;
1854  case WJB_END_ARRAY:
1855  if (!single_scalar)
1856  result->res = pushJsonbValue(&result->parseState,
1857  type, NULL);
1858  break;
1859  case WJB_BEGIN_OBJECT:
1860  case WJB_END_OBJECT:
1861  result->res = pushJsonbValue(&result->parseState,
1862  type, NULL);
1863  break;
1864  case WJB_ELEM:
1865  case WJB_KEY:
1866  case WJB_VALUE:
1867  if (v.type == jbvString)
1868  {
1869  /* copy string values in the aggregate context */
1870  char *buf = palloc(v.val.string.len + 1);
1871 
1872  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1873  v.val.string.val = buf;
1874  }
1875  else if (v.type == jbvNumeric)
1876  {
1877  /* same for numeric */
1878  v.val.numeric =
1880  NumericGetDatum(v.val.numeric)));
1881  }
1882  result->res = pushJsonbValue(&result->parseState,
1883  single_scalar ? WJB_VALUE : type,
1884  &v);
1885  break;
1886  default:
1887  elog(ERROR, "unknown jsonb iterator token type");
1888  }
1889  }
1890 
1891  MemoryContextSwitchTo(oldcontext);
1892 
1894 }

References AggCheckCallContext(), buf, datum_to_jsonb_internal(), DatumGetNumeric(), DirectFunctionCall1, elog(), ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, get_fn_expr_argtype(), InvalidOid, jbvNull, jbvNumeric, jbvString, json_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, skip, JsonbParseState::skip_nulls, snprintf, type, JsonbValue::type, JsonbParseState::unique_keys, 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 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 1928 of file jsonb.c.

1929 {
1930  return jsonb_object_agg_transfn_worker(fcinfo, true, true);
1931 }

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_unique_transfn()

Datum jsonb_object_agg_unique_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1919 of file jsonb.c.

1920 {
1921  return jsonb_object_agg_transfn_worker(fcinfo, false, true);
1922 }

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_two_arg()

Datum jsonb_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1383 of file jsonb.c.

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

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

113 {
114  Jsonb *jb = PG_GETARG_JSONB_P(0);
115  char *out;
116 
117  out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
118 
119  PG_RETURN_CSTRING(out);
120 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:478
#define VARSIZE(PTR)
Definition: varatt.h:279

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

355 {
356  switch (scalarVal->type)
357  {
358  case jbvNull:
359  appendBinaryStringInfo(out, "null", 4);
360  break;
361  case jbvString:
362  escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len));
363  break;
364  case jbvNumeric:
367  PointerGetDatum(scalarVal->val.numeric))));
368  break;
369  case jbvBool:
370  if (scalarVal->val.boolean)
371  appendBinaryStringInfo(out, "true", 4);
372  else
373  appendBinaryStringInfo(out, "false", 5);
374  break;
375  default:
376  elog(ERROR, "unknown jsonb scalar type");
377  }
378 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:806
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1525
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1655
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:227
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 93 of file jsonb.c.

94 {
96  int version = pq_getmsgint(buf, 1);
97  char *str;
98  int nbytes;
99 
100  if (version == 1)
101  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
102  else
103  elog(ERROR, "unsupported jsonb version number %d", version);
104 
105  return jsonb_from_cstring(str, nbytes, false, NULL);
106 }
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:549
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 128 of file jsonb.c.

129 {
130  Jsonb *jb = PG_GETARG_JSONB_P(0);
132  StringInfo jtext = makeStringInfo();
133  int version = 1;
134 
135  (void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
136 
138  pq_sendint8(&buf, version);
139  pq_sendtext(&buf, jtext->data, jtext->len);
140  pfree(jtext->data);
141  pfree(jtext);
142 
144 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:175
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
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 234 of file jsonb.c.

235 {
236  Jsonb *in = PG_GETARG_JSONB_P(0);
237  const char *result = JsonbContainerTypeName(&in->root);
238 
240 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:164
text * cstring_to_text(const char *s)
Definition: varlena.c:182

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

165 {
166  JsonbValue scalar;
167 
168  if (JsonbExtractScalar(jbc, &scalar))
169  return JsonbTypeName(&scalar);
170  else if (JsonContainerIsArray(jbc))
171  return "array";
172  else if (JsonContainerIsObject(jbc))
173  return "object";
174  else
175  {
176  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
177  return "unknown";
178  }
179 }
const char * JsonbTypeName(JsonbValue *val)
Definition: jsonb.c:185
#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 1972 of file jsonb.c.

1973 {
1974  JsonbIterator *it;
1976  JsonbValue tmp;
1977 
1978  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1979  {
1980  /* inform caller about actual type of container */
1981  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1982  return false;
1983  }
1984 
1985  /*
1986  * A root scalar is stored as an array of one element, so we get the array
1987  * and then its first (and only) member.
1988  */
1989  it = JsonbIteratorInit(jbc);
1990 
1991  tok = JsonbIteratorNext(&it, &tmp, true);
1992  Assert(tok == WJB_BEGIN_ARRAY);
1993  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1994 
1995  tok = JsonbIteratorNext(&it, res, true);
1996  Assert(tok == WJB_ELEM);
1998 
1999  tok = JsonbIteratorNext(&it, &tmp, true);
2000  Assert(tok == WJB_END_ARRAY);
2001 
2002  tok = JsonbIteratorNext(&it, &tmp, true);
2003  Assert(tok == WJB_DONE);
2004 
2005  return true;
2006 }
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:171
#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 478 of file jsonb.c.

479 {
480  return JsonbToCStringWorker(out, in, estimated_len, false);
481 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:496

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

488 {
489  return JsonbToCStringWorker(out, in, estimated_len, true);
490 }

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToCStringWorker()

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

Definition at line 496 of file jsonb.c.

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

186 {
187  switch (val->type)
188  {
189  case jbvBinary:
190  return JsonbContainerTypeName(val->val.binary.data);
191  case jbvObject:
192  return "object";
193  case jbvArray:
194  return "array";
195  case jbvNumeric:
196  return "number";
197  case jbvString:
198  return "string";
199  case jbvBool:
200  return "boolean";
201  case jbvNull:
202  return "null";
203  case jbvDatetime:
204  switch (val->val.datetime.typid)
205  {
206  case DATEOID:
207  return "date";
208  case TIMEOID:
209  return "time without time zone";
210  case TIMETZOID:
211  return "time with time zone";
212  case TIMESTAMPOID:
213  return "timestamp without time zone";
214  case TIMESTAMPTZOID:
215  return "timestamp with time zone";
216  default:
217  elog(ERROR, "unrecognized jsonb value datetime type: %d",
218  val->val.datetime.typid);
219  }
220  return "unknown";
221  default:
222  elog(ERROR, "unrecognized jsonb value type: %d", val->type);
223  return "unknown";
224  }
225 }
@ 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 1092 of file jsonb.c.

1093 {
1094  Datum val = PG_GETARG_DATUM(0);
1095  Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1096  JsonTypeCategory tcategory;
1097  Oid outfuncoid;
1098 
1099  if (val_type == InvalidOid)
1100  ereport(ERROR,
1101  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1102  errmsg("could not determine input data type")));
1103 
1104  json_categorize_type(val_type, true,
1105  &tcategory, &outfuncoid);
1106 
1107  PG_RETURN_DATUM(datum_to_jsonb(val, tcategory, outfuncoid));
1108 }
Datum datum_to_jsonb(Datum val, JsonTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:1116

References datum_to_jsonb(), ereport, errcode(), errmsg(), ERROR, 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 1053 of file jsonb.c.

1054 {
1055  JsonTypeCategory tcategory;
1056  Oid outfuncoid;
1057 
1058  json_categorize_type(typoid, true, &tcategory, &outfuncoid);
1059 
1060  switch (tcategory)
1061  {
1062  case JSONTYPE_NULL:
1063  case JSONTYPE_BOOL:
1064  case JSONTYPE_JSON:
1065  case JSONTYPE_JSONB:
1066  return true;
1067 
1068  case JSONTYPE_DATE:
1069  case JSONTYPE_TIMESTAMP:
1070  case JSONTYPE_TIMESTAMPTZ:
1071  return false;
1072 
1073  case JSONTYPE_ARRAY:
1074  return false; /* TODO recurse into elements */
1075 
1076  case JSONTYPE_COMPOSITE:
1077  return false; /* TODO recurse into fields */
1078 
1079  case JSONTYPE_NUMERIC:
1080  case JSONTYPE_CAST:
1081  case JSONTYPE_OTHER:
1082  return func_volatile(outfuncoid) == PROVOLATILE_IMMUTABLE;
1083  }
1084 
1085  return false; /* not reached */
1086 }
@ JSONTYPE_OTHER
Definition: jsonfuncs.h:80
char func_volatile(Oid funcid)
Definition: lsyscache.c:1784

References func_volatile(), json_categorize_type(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_JSONB, JSONTYPE_NULL, JSONTYPE_NUMERIC, JSONTYPE_OTHER, JSONTYPE_TIMESTAMP, and JSONTYPE_TIMESTAMPTZ.

Referenced by contain_mutable_functions_walker().