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.

Macros

#define pg_parse_json_or_ereport(lex, sem)    (void) pg_parse_json_or_errsave(lex, sem, NULL)
 

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)
 
bool pg_parse_json_or_errsave (JsonLexContext *lex, JsonSemAction *sem, struct Node *escontext)
 
void json_errsave_error (JsonParseErrorType error, JsonLexContext *lex, struct Node *escontext)
 
JsonTokenType json_get_first_token (text *json, bool throw_error)
 
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)
 

Macro Definition Documentation

◆ pg_parse_json_or_ereport

#define pg_parse_json_or_ereport (   lex,
  sem 
)     (void) pg_parse_json_or_errsave(lex, sem, NULL)

Definition at line 46 of file jsonfuncs.h.

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:25
@ jtiKey
Definition: jsonfuncs.h:26
@ jtiAll
Definition: jsonfuncs.h:30
@ jtiNumeric
Definition: jsonfuncs.h:28
@ jtiBool
Definition: jsonfuncs.h:29
@ jtiString
Definition: jsonfuncs.h:27

Function Documentation

◆ iterate_json_values()

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

Definition at line 5432 of file jsonfuncs.c.

5434 {
5435  JsonLexContext *lex = makeJsonLexContext(json, true);
5436  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5438 
5439  state->lex = lex;
5440  state->action = action;
5441  state->action_state = action_state;
5442  state->flags = flags;
5443 
5444  sem->semstate = (void *) state;
5447 
5448  pg_parse_json_or_ereport(lex, sem);
5449 }
static JsonParseErrorType iterate_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:5484
static JsonParseErrorType iterate_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5456
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: jsonfuncs.c:528
#define pg_parse_json_or_ereport(lex, sem)
Definition: jsonfuncs.h:46
void * palloc0(Size size)
Definition: mcxt.c:1257
json_ofield_action object_field_start
Definition: jsonapi.h:119
json_scalar_action scalar
Definition: jsonapi.h:123
void * semstate
Definition: jsonapi.h:114
Definition: regguts.h:323

References generate_unaccent_rules::action, iterate_values_object_field_start(), iterate_values_scalar(), makeJsonLexContext(), JsonSemAction::object_field_start, palloc0(), pg_parse_json_or_ereport, JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by json_to_tsvector_worker().

◆ iterate_jsonb_values()

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

Definition at line 5364 of file jsonfuncs.c.

5366 {
5367  JsonbIterator *it;
5368  JsonbValue v;
5370 
5371  it = JsonbIteratorInit(&jb->root);
5372 
5373  /*
5374  * Just recursively iterating over jsonb and call callback on all
5375  * corresponding elements
5376  */
5377  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5378  {
5379  if (type == WJB_KEY)
5380  {
5381  if (flags & jtiKey)
5382  action(state, v.val.string.val, v.val.string.len);
5383 
5384  continue;
5385  }
5386  else if (!(type == WJB_VALUE || type == WJB_ELEM))
5387  {
5388  /* do not call callback for composite JsonbValue */
5389  continue;
5390  }
5391 
5392  /* JsonbValue is a value of object or element of array */
5393  switch (v.type)
5394  {
5395  case jbvString:
5396  if (flags & jtiString)
5397  action(state, v.val.string.val, v.val.string.len);
5398  break;
5399  case jbvNumeric:
5400  if (flags & jtiNumeric)
5401  {
5402  char *val;
5403 
5405  NumericGetDatum(v.val.numeric)));
5406 
5407  action(state, val, strlen(val));
5408  pfree(val);
5409  }
5410  break;
5411  case jbvBool:
5412  if (flags & jtiBool)
5413  {
5414  if (v.val.boolean)
5415  action(state, "true", 4);
5416  else
5417  action(state, "false", 5);
5418  }
5419  break;
5420  default:
5421  /* do not call callback for composite JsonbValue */
5422  break;
5423  }
5424  }
5425 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:806
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
long val
Definition: informix.c:664
@ jbvNumeric
Definition: jsonb.h:230
@ jbvBool
Definition: jsonb.h:231
@ jbvString
Definition: jsonb.h:229
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_DONE
Definition: jsonb.h:22
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_ELEM
Definition: jsonb.h:25
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:819
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:855
void pfree(void *pointer)
Definition: mcxt.c:1456
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:72
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
enum jbvType type
Definition: jsonb.h:255
char * val
Definition: jsonb.h:264
JsonbContainer root
Definition: jsonb.h:215

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

