PostgreSQL Source Code  git master
jsonfuncs.h File Reference
#include "common/jsonapi.h"
#include "utils/jsonb.h"
Include dependency graph for jsonfuncs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef enum JsonToIndex JsonToIndex
 
typedef void(* JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len)
 
typedef text *(* JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len)
 

Enumerations

enum  JsonToIndex {
  jtiKey = 0x01, jtiString = 0x02, jtiNumeric = 0x04, jtiBool = 0x08,
  jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool
}
 

Functions

JsonLexContextmakeJsonLexContext (text *json, bool need_escapes)
 
void pg_parse_json_or_ereport (JsonLexContext *lex, JsonSemAction *sem)
 
void json_ereport_error (JsonParseErrorType error, JsonLexContext *lex)
 
uint32 parse_jsonb_index_flags (Jsonb *jb)
 
void iterate_jsonb_values (Jsonb *jb, uint32 flags, void *state, JsonIterateStringValuesAction action)
 
void iterate_json_values (text *json, uint32 flags, void *action_state, JsonIterateStringValuesAction action)
 
Jsonbtransform_jsonb_string_values (Jsonb *jsonb, void *action_state, JsonTransformStringValuesAction transform_action)
 
texttransform_json_string_values (text *json, void *action_state, JsonTransformStringValuesAction transform_action)
 

Typedef Documentation

◆ JsonIterateStringValuesAction

typedef void(* JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len)

Definition at line 34 of file jsonfuncs.h.

◆ JsonToIndex

typedef enum JsonToIndex JsonToIndex

◆ JsonTransformStringValuesAction

typedef text*(* JsonTransformStringValuesAction) (void *state, char *elem_value, int elem_len)

Definition at line 37 of file jsonfuncs.h.

Enumeration Type Documentation

◆ JsonToIndex

Enumerator
jtiKey 
jtiString 
jtiNumeric 
jtiBool 
jtiAll 

Definition at line 24 of file jsonfuncs.h.

25 {
26  jtiKey = 0x01,
27  jtiString = 0x02,
28  jtiNumeric = 0x04,
29  jtiBool = 0x08,
31 } JsonToIndex;
JsonToIndex
Definition: jsonfuncs.h:24

Function Documentation

◆ iterate_json_values()

void iterate_json_values ( text json,
uint32  flags,
void *  action_state,
JsonIterateStringValuesAction  action 
)

Definition at line 5424 of file jsonfuncs.c.

References IterateJsonStringValuesState::action, generate_unaccent_rules::action, IterateJsonStringValuesState::action_state, IterateJsonStringValuesState::flags, iterate_values_object_field_start(), iterate_values_scalar(), OkeysState::lex, IterateJsonStringValuesState::lex, makeJsonLexContext(), JsonSemAction::object_field_start, palloc0(), pg_parse_json_or_ereport(), JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by json_to_tsvector_worker().

5426 {
5427  JsonLexContext *lex = makeJsonLexContext(json, true);
5428  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5430 
5431  state->lex = lex;
5432  state->action = action;
5433  state->action_state = action_state;
5434  state->flags = flags;
5435 
5436  sem->semstate = (void *) state;
5439 
5440  pg_parse_json_or_ereport(lex, sem);
5441 }
JsonIterateStringValuesAction action
Definition: jsonfuncs.c:65
static void iterate_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5448
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:517
json_scalar_action scalar
Definition: jsonapi.h:115
void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonfuncs.c:501
void * palloc0(Size size)
Definition: mcxt.c:1093
Definition: regguts.h:317
JsonLexContext * lex
Definition: jsonfuncs.c:64
json_ofield_action object_field_start
Definition: jsonapi.h:111
static void iterate_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:5474
void * semstate
Definition: jsonapi.h:106

◆ iterate_jsonb_values()

void iterate_jsonb_values ( Jsonb jb,
uint32  flags,
void *  state,
JsonIterateStringValuesAction  action 
)

Definition at line 5356 of file jsonfuncs.c.

References generate_unaccent_rules::action, DatumGetCString, DirectFunctionCall1, jbvBool, jbvNumeric, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), jtiBool, jtiKey, jtiNumeric, jtiString, numeric_out(), NumericGetDatum, pfree(), Jsonb::root, JsonbValue::type, generate_unaccent_rules::type, JsonbValue::val, val, WJB_DONE, WJB_ELEM, WJB_KEY, and WJB_VALUE.

