PostgreSQL Source Code  git master
jsonb.c File Reference
#include "postgres.h"
#include "access/htup_details.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/json.h"
#include "utils/jsonb.h"
#include "utils/jsonfuncs.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
Include dependency graph for jsonb.c:

Go to the source code of this file.

Data Structures

struct  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, const Datum *vals, const bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid)
 
static void array_to_jsonb_internal (Datum array, JsonbInState *result)
 
static void datum_to_jsonb_internal (Datum val, bool is_null, JsonbInState *result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
 
static void add_jsonb (Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
 
static 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, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null, bool unique_keys)
 
Datum jsonb_build_object (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array_worker (int nargs, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
 
Datum jsonb_build_array (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_object (PG_FUNCTION_ARGS)
 
Datum jsonb_object_two_arg (PG_FUNCTION_ARGS)
 
static Datum jsonb_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null)
 
Datum jsonb_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_finalfn (PG_FUNCTION_ARGS)
 
static Datum jsonb_object_agg_transfn_worker (FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
 
Datum jsonb_object_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_unique_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_unique_strict_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_finalfn (PG_FUNCTION_ARGS)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
static void cannotCastJsonbValue (enum jbvType type, const char *sqltype)
 
Datum jsonb_bool (PG_FUNCTION_ARGS)
 
Datum jsonb_numeric (PG_FUNCTION_ARGS)
 
Datum jsonb_int2 (PG_FUNCTION_ARGS)
 
Datum jsonb_int4 (PG_FUNCTION_ARGS)
 
Datum jsonb_int8 (PG_FUNCTION_ARGS)
 
Datum jsonb_float4 (PG_FUNCTION_ARGS)
 
Datum jsonb_float8 (PG_FUNCTION_ARGS)
 

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

617 {
618  if (indent)
619  {
620  appendStringInfoCharMacro(out, '\n');
621  appendStringInfoSpaces(out, level * 4);
622  }
623 }
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:212
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:203

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

1019 {
1020  JsonTypeCategory tcategory;
1021  Oid outfuncoid;
1022 
1023  if (val_type == InvalidOid)
1024  ereport(ERROR,
1025  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1026  errmsg("could not determine input data type")));
1027 
1028  if (is_null)
1029  {
1030  tcategory = JSONTYPE_NULL;
1031  outfuncoid = InvalidOid;
1032  }
1033  else
1034  json_categorize_type(val_type, true,
1035  &tcategory, &outfuncoid);
1036 
1037  datum_to_jsonb_internal(val, is_null, result, tcategory, outfuncoid,
1038  key_scalar);
1039 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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:639
void json_categorize_type(Oid typoid, bool is_jsonb, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonfuncs.c:5897
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,
const Datum vals,
const bool nulls,
int *  valcount,
JsonTypeCategory  tcategory,
Oid  outfuncoid 
)
static

Definition at line 863 of file jsonb.c.

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

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

896 {
897  ArrayType *v = DatumGetArrayTypeP(array);
898  Oid element_type = ARR_ELEMTYPE(v);
899  int *dim;
900  int ndim;
901  int nitems;
902  int count = 0;
903  Datum *elements;
904  bool *nulls;
905  int16 typlen;
906  bool typbyval;
907  char typalign;
908  JsonTypeCategory tcategory;
909  Oid outfuncoid;
910 
911  ndim = ARR_NDIM(v);
912  dim = ARR_DIMS(v);
913  nitems = ArrayGetNItems(ndim, dim);
914 
915  if (nitems <= 0)
916  {
917  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
918  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
919  return;
920  }
921 
922  get_typlenbyvalalign(element_type,
923  &typlen, &typbyval, &typalign);
924 
925  json_categorize_type(element_type, true,
926  &tcategory, &outfuncoid);
927 
928  deconstruct_array(v, element_type, typlen, typbyval,
929  typalign, &elements, &nulls,
930  &nitems);
931 
932  array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
933  outfuncoid);
934 
935  pfree(elements);
936  pfree(nulls);
937 }
#define ARR_NDIM(a)
Definition: array.h:290
#define DatumGetArrayTypeP(X)
Definition: array.h:261
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3612
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
signed short int16
Definition: c.h:480
#define nitems(x)
Definition: indent.h:31
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2227
void pfree(void *pointer)
Definition: mcxt.c:1401
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 2009 of file jsonb.c.

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

279 {
280  if (len > JENTRY_OFFLENMASK)
281  ereturn(escontext, false,
282  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
283  errmsg("string too long to represent as jsonb string"),
284  errdetail("Due to an implementation restriction, jsonb strings cannot exceed %d bytes.",
286 
287  return true;
288 }
int errdetail(const char *fmt,...)
Definition: elog.c:1205
#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 1472 of file jsonb.c.

1473 {
1474  JsonbParseState *result,
1475  *icursor,
1476  *ocursor;
1477 
1478  if (state == NULL)
1479  return NULL;
1480 
1481  result = palloc(sizeof(JsonbParseState));
1482  icursor = state;
1483  ocursor = result;
1484  for (;;)
1485  {
1486  ocursor->contVal = icursor->contVal;
1487  ocursor->size = icursor->size;
1488  ocursor->unique_keys = icursor->unique_keys;
1489  ocursor->skip_nulls = icursor->skip_nulls;
1490  icursor = icursor->next;
1491  if (icursor == NULL)
1492  break;
1493  ocursor->next = palloc(sizeof(JsonbParseState));
1494  ocursor = ocursor->next;
1495  }
1496  ocursor->next = NULL;
1497 
1498  return result;
1499 }
void * palloc(Size size)
Definition: mcxt.c:1197
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 943 of file jsonb.c.

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

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

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

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

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

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, freeJsonLexContext(), 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 1641 of file jsonb.c.

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

1636 {
1637  return jsonb_agg_transfn_worker(fcinfo, true);
1638 }
static Datum jsonb_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null)
Definition: jsonb.c:1502

References jsonb_agg_transfn_worker().

◆ jsonb_agg_transfn()

Datum jsonb_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1626 of file jsonb.c.

1627 {
1628  return jsonb_agg_transfn_worker(fcinfo, false);
1629 }

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

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

2040 {
2041  Jsonb *in = PG_GETARG_JSONB_P(0);
2042  JsonbValue v;
2043 
2044  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
2045  cannotCastJsonbValue(v.type, "boolean");
2046 
2047  PG_FREE_IF_COPY(in, 0);
2048 
2049  PG_RETURN_BOOL(v.val.boolean);
2050 }
#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:2009
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1969
#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 1238 of file jsonb.c.

1239 {
1240  Datum *args;
1241  bool *nulls;
1242  Oid *types;
1243 
1244  /* build argument values to build the object */
1245  int nargs = extract_variadic_args(fcinfo, 0, true,
1246  &args, &types, &nulls);
1247 
1248  if (nargs < 0)
1249  PG_RETURN_NULL();
1250 
1251  PG_RETURN_DATUM(jsonb_build_array_worker(nargs, args, nulls, types, false));
1252 }
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, const Datum *args, const bool *nulls, const Oid *types, bool absent_on_null)
Definition: jsonb.c:1211

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

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

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,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null 
)

Definition at line 1211 of file jsonb.c.

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

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

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

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

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

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,
const Datum args,
const bool nulls,
const Oid types,
bool  absent_on_null,
bool  unique_keys 
)

Definition at line 1126 of file jsonb.c.

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

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

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

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

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

250 {
251  JsonLexContext lex;
253  JsonSemAction sem;
254 
255  memset(&state, 0, sizeof(state));
256  memset(&sem, 0, sizeof(sem));
258 
259  state.unique_keys = unique_keys;
260  state.escontext = escontext;
261  sem.semstate = (void *) &state;
262 
267  sem.scalar = jsonb_in_scalar;
269 
270  if (!pg_parse_json_or_errsave(&lex, &sem, escontext))
271  return (Datum) 0;
272 
273  /* after parsing, the item member has the composed jsonb structure */
275 }
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:153
bool pg_parse_json_or_errsave(JsonLexContext *lex, JsonSemAction *sem, Node *escontext)
Definition: jsonfuncs.c:516
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261

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

149 {
150  return jsonb_from_cstring(VARDATA_ANY(js),
151  VARSIZE_ANY_EXHDR(js),
152  unique_keys,
153  NULL);
154 }
static Datum jsonb_from_cstring(char *json, int len, bool unique_keys, Node *escontext)
Definition: jsonb.c:249
#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 73 of file jsonb.c.

74 {
75  char *json = PG_GETARG_CSTRING(0);
76 
77  return jsonb_from_cstring(json, strlen(json), false, fcinfo->context);
78 }
#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 322 of file jsonb.c.

323 {
324  JsonbInState *_state = (JsonbInState *) pstate;
325 
326  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
327 
328  return JSON_SUCCESS;
329 }
@ 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 312 of file jsonb.c.

313 {
314  JsonbInState *_state = (JsonbInState *) pstate;
315 
316  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
317 
318  return JSON_SUCCESS;
319 }

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

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

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

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

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

292 {
293  JsonbInState *_state = (JsonbInState *) pstate;
294 
295  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
296  _state->parseState->unique_keys = _state->unique_keys;
297 
298  return JSON_SUCCESS;
299 }
bool unique_keys
Definition: jsonb.c:32

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

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

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

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

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

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

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

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

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

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

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

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

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

1908 {
1909  return jsonb_object_agg_transfn_worker(fcinfo, true, false);
1910 }
static Datum jsonb_object_agg_transfn_worker(FunctionCallInfo fcinfo, bool absent_on_null, bool unique_keys)
Definition: jsonb.c:1674

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_transfn()

Datum jsonb_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1897 of file jsonb.c.

1898 {
1899  return jsonb_object_agg_transfn_worker(fcinfo, false, false);
1900 }

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

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

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

1926 {
1927  return jsonb_object_agg_transfn_worker(fcinfo, true, true);
1928 }

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_agg_unique_transfn()

Datum jsonb_object_agg_unique_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1916 of file jsonb.c.

1917 {
1918  return jsonb_object_agg_transfn_worker(fcinfo, false, true);
1919 }

References jsonb_object_agg_transfn_worker().

◆ jsonb_object_two_arg()

Datum jsonb_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1380 of file jsonb.c.

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

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

109 {
110  Jsonb *jb = PG_GETARG_JSONB_P(0);
111  char *out;
112 
113  out = JsonbToCString(NULL, &jb->root, VARSIZE(jb));
114 
115  PG_RETURN_CSTRING(out);
116 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:474
#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 350 of file jsonb.c.

351 {
352  switch (scalarVal->type)
353  {
354  case jbvNull:
355  appendBinaryStringInfo(out, "null", 4);
356  break;
357  case jbvString:
358  escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len));
359  break;
360  case jbvNumeric:
363  PointerGetDatum(scalarVal->val.numeric))));
364  break;
365  case jbvBool:
366  if (scalarVal->val.boolean)
367  appendBinaryStringInfo(out, "true", 4);
368  else
369  appendBinaryStringInfo(out, "false", 5);
370  break;
371  default:
372  elog(ERROR, "unknown jsonb scalar type");
373  }
374 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:805
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1549
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1587
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:233
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182

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