Referenced by jsonb_to_tsvector_worker().

◆ json_errsave_error()

void json_errsave_error ( JsonParseErrorType  error,
JsonLexContext lex,
struct Node escontext 
)

Definition at line 628 of file jsonfuncs.c.

630 {
634  errsave(escontext,
635  (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
636  errmsg("unsupported Unicode escape sequence"),
638  report_json_context(lex)));
639  else if (error == JSON_SEM_ACTION_FAILED)
640  {
641  /* semantic action function had better have reported something */
642  if (!SOFT_ERROR_OCCURRED(escontext))
643  elog(ERROR, "JSON semantic action function did not provide error information");
644  }
645  else
646  errsave(escontext,
647  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
648  errmsg("invalid input syntax for type %s", "json"),
650  report_json_context(lex)));
651 }
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1229
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define errsave(context,...)
Definition: elog.h:260
#define ERROR
Definition: elog.h:39
char * json_errdetail(JsonParseErrorType error, JsonLexContext *lex)
Definition: jsonapi.c:1136
@ JSON_SEM_ACTION_FAILED
Definition: jsonapi.h:57
@ JSON_UNICODE_CODE_POINT_ZERO
Definition: jsonapi.h:51
@ JSON_UNICODE_UNTRANSLATABLE
Definition: jsonapi.h:54
@ JSON_UNICODE_HIGH_ESCAPE
Definition: jsonapi.h:53
static int report_json_context(JsonLexContext *lex)
Definition: jsonfuncs.c:664
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52
static void error(void)
Definition: sql-dyntest.c:147

References elog(), errcode(), errdetail_internal(), errmsg(), ERROR, error(), errsave, json_errdetail(), JSON_SEM_ACTION_FAILED, JSON_UNICODE_CODE_POINT_ZERO, JSON_UNICODE_HIGH_ESCAPE, JSON_UNICODE_UNTRANSLATABLE, report_json_context(), and SOFT_ERROR_OCCURRED.

Referenced by get_array_start(), json_get_first_token(), json_typeof(), json_validate(), and pg_parse_json_or_errsave().

◆ json_get_first_token()

JsonTokenType json_get_first_token ( text json,
bool  throw_error 
)

Definition at line 5670 of file jsonfuncs.c.

5671 {
5672  JsonLexContext *lex;
5673  JsonParseErrorType result;
5674 
5675  lex = makeJsonLexContext(json, false);
5676 
5677  /* Lex exactly one token from the input and check its type. */
5678  result = json_lex(lex);
5679 
5680  if (result == JSON_SUCCESS)
5681  return lex->token_type;
5682 
5683  if (throw_error)
5684  json_errsave_error(result, lex, NULL);
5685 
5686  return JSON_TOKEN_INVALID; /* invalid json */
5687 }
JsonParseErrorType json_lex(JsonLexContext *lex)
Definition: jsonapi.c:552
JsonParseErrorType
Definition: jsonapi.h:37
@ JSON_SUCCESS
Definition: jsonapi.h:38
@ JSON_TOKEN_INVALID
Definition: jsonapi.h:21
void json_errsave_error(JsonParseErrorType error, JsonLexContext *lex, Node *escontext)
Definition: jsonfuncs.c:628
JsonTokenType token_type
Definition: jsonapi.h:82

References json_errsave_error(), json_lex(), JSON_SUCCESS, JSON_TOKEN_INVALID, makeJsonLexContext(), and JsonLexContext::token_type.

Referenced by ExecEvalJsonIsPredicate().