Referenced by jsonb_to_tsvector_worker().

5358 {
5359  JsonbIterator *it;
5360  JsonbValue v;
5362 
5363  it = JsonbIteratorInit(&jb->root);
5364 
5365  /*
5366  * Just recursively iterating over jsonb and call callback on all
5367  * corresponding elements
5368  */
5369  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5370  {
5371  if (type == WJB_KEY)
5372  {
5373  if (flags & jtiKey)
5374  action(state, v.val.string.val, v.val.string.len);
5375 
5376  continue;
5377  }
5378  else if (!(type == WJB_VALUE || type == WJB_ELEM))
5379  {
5380  /* do not call callback for composite JsonbValue */
5381  continue;
5382  }
5383 
5384  /* JsonbValue is a value of object or element of array */
5385  switch (v.type)
5386  {
5387  case jbvString:
5388  if (flags & jtiString)
5389  action(state, v.val.string.val, v.val.string.len);
5390  break;
5391  case jbvNumeric:
5392  if (flags & jtiNumeric)
5393  {
5394  char *val;
5395 
5397  NumericGetDatum(v.val.numeric)));
5398 
5399  action(state, val, strlen(val));
5400  pfree(val);
5401  }
5402  break;
5403  case jbvBool:
5404  if (flags & jtiBool)
5405  {
5406  if (v.val.boolean)
5407  action(state, "true", 4);
5408  else
5409  action(state, "false", 5);
5410  }
5411  break;
5412  default:
5413  /* do not call callback for composite JsonbValue */
5414  break;
5415  }
5416  }
5417 }
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:61
Definition: jsonb.h:239
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:734
Definition: jsonb.h:22
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
void pfree(void *pointer)
Definition: mcxt.c:1169
#define DatumGetCString(X)
Definition: postgres.h:610
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:223
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
Definition: regguts.h:317
enum jbvType type
Definition: jsonb.h:263
long val
Definition: informix.c:664
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25

◆ json_ereport_error()

void json_ereport_error ( JsonParseErrorType  error,
JsonLexContext lex 
)

Definition at line 611 of file jsonfuncs.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, json_errdetail(), JSON_UNICODE_CODE_POINT_ZERO, JSON_UNICODE_HIGH_ESCAPE, and report_json_context().

Referenced by get_array_start(), json_typeof(), and pg_parse_json_or_ereport().

612 {
615  ereport(ERROR,
616  (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
617  errmsg("unsupported Unicode escape sequence"),
618  errdetail("%s", json_errdetail(error, lex)),
619  report_json_context(lex)));
620  else
621  ereport(ERROR,
622  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
623  errmsg("invalid input syntax for type %s", "json"),
624  errdetail("%s", json_errdetail(error, lex)),
625  report_json_context(lex)));
626 }
static void error(void)
Definition: sql-dyntest.c:147
char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
Definition: jsonapi.c:1070
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
int errdetail(const char *fmt,...)
Definition: elog.c:1042
static int report_json_context(JsonLexContext *lex)
Definition: jsonfuncs.c:639
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ makeJsonLexContext()

JsonLexContext* makeJsonLexContext ( text json,
bool  need_escapes 
)

Definition at line 517 of file jsonfuncs.c.

References GetDatabaseEncoding(), makeJsonLexContextCstringLen(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by datum_to_jsonb(), each_worker(), elements_worker(), get_worker(), iterate_json_values(), json_array_length(), json_in(), json_object_keys(), json_strip_nulls(), json_typeof(), populate_recordset_worker(), and transform_json_string_values().

518 {
520  VARSIZE_ANY_EXHDR(json),
522  need_escapes);
523 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:144
int GetDatabaseEncoding(void)
Definition: mbutils.c:1210
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

◆ parse_jsonb_index_flags()

uint32 parse_jsonb_index_flags ( Jsonb jb)

Definition at line 5288 of file jsonfuncs.c.

References elog, ereport, errcode(), errhint(), errmsg(), ERROR, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), jtiAll, jtiBool, jtiKey, jtiNumeric, jtiString, pg_strncasecmp(), pnstrdup(), Jsonb::root, JsonbValue::type, generate_unaccent_rules::type, JsonbValue::val, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, and WJB_END_ARRAY.

