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

Go to the source code of this file.

Data Structures

struct  JsonAggState
 

Typedefs

typedef struct JsonAggState JsonAggState
 

Enumerations

enum  JsonTypeCategory {
  JSONTYPE_NULL, JSONTYPE_BOOL, JSONTYPE_NUMERIC, JSONTYPE_DATE,
  JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, JSONTYPE_JSON, JSONTYPE_ARRAY,
  JSONTYPE_COMPOSITE, JSONTYPE_CAST, JSONTYPE_OTHER
}
 

Functions

static void composite_to_json (Datum composite, StringInfo result, bool use_line_feeds)
 
static void array_dim_to_json (StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
 
static void array_to_json_internal (Datum array, StringInfo result, bool use_line_feeds)
 
static void json_categorize_type (Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
 
static void datum_to_json (Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
 
static void add_json (Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
 
static textcatenate_stringinfo_string (StringInfo buffer, const char *addon)
 
Datum json_in (PG_FUNCTION_ARGS)
 
Datum json_out (PG_FUNCTION_ARGS)
 
Datum json_send (PG_FUNCTION_ARGS)
 
Datum json_recv (PG_FUNCTION_ARGS)
 
char * JsonEncodeDateTime (char *buf, Datum value, Oid typid, const int *tzp)
 
Datum array_to_json (PG_FUNCTION_ARGS)
 
Datum array_to_json_pretty (PG_FUNCTION_ARGS)
 
Datum row_to_json (PG_FUNCTION_ARGS)
 
Datum row_to_json_pretty (PG_FUNCTION_ARGS)
 
Datum to_json (PG_FUNCTION_ARGS)
 
Datum json_agg_transfn (PG_FUNCTION_ARGS)
 
Datum json_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum json_object_agg_transfn (PG_FUNCTION_ARGS)
 
Datum json_object_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum json_build_object (PG_FUNCTION_ARGS)
 
Datum json_build_object_noargs (PG_FUNCTION_ARGS)
 
Datum json_build_array (PG_FUNCTION_ARGS)
 
Datum json_build_array_noargs (PG_FUNCTION_ARGS)
 
Datum json_object (PG_FUNCTION_ARGS)
 
Datum json_object_two_arg (PG_FUNCTION_ARGS)
 
void escape_json (StringInfo buf, const char *str)
 
Datum json_typeof (PG_FUNCTION_ARGS)
 

Typedef Documentation

◆ JsonAggState

typedef struct JsonAggState JsonAggState

Enumeration Type Documentation

◆ JsonTypeCategory

Enumerator
JSONTYPE_NULL 
JSONTYPE_BOOL 
JSONTYPE_NUMERIC 
JSONTYPE_DATE 
JSONTYPE_TIMESTAMP 
JSONTYPE_TIMESTAMPTZ 
JSONTYPE_JSON 
JSONTYPE_ARRAY 
JSONTYPE_COMPOSITE 
JSONTYPE_CAST 
JSONTYPE_OTHER 

Definition at line 30 of file json.c.

31 {
32  JSONTYPE_NULL, /* null, so we didn't bother to identify */
33  JSONTYPE_BOOL, /* boolean (built-in types only) */
34  JSONTYPE_NUMERIC, /* numeric (ditto) */
35  JSONTYPE_DATE, /* we use special formatting for datetimes */
38  JSONTYPE_JSON, /* JSON itself (and JSONB) */
39  JSONTYPE_ARRAY, /* array */
40  JSONTYPE_COMPOSITE, /* composite */
41  JSONTYPE_CAST, /* something with an explicit cast to JSON */
42  JSONTYPE_OTHER /* all else */
JsonTypeCategory
Definition: json.c:30

Function Documentation

◆ add_json()

static void add_json ( Datum  val,
bool  is_null,
StringInfo  result,
Oid  val_type,
bool  key_scalar 
)
static

Definition at line 636 of file json.c.

References datum_to_json(), ereport, errcode(), errmsg(), ERROR, InvalidOid, json_categorize_type(), and JSONTYPE_NULL.

Referenced by json_build_array(), and json_build_object().

638 {
639  JsonTypeCategory tcategory;
640  Oid outfuncoid;
641 
642  if (val_type == InvalidOid)
643  ereport(ERROR,
644  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
645  errmsg("could not determine input data type")));
646 
647  if (is_null)
648  {
649  tcategory = JSONTYPE_NULL;
650  outfuncoid = InvalidOid;
651  }
652  else
653  json_categorize_type(val_type,
654  &tcategory, &outfuncoid);
655 
656  datum_to_json(val, is_null, result, tcategory, outfuncoid, key_scalar);
657 }
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
JsonTypeCategory
Definition: json.c:30
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
long val
Definition: informix.c:664

◆ array_dim_to_json()

static void array_dim_to_json ( StringInfo  result,
int  dim,
int  ndims,
int *  dims,
Datum vals,
bool nulls,
int *  valcount,
JsonTypeCategory  tcategory,
Oid  outfuncoid,
bool  use_line_feeds 
)
static

Definition at line 474 of file json.c.

References appendStringInfoChar(), appendStringInfoString(), Assert, datum_to_json(), and i.

Referenced by array_to_json_internal().

477 {
478  int i;
479  const char *sep;
480 
481  Assert(dim < ndims);
482 
483  sep = use_line_feeds ? ",\n " : ",";
484 
485  appendStringInfoChar(result, '[');
486 
487  for (i = 1; i <= dims[dim]; i++)
488  {
489  if (i > 1)
490  appendStringInfoString(result, sep);
491 
492  if (dim + 1 == ndims)
493  {
494  datum_to_json(vals[*valcount], nulls[*valcount], result, tcategory,
495  outfuncoid, false);
496  (*valcount)++;
497  }
498  else
499  {
500  /*
501  * Do we want line feeds on inner dimensions of arrays? For now
502  * we'll say no.
503  */
504  array_dim_to_json(result, dim + 1, ndims, dims, vals, nulls,
505  valcount, tcategory, outfuncoid, false);
506  }
507  }
508 
509  appendStringInfoChar(result, ']');
510 }
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
Definition: json.c:474
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#define Assert(condition)
Definition: c.h:738
int i

◆ array_to_json()

Datum array_to_json ( PG_FUNCTION_ARGS  )

Definition at line 663 of file json.c.

References array_to_json_internal(), cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, makeStringInfo(), PG_GETARG_DATUM, and PG_RETURN_TEXT_P.

664 {
665  Datum array = PG_GETARG_DATUM(0);
666  StringInfo result;
667 
668  result = makeStringInfo();
669 
670  array_to_json_internal(array, result, false);
671 
673 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
Definition: json.c:516

◆ array_to_json_internal()

static void array_to_json_internal ( Datum  array,
StringInfo  result,
bool  use_line_feeds 
)
static

Definition at line 516 of file json.c.

References appendStringInfoString(), ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, array_dim_to_json(), ArrayGetNItems(), DatumGetArrayTypeP, deconstruct_array(), get_typlenbyvalalign(), json_categorize_type(), pfree(), and typalign.

Referenced by array_to_json(), array_to_json_pretty(), and datum_to_json().

517 {
518  ArrayType *v = DatumGetArrayTypeP(array);
519  Oid element_type = ARR_ELEMTYPE(v);
520  int *dim;
521  int ndim;
522  int nitems;
523  int count = 0;
524  Datum *elements;
525  bool *nulls;
526  int16 typlen;
527  bool typbyval;
528  char typalign;
529  JsonTypeCategory tcategory;
530  Oid outfuncoid;
531 
532  ndim = ARR_NDIM(v);
533  dim = ARR_DIMS(v);
534  nitems = ArrayGetNItems(ndim, dim);
535 
536  if (nitems <= 0)
537  {
538  appendStringInfoString(result, "[]");
539  return;
540  }
541 
542  get_typlenbyvalalign(element_type,
543  &typlen, &typbyval, &typalign);
544 
545  json_categorize_type(element_type,
546  &tcategory, &outfuncoid);
547 
548  deconstruct_array(v, element_type, typlen, typbyval,
549  typalign, &elements, &nulls,
550  &nitems);
551 
552  array_dim_to_json(result, 0, ndim, dim, elements, nulls, &count, tcategory,
553  outfuncoid, use_line_feeds);
554 
555  pfree(elements);
556  pfree(nulls);
557 }
signed short int16
Definition: c.h:354
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2075
static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, Datum *vals, bool *nulls, int *valcount, JsonTypeCategory tcategory, Oid outfuncoid, bool use_line_feeds)
Definition: json.c:474
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:1056
char typalign
Definition: pg_type.h:170
#define ARR_DIMS(a)
Definition: array.h:282
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
JsonTypeCategory
Definition: json.c:30
uintptr_t Datum
Definition: postgres.h:367
#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

◆ array_to_json_pretty()

Datum array_to_json_pretty ( PG_FUNCTION_ARGS  )

Definition at line 679 of file json.c.

References array_to_json_internal(), cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, makeStringInfo(), PG_GETARG_BOOL, PG_GETARG_DATUM, and PG_RETURN_TEXT_P.

680 {
681  Datum array = PG_GETARG_DATUM(0);
682  bool use_line_feeds = PG_GETARG_BOOL(1);
683  StringInfo result;
684 
685  result = makeStringInfo();
686 
687  array_to_json_internal(array, result, use_line_feeds);
688 
690 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
Definition: json.c:516

◆ catenate_stringinfo_string()

static text * catenate_stringinfo_string ( StringInfo  buffer,
const char *  addon 
)
static

Definition at line 973 of file json.c.

References StringInfoData::data, StringInfoData::len, palloc(), SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by json_agg_finalfn(), and json_object_agg_finalfn().

974 {
975  /* custom version of cstring_to_text_with_len */
976  int buflen = buffer->len;
977  int addlen = strlen(addon);
978  text *result = (text *) palloc(buflen + addlen + VARHDRSZ);
979 
980  SET_VARSIZE(result, buflen + addlen + VARHDRSZ);
981  memcpy(VARDATA(result), buffer->data, buflen);
982  memcpy(VARDATA(result) + buflen, addon, addlen);
983 
984  return result;
985 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:561
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:555
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ composite_to_json()

static void composite_to_json ( Datum  composite,
StringInfo  result,
bool  use_line_feeds 
)
static

Definition at line 563 of file json.c.

References appendStringInfoChar(), appendStringInfoString(), attname, datum_to_json(), DatumGetHeapTupleHeader, escape_json(), heap_getattr, HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, i, InvalidOid, json_categorize_type(), JSONTYPE_NULL, lookup_rowtype_tupdesc(), NameStr, TupleDescData::natts, ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, TupleDescAttr, and val.

Referenced by datum_to_json(), row_to_json(), and row_to_json_pretty().

564 {
565  HeapTupleHeader td;
566  Oid tupType;
567  int32 tupTypmod;
568  TupleDesc tupdesc;
569  HeapTupleData tmptup,
570  *tuple;
571  int i;
572  bool needsep = false;
573  const char *sep;
574 
575  sep = use_line_feeds ? ",\n " : ",";
576 
577  td = DatumGetHeapTupleHeader(composite);
578 
579  /* Extract rowtype info and find a tupdesc */
580  tupType = HeapTupleHeaderGetTypeId(td);
581  tupTypmod = HeapTupleHeaderGetTypMod(td);
582  tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
583 
584  /* Build a temporary HeapTuple control structure */
586  tmptup.t_data = td;
587  tuple = &tmptup;
588 
589  appendStringInfoChar(result, '{');
590 
591  for (i = 0; i < tupdesc->natts; i++)
592  {
593  Datum val;
594  bool isnull;
595  char *attname;
596  JsonTypeCategory tcategory;
597  Oid outfuncoid;
598  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
599 
600  if (att->attisdropped)
601  continue;
602 
603  if (needsep)
604  appendStringInfoString(result, sep);
605  needsep = true;
606 
607  attname = NameStr(att->attname);
608  escape_json(result, attname);
609  appendStringInfoChar(result, ':');
610 
611  val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
612 
613  if (isnull)
614  {
615  tcategory = JSONTYPE_NULL;
616  outfuncoid = InvalidOid;
617  }
618  else
619  json_categorize_type(att->atttypid, &tcategory, &outfuncoid);
620 
621  datum_to_json(val, isnull, result, tcategory, outfuncoid, false);
622  }
623 
624  appendStringInfoChar(result, '}');
625  ReleaseTupleDesc(tupdesc);
626 }
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1279
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1710
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
unsigned int Oid
Definition: postgres_ext.h:31
#define DatumGetHeapTupleHeader(X)
Definition: fmgr.h:289
signed int int32
Definition: c.h:355
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:468
NameData attname
Definition: pg_attribute.h:40
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
uint32 t_len
Definition: htup.h:64
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
JsonTypeCategory
Definition: json.c:30
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#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
#define InvalidOid
Definition: postgres_ext.h:36
int i
#define NameStr(name)
Definition: c.h:615
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
long val
Definition: informix.c:664
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:452

◆ datum_to_json()

static void datum_to_json ( Datum  val,
bool  is_null,
StringInfo  result,
JsonTypeCategory  tcategory,
Oid  outfuncoid,
bool  key_scalar 
)
static

Definition at line 246 of file json.c.

References appendStringInfo(), appendStringInfoString(), array_to_json_internal(), Assert, buf, check_stack_depth(), composite_to_json(), DatumGetBool, DatumGetTextPP, ereport, errcode(), errmsg(), ERROR, escape_json(), IsValidJsonNumber(), JsonEncodeDateTime(), JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_NUMERIC, JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, MAXDATELEN, OidFunctionCall1, OidOutputFunctionCall(), pfree(), and text_to_cstring().

Referenced by add_json(), array_dim_to_json(), composite_to_json(), json_agg_transfn(), json_object_agg_transfn(), and to_json().

249 {
250  char *outputstr;
251  text *jsontext;
252 
254 
255  /* callers are expected to ensure that null keys are not passed in */
256  Assert(!(key_scalar && is_null));
257 
258  if (is_null)
259  {
260  appendStringInfoString(result, "null");
261  return;
262  }
263 
264  if (key_scalar &&
265  (tcategory == JSONTYPE_ARRAY ||
266  tcategory == JSONTYPE_COMPOSITE ||
267  tcategory == JSONTYPE_JSON ||
268  tcategory == JSONTYPE_CAST))
269  ereport(ERROR,
270  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
271  errmsg("key value must be scalar, not array, composite, or json")));
272 
273  switch (tcategory)
274  {
275  case JSONTYPE_ARRAY:
276  array_to_json_internal(val, result, false);
277  break;
278  case JSONTYPE_COMPOSITE:
279  composite_to_json(val, result, false);
280  break;
281  case JSONTYPE_BOOL:
282  outputstr = DatumGetBool(val) ? "true" : "false";
283  if (key_scalar)
284  escape_json(result, outputstr);
285  else
286  appendStringInfoString(result, outputstr);
287  break;
288  case JSONTYPE_NUMERIC:
289  outputstr = OidOutputFunctionCall(outfuncoid, val);
290 
291  /*
292  * Don't call escape_json for a non-key if it's a valid JSON
293  * number.
294  */
295  if (!key_scalar && IsValidJsonNumber(outputstr, strlen(outputstr)))
296  appendStringInfoString(result, outputstr);
297  else
298  escape_json(result, outputstr);
299  pfree(outputstr);
300  break;
301  case JSONTYPE_DATE:
302  {
303  char buf[MAXDATELEN + 1];
304 
305  JsonEncodeDateTime(buf, val, DATEOID, NULL);
306  appendStringInfo(result, "\"%s\"", buf);
307  }
308  break;
309  case JSONTYPE_TIMESTAMP:
310  {
311  char buf[MAXDATELEN + 1];
312 
313  JsonEncodeDateTime(buf, val, TIMESTAMPOID, NULL);
314  appendStringInfo(result, "\"%s\"", buf);
315  }
316  break;
318  {
319  char buf[MAXDATELEN + 1];
320 
321  JsonEncodeDateTime(buf, val, TIMESTAMPTZOID, NULL);
322  appendStringInfo(result, "\"%s\"", buf);
323  }
324  break;
325  case JSONTYPE_JSON:
326  /* JSON and JSONB output will already be escaped */
327  outputstr = OidOutputFunctionCall(outfuncoid, val);
328  appendStringInfoString(result, outputstr);
329  pfree(outputstr);
330  break;
331  case JSONTYPE_CAST:
332  /* outfuncoid refers to a cast function, not an output function */
333  jsontext = DatumGetTextPP(OidFunctionCall1(outfuncoid, val));
334  outputstr = text_to_cstring(jsontext);
335  appendStringInfoString(result, outputstr);
336  pfree(outputstr);
337  pfree(jsontext);
338  break;
339  default:
340  outputstr = OidOutputFunctionCall(outfuncoid, val);
341  escape_json(result, outputstr);
342  pfree(outputstr);
343  break;
344  }
345 }
#define MAXDATELEN
Definition: datetime.h:201
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1279
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition: json.c:563
#define DatumGetTextPP(X)
Definition: fmgr.h:286
int errcode(int sqlerrcode)
Definition: elog.c:610
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:653
char * JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp)
Definition: json.c:353
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
void check_stack_depth(void)
Definition: postgres.c:3292
#define DatumGetBool(X)
Definition: postgres.h:393
bool IsValidJsonNumber(const char *str, int len)
Definition: jsonapi.c:115
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
static void array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
Definition: json.c:516
char * text_to_cstring(const text *t)
Definition: varlena.c:204
char * OidOutputFunctionCall(Oid functionId, Datum val)
Definition: fmgr.c:1655
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555
long val
Definition: informix.c:664

◆ escape_json()

void escape_json ( StringInfo  buf,
const char *  str 
)

Definition at line 1279 of file json.c.

References appendStringInfo(), appendStringInfoCharMacro, and appendStringInfoString().

Referenced by composite_to_json(), datum_to_json(), escape_yaml(), ExplainDummyGroup(), ExplainOpenGroup(), ExplainProperty(), ExplainPropertyList(), ExplainPropertyListNested(), hstore_to_json(), hstore_to_json_loose(), json_object(), json_object_two_arg(), jsonb_put_escaped_value(), populate_scalar(), printJsonPathItem(), sn_object_field_start(), sn_scalar(), transform_string_values_object_field_start(), and transform_string_values_scalar().

1280 {
1281  const char *p;
1282 
1283  appendStringInfoCharMacro(buf, '"');
1284  for (p = str; *p; p++)
1285  {
1286  switch (*p)
1287  {
1288  case '\b':
1289  appendStringInfoString(buf, "\\b");
1290  break;
1291  case '\f':
1292  appendStringInfoString(buf, "\\f");
1293  break;
1294  case '\n':
1295  appendStringInfoString(buf, "\\n");
1296  break;
1297  case '\r':
1298  appendStringInfoString(buf, "\\r");
1299  break;
1300  case '\t':
1301  appendStringInfoString(buf, "\\t");
1302  break;
1303  case '"':
1304  appendStringInfoString(buf, "\\\"");
1305  break;
1306  case '\\':
1307  appendStringInfoString(buf, "\\\\");
1308  break;
1309  default:
1310  if ((unsigned char) *p < ' ')
1311  appendStringInfo(buf, "\\u%04x", (int) *p);
1312  else
1313  appendStringInfoCharMacro(buf, *p);
1314  break;
1315  }
1316  }
1317  appendStringInfoCharMacro(buf, '"');
1318 }
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176

◆ json_agg_finalfn()

Datum json_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 834 of file json.c.

References AggCheckCallContext(), Assert, catenate_stringinfo_string(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_TEXT_P, and JsonAggState::str.

835 {
837 
838  /* cannot be called directly because of internal-type argument */
839  Assert(AggCheckCallContext(fcinfo, NULL));
840 
841  state = PG_ARGISNULL(0) ?
842  NULL :
844 
845  /* NULL result for no rows in, as is standard with aggregates */
846  if (state == NULL)
847  PG_RETURN_NULL();
848 
849  /* Else return state with appropriate array terminator added */
851 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
static text * catenate_stringinfo_string(StringInfo buffer, const char *addon)
Definition: json.c:973
StringInfo str
Definition: json.c:47
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:738
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4661
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ json_agg_transfn()

Datum json_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 758 of file json.c.

References AggCheckCallContext(), appendStringInfoChar(), appendStringInfoString(), datum_to_json(), elog, ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), JSONTYPE_ARRAY, JSONTYPE_COMPOSITE, JSONTYPE_NULL, makeStringInfo(), MemoryContextSwitchTo(), palloc(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, JsonAggState::str, val, JsonAggState::val_category, and JsonAggState::val_output_func.

759 {
760  MemoryContext aggcontext,
761  oldcontext;
763  Datum val;
764 
765  if (!AggCheckCallContext(fcinfo, &aggcontext))
766  {
767  /* cannot be called directly because of internal-type argument */
768  elog(ERROR, "json_agg_transfn called in non-aggregate context");
769  }
770 
771  if (PG_ARGISNULL(0))
772  {
773  Oid arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
774 
775  if (arg_type == InvalidOid)
776  ereport(ERROR,
777  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
778  errmsg("could not determine input data type")));
779 
780  /*
781  * Make this state object in a context where it will persist for the
782  * duration of the aggregate call. MemoryContextSwitchTo is only
783  * needed the first time, as the StringInfo routines make sure they
784  * use the right context to enlarge the object if necessary.
785  */
786  oldcontext = MemoryContextSwitchTo(aggcontext);
787  state = (JsonAggState *) palloc(sizeof(JsonAggState));
788  state->str = makeStringInfo();
789  MemoryContextSwitchTo(oldcontext);
790 
791  appendStringInfoChar(state->str, '[');
792  json_categorize_type(arg_type, &state->val_category,
793  &state->val_output_func);
794  }
795  else
796  {
797  state = (JsonAggState *) PG_GETARG_POINTER(0);
798  appendStringInfoString(state->str, ", ");
799  }
800 
801  /* fast path for NULLs */
802  if (PG_ARGISNULL(1))
803  {
804  datum_to_json((Datum) 0, true, state->str, JSONTYPE_NULL,
805  InvalidOid, false);
806  PG_RETURN_POINTER(state);
807  }
808 
809  val = PG_GETARG_DATUM(1);
810 
811  /* add some whitespace if structured type and not first item */
812  if (!PG_ARGISNULL(0) &&
813  (state->val_category == JSONTYPE_ARRAY ||
814  state->val_category == JSONTYPE_COMPOSITE))
815  {
816  appendStringInfoString(state->str, "\n ");
817  }
818 
819  datum_to_json(val, false, state->str, state->val_category,
820  state->val_output_func, false);
821 
822  /*
823  * The transition type for json_agg() is declared to be "internal", which
824  * is a pass-by-value type the same size as a pointer. So we can safely
825  * pass the JsonAggState pointer through nodeAgg.c's machinations.
826  */
827  PG_RETURN_POINTER(state);
828 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:610
Oid val_output_func
Definition: json.c:51
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1802
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
StringInfo str
Definition: json.c:47
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
JsonTypeCategory val_category
Definition: json.c:50
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4661
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
long val
Definition: informix.c:664

◆ json_build_array()

Datum json_build_array ( PG_FUNCTION_ARGS  )

Definition at line 1057 of file json.c.

References add_json(), appendStringInfoChar(), appendStringInfoString(), generate_unaccent_rules::args, cstring_to_text_with_len(), StringInfoData::data, extract_variadic_args(), i, StringInfoData::len, makeStringInfo(), PG_RETURN_NULL, PG_RETURN_TEXT_P, and types.

1058 {
1059  int nargs;
1060  int i;
1061  const char *sep = "";
1062  StringInfo result;
1063  Datum *args;
1064  bool *nulls;
1065  Oid *types;
1066 
1067  /* fetch argument values to build the array */
1068  nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
1069 
1070  if (nargs < 0)
1071  PG_RETURN_NULL();
1072 
1073  result = makeStringInfo();
1074 
1075  appendStringInfoChar(result, '[');
1076 
1077  for (i = 0; i < nargs; i++)
1078  {
1079  appendStringInfoString(result, sep);
1080  sep = ", ";
1081  add_json(args[i], nulls[i], result, types[i], false);
1082  }
1083 
1084  appendStringInfoChar(result, ']');
1085 
1087 }
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1727
struct typedefs * types
Definition: ecpg.c:29
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
uintptr_t Datum
Definition: postgres.h:367
static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
Definition: json.c:636
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
int i
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ json_build_array_noargs()

Datum json_build_array_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1093 of file json.c.

References cstring_to_text_with_len(), and PG_RETURN_TEXT_P.

1094 {
1096 }
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361

◆ json_build_object()

Datum json_build_object ( PG_FUNCTION_ARGS  )

Definition at line 991 of file json.c.

References add_json(), appendStringInfoChar(), appendStringInfoString(), generate_unaccent_rules::args, cstring_to_text_with_len(), StringInfoData::data, ereport, errcode(), errhint(), errmsg(), ERROR, extract_variadic_args(), i, StringInfoData::len, makeStringInfo(), PG_NARGS, PG_RETURN_NULL, PG_RETURN_TEXT_P, and types.

992 {
993  int nargs = PG_NARGS();
994  int i;
995  const char *sep = "";
996  StringInfo result;
997  Datum *args;
998  bool *nulls;
999  Oid *types;
1000 
1001  /* fetch argument values to build the object */
1002  nargs = extract_variadic_args(fcinfo, 0, false, &args, &types, &nulls);
1003 
1004  if (nargs < 0)
1005  PG_RETURN_NULL();
1006 
1007  if (nargs % 2 != 0)
1008  ereport(ERROR,
1009  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1010  errmsg("argument list must have even number of elements"),
1011  /* translator: %s is a SQL function name */
1012  errhint("The arguments of %s must consist of alternating keys and values.",
1013  "json_build_object()")));
1014 
1015  result = makeStringInfo();
1016 
1017  appendStringInfoChar(result, '{');
1018 
1019  for (i = 0; i < nargs; i += 2)
1020  {
1021  appendStringInfoString(result, sep);
1022  sep = ", ";
1023 
1024  /* process key */
1025  if (nulls[i])
1026  ereport(ERROR,
1027  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1028  errmsg("argument %d cannot be null", i + 1),
1029  errhint("Object keys should be text.")));
1030 
1031  add_json(args[i], false, result, types[i], true);
1032 
1033  appendStringInfoString(result, " : ");
1034 
1035  /* process value */
1036  add_json(args[i + 1], nulls[i + 1], result, types[i + 1], false);
1037  }
1038 
1039  appendStringInfoChar(result, '}');
1040 
1042 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, bool convert_unknown, Datum **args, Oid **types, bool **nulls)
Definition: funcapi.c:1727
struct typedefs * types
Definition: ecpg.c:29
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:144
static void add_json(Datum val, bool is_null, StringInfo result, Oid val_type, bool key_scalar)
Definition: json.c:636
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_NARGS()
Definition: fmgr.h:198
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ json_build_object_noargs()

Datum json_build_object_noargs ( PG_FUNCTION_ARGS  )

Definition at line 1048 of file json.c.

References cstring_to_text_with_len(), and PG_RETURN_TEXT_P.

1049 {
1051 }
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361

◆ json_categorize_type()

static void json_categorize_type ( Oid  typoid,
JsonTypeCategory tcategory,
Oid outfuncoid 
)
static

Definition at line 144 of file json.c.

References COERCION_EXPLICIT, COERCION_PATH_FUNC, find_coercion_pathway(), FirstNormalObjectId, get_element_type(), getBaseType(), getTypeOutputInfo(), InvalidOid, JSONTYPE_ARRAY, JSONTYPE_BOOL, JSONTYPE_CAST, JSONTYPE_COMPOSITE, JSONTYPE_DATE, JSONTYPE_JSON, JSONTYPE_NUMERIC, JSONTYPE_OTHER, JSONTYPE_TIMESTAMP, JSONTYPE_TIMESTAMPTZ, OidIsValid, and type_is_rowtype().

Referenced by add_json(), array_to_json_internal(), composite_to_json(), json_agg_transfn(), json_object_agg_transfn(), and to_json().

147 {
148  bool typisvarlena;
149 
150  /* Look through any domain */
151  typoid = getBaseType(typoid);
152 
153  *outfuncoid = InvalidOid;
154 
155  /*
156  * We need to get the output function for everything except date and
157  * timestamp types, array and composite types, booleans, and non-builtin
158  * types where there's a cast to json.
159  */
160 
161  switch (typoid)
162  {
163  case BOOLOID:
164  *tcategory = JSONTYPE_BOOL;
165  break;
166 
167  case INT2OID:
168  case INT4OID:
169  case INT8OID:
170  case FLOAT4OID:
171  case FLOAT8OID:
172  case NUMERICOID:
173  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
174  *tcategory = JSONTYPE_NUMERIC;
175  break;
176 
177  case DATEOID:
178  *tcategory = JSONTYPE_DATE;
179  break;
180 
181  case TIMESTAMPOID:
182  *tcategory = JSONTYPE_TIMESTAMP;
183  break;
184 
185  case TIMESTAMPTZOID:
186  *tcategory = JSONTYPE_TIMESTAMPTZ;
187  break;
188 
189  case JSONOID:
190  case JSONBOID:
191  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
192  *tcategory = JSONTYPE_JSON;
193  break;
194 
195  default:
196  /* Check for arrays and composites */
197  if (OidIsValid(get_element_type(typoid)) || typoid == ANYARRAYOID
198  || typoid == ANYCOMPATIBLEARRAYOID || typoid == RECORDARRAYOID)
199  *tcategory = JSONTYPE_ARRAY;
200  else if (type_is_rowtype(typoid)) /* includes RECORDOID */
201  *tcategory = JSONTYPE_COMPOSITE;
202  else
203  {
204  /* It's probably the general case ... */
205  *tcategory = JSONTYPE_OTHER;
206  /* but let's look for a cast to json, if it's not built-in */
207  if (typoid >= FirstNormalObjectId)
208  {
209  Oid castfunc;
210  CoercionPathType ctype;
211 
212  ctype = find_coercion_pathway(JSONOID, typoid,
214  &castfunc);
215  if (ctype == COERCION_PATH_FUNC && OidIsValid(castfunc))
216  {
217  *tcategory = JSONTYPE_CAST;
218  *outfuncoid = castfunc;
219  }
220  else
221  {
222  /* non builtin type with no cast */
223  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
224  }
225  }
226  else
227  {
228  /* any other builtin type */
229  getTypeOutputInfo(typoid, outfuncoid, &typisvarlena);
230  }
231  }
232  break;
233  }
234 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2700
Oid get_element_type(Oid typid)
Definition: lsyscache.c:2552
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
CoercionPathType
Definition: parse_coerce.h:24
#define FirstNormalObjectId
Definition: transam.h:141
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2459
#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:2325

◆ json_in()

Datum json_in ( PG_FUNCTION_ARGS  )

Definition at line 76 of file json.c.

References cstring_to_text(), makeJsonLexContext(), nullSemAction, PG_GETARG_CSTRING, pg_parse_json_or_ereport(), and PG_RETURN_TEXT_P.

77 {
78  char *json = PG_GETARG_CSTRING(0);
79  text *result = cstring_to_text(json);
80  JsonLexContext *lex;
81 
82  /* validate it */
83  lex = makeJsonLexContext(result, false);
85 
86  /* Internal representation is the same as text, for now */
87  PG_RETURN_TEXT_P(result);
88 }
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:513
JsonSemAction nullSemAction
Definition: jsonapi.c:67
void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonfuncs.c:497
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
Definition: c.h:555

◆ json_object()

Datum json_object ( PG_FUNCTION_ARGS  )

Definition at line 1105 of file json.c.

References appendStringInfoChar(), appendStringInfoString(), ARR_DIMS, ARR_NDIM, cstring_to_text_with_len(), CStringGetTextDatum, StringInfoData::data, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, escape_json(), i, initStringInfo(), StringInfoData::len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_DATUM, PG_RETURN_TEXT_P, and TextDatumGetCString.

1106 {
1107  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
1108  int ndims = ARR_NDIM(in_array);
1109  StringInfoData result;
1110  Datum *in_datums;
1111  bool *in_nulls;
1112  int in_count,
1113  count,
1114  i;
1115  text *rval;
1116  char *v;
1117 
1118  switch (ndims)
1119  {
1120  case 0:
1122  break;
1123 
1124  case 1:
1125  if ((ARR_DIMS(in_array)[0]) % 2)
1126  ereport(ERROR,
1127  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1128  errmsg("array must have even number of elements")));
1129  break;
1130 
1131  case 2:
1132  if ((ARR_DIMS(in_array)[1]) != 2)
1133  ereport(ERROR,
1134  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1135  errmsg("array must have two columns")));
1136  break;
1137 
1138  default:
1139  ereport(ERROR,
1140  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1141  errmsg("wrong number of array subscripts")));
1142  }
1143 
1144  deconstruct_array(in_array,
1145  TEXTOID, -1, false, TYPALIGN_INT,
1146  &in_datums, &in_nulls, &in_count);
1147 
1148  count = in_count / 2;
1149 
1150  initStringInfo(&result);
1151 
1152  appendStringInfoChar(&result, '{');
1153 
1154  for (i = 0; i < count; ++i)
1155  {
1156  if (in_nulls[i * 2])
1157  ereport(ERROR,
1158  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1159  errmsg("null value not allowed for object key")));
1160 
1161  v = TextDatumGetCString(in_datums[i * 2]);
1162  if (i > 0)
1163  appendStringInfoString(&result, ", ");
1164  escape_json(&result, v);
1165  appendStringInfoString(&result, " : ");
1166  pfree(v);
1167  if (in_nulls[i * 2 + 1])
1168  appendStringInfoString(&result, "null");
1169  else
1170  {
1171  v = TextDatumGetCString(in_datums[i * 2 + 1]);
1172  escape_json(&result, v);
1173  pfree(v);
1174  }
1175  }
1176 
1177  appendStringInfoChar(&result, '}');
1178 
1179  pfree(in_datums);
1180  pfree(in_nulls);
1181 
1182  rval = cstring_to_text_with_len(result.data, result.len);
1183  pfree(result.data);
1184 
1185  PG_RETURN_TEXT_P(rval);
1186 
1187 }
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1279
int errcode(int sqlerrcode)
Definition: elog.c:610
#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
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define TextDatumGetCString(d)
Definition: builtins.h:88
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#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
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:87
Definition: c.h:555

◆ json_object_agg_finalfn()

Datum json_object_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 950 of file json.c.

References AggCheckCallContext(), Assert, catenate_stringinfo_string(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_TEXT_P, and JsonAggState::str.

951 {
953 
954  /* cannot be called directly because of internal-type argument */
955  Assert(AggCheckCallContext(fcinfo, NULL));
956 
957  state = PG_ARGISNULL(0) ? NULL : (JsonAggState *) PG_GETARG_POINTER(0);
958 
959  /* NULL result for no rows in, as is standard with aggregates */
960  if (state == NULL)
961  PG_RETURN_NULL();
962 
963  /* Else return state with appropriate object terminator added */
965 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
static text * catenate_stringinfo_string(StringInfo buffer, const char *addon)
Definition: json.c:973
StringInfo str
Definition: json.c:47
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:738
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4661
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ json_object_agg_transfn()

Datum json_object_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 859 of file json.c.

References AggCheckCallContext(), appendStringInfoString(), arg, datum_to_json(), elog, ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), JsonAggState::key_category, JsonAggState::key_output_func, makeStringInfo(), MemoryContextSwitchTo(), palloc(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, JsonAggState::str, JsonAggState::val_category, and JsonAggState::val_output_func.

860 {
861  MemoryContext aggcontext,
862  oldcontext;
864  Datum arg;
865 
866  if (!AggCheckCallContext(fcinfo, &aggcontext))
867  {
868  /* cannot be called directly because of internal-type argument */
869  elog(ERROR, "json_object_agg_transfn called in non-aggregate context");
870  }
871 
872  if (PG_ARGISNULL(0))
873  {
874  Oid arg_type;
875 
876  /*
877  * Make the StringInfo in a context where it will persist for the
878  * duration of the aggregate call. Switching context is only needed
879  * for this initial step, as the StringInfo routines make sure they
880  * use the right context to enlarge the object if necessary.
881  */
882  oldcontext = MemoryContextSwitchTo(aggcontext);
883  state = (JsonAggState *) palloc(sizeof(JsonAggState));
884  state->str = makeStringInfo();
885  MemoryContextSwitchTo(oldcontext);
886 
887  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
888 
889  if (arg_type == InvalidOid)
890  ereport(ERROR,
891  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
892  errmsg("could not determine data type for argument %d", 1)));
893 
894  json_categorize_type(arg_type, &state->key_category,
895  &state->key_output_func);
896 
897  arg_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
898 
899  if (arg_type == InvalidOid)
900  ereport(ERROR,
901  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
902  errmsg("could not determine data type for argument %d", 2)));
903 
904  json_categorize_type(arg_type, &state->val_category,
905  &state->val_output_func);
906 
907  appendStringInfoString(state->str, "{ ");
908  }
909  else
910  {
911  state = (JsonAggState *) PG_GETARG_POINTER(0);
912  appendStringInfoString(state->str, ", ");
913  }
914 
915  /*
916  * Note: since json_object_agg() is declared as taking type "any", the
917  * parser will not do any type conversion on unknown-type literals (that
918  * is, undecorated strings or NULLs). Such values will arrive here as
919  * type UNKNOWN, which fortunately does not matter to us, since
920  * unknownout() works fine.
921  */
922 
923  if (PG_ARGISNULL(1))
924  ereport(ERROR,
925  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
926  errmsg("field name must not be null")));
927 
928  arg = PG_GETARG_DATUM(1);
929 
930  datum_to_json(arg, false, state->str, state->key_category,
931  state->key_output_func, true);
932 
933  appendStringInfoString(state->str, " : ");
934 
935  if (PG_ARGISNULL(2))
936  arg = (Datum) 0;
937  else
938  arg = PG_GETARG_DATUM(2);
939 
940  datum_to_json(arg, PG_ARGISNULL(2), state->str, state->val_category,
941  state->val_output_func, false);
942 
943  PG_RETURN_POINTER(state);
944 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:610
Oid val_output_func
Definition: json.c:51
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
Oid key_output_func
Definition: json.c:49
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1802
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
StringInfo str
Definition: json.c:47
JsonTypeCategory key_category
Definition: json.c:48
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
JsonTypeCategory val_category
Definition: json.c:50
Definition: regguts.h:298
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4661
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
void * arg

◆ json_object_two_arg()

Datum json_object_two_arg ( PG_FUNCTION_ARGS  )

Definition at line 1196 of file json.c.

References appendStringInfoChar(), appendStringInfoString(), ARR_NDIM, cstring_to_text_with_len(), CStringGetTextDatum, StringInfoData::data, deconstruct_array(), ereport, errcode(), errmsg(), ERROR, escape_json(), i, initStringInfo(), StringInfoData::len, pfree(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_DATUM, PG_RETURN_TEXT_P, and TextDatumGetCString.

1197 {
1198  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(0);
1199  ArrayType *val_array = PG_GETARG_ARRAYTYPE_P(1);
1200  int nkdims = ARR_NDIM(key_array);
1201  int nvdims = ARR_NDIM(val_array);
1202  StringInfoData result;
1203  Datum *key_datums,
1204  *val_datums;
1205  bool *key_nulls,
1206  *val_nulls;
1207  int key_count,
1208  val_count,
1209  i;
1210  text *rval;
1211  char *v;
1212 
1213  if (nkdims > 1 || nkdims != nvdims)
1214  ereport(ERROR,
1215  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1216  errmsg("wrong number of array subscripts")));
1217 
1218  if (nkdims == 0)
1220 
1221  deconstruct_array(key_array,
1222  TEXTOID, -1, false, TYPALIGN_INT,
1223  &key_datums, &key_nulls, &key_count);
1224 
1225  deconstruct_array(val_array,
1226  TEXTOID, -1, false, TYPALIGN_INT,
1227  &val_datums, &val_nulls, &val_count);
1228 
1229  if (key_count != val_count)
1230  ereport(ERROR,
1231  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
1232  errmsg("mismatched array dimensions")));
1233 
1234  initStringInfo(&result);
1235 
1236  appendStringInfoChar(&result, '{');
1237 
1238  for (i = 0; i < key_count; ++i)
1239  {
1240  if (key_nulls[i])
1241  ereport(ERROR,
1242  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1243  errmsg("null value not allowed for object key")));
1244 
1245  v = TextDatumGetCString(key_datums[i]);
1246  if (i > 0)
1247  appendStringInfoString(&result, ", ");
1248  escape_json(&result, v);
1249  appendStringInfoString(&result, " : ");
1250  pfree(v);
1251  if (val_nulls[i])
1252  appendStringInfoString(&result, "null");
1253  else
1254  {
1255  v = TextDatumGetCString(val_datums[i]);
1256  escape_json(&result, v);
1257  pfree(v);
1258  }
1259  }
1260 
1261  appendStringInfoChar(&result, '}');
1262 
1263  pfree(key_datums);
1264  pfree(key_nulls);
1265  pfree(val_datums);
1266  pfree(val_nulls);
1267 
1268  rval = cstring_to_text_with_len(result.data, result.len);
1269  pfree(result.data);
1270 
1271  PG_RETURN_TEXT_P(rval);
1272 }
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1279
int errcode(int sqlerrcode)
Definition: elog.c:610
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define TextDatumGetCString(d)
Definition: builtins.h:88
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#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
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
#define CStringGetTextDatum(s)
Definition: builtins.h:87
Definition: c.h:555