◆ makeJsonLexContext()

JsonLexContext* makeJsonLexContext ( text json,
bool  need_escapes 
)

Definition at line 528 of file jsonfuncs.c.

529 {
530  /*
531  * Most callers pass a detoasted datum, but it's not clear that they all
532  * do. pg_detoast_datum_packed() is cheap insurance.
533  */
534  json = pg_detoast_datum_packed(json);
535 
537  VARSIZE_ANY_EXHDR(json),
539  need_escapes);
540 }
struct varlena * pg_detoast_datum_packed(struct varlena *datum)
Definition: fmgr.c:1835
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes)
Definition: jsonapi.c:145
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

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

◆ parse_jsonb_index_flags()

uint32 parse_jsonb_index_flags ( Jsonb jb)

Definition at line 5296 of file jsonfuncs.c.

5297 {
5298  JsonbIterator *it;
5299  JsonbValue v;
5301  uint32 flags = 0;
5302 
5303  it = JsonbIteratorInit(&jb->root);
5304 
5305  type = JsonbIteratorNext(&it, &v, false);
5306 
5307  /*
5308  * We iterate over array (scalar internally is represented as array, so,
5309  * we will accept it too) to check all its elements. Flag names are
5310  * chosen the same as jsonb_typeof uses.
5311  */
5312  if (type != WJB_BEGIN_ARRAY)
5313  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5314  errmsg("wrong flag type, only arrays and scalars are allowed")));
5315 
5316  while ((type = JsonbIteratorNext(&it, &v, false)) == WJB_ELEM)
5317  {
5318  if (v.type != jbvString)
5319  ereport(ERROR,
5320  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5321  errmsg("flag array element is not a string"),
5322  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
5323 
5324  if (v.val.string.len == 3 &&
5325  pg_strncasecmp(v.val.string.val, "all", 3) == 0)
5326  flags |= jtiAll;
5327  else if (v.val.string.len == 3 &&
5328  pg_strncasecmp(v.val.string.val, "key", 3) == 0)
5329  flags |= jtiKey;
5330  else if (v.val.string.len == 6 &&
5331  pg_strncasecmp(v.val.string.val, "string", 6) == 0)
5332  flags |= jtiString;
5333  else if (v.val.string.len == 7 &&
5334  pg_strncasecmp(v.val.string.val, "numeric", 7) == 0)
5335  flags |= jtiNumeric;
5336  else if (v.val.string.len == 7 &&
5337  pg_strncasecmp(v.val.string.val, "boolean", 7) == 0)
5338  flags |= jtiBool;
5339  else
5340  ereport(ERROR,
5341  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5342  errmsg("wrong flag in flag array: \"%s\"",
5343  pnstrdup(v.val.string.val, v.val.string.len)),
5344  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\".")));
5345  }
5346 
5347  /* expect end of array now */
5348  if (type != WJB_END_ARRAY)
5349  elog(ERROR, "unexpected end of flag array");
5350 
5351  /* get final WJB_DONE and free iterator */
5352  type = JsonbIteratorNext(&it, &v, false);
5353  if (type != WJB_DONE)
5354  elog(ERROR, "unexpected end of flag array");
5355 
5356  return flags;
5357 }
unsigned int uint32
Definition: c.h:490
int errhint(const char *fmt,...)
Definition: elog.c:1316
#define ereport(elevel,...)
Definition: elog.h:149
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1655
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69

References elog(), ereport, errcode(), errhint(), errmsg(), ERROR, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), jtiAll, jtiBool, jtiKey, jtiNumeric, jtiString, pg_strncasecmp(), pnstrdup(), Jsonb::root, generate_unaccent_rules::type, JsonbValue::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().

◆ pg_parse_json_or_errsave()

bool pg_parse_json_or_errsave ( JsonLexContext lex,
JsonSemAction sem,
struct Node escontext 
)

Definition at line 507 of file jsonfuncs.c.