90 {
92  int version = pq_getmsgint(buf, 1);
93  char *str;
94  int nbytes;
95 
96  if (version == 1)
97  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
98  else
99  elog(ERROR, "unsupported jsonb version number %d", version);
100 
101  return jsonb_from_cstring(str, nbytes, false, NULL);
102 }
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

125 {
126  Jsonb *jb = PG_GETARG_JSONB_P(0);
128  StringInfo jtext = makeStringInfo();
129  int version = 1;
130 
131  (void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
132 
134  pq_sendint8(&buf, version);
135  pq_sendtext(&buf, jtext->data, jtext->len);
136  pfree(jtext->data);
137  pfree(jtext);
138 
140 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:128
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 230 of file jsonb.c.

231 {
232  Jsonb *in = PG_GETARG_JSONB_P(0);
233  const char *result = JsonbContainerTypeName(&in->root);
234 
236 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static const char * JsonbContainerTypeName(JsonbContainer *jbc)
Definition: jsonb.c:160
text * cstring_to_text(const char *s)
Definition: varlena.c:184

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

◆ JsonbContainerTypeName()

static const char* JsonbContainerTypeName ( JsonbContainer jbc)
static

Definition at line 160 of file jsonb.c.

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

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

475 {
476  return JsonbToCStringWorker(out, in, estimated_len, false);
477 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:492

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

484 {
485  return JsonbToCStringWorker(out, in, estimated_len, true);
486 }

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

◆ JsonbToCStringWorker()

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

Definition at line 492 of file jsonb.c.

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

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

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

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

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

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

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