◆ json_out()

Datum json_out ( PG_FUNCTION_ARGS  )

Definition at line 94 of file json.c.

References PG_GETARG_DATUM, PG_RETURN_CSTRING, and TextDatumGetCString.

95 {
96  /* we needn't detoast because text_to_cstring will handle that */
97  Datum txt = PG_GETARG_DATUM(0);
98 
100 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define TextDatumGetCString(d)
Definition: builtins.h:88
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352

◆ json_recv()

Datum json_recv ( PG_FUNCTION_ARGS  )

Definition at line 120 of file json.c.

References buf, cstring_to_text_with_len(), StringInfoData::cursor, GetDatabaseEncoding(), StringInfoData::len, makeJsonLexContextCstringLen(), nullSemAction, PG_GETARG_POINTER, pg_parse_json_or_ereport(), PG_RETURN_TEXT_P, pq_getmsgtext(), and JsonAggState::str.

121 {
123  char *str;
124  int nbytes;
125  JsonLexContext *lex;
126 
127  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
128 
129  /* Validate it. */
130  lex = makeJsonLexContextCstringLen(str, nbytes, GetDatabaseEncoding(), false);
132 
134 }
StringInfoData * StringInfo
Definition: stringinfo.h:44
JsonSemAction nullSemAction
Definition: jsonapi.c:67
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:155
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonfuncs.c:497
int GetDatabaseEncoding(void)
Definition: mbutils.c:1151
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361

◆ json_send()

Datum json_send ( PG_FUNCTION_ARGS  )

Definition at line 106 of file json.c.

References buf, PG_GETARG_TEXT_PP, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

107 {
108  text *t = PG_GETARG_TEXT_PP(0);
110 
111  pq_begintypsend(&buf);
114 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
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
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static char * buf
Definition: pg_test_fsync.c:67
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ json_typeof()

Datum json_typeof ( PG_FUNCTION_ARGS  )

Definition at line 1333 of file json.c.

References cstring_to_text(), elog, ERROR, json_ereport_error(), json_lex(), JSON_SUCCESS, JSON_TOKEN_ARRAY_START, JSON_TOKEN_FALSE, JSON_TOKEN_NULL, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_START, JSON_TOKEN_STRING, JSON_TOKEN_TRUE, makeJsonLexContext(), PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, JsonLexContext::token_type, and generate_unaccent_rules::type.

1334 {
1335  text *json;
1336 
1337  JsonLexContext *lex;
1338  JsonTokenType tok;
1339  char *type;
1340  JsonParseErrorType result;
1341 
1342  json = PG_GETARG_TEXT_PP(0);
1343  lex = makeJsonLexContext(json, false);
1344 
1345  /* Lex exactly one token from the input and check its type. */
1346  result = json_lex(lex);
1347  if (result != JSON_SUCCESS)
1348  json_ereport_error(result, lex);
1349  tok = lex->token_type;
1350  switch (tok)
1351  {
1353  type = "object";
1354  break;
1356  type = "array";
1357  break;
1358  case JSON_TOKEN_STRING:
1359  type = "string";
1360  break;
1361  case JSON_TOKEN_NUMBER:
1362  type = "number";
1363  break;
1364  case JSON_TOKEN_TRUE:
1365  case JSON_TOKEN_FALSE:
1366  type = "boolean";
1367  break;
1368  case JSON_TOKEN_NULL:
1369  type = "null";
1370  break;
1371  default:
1372  elog(ERROR, "unexpected json token: %d", tok);
1373  }
1374 
1376 }
JsonTokenType token_type
Definition: jsonapi.h:80
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:513
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
JsonParseErrorType
Definition: jsonapi.h:36
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
JsonParseErrorType json_lex(JsonLexContext *lex)
Definition: jsonapi.c:526
void json_ereport_error(JsonParseErrorType error, JsonLexContext *lex)
Definition: jsonfuncs.c:607
#define elog(elevel,...)
Definition: elog.h:214
Definition: c.h:555
JsonTokenType
Definition: jsonapi.h:19

◆ JsonEncodeDateTime()

char* JsonEncodeDateTime ( char *  buf,
Datum  value,
Oid  typid,
const int *  tzp 
)

Definition at line 353 of file json.c.

References buf, DATE_NOT_FINITE, DatumGetDateADT, DatumGetTimeADT, DatumGetTimestamp, DatumGetTimestampTz, DatumGetTimeTzADTP, elog, EncodeDateOnly(), EncodeDateTime(), EncodeSpecialDate(), EncodeSpecialTimestamp(), EncodeTimeOnly(), ereport, errcode(), errmsg(), ERROR, j2date(), MAXDATELEN, palloc(), POSTGRES_EPOCH_JDATE, time2tm(), timestamp2tm(), TIMESTAMP_NOT_FINITE, timetz2tm(), tm, pg_tm::tm_isdst, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, USE_XSD_DATES, and USECS_PER_SEC.

Referenced by convertJsonbScalar(), datum_to_json(), and datum_to_jsonb().

354 {
355  if (!buf)
356  buf = palloc(MAXDATELEN + 1);
357 
358  switch (typid)
359  {
360  case DATEOID:
361  {
362  DateADT date;
363  struct pg_tm tm;
364 
365  date = DatumGetDateADT(value);
366 
367  /* Same as date_out(), but forcing DateStyle */
368  if (DATE_NOT_FINITE(date))
369  EncodeSpecialDate(date, buf);
370  else
371  {
373  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
375  }
376  }
377  break;
378  case TIMEOID:
379  {
380  TimeADT time = DatumGetTimeADT(value);
381  struct pg_tm tt,
382  *tm = &tt;
383  fsec_t fsec;
384 
385  /* Same as time_out(), but forcing DateStyle */
386  time2tm(time, tm, &fsec);
387  EncodeTimeOnly(tm, fsec, false, 0, USE_XSD_DATES, buf);
388  }
389  break;
390  case TIMETZOID:
391  {
393  struct pg_tm tt,
394  *tm = &tt;
395  fsec_t fsec;
396  int tz;
397 
398  /* Same as timetz_out(), but forcing DateStyle */
399  timetz2tm(time, tm, &fsec, &tz);
400  EncodeTimeOnly(tm, fsec, true, tz, USE_XSD_DATES, buf);
401  }
402  break;
403  case TIMESTAMPOID:
404  {
406  struct pg_tm tm;
407  fsec_t fsec;
408 
409  timestamp = DatumGetTimestamp(value);
410  /* Same as timestamp_out(), but forcing DateStyle */
411  if (TIMESTAMP_NOT_FINITE(timestamp))
412  EncodeSpecialTimestamp(timestamp, buf);
413  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
414  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
415  else
416  ereport(ERROR,
417  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
418  errmsg("timestamp out of range")));
419  }
420  break;
421  case TIMESTAMPTZOID:
422  {
424  struct pg_tm tm;
425  int tz;
426  fsec_t fsec;
427  const char *tzn = NULL;
428 
429  timestamp = DatumGetTimestampTz(value);
430 
431  /*
432  * If a time zone is specified, we apply the time-zone shift,
433  * convert timestamptz to pg_tm as if it were without a time
434  * zone, and then use the specified time zone for converting
435  * the timestamp into a string.
436  */
437  if (tzp)
438  {
439  tz = *tzp;
440  timestamp -= (TimestampTz) tz * USECS_PER_SEC;
441  }
442 
443  /* Same as timestamptz_out(), but forcing DateStyle */
444  if (TIMESTAMP_NOT_FINITE(timestamp))
445  EncodeSpecialTimestamp(timestamp, buf);
446  else if (timestamp2tm(timestamp, tzp ? NULL : &tz, &tm, &fsec,
447  tzp ? NULL : &tzn, NULL) == 0)
448  {
449  if (tzp)
450  tm.tm_isdst = 1; /* set time-zone presence flag */
451 
452  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
453  }
454  else
455  ereport(ERROR,
456  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
457  errmsg("timestamp out of range")));
458  }
459  break;
460  default:
461  elog(ERROR, "unknown jsonb value datetime type oid %d", typid);
462  return NULL;
463  }
464 
465  return buf;
466 }
#define MAXDATELEN
Definition: datetime.h:201
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3855
#define DatumGetDateADT(X)
Definition: date.h:53
int tm_isdst
Definition: pgtime.h:35
#define USECS_PER_SEC
Definition: timestamp.h:94
int32 DateADT
Definition: date.h:23
int64 timestamp
int64 TimestampTz
Definition: timestamp.h:39
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1791
#define DatumGetTimeTzADTP(X)
Definition: date.h:55
void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str)
Definition: datetime.c:3940
int errcode(int sqlerrcode)
Definition: elog.c:610
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition: date.c:1281
long date
Definition: pgtypes_date.h:9
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1536
Definition: pgtime.h:25
static struct pg_tm tm
Definition: localtime.c:108
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
#define ERROR
Definition: elog.h:43
#define DATE_NOT_FINITE(j)
Definition: date.h:43
int tm_mday
Definition: pgtime.h:30
static char * buf
Definition: pg_test_fsync.c:67
int tm_mon
Definition: pgtime.h:31
#define DatumGetTimestampTz(X)
Definition: timestamp.h:28
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:3970
void EncodeSpecialDate(DateADT dt, char *str)
Definition: date.c:284
int32 fsec_t
Definition: timestamp.h:41
int64 TimeADT
Definition: date.h:25
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:294
int64 Timestamp
Definition: timestamp.h:38
#define DatumGetTimeADT(X)
Definition: date.h:54
int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp)
Definition: date.c:2154
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:144
#define USE_XSD_DATES
Definition: miscadmin.h:217
int tm_year
Definition: pgtime.h:32
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
Definition: date.h:27
#define DatumGetTimestamp(X)
Definition: timestamp.h:27