509 {
510  JsonParseErrorType result;
511 
512  result = pg_parse_json(lex, sem);
513  if (result != JSON_SUCCESS)
514  {
515  json_errsave_error(result, lex, escontext);
516  return false;
517  }
518  return true;
519 }
JsonParseErrorType pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: jsonapi.c:169

References json_errsave_error(), JSON_SUCCESS, and pg_parse_json().

Referenced by json_in(), and jsonb_from_cstring().

◆ transform_json_string_values()

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

Definition at line 5552 of file jsonfuncs.c.

5554 {
5555  JsonLexContext *lex = makeJsonLexContext(json, true);
5556  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5558 
5559  state->lex = lex;
5560  state->strval = makeStringInfo();
5561  state->action = transform_action;
5562  state->action_state = action_state;
5563 
5564  sem->semstate = (void *) state;
5572 
5573  pg_parse_json_or_ereport(lex, sem);
5574 
5575  return cstring_to_text_with_len(state->strval->data, state->strval->len);
5576 }
static JsonParseErrorType transform_string_values_array_start(void *state)
Definition: jsonfuncs.c:5604
static JsonParseErrorType transform_string_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:5624
static JsonParseErrorType transform_string_values_array_end(void *state)
Definition: jsonfuncs.c:5614
static JsonParseErrorType transform_string_values_object_end(void *state)
Definition: jsonfuncs.c:5594
static JsonParseErrorType transform_string_values_object_start(void *state)
Definition: jsonfuncs.c:5584
static JsonParseErrorType transform_string_values_array_element_start(void *state, bool isnull)
Definition: jsonfuncs.c:5642
static JsonParseErrorType transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5653
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
json_struct_action array_end
Definition: jsonapi.h:118
json_struct_action object_start
Definition: jsonapi.h:115
json_aelem_action array_element_start
Definition: jsonapi.h:121
json_struct_action array_start
Definition: jsonapi.h:117
json_struct_action object_end
Definition: jsonapi.h:116
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:194

References JsonSemAction::array_element_start, JsonSemAction::array_end, JsonSemAction::array_start, cstring_to_text_with_len(), makeJsonLexContext(), makeStringInfo(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, palloc0(), pg_parse_json_or_ereport, JsonSemAction::scalar, JsonSemAction::semstate, 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().

◆ transform_jsonb_string_values()

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

Definition at line 5505 of file jsonfuncs.c.

5507 {
5508  JsonbIterator *it;
5509  JsonbValue v,
5510  *res = NULL;
5512  JsonbParseState *st = NULL;
5513  text *out;
5514  bool is_scalar = false;
5515 
5516  it = JsonbIteratorInit(&jsonb->root);
5517  is_scalar = it->isScalar;
5518 
5519  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5520  {
5521  if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
5522  {
5523  out = transform_action(action_state, v.val.string.val, v.val.string.len);
5524  /* out is probably not toasted, but let's be sure */
5525  out = pg_detoast_datum_packed(out);
5526  v.val.string.val = VARDATA_ANY(out);
5527  v.val.string.len = VARSIZE_ANY_EXHDR(out);
5528  res = pushJsonbValue(&st, type, type < WJB_BEGIN_ARRAY ? &v : NULL);
5529  }
5530  else
5531  {
5532  res = pushJsonbValue(&st, type, (type == WJB_KEY ||
5533  type == WJB_VALUE ||
5534  type == WJB_ELEM) ? &v : NULL);
5535  }
5536  }
5537 
5538  if (res->type == jbvArray)
5539  res->val.array.rawScalar = is_scalar;
5540 
5541  return JsonbValueToJsonb(res);
5542 }
@ jbvArray
Definition: jsonb.h:233
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:568
bool isScalar
Definition: jsonb.h:347
Definition: c.h:671

References JsonbIterator::isScalar, jbvArray, jbvString, JsonbIteratorInit(), JsonbIteratorNext(), JsonbValueToJsonb(), pg_detoast_datum_packed(), pushJsonbValue(), res, Jsonb::root, generate_unaccent_rules::type, JsonbValue::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().