Referenced by json_to_tsvector(), json_to_tsvector_byid(), jsonb_to_tsvector(), and jsonb_to_tsvector_byid().

5289 {
5290  JsonbIterator *it;
5291  JsonbValue v;
5293  uint32 flags = 0;
5294 
5295  it = JsonbIteratorInit(&jb->root);
5296 
5297  type = JsonbIteratorNext(&it, &v, false);
5298 
5299  /*
5300  * We iterate over array (scalar internally is represented as array, so,
5301  * we will accept it too) to check all its elements. Flag names are
5302  * chosen the same as jsonb_typeof uses.
5303  */
5304  if (type != WJB_BEGIN_ARRAY)
5305  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5306  errmsg("wrong flag type, only arrays and scalars are allowed")));
5307 
5308  while ((type = JsonbIteratorNext(&it, &v, false)) == WJB_ELEM)
5309  {
5310  if (v.type != jbvString)
5311  ereport(ERROR,
5312  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5313  errmsg("flag array element is not a string"),
5314  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
5315 
5316  if (v.val.string.len == 3 &&
5317  pg_strncasecmp(v.val.string.val, "all", 3) == 0)
5318  flags |= jtiAll;
5319  else if (v.val.string.len == 3 &&
5320  pg_strncasecmp(v.val.string.val, "key", 3) == 0)
5321  flags |= jtiKey;
5322  else if (v.val.string.len == 6 &&
5323  pg_strncasecmp(v.val.string.val, "string", 6) == 0)
5324  flags |= jtiString;
5325  else if (v.val.string.len == 7 &&
5326  pg_strncasecmp(v.val.string.val, "numeric", 7) == 0)
5327  flags |= jtiNumeric;
5328  else if (v.val.string.len == 7 &&
5329  pg_strncasecmp(v.val.string.val, "boolean", 7) == 0)
5330  flags |= jtiBool;
5331  else
5332  ereport(ERROR,
5333  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5334  errmsg("wrong flag in flag array: \"%s\"",
5335  pnstrdup(v.val.string.val, v.val.string.len)),
5336  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
5337  }
5338 
5339  /* expect end of array now */
5340  if (type != WJB_END_ARRAY)
5341  elog(ERROR, "unexpected end of flag array");
5342 
5343  /* get final WJB_DONE and free iterator */
5344  type = JsonbIteratorNext(&it, &v, false);
5345  if (type != WJB_DONE)
5346  elog(ERROR, "unexpected end of flag array");
5347 
5348  return flags;
5349 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
int errcode(int sqlerrcode)
Definition: elog.c:698
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define ERROR
Definition: elog.h:46
unsigned int uint32
Definition: c.h:441
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:223
#define ereport(elevel,...)
Definition: elog.h:157
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25

◆ pg_parse_json_or_ereport()

void pg_parse_json_or_ereport ( JsonLexContext lex,
JsonSemAction sem 
)

Definition at line 501 of file jsonfuncs.c.

References json_ereport_error(), JSON_SUCCESS, pg_parse_json(), and OkeysState::result.

Referenced by datum_to_jsonb(), each_worker(), elements_worker(), get_json_object_as_hash(), get_worker(), iterate_json_values(), json_array_length(), json_in(), json_object_keys(), json_recv(), json_strip_nulls(), jsonb_from_cstring(), populate_array_json(), populate_recordset_worker(), and transform_json_string_values().

502 {
503  JsonParseErrorType result;
504 
505  result = pg_parse_json(lex, sem);
506  if (result != JSON_SUCCESS)
507  json_ereport_error(result, lex);
508 }
JsonParseErrorType pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonapi.c:168
JsonParseErrorType
Definition: jsonapi.h:36
void json_ereport_error(JsonParseErrorType error, JsonLexContext *lex)
Definition: jsonfuncs.c:611

◆ transform_json_string_values()

text* transform_json_string_values ( text json,
void *  action_state,
JsonTransformStringValuesAction  transform_action 
)

Definition at line 5538 of file jsonfuncs.c.

References TransformJsonStringValuesState::action, TransformJsonStringValuesState::action_state, JsonSemAction::array_element_start, JsonSemAction::array_end, JsonSemAction::array_start, cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, OkeysState::lex, TransformJsonStringValuesState::lex, makeJsonLexContext(), makeStringInfo(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, palloc0(), pg_parse_json_or_ereport(), JsonSemAction::scalar, JsonSemAction::semstate, TransformJsonStringValuesState::strval, transform_string_values_array_element_start(), transform_string_values_array_end(), transform_string_values_array_start(), transform_string_values_object_end(), transform_string_values_object_field_start(), transform_string_values_object_start(), and transform_string_values_scalar().

Referenced by ts_headline_json_byid_opt().

5540 {
5541  JsonLexContext *lex = makeJsonLexContext(json, true);
5542  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5544 
5545  state->lex = lex;
5546  state->strval = makeStringInfo();
5547  state->action = transform_action;
5548  state->action_state = action_state;
5549 
5550  sem->semstate = (void *) state;
5559 
5560  pg_parse_json_or_ereport(lex, sem);
5561 
5562  return cstring_to_text_with_len(state->strval->data, state->strval->len);
5563 }
json_struct_action array_end
Definition: jsonapi.h:110
json_struct_action object_end
Definition: jsonapi.h:108
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
json_struct_action object_start
Definition: jsonapi.h:107
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:517
static void transform_string_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:5603
json_scalar_action scalar
Definition: jsonapi.h:115
static void transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5628
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:201
static void transform_string_values_object_end(void *state)
Definition: jsonfuncs.c:5579
static void transform_string_values_array_element_start(void *state, bool isnull)
Definition: jsonfuncs.c:5619
void pg_parse_json_or_ereport(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonfuncs.c:501
void * palloc0(Size size)
Definition: mcxt.c:1093
json_aelem_action array_element_start
Definition: jsonapi.h:113
static void transform_string_values_object_start(void *state)
Definition: jsonfuncs.c:5571
json_struct_action array_start
Definition: jsonapi.h:109
Definition: regguts.h:317
static void transform_string_values_array_end(void *state)
Definition: jsonfuncs.c:5595
JsonTransformStringValuesAction action
Definition: jsonfuncs.c:77
static void transform_string_values_array_start(void *state)
Definition: jsonfuncs.c:5587
json_ofield_action object_field_start
Definition: jsonapi.h:111
void * semstate
Definition: jsonapi.h:106

◆ transform_jsonb_string_values()

Jsonb* transform_jsonb_string_values ( Jsonb jsonb,
void *  action_state,
JsonTransformStringValuesAction  transform_action 
)

Definition at line 5493 of file jsonfuncs.c.

References JsonbIterator::isScalar, jbvArray, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), JsonbValueToJsonb(), pushJsonbValue(), Jsonb::root, JsonbValue::type, generate_unaccent_rules::type, JsonbValue::val, VARDATA_ANY, VARSIZE_ANY_EXHDR, WJB_BEGIN_ARRAY, WJB_DONE, WJB_ELEM, WJB_KEY, and WJB_VALUE.

Referenced by ts_headline_jsonb_byid_opt().

5495 {
5496  JsonbIterator *it;
5497  JsonbValue v,
5498  *res = NULL;
5500  JsonbParseState *st = NULL;
5501  text *out;
5502  bool is_scalar = false;
5503 
5504  it = JsonbIteratorInit(&jsonb->root);
5505  is_scalar = it->isScalar;
5506 
5507  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5508  {
5509  if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
5510  {
5511  out = transform_action(action_state, v.val.string.val, v.val.string.len);
5512  v.val.string.val = VARDATA_ANY(out);
5513  v.val.string.len = VARSIZE_ANY_EXHDR(out);
5514  res = pushJsonbValue(&st, type, type < WJB_BEGIN_ARRAY ? &v : NULL);
5515  }
5516  else
5517  {
5518  res = pushJsonbValue(&st, type, (type == WJB_KEY ||
5519  type == WJB_VALUE ||
5520  type == WJB_ELEM) ? &v : NULL);
5521  }
5522  }
5523 
5524  if (res->type == jbvArray)
5525  res->val.array.rawScalar = is_scalar;
5526 
5527  return JsonbValueToJsonb(res);
5528 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:92
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:566
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:223
bool isScalar
Definition: jsonb.h:353
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:812
enum jbvType type
Definition: jsonb.h:263
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:848
Definition: jsonb.h:25