◆ row_to_json()

Datum row_to_json ( PG_FUNCTION_ARGS  )

Definition at line 696 of file json.c.

References composite_to_json(), cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, makeStringInfo(), PG_GETARG_DATUM, and PG_RETURN_TEXT_P.

697 {
698  Datum array = PG_GETARG_DATUM(0);
699  StringInfo result;
700 
701  result = makeStringInfo();
702 
703  composite_to_json(array, result, false);
704 
706 }
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition: json.c:563
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361

◆ row_to_json_pretty()

Datum row_to_json_pretty ( PG_FUNCTION_ARGS  )

Definition at line 712 of file json.c.

References composite_to_json(), cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, makeStringInfo(), PG_GETARG_BOOL, PG_GETARG_DATUM, and PG_RETURN_TEXT_P.

713 {
714  Datum array = PG_GETARG_DATUM(0);
715  bool use_line_feeds = PG_GETARG_BOOL(1);
716  StringInfo result;
717 
718  result = makeStringInfo();
719 
720  composite_to_json(array, result, use_line_feeds);
721 
723 }
static void composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
Definition: json.c:563
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361

◆ to_json()

Datum to_json ( PG_FUNCTION_ARGS  )

Definition at line 729 of file json.c.

References cstring_to_text_with_len(), StringInfoData::data, datum_to_json(), ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), InvalidOid, json_categorize_type(), StringInfoData::len, makeStringInfo(), PG_GETARG_DATUM, PG_RETURN_TEXT_P, and val.

730 {
732  Oid val_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
733  StringInfo result;
734  JsonTypeCategory tcategory;
735  Oid outfuncoid;
736 
737  if (val_type == InvalidOid)
738  ereport(ERROR,
739  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
740  errmsg("could not determine input data type")));
741 
742  json_categorize_type(val_type,
743  &tcategory, &outfuncoid);
744 
745  result = makeStringInfo();
746 
747  datum_to_json(val, false, result, tcategory, outfuncoid, false);
748 
750 }
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)
Definition: json.c:246
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
Definition: json.c:144
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1802
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
JsonTypeCategory
Definition: json.c:30
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
int errmsg(const char *fmt,...)
Definition: elog.c:824
long val
Definition: informix.c:664