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

Go to the source code of this file.

Data Structures

struct  JsonbInState
 
struct  JsonbAggState
 

Typedefs

typedef struct JsonbInState JsonbInState
 
typedef struct JsonbAggState JsonbAggState
 

Enumerations

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

Functions

static Datum jsonb_from_cstring (char *json, int len)
 
static size_t checkStringLen (size_t len)
 
static void jsonb_in_object_start (void *pstate)
 
static void jsonb_in_object_end (void *pstate)
 
static void jsonb_in_array_start (void *pstate)
 
static void jsonb_in_array_end (void *pstate)
 
static void jsonb_in_object_field_start (void *pstate, char *fname, bool isnull)
 
static void jsonb_put_escaped_value (StringInfo out, JsonbValue *scalarVal)
 
static void jsonb_in_scalar (void *pstate, char *token, JsonTokenType tokentype)
 
static void jsonb_categorize_type (Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
 
static void composite_to_jsonb (Datum composite, JsonbInState *result)
 
static void array_dim_to_jsonb (JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonbTypeCategory tcategory, Oid outfuncoid)
 
static void array_to_jsonb_internal (Datum array, JsonbInState *result)
 
static void datum_to_jsonb (Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
 
static void add_jsonb (Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
 
static JsonbParseStateclone_parse_state (JsonbParseState *state)
 
static char * JsonbToCStringWorker (StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
 
static void add_indent (StringInfo out, bool indent, int level)
 
Datum jsonb_in (PG_FUNCTION_ARGS)
 
Datum jsonb_recv (PG_FUNCTION_ARGS)
 
Datum jsonb_out (PG_FUNCTION_ARGS)
 
Datum jsonb_send (PG_FUNCTION_ARGS)
 
static const char * JsonbContainerTypeName (JsonbContainer *jbc)
 
const char * JsonbTypeName (JsonbValue *jbv)
 
Datum jsonb_typeof (PG_FUNCTION_ARGS)
 
char * JsonbToCString (StringInfo out, JsonbContainer *in, int estimated_len)
 
char * JsonbToCStringIndent (StringInfo out, JsonbContainer *in, int estimated_len)
 
Datum to_jsonb (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object (PG_FUNCTION_ARGS)
 
Datum jsonb_build_object_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array (PG_FUNCTION_ARGS)
 
Datum jsonb_build_array_noargs (PG_FUNCTION_ARGS)
 
Datum jsonb_object (PG_FUNCTION_ARGS)
 
Datum jsonb_object_two_arg (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_transfn (PG_FUNCTION_ARGS)
 
Datum jsonb_object_agg_finalfn (PG_FUNCTION_ARGS)
 
bool JsonbExtractScalar (JsonbContainer *jbc, JsonbValue *res)
 
static void cannotCastJsonbValue (enum jbvType type, const char *sqltype)
 
Datum jsonb_bool (PG_FUNCTION_ARGS)
 
Datum jsonb_numeric (PG_FUNCTION_ARGS)
 
Datum jsonb_int2 (PG_FUNCTION_ARGS)
 
Datum jsonb_int4 (PG_FUNCTION_ARGS)
 
Datum jsonb_int8 (PG_FUNCTION_ARGS)
 
Datum jsonb_float4 (PG_FUNCTION_ARGS)
 
Datum jsonb_float8 (PG_FUNCTION_ARGS)
 

Typedef Documentation

◆ JsonbAggState

typedef struct JsonbAggState JsonbAggState

◆ JsonbInState

typedef struct JsonbInState JsonbInState

Enumeration Type Documentation

◆ JsonbTypeCategory

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

Definition at line 39 of file jsonb.c.

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

Function Documentation

◆ add_indent()

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

Definition at line 602 of file jsonb.c.

References appendBinaryStringInfo(), appendStringInfoCharMacro, and i.

Referenced by JsonbToCStringWorker().

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

◆ add_jsonb()

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

Definition at line 1106 of file jsonb.c.

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

Referenced by jsonb_build_array(), and jsonb_build_object().

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

◆ array_dim_to_jsonb()

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

Definition at line 954 of file jsonb.c.

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

Referenced by array_to_jsonb_internal().

957 {
958  int i;
959 
960  Assert(dim < ndims);
961 
962  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
963 
964  for (i = 1; i <= dims[dim]; i++)
965  {
966  if (dim + 1 == ndims)
967  {
968  datum_to_jsonb(vals[*valcount], nulls[*valcount], result, tcategory,
969  outfuncoid, false);
970  (*valcount)++;
971  }
972  else
973  {
974  array_dim_to_jsonb(result, dim + 1, ndims, dims, vals, nulls,
975  valcount, tcategory, outfuncoid);
976  }
977  }
978 
979  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
980 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonbTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:954
#define Assert(condition)
Definition: c.h:732
int i

◆ array_to_jsonb_internal()

static void array_to_jsonb_internal ( Datum  array,
JsonbInState result 
)
static

Definition at line 986 of file jsonb.c.

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

Referenced by datum_to_jsonb().

987 {
988  ArrayType *v = DatumGetArrayTypeP(array);
989  Oid element_type = ARR_ELEMTYPE(v);
990  int *dim;
991  int ndim;
992  int nitems;
993  int count = 0;
994  Datum *elements;
995  bool *nulls;
996  int16 typlen;
997  bool typbyval;
998  char typalign;
999  JsonbTypeCategory tcategory;
1000  Oid outfuncoid;
1001 
1002  ndim = ARR_NDIM(v);
1003  dim = ARR_DIMS(v);
1004  nitems = ArrayGetNItems(ndim, dim);
1005 
1006  if (nitems <= 0)
1007  {
1008  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
1009  result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
1010  return;
1011  }
1012 
1013  get_typlenbyvalalign(element_type,
1014  &typlen, &typbyval, &typalign);
1015 
1016  jsonb_categorize_type(element_type,
1017  &tcategory, &outfuncoid);
1018 
1019  deconstruct_array(v, element_type, typlen, typbyval,
1020  typalign, &elements, &nulls,
1021  &nitems);
1022 
1023  array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
1024  outfuncoid);
1025 
1026  pfree(elements);
1027  pfree(nulls);
1028 }
signed short int16
Definition: c.h:345
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2049
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
unsigned int Oid
Definition: postgres_ext.h:31
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
void pfree(void *pointer)
Definition: mcxt.c:1056
char typalign
Definition: pg_type.h:170
#define ARR_DIMS(a)
Definition: array.h:282
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonbTypeCategory tcategory, Oid outfuncoid)
Definition: jsonb.c:954
uintptr_t Datum
Definition: postgres.h:367
JsonbTypeCategory
Definition: jsonb.c:39
#define ARR_NDIM(a)
Definition: array.h:278
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ cannotCastJsonbValue()

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

Definition at line 1935 of file jsonb.c.

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

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

1936 {
1937  static const struct
1938  {
1939  enum jbvType type;
1940  const char *msg;
1941  }
1942  messages[] =
1943  {
1944  {jbvNull, gettext_noop("cannot cast jsonb null to type %s")},
1945  {jbvString, gettext_noop("cannot cast jsonb string to type %s")},
1946  {jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")},
1947  {jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")},
1948  {jbvArray, gettext_noop("cannot cast jsonb array to type %s")},
1949  {jbvObject, gettext_noop("cannot cast jsonb object to type %s")},
1950  {jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")}
1951  };
1952  int i;
1953 
1954  for (i = 0; i < lengthof(messages); i++)
1955  if (messages[i].type == type)
1956  ereport(ERROR,
1957  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1958  errmsg(messages[i].msg, sqltype)));
1959 
1960  /* should be unreachable */
1961  elog(ERROR, "unknown jsonb type: %d", (int) type);
1962 }
jbvType
Definition: jsonb.h:233
Definition: jsonb.h:239
#define gettext_noop(x)
Definition: c.h:1117
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
#define lengthof(array)
Definition: c.h:662
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i

◆ checkStringLen()

static size_t checkStringLen ( size_t  len)
static

Definition at line 282 of file jsonb.c.

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

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

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

◆ clone_parse_state()

static JsonbParseState * clone_parse_state ( JsonbParseState state)
static

Definition at line 1477 of file jsonb.c.

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

Referenced by jsonb_agg_finalfn(), and jsonb_object_agg_finalfn().

1478 {
1479  JsonbParseState *result,
1480  *icursor,
1481  *ocursor;
1482 
1483  if (state == NULL)
1484  return NULL;
1485 
1486  result = palloc(sizeof(JsonbParseState));
1487  icursor = state;
1488  ocursor = result;
1489  for (;;)
1490  {
1491  ocursor->contVal = icursor->contVal;
1492  ocursor->size = icursor->size;
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 }
struct JsonbParseState * next
Definition: jsonb.h:331
JsonbValue contVal
Definition: jsonb.h:329
void * palloc(Size size)
Definition: mcxt.c:949

◆ composite_to_jsonb()

static void composite_to_jsonb ( Datum  composite,
JsonbInState result 
)
static

Definition at line 1034 of file jsonb.c.

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

Referenced by datum_to_jsonb().

1035 {
1036  HeapTupleHeader td;
1037  Oid tupType;
1038  int32 tupTypmod;
1039  TupleDesc tupdesc;
1040  HeapTupleData tmptup,
1041  *tuple;
1042  int i;
1043 
1044  td = DatumGetHeapTupleHeader(composite);
1045 
1046  /* Extract rowtype info and find a tupdesc */
1047  tupType = HeapTupleHeaderGetTypeId(td);
1048  tupTypmod = HeapTupleHeaderGetTypMod(td);
1049  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
1050 
1051  /* Build a temporary HeapTuple control structure */
1052  tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
1053  tmptup.t_data = td;
1054  tuple = &tmptup;
1055 
1056  result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_OBJECT, NULL);
1057 
1058  for (i = 0; i < tupdesc->natts; i++)
1059  {
1060  Datum val;
1061  bool isnull;
1062  char *attname;
1063  JsonbTypeCategory tcategory;
1064  Oid outfuncoid;
1065  JsonbValue v;
1066  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1067 
1068  if (att->attisdropped)
1069  continue;
1070 
1071  attname = NameStr(att->attname);
1072 
1073  v.type = jbvString;
1074  /* don't need checkStringLen here - can't exceed maximum name length */
1075  v.val.string.len = strlen(attname);
1076  v.val.string.val = attname;
1077 
1078  result->res = pushJsonbValue(&result->parseState, WJB_KEY, &v);
1079 
1080  val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
1081 
1082  if (isnull)
1083  {
1084  tcategory = JSONBTYPE_NULL;
1085  outfuncoid = InvalidOid;
1086  }
1087  else
1088  jsonb_categorize_type(att->atttypid, &tcategory, &outfuncoid);
1089 
1090  datum_to_jsonb(val, isnull, result, tcategory, outfuncoid, false);
1091  }
1092 
1093  result->res = pushJsonbValue(&result->parseState, WJB_END_OBJECT, NULL);
1094  ReleaseTupleDesc(tupdesc);
1095 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1652
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * val
Definition: jsonb.h:272
unsigned int Oid
Definition: postgres_ext.h:31
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:289
signed int int32
Definition: c.h:346
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
NameData attname
Definition: pg_attribute.h:40
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
Definition: jsonb.h:23
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:458
JsonbTypeCategory
Definition: jsonb.c:39
#define InvalidOid
Definition: postgres_ext.h:36
enum jbvType type
Definition: jsonb.h:263
int i
#define NameStr(name)
Definition: c.h:609
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
long val
Definition: informix.c:684
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ datum_to_jsonb()

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

Definition at line 731 of file jsonb.c.

References JsonSemAction::array_end, JsonSemAction::array_start, array_to_jsonb_internal(), Assert, check_stack_depth(), checkStringLen(), composite_to_jsonb(), JsonbParseState::contVal, CStringGetDatum, DatumGetBool, DatumGetJsonbP, DatumGetNumeric, DatumGetTextPP, DirectFunctionCall3, elog, ereport, errcode(), errmsg(), ERROR, Int32GetDatum, InvalidOid, JB_ROOT_IS_SCALAR, jbvArray, jbvBool, jbvNull, jbvNumeric, jbvObject, jbvString, jsonb_in_array_end(), jsonb_in_array_start(), jsonb_in_object_end(), jsonb_in_object_field_start(), jsonb_in_object_start(), jsonb_in_scalar(), JsonbIteratorInit(), JsonbIteratorNext(), JSONBTYPE_ARRAY, JSONBTYPE_BOOL, JSONBTYPE_COMPOSITE, JSONBTYPE_DATE, JSONBTYPE_JSON, JSONBTYPE_JSONB, JSONBTYPE_JSONCAST, JSONBTYPE_NUMERIC, JSONBTYPE_TIMESTAMP, JSONBTYPE_TIMESTAMPTZ, JsonEncodeDateTime(), makeJsonLexContext(), numeric_in(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, ObjectIdGetDatum, OidFunctionCall1, OidOutputFunctionCall(), JsonbInState::parseState, pfree(), pg_parse_json(), pushJsonbValue(), JsonbInState::res, Jsonb::root, JsonSemAction::scalar, JsonSemAction::semstate, JsonbValue::type, generate_unaccent_rules::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_BEGIN_OBJECT, WJB_DONE, WJB_ELEM, WJB_END_ARRAY, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

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

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

◆ jsonb_agg_finalfn()

Datum jsonb_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1627 of file jsonb.c.

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

1628 {
1629  JsonbAggState *arg;
1630  JsonbInState result;
1631  Jsonb *out;
1632 
1633  /* cannot be called directly because of internal-type argument */
1634  Assert(AggCheckCallContext(fcinfo, NULL));
1635 
1636  if (PG_ARGISNULL(0))
1637  PG_RETURN_NULL(); /* returns null iff no input values */
1638 
1639  arg = (JsonbAggState *) PG_GETARG_POINTER(0);
1640 
1641  /*
1642  * We need to do a shallow clone of the argument in case the final
1643  * function is called more than once, so we avoid changing the argument. A
1644  * shallow clone is sufficient as we aren't going to change any of the
1645  * values, just add the final array end marker.
1646  */
1647 
1648  result.parseState = clone_parse_state(arg->res->parseState);
1649 
1650  result.res = pushJsonbValue(&result.parseState,
1651  WJB_END_ARRAY, NULL);
1652 
1653  out = JsonbValueToJsonb(result.res);
1654 
1655  PG_RETURN_POINTER(out);
1656 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
static JsonbParseState * clone_parse_state(JsonbParseState *state)
Definition: jsonb.c:1477
JsonbInState * res
Definition: jsonb.c:57
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:732
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
void * arg
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ jsonb_agg_transfn()

Datum jsonb_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1509 of file jsonb.c.

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

1510 {
1511  MemoryContext oldcontext,
1512  aggcontext;
1514  JsonbInState elem;
1515  Datum val;
1516  JsonbInState *result;
1517  bool single_scalar = false;
1518  JsonbIterator *it;
1519  Jsonb *jbelem;
1520  JsonbValue v;
1522 
1523  if (!AggCheckCallContext(fcinfo, &aggcontext))
1524  {
1525  /* cannot be called directly because of internal-type argument */
1526  elog(ERROR, "jsonb_agg_transfn called in non-aggregate context");
1527  }
1528 
1529  /* set up the accumulator on the first go round */
1530 
1531  if (PG_ARGISNULL(0))
1532  {
1533  Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1534 
1535  if (arg_type == InvalidOid)
1536  ereport(ERROR,
1537  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1538  errmsg("could not determine input data type")));
1539 
1540  oldcontext = MemoryContextSwitchTo(aggcontext);
1541  state = palloc(sizeof(JsonbAggState));
1542  result = palloc0(sizeof(JsonbInState));
1543  state->res = result;
1544  result->res = pushJsonbValue(&result->parseState,
1545  WJB_BEGIN_ARRAY, NULL);
1546  MemoryContextSwitchTo(oldcontext);
1547 
1548  jsonb_categorize_type(arg_type, &state->val_category,
1549  &state->val_output_func);
1550  }
1551  else
1552  {
1553  state = (JsonbAggState *) PG_GETARG_POINTER(0);
1554  result = state->res;
1555  }
1556 
1557  /* turn the argument into jsonb in the normal function context */
1558 
1559  val = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
1560 
1561  memset(&elem, 0, sizeof(JsonbInState));
1562 
1563  datum_to_jsonb(val, PG_ARGISNULL(1), &elem, state->val_category,
1564  state->val_output_func, false);
1565 
1566  jbelem = JsonbValueToJsonb(elem.res);
1567 
1568  /* switch to the aggregate context for accumulation operations */
1569 
1570  oldcontext = MemoryContextSwitchTo(aggcontext);
1571 
1572  it = JsonbIteratorInit(&jbelem->root);
1573 
1574  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1575  {
1576  switch (type)
1577  {
1578  case WJB_BEGIN_ARRAY:
1579  if (v.val.array.rawScalar)
1580  single_scalar = true;
1581  else
1582  result->res = pushJsonbValue(&result->parseState,
1583  type, NULL);
1584  break;
1585  case WJB_END_ARRAY:
1586  if (!single_scalar)
1587  result->res = pushJsonbValue(&result->parseState,
1588  type, NULL);
1589  break;
1590  case WJB_BEGIN_OBJECT:
1591  case WJB_END_OBJECT:
1592  result->res = pushJsonbValue(&result->parseState,
1593  type, NULL);
1594  break;
1595  case WJB_ELEM:
1596  case WJB_KEY:
1597  case WJB_VALUE:
1598  if (v.type == jbvString)
1599  {
1600  /* copy string values in the aggregate context */
1601  char *buf = palloc(v.val.string.len + 1);
1602 
1603  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1604  v.val.string.val = buf;
1605  }
1606  else if (v.type == jbvNumeric)
1607  {
1608  /* same for numeric */
1609  v.val.numeric =
1611  NumericGetDatum(v.val.numeric)));
1612  }
1613  result->res = pushJsonbValue(&result->parseState,
1614  type, &v);
1615  break;
1616  default:
1617  elog(ERROR, "unknown jsonb iterator token type");
1618  }
1619  }
1620 
1621  MemoryContextSwitchTo(oldcontext);
1622 
1623  PG_RETURN_POINTER(state);
1624 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
Datum numeric_uplus(PG_FUNCTION_ARGS)
Definition: numeric.c:1170
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
JsonbInState * res
Definition: jsonb.c:57
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: jsonb.h:22
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
unsigned int Oid
Definition: postgres_ext.h:31
JsonbTypeCategory val_category
Definition: jsonb.c:60
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
static char * buf
Definition: pg_test_fsync.c:68
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
Definition: jsonb.h:23
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:223
void * palloc0(Size size)
Definition: mcxt.c:980
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
Oid val_output_func
Definition: jsonb.c:61
#define elog(elevel,...)
Definition: elog.h:226
#define snprintf
Definition: port.h:192
long val
Definition: informix.c:684
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795
Definition: jsonb.h:25

◆ jsonb_bool()

Datum jsonb_bool ( PG_FUNCTION_ARGS  )

Definition at line 1965 of file jsonb.c.

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

1966 {
1967  Jsonb *in = PG_GETARG_JSONB_P(0);
1968  JsonbValue v;
1969 
1970  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool)
1971  cannotCastJsonbValue(v.type, "boolean");
1972 
1973  PG_FREE_IF_COPY(in, 0);
1974 
1975  PG_RETURN_BOOL(v.val.boolean);
1976 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
JsonbContainer root
Definition: jsonb.h:223
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_build_array()

Datum jsonb_build_array ( PG_FUNCTION_ARGS  )

Definition at line 1226 of file jsonb.c.

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

1227 {
1228  int nargs;
1229  int i;
1230  JsonbInState result;
1231  Datum *args;
1232  bool *nulls;
1233  Oid *types;
1234 
1235  /* build argument values to build the array */
1236  nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1237 
1238  if (nargs < 0)
1239  PG_RETURN_NULL();
1240 
1241  memset(&result, 0, sizeof(JsonbInState));
1242 
1243  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1244 
1245  for (i = 0; i < nargs; i++)
1246  add_jsonb(args[i], nulls[i], &result, types[i], false);
1247 
1248  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1249 
1251 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1464
struct typedefs * types
Definition: ecpg.c:29
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1106
unsigned int Oid
Definition: postgres_ext.h:31
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
uintptr_t Datum
Definition: postgres.h:367
int i
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ jsonb_build_array_noargs()

Datum jsonb_build_array_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1257 of file jsonb.c.

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

1258 {
1259  JsonbInState result;
1260 
1261  memset(&result, 0, sizeof(JsonbInState));
1262 
1263  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_ARRAY, NULL);
1264  result.res = pushJsonbValue(&result.parseState, WJB_END_ARRAY, NULL);
1265 
1267 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_build_object()

Datum jsonb_build_object ( PG_FUNCTION_ARGS  )

Definition at line 1160 of file jsonb.c.

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

1161 {
1162  int nargs;
1163  int i;
1164  JsonbInState result;
1165  Datum *args;
1166  bool *nulls;
1167  Oid *types;
1168 
1169  /* build argument values to build the object */
1170  nargs = extract_variadic_args(fcinfo, 0, true, &args, &types, &nulls);
1171 
1172  if (nargs < 0)
1173  PG_RETURN_NULL();
1174 
1175  if (nargs % 2 != 0)
1176  ereport(ERROR,
1177  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1178  errmsg("argument list must have even number of elements"),
1179  /* translator: %s is a SQL function name */
1180  errhint("The arguments of %s must consist of alternating keys and values.",
1181  "jsonb_build_object()")));
1182 
1183  memset(&result, 0, sizeof(JsonbInState));
1184 
1185  result.res = pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1186 
1187  for (i = 0; i < nargs; i += 2)
1188  {
1189  /* process key */
1190  if (nulls[i])
1191  ereport(ERROR,
1192  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1193  errmsg("argument %d: key must not be null", i + 1)));
1194 
1195  add_jsonb(args[i], false, &result, types[i], true);
1196 
1197  /* process value */
1198  add_jsonb(args[i + 1], nulls[i + 1], &result, types[i + 1], false);
1199  }
1200 
1201  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1202 
1204 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
int errhint(const char *fmt,...)
Definition: elog.c:974
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1464
struct typedefs * types
Definition: ecpg.c:29
static void add_jsonb(Datum val, bool is_null, JsonbInState *result, Oid val_type, bool key_scalar)
Definition: jsonb.c:1106
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ jsonb_build_object_noargs()

Datum jsonb_build_object_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1210 of file jsonb.c.

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

1211 {
1212  JsonbInState result;
1213 
1214  memset(&result, 0, sizeof(JsonbInState));
1215 
1216  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1217  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1218 
1220 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_categorize_type()

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

Definition at line 623 of file jsonb.c.

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

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

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

◆ jsonb_float4()

Datum jsonb_float4 ( PG_FUNCTION_ARGS  )

Definition at line 2054 of file jsonb.c.

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.

2055 {
2056  Jsonb *in = PG_GETARG_JSONB_P(0);
2057  JsonbValue v;
2058  Datum retValue;
2059 
2060  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2061  cannotCastJsonbValue(v.type, "real");
2062 
2064  NumericGetDatum(v.val.numeric));
2065 
2066  PG_FREE_IF_COPY(in, 0);
2067 
2068  PG_RETURN_DATUM(retValue);
2069 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
Datum numeric_float4(PG_FUNCTION_ARGS)
Definition: numeric.c:3485
JsonbContainer root
Definition: jsonb.h:223
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_float8()

Datum jsonb_float8 ( PG_FUNCTION_ARGS  )

Definition at line 2072 of file jsonb.c.

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.

2073 {
2074  Jsonb *in = PG_GETARG_JSONB_P(0);
2075  JsonbValue v;
2076  Datum retValue;
2077 
2078  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2079  cannotCastJsonbValue(v.type, "double precision");
2080 
2082  NumericGetDatum(v.val.numeric));
2083 
2084  PG_FREE_IF_COPY(in, 0);
2085 
2086  PG_RETURN_DATUM(retValue);
2087 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:3414
JsonbContainer root
Definition: jsonb.h:223
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_from_cstring()

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

Definition at line 256 of file jsonb.c.

References JsonSemAction::array_end, JsonSemAction::array_start, 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(), makeJsonLexContextCstringLen(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, pg_parse_json(), PG_RETURN_POINTER, JsonbInState::res, JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by jsonb_in(), and jsonb_recv().

257 {
258  JsonLexContext *lex;
260  JsonSemAction sem;
261 
262  memset(&state, 0, sizeof(state));
263  memset(&sem, 0, sizeof(sem));
264  lex = makeJsonLexContextCstringLen(json, len, true);
265 
266  sem.semstate = (void *) &state;
267 
272  sem.scalar = jsonb_in_scalar;
274 
275  pg_parse_json(lex, &sem);
276 
277  /* after parsing, the item member has the composed jsonb structure */
279 }
json_struct_action array_end
Definition: jsonapi.h:88
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
static void jsonb_in_object_end(void *pstate)
Definition: jsonb.c:303
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
json_struct_action object_end
Definition: jsonapi.h:86
static void jsonb_in_array_start(void *pstate)
Definition: jsonb.c:311
json_struct_action object_start
Definition: jsonapi.h:85
json_scalar_action scalar
Definition: jsonapi.h:93
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
Definition: jsonb.c:371
static void jsonb_in_array_end(void *pstate)
Definition: jsonb.c:319
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:332
json_struct_action array_start
Definition: jsonapi.h:87
Definition: regguts.h:298
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
Definition: json.c:309
static void jsonb_in_object_start(void *pstate)
Definition: jsonb.c:295
json_ofield_action object_field_start
Definition: jsonapi.h:89
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
Definition: jsonb.c:327
void * semstate
Definition: jsonapi.h:84

◆ jsonb_in()

Datum jsonb_in ( PG_FUNCTION_ARGS  )

Definition at line 97 of file jsonb.c.

References jsonb_from_cstring(), and PG_GETARG_CSTRING.

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

◆ jsonb_in_array_end()

static void jsonb_in_array_end ( void *  pstate)
static

Definition at line 319 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

320 {
321  JsonbInState *_state = (JsonbInState *) pstate;
322 
323  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
324 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_in_array_start()

static void jsonb_in_array_start ( void *  pstate)
static

Definition at line 311 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

312 {
313  JsonbInState *_state = (JsonbInState *) pstate;
314 
315  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
316 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_in_object_end()

static void jsonb_in_object_end ( void *  pstate)
static

Definition at line 303 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

304 {
305  JsonbInState *_state = (JsonbInState *) pstate;
306 
307  _state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
308 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_in_object_field_start()

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

Definition at line 327 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

328 {
329  JsonbInState *_state = (JsonbInState *) pstate;
330  JsonbValue v;
331 
332  Assert(fname != NULL);
333  v.type = jbvString;
334  v.val.string.len = checkStringLen(strlen(fname));
335  v.val.string.val = fname;
336 
337  _state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
338 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
char * val
Definition: jsonb.h:272
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
static size_t checkStringLen(size_t len)
Definition: jsonb.c:282
Definition: jsonb.h:23
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263

◆ jsonb_in_object_start()

static void jsonb_in_object_start ( void *  pstate)
static

Definition at line 295 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

296 {
297  JsonbInState *_state = (JsonbInState *) pstate;
298 
299  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
300 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558

◆ jsonb_in_scalar()

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

Definition at line 371 of file jsonb.c.

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

Referenced by datum_to_jsonb(), and jsonb_from_cstring().

372 {
373  JsonbInState *_state = (JsonbInState *) pstate;
374  JsonbValue v;
375  Datum numd;
376 
377  switch (tokentype)
378  {
379 
380  case JSON_TOKEN_STRING:
381  Assert(token != NULL);
382  v.type = jbvString;
383  v.val.string.len = checkStringLen(strlen(token));
384  v.val.string.val = token;
385  break;
386  case JSON_TOKEN_NUMBER:
387 
388  /*
389  * No need to check size of numeric values, because maximum
390  * numeric size is well below the JsonbValue restriction
391  */
392  Assert(token != NULL);
393  v.type = jbvNumeric;
395  CStringGetDatum(token),
397  Int32GetDatum(-1));
398  v.val.numeric = DatumGetNumeric(numd);
399  break;
400  case JSON_TOKEN_TRUE:
401  v.type = jbvBool;
402  v.val.boolean = true;
403  break;
404  case JSON_TOKEN_FALSE:
405  v.type = jbvBool;
406  v.val.boolean = false;
407  break;
408  case JSON_TOKEN_NULL:
409  v.type = jbvNull;
410  break;
411  default:
412  /* should not be possible */
413  elog(ERROR, "invalid json token type");
414  break;
415  }
416 
417  if (_state->parseState == NULL)
418  {
419  /* single scalar */
420  JsonbValue va;
421 
422  va.type = jbvArray;
423  va.val.array.rawScalar = true;
424  va.val.array.nElems = 1;
425 
426  _state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, &va);
427  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
428  _state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
429  }
430  else
431  {
432  JsonbValue *o = &_state->parseState->contVal;
433 
434  switch (o->type)
435  {
436  case jbvArray:
437  _state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
438  break;
439  case jbvObject:
440  _state->res = pushJsonbValue(&_state->parseState, WJB_VALUE, &v);
441  break;
442  default:
443  elog(ERROR, "unexpected parent of nested structure");
444  }
445  }
446 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
static size_t checkStringLen(size_t len)
Definition: jsonb.c:282
#define CStringGetDatum(X)
Definition: postgres.h:578
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:573
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:621
uintptr_t Datum
Definition: postgres.h:367
JsonbValue contVal
Definition: jsonb.h:329
#define InvalidOid
Definition: postgres_ext.h:36
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263
#define Int32GetDatum(X)
Definition: postgres.h:479
#define elog(elevel,...)
Definition: elog.h:226
Definition: jsonb.h:25

◆ jsonb_int2()

Datum jsonb_int2 ( PG_FUNCTION_ARGS  )

Definition at line 2000 of file jsonb.c.

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.

2001 {
2002  Jsonb *in = PG_GETARG_JSONB_P(0);
2003  JsonbValue v;
2004  Datum retValue;
2005 
2006  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2007  cannotCastJsonbValue(v.type, "smallint");
2008 
2009  retValue = DirectFunctionCall1(numeric_int2,
2010  NumericGetDatum(v.val.numeric));
2011 
2012  PG_FREE_IF_COPY(in, 0);
2013 
2014  PG_RETURN_DATUM(retValue);
2015 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
Datum numeric_int2(PG_FUNCTION_ARGS)
Definition: numeric.c:3348
JsonbContainer root
Definition: jsonb.h:223
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_int4()

Datum jsonb_int4 ( PG_FUNCTION_ARGS  )

Definition at line 2018 of file jsonb.c.

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.

2019 {
2020  Jsonb *in = PG_GETARG_JSONB_P(0);
2021  JsonbValue v;
2022  Datum retValue;
2023 
2024  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2025  cannotCastJsonbValue(v.type, "integer");
2026 
2027  retValue = DirectFunctionCall1(numeric_int4,
2028  NumericGetDatum(v.val.numeric));
2029 
2030  PG_FREE_IF_COPY(in, 0);
2031 
2032  PG_RETURN_DATUM(retValue);
2033 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_int4(PG_FUNCTION_ARGS)
Definition: numeric.c:3257
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
JsonbContainer root
Definition: jsonb.h:223
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_int8()

Datum jsonb_int8 ( PG_FUNCTION_ARGS  )

Definition at line 2036 of file jsonb.c.

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.

2037 {
2038  Jsonb *in = PG_GETARG_JSONB_P(0);
2039  JsonbValue v;
2040  Datum retValue;
2041 
2042  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
2043  cannotCastJsonbValue(v.type, "bigint");
2044 
2045  retValue = DirectFunctionCall1(numeric_int8,
2046  NumericGetDatum(v.val.numeric));
2047 
2048  PG_FREE_IF_COPY(in, 0);
2049 
2050  PG_RETURN_DATUM(retValue);
2051 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_int8(PG_FUNCTION_ARGS)
Definition: numeric.c:3304
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
JsonbContainer root
Definition: jsonb.h:223
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_numeric()

Datum jsonb_numeric ( PG_FUNCTION_ARGS  )

Definition at line 1979 of file jsonb.c.

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

1980 {
1981  Jsonb *in = PG_GETARG_JSONB_P(0);
1982  JsonbValue v;
1983  Numeric retValue;
1984 
1985  if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric)
1986  cannotCastJsonbValue(v.type, "numeric");
1987 
1988  /*
1989  * v.val.numeric points into jsonb body, so we need to make a copy to
1990  * return
1991  */
1992  retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric));
1993 
1994  PG_FREE_IF_COPY(in, 0);
1995 
1996  PG_RETURN_NUMERIC(retValue);
1997 }
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:54
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
#define DatumGetNumericCopy(X)
Definition: numeric.h:50
static void cannotCastJsonbValue(enum jbvType type, const char *sqltype)
Definition: jsonb.c:1935
JsonbContainer root
Definition: jsonb.h:223
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
enum jbvType type
Definition: jsonb.h:263
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_object()

Datum jsonb_object ( PG_FUNCTION_ARGS  )

Definition at line 1278 of file jsonb.c.

References ARR_DIMS, ARR_NDIM, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, i, jbvNull, jbvString, JsonbValueToJsonb(), 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.

1279 {
1280  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
1281  int ndims = ARR_NDIM(in_array);
1282  Datum *in_datums;
1283  bool *in_nulls;
1284  int in_count,
1285  count,
1286  i;
1287  JsonbInState result;
1288 
1289  memset(&result, 0, sizeof(JsonbInState));
1290 
1291  (void) pushJsonbValue(&result.parseState, WJB_BEGIN_OBJECT, NULL);
1292 
1293  switch (ndims)
1294  {
1295  case 0:
1296  goto close_object;
1297  break;
1298 
1299  case 1:
1300  if ((ARR_DIMS(in_array)[0]) % 2)
1301  ereport(ERROR,
1302  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1303  errmsg("array must have even number of elements")));
1304  break;
1305 
1306  case 2:
1307  if ((ARR_DIMS(in_array)[1]) != 2)
1308  ereport(ERROR,
1309  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1310  errmsg("array must have two columns")));
1311  break;
1312 
1313  default:
1314  ereport(ERROR,
1315  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1316  errmsg("wrong number of array subscripts")));
1317  }
1318 
1319  deconstruct_array(in_array,
1320  TEXTOID, -1, false, 'i',
1321  &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 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
Definition: jsonb.h:23
#define ereport(elevel, rest)
Definition: elog.h:141
#define TextDatumGetCString(d)
Definition: builtins.h:84
uintptr_t Datum
Definition: postgres.h:367
#define ARR_NDIM(a)
Definition: array.h:278
enum jbvType type
Definition: jsonb.h:263
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i

◆ jsonb_object_agg_finalfn()

Datum jsonb_object_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1858 of file jsonb.c.

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

1859 {
1860  JsonbAggState *arg;
1861  JsonbInState result;
1862  Jsonb *out;
1863 
1864  /* cannot be called directly because of internal-type argument */
1865  Assert(AggCheckCallContext(fcinfo, NULL));
1866 
1867  if (PG_ARGISNULL(0))
1868  PG_RETURN_NULL(); /* returns null iff no input values */
1869 
1870  arg = (JsonbAggState *) PG_GETARG_POINTER(0);
1871 
1872  /*
1873  * We need to do a shallow clone of the argument's res field in case the
1874  * final function is called more than once, so we avoid changing the
1875  * aggregate state value. A shallow clone is sufficient as we aren't
1876  * going to change any of the values, just add the final object end
1877  * marker.
1878  */
1879 
1880  result.parseState = clone_parse_state(arg->res->parseState);
1881 
1882  result.res = pushJsonbValue(&result.parseState,
1883  WJB_END_OBJECT, NULL);
1884 
1885  out = JsonbValueToJsonb(result.res);
1886 
1887  PG_RETURN_POINTER(out);
1888 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
static JsonbParseState * clone_parse_state(JsonbParseState *state)
Definition: jsonb.c:1477
JsonbInState * res
Definition: jsonb.c:57
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:732
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
void * arg
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ jsonb_object_agg_transfn()

Datum jsonb_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1662 of file jsonb.c.

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

1663 {
1664  MemoryContext oldcontext,
1665  aggcontext;
1666  JsonbInState elem;
1668  Datum val;
1669  JsonbInState *result;
1670  bool single_scalar;
1671  JsonbIterator *it;
1672  Jsonb *jbkey,
1673  *jbval;
1674  JsonbValue v;
1676 
1677  if (!AggCheckCallContext(fcinfo, &aggcontext))
1678  {
1679  /* cannot be called directly because of internal-type argument */
1680  elog(ERROR, "jsonb_object_agg_transfn called in non-aggregate context");
1681  }
1682 
1683  /* set up the accumulator on the first go round */
1684 
1685  if (PG_ARGISNULL(0))
1686  {
1687  Oid arg_type;
1688 
1689  oldcontext = MemoryContextSwitchTo(aggcontext);
1690  state = palloc(sizeof(JsonbAggState));
1691  result = palloc0(sizeof(JsonbInState));
1692  state->res = result;
1693  result->res = pushJsonbValue(&result->parseState,
1694  WJB_BEGIN_OBJECT, NULL);
1695  MemoryContextSwitchTo(oldcontext);
1696 
1697  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
1698 
1699  if (arg_type == InvalidOid)
1700  ereport(ERROR,
1701  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1702  errmsg("could not determine input data type")));
1703 
1704  jsonb_categorize_type(arg_type, &state->key_category,
1705  &state->key_output_func);
1706 
1707  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
1708 
1709  if (arg_type == InvalidOid)
1710  ereport(ERROR,
1711  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1712  errmsg("could not determine input data type")));
1713 
1714  jsonb_categorize_type(arg_type, &state->val_category,
1715  &state->val_output_func);
1716  }
1717  else
1718  {
1719  state = (JsonbAggState *) PG_GETARG_POINTER(0);
1720  result = state->res;
1721  }
1722 
1723  /* turn the argument into jsonb in the normal function context */
1724 
1725  if (PG_ARGISNULL(1))
1726  ereport(ERROR,
1727  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1728  errmsg("field name must not be null")));
1729 
1730  val = PG_GETARG_DATUM(1);
1731 
1732  memset(&elem, 0, sizeof(JsonbInState));
1733 
1734  datum_to_jsonb(val, false, &elem, state->key_category,
1735  state->key_output_func, true);
1736 
1737  jbkey = JsonbValueToJsonb(elem.res);
1738 
1739  val = PG_ARGISNULL(2) ? (Datum) 0 : PG_GETARG_DATUM(2);
1740 
1741  memset(&elem, 0, sizeof(JsonbInState));
1742 
1743  datum_to_jsonb(val, PG_ARGISNULL(2), &elem, state->val_category,
1744  state->val_output_func, false);
1745 
1746  jbval = JsonbValueToJsonb(elem.res);
1747 
1748  it = JsonbIteratorInit(&jbkey->root);
1749 
1750  /* switch to the aggregate context for accumulation operations */
1751 
1752  oldcontext = MemoryContextSwitchTo(aggcontext);
1753 
1754  /*
1755  * keys should be scalar, and we should have already checked for that
1756  * above when calling datum_to_jsonb, so we only need to look for these
1757  * things.
1758  */
1759 
1760  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1761  {
1762  switch (type)
1763  {
1764  case WJB_BEGIN_ARRAY:
1765  if (!v.val.array.rawScalar)
1766  elog(ERROR, "unexpected structure for key");
1767  break;
1768  case WJB_ELEM:
1769  if (v.type == jbvString)
1770  {
1771  /* copy string values in the aggregate context */
1772  char *buf = palloc(v.val.string.len + 1);
1773 
1774  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1775  v.val.string.val = buf;
1776  }
1777  else
1778  {
1779  ereport(ERROR,
1780  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1781  errmsg("object keys must be strings")));
1782  }
1783  result->res = pushJsonbValue(&result->parseState,
1784  WJB_KEY, &v);
1785  break;
1786  case WJB_END_ARRAY:
1787  break;
1788  default:
1789  elog(ERROR, "unexpected structure for key");
1790  break;
1791  }
1792  }
1793 
1794  it = JsonbIteratorInit(&jbval->root);
1795 
1796  single_scalar = false;
1797 
1798  /*
1799  * values can be anything, including structured and null, so we treat them
1800  * as in json_agg_transfn, except that single scalars are always pushed as
1801  * WJB_VALUE items.
1802  */
1803 
1804  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
1805  {
1806  switch (type)
1807  {
1808  case WJB_BEGIN_ARRAY:
1809  if (v.val.array.rawScalar)
1810  single_scalar = true;
1811  else
1812  result->res = pushJsonbValue(&result->parseState,
1813  type, NULL);
1814  break;
1815  case WJB_END_ARRAY:
1816  if (!single_scalar)
1817  result->res = pushJsonbValue(&result->parseState,
1818  type, NULL);
1819  break;
1820  case WJB_BEGIN_OBJECT:
1821  case WJB_END_OBJECT:
1822  result->res = pushJsonbValue(&result->parseState,
1823  type, NULL);
1824  break;
1825  case WJB_ELEM:
1826  case WJB_KEY:
1827  case WJB_VALUE:
1828  if (v.type == jbvString)
1829  {
1830  /* copy string values in the aggregate context */
1831  char *buf = palloc(v.val.string.len + 1);
1832 
1833  snprintf(buf, v.val.string.len + 1, "%s", v.val.string.val);
1834  v.val.string.val = buf;
1835  }
1836  else if (v.type == jbvNumeric)
1837  {
1838  /* same for numeric */
1839  v.val.numeric =
1841  NumericGetDatum(v.val.numeric)));
1842  }
1843  result->res = pushJsonbValue(&result->parseState,
1844  single_scalar ? WJB_VALUE : type,
1845  &v);
1846  break;
1847  default:
1848  elog(ERROR, "unknown jsonb iterator token type");
1849  }
1850  }
1851 
1852  MemoryContextSwitchTo(oldcontext);
1853 
1854  PG_RETURN_POINTER(state);
1855 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
Datum numeric_uplus(PG_FUNCTION_ARGS)
Definition: numeric.c:1170
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
JsonbInState * res
Definition: jsonb.c:57
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Definition: jsonb.h:22
int errcode(int sqlerrcode)
Definition: elog.c:570
Oid key_output_func
Definition: jsonb.c:59
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
unsigned int Oid
Definition: postgres_ext.h:31
JsonbTypeCategory val_category
Definition: jsonb.c:60
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
static char * buf
Definition: pg_test_fsync.c:68
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
Definition: jsonb.h:23
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:223
void * palloc0(Size size)
Definition: mcxt.c:980
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
JsonbTypeCategory key_category
Definition: jsonb.c:58
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
Oid val_output_func
Definition: jsonb.c:61
#define elog(elevel,...)
Definition: elog.h:226
#define snprintf
Definition: port.h:192
long val
Definition: informix.c:684
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795
Definition: jsonb.h:25

◆ jsonb_object_two_arg()

Datum jsonb_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1380 of file jsonb.c.

References ARR_NDIM, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, i, jbvNull, jbvString, JsonbValueToJsonb(), 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.

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(key_array,
1408  TEXTOID, -1, false, 'i',
1409  &key_datums, &key_nulls, &key_count);
1410 
1411  deconstruct_array(val_array,
1412  TEXTOID, -1, false, 'i',
1413  &val_datums, &val_nulls, &val_count);
1414 
1415  if (key_count != val_count)
1416  ereport(ERROR,
1417  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1418  errmsg("mismatched array dimensions")));
1419 
1420  for (i = 0; i < key_count; ++i)
1421  {
1422  JsonbValue v;
1423  char *str;
1424  int len;
1425 
1426  if (key_nulls[i])
1427  ereport(ERROR,
1428  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1429  errmsg("null value not allowed for object key")));
1430 
1431  str = TextDatumGetCString(key_datums[i]);
1432  len = strlen(str);
1433 
1434  v.type = jbvString;
1435 
1436  v.val.string.len = len;
1437  v.val.string.val = str;
1438 
1439  (void) pushJsonbValue(&result.parseState, WJB_KEY, &v);
1440 
1441  if (val_nulls[i])
1442  {
1443  v.type = jbvNull;
1444  }
1445  else
1446  {
1447  str = TextDatumGetCString(val_datums[i]);
1448  len = strlen(str);
1449 
1450  v.type = jbvString;
1451 
1452  v.val.string.len = len;
1453  v.val.string.val = str;
1454  }
1455 
1456  (void) pushJsonbValue(&result.parseState, WJB_VALUE, &v);
1457  }
1458 
1459  pfree(key_datums);
1460  pfree(key_nulls);
1461  pfree(val_datums);
1462  pfree(val_nulls);
1463 
1464 close_object:
1465  result.res = pushJsonbValue(&result.parseState, WJB_END_OBJECT, NULL);
1466 
1468 }
JsonbParseState * parseState
Definition: jsonb.c:34
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
Definition: jsonb.h:23
#define ereport(elevel, rest)
Definition: elog.h:141
#define TextDatumGetCString(d)
Definition: builtins.h:84
uintptr_t Datum
Definition: postgres.h:367
#define ARR_NDIM(a)
Definition: array.h:278
enum jbvType type
Definition: jsonb.h:263
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i

◆ jsonb_out()

Datum jsonb_out ( PG_FUNCTION_ARGS  )

Definition at line 132 of file jsonb.c.

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

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

◆ jsonb_put_escaped_value()

static void jsonb_put_escaped_value ( StringInfo  out,
JsonbValue scalarVal 
)
static

Definition at line 341 of file jsonb.c.

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

342 {
343  switch (scalarVal->type)
344  {
345  case jbvNull:
346  appendBinaryStringInfo(out, "null", 4);
347  break;
348  case jbvString:
349  escape_json(out, pnstrdup(scalarVal->val.string.val, scalarVal->val.string.len));
350  break;
351  case jbvNumeric:
354  PointerGetDatum(scalarVal->val.numeric))));
355  break;
356  case jbvBool:
357  if (scalarVal->val.boolean)
358  appendBinaryStringInfo(out, "true", 4);
359  else
360  appendBinaryStringInfo(out, "false", 5);
361  break;
362  default:
363  elog(ERROR, "unknown jsonb scalar type");
364  }
365 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2483
#define PointerGetDatum(X)
Definition: postgres.h:556
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:655
Definition: jsonb.h:236
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:566
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:226
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ jsonb_recv()

Datum jsonb_recv ( PG_FUNCTION_ARGS  )

Definition at line 113 of file jsonb.c.

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

114 {
116  int version = pq_getmsgint(buf, 1);
117  char *str;
118  int nbytes;
119 
120  if (version == 1)
121  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
122  else
123  elog(ERROR, "unsupported jsonb version number %d", version);
124 
125  return jsonb_from_cstring(str, nbytes);
126 }
static Datum jsonb_from_cstring(char *json, int len)
Definition: jsonb.c:256
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:68
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
#define elog(elevel,...)
Definition: elog.h:226
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417

◆ jsonb_send()

Datum jsonb_send ( PG_FUNCTION_ARGS  )

Definition at line 148 of file jsonb.c.

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.

149 {
150  Jsonb *jb = PG_GETARG_JSONB_P(0);
152  StringInfo jtext = makeStringInfo();
153  int version = 1;
154 
155  (void) JsonbToCString(jtext, &jb->root, VARSIZE(jb));
156 
157  pq_begintypsend(&buf);
158  pq_sendint8(&buf, version);
159  pq_sendtext(&buf, jtext->data, jtext->len);
160  pfree(jtext->data);
161  pfree(jtext);
162 
164 }
Definition: jsonb.h:220
#define VARSIZE(PTR)
Definition: postgres.h:303
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
void pfree(void *pointer)
Definition: mcxt.c:1056
static char * buf
Definition: pg_test_fsync.c:68
JsonbContainer root
Definition: jsonb.h:223
char * JsonbToCString(StringInfo out, JsonbContainer *in, int estimated_len)
Definition: jsonb.c:460
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:129
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_typeof()

Datum jsonb_typeof ( PG_FUNCTION_ARGS  )

Definition at line 240 of file jsonb.c.

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

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

◆ JsonbContainerTypeName()

static const char* JsonbContainerTypeName ( JsonbContainer jbc)
static

Definition at line 170 of file jsonb.c.

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

Referenced by jsonb_typeof(), and JsonbTypeName().

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

◆ JsonbExtractScalar()

bool JsonbExtractScalar ( JsonbContainer jbc,
JsonbValue res 
)

Definition at line 1895 of file jsonb.c.

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

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

1896 {
1897  JsonbIterator *it;
1899  JsonbValue tmp;
1900 
1901  if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
1902  {
1903  /* inform caller about actual type of container */
1904  res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject;
1905  return false;
1906  }
1907 
1908  /*
1909  * A root scalar is stored as an array of one element, so we get the array
1910  * and then its first (and only) member.
1911  */
1912  it = JsonbIteratorInit(jbc);
1913 
1914  tok = JsonbIteratorNext(&it, &tmp, true);
1915  Assert(tok == WJB_BEGIN_ARRAY);
1916  Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar);
1917 
1918  tok = JsonbIteratorNext(&it, res, true);
1919  Assert(tok == WJB_ELEM);
1920  Assert(IsAJsonbScalar(res));
1921 
1922  tok = JsonbIteratorNext(&it, &tmp, true);
1923  Assert(tok == WJB_END_ARRAY);
1924 
1925  tok = JsonbIteratorNext(&it, &tmp, true);
1926  Assert(tok == WJB_DONE);
1927 
1928  return true;
1929 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
Definition: jsonb.h:22
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
JsonbIteratorToken
Definition: jsonb.h:20
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
#define IsAJsonbScalar(jsonbval)
Definition: jsonb.h:305
enum jbvType type
Definition: jsonb.h:263
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:123
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795
Definition: jsonb.h:25

◆ JsonbToCString()

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

Definition at line 460 of file jsonb.c.

References JsonbToCStringWorker().

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

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

◆ JsonbToCStringIndent()

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

Definition at line 469 of file jsonb.c.

References JsonbToCStringWorker().

Referenced by jsonb_pretty().

470 {
471  return JsonbToCStringWorker(out, in, estimated_len, true);
472 }
static char * JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent)
Definition: jsonb.c:478

◆ JsonbToCStringWorker()

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

Definition at line 478 of file jsonb.c.

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

Referenced by JsonbToCString(), and JsonbToCStringIndent().

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

◆ JsonbTypeName()

const char* JsonbTypeName ( JsonbValue jbv)

Definition at line 191 of file jsonb.c.

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

Referenced by executeItemOptUnwrapTarget(), and JsonbContainerTypeName().

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

◆ to_jsonb()

Datum to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1133 of file jsonb.c.

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

1134 {
1135  Datum val = PG_GETARG_DATUM(0);
1136  Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
1137  JsonbInState result;
1138  JsonbTypeCategory tcategory;
1139  Oid outfuncoid;
1140 
1141  if (val_type == InvalidOid)
1142  ereport(ERROR,
1143  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1144  errmsg("could not determine input data type")));
1145 
1146  jsonb_categorize_type(val_type,
1147  &tcategory, &outfuncoid);
1148 
1149  memset(&result, 0, sizeof(JsonbInState));
1150 
1151  datum_to_jsonb(val, false, &result, tcategory, outfuncoid, false);
1152 
1154 }
JsonbValue * res
Definition: jsonb.c:35
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, JsonbTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: jsonb.c:731
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
static void jsonb_categorize_type(Oid typoid, JsonbTypeCategory *tcategory, Oid *outfuncoid)
Definition: jsonb.c:623
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
JsonbTypeCategory
Definition: jsonb.c:39
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:784
long val
Definition: informix.c:684