PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
jsonapi.h File Reference
#include "jsonb.h"
#include "lib/stringinfo.h"
Include dependency graph for jsonapi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  JsonLexContext
 
struct  JsonSemAction
 

Typedefs

typedef struct JsonLexContext JsonLexContext
 
typedef void(* json_struct_action )(void *state)
 
typedef void(* json_ofield_action )(void *state, char *fname, bool isnull)
 
typedef void(* json_aelem_action )(void *state, bool isnull)
 
typedef void(* json_scalar_action )(void *state, char *token, JsonTokenType tokentype)
 
typedef struct JsonSemAction JsonSemAction
 
typedef void(* JsonIterateStringValuesAction )(void *state, char *elem_value, int elem_len)
 
typedef text *(* JsonTransformStringValuesAction )(void *state, char *elem_value, int elem_len)
 

Enumerations

enum  JsonTokenType {
  JSON_TOKEN_INVALID, JSON_TOKEN_STRING, JSON_TOKEN_NUMBER, JSON_TOKEN_OBJECT_START,
  JSON_TOKEN_OBJECT_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_ARRAY_END, JSON_TOKEN_COMMA,
  JSON_TOKEN_COLON, JSON_TOKEN_TRUE, JSON_TOKEN_FALSE, JSON_TOKEN_NULL,
  JSON_TOKEN_END
}
 

Functions

void pg_parse_json (JsonLexContext *lex, JsonSemAction *sem)
 
int json_count_array_elements (JsonLexContext *lex)
 
JsonLexContextmakeJsonLexContext (text *json, bool need_escapes)
 
JsonLexContextmakeJsonLexContextCstringLen (char *json, int len, bool need_escapes)
 
bool IsValidJsonNumber (const char *str, int len)
 
void iterate_jsonb_string_values (Jsonb *jb, void *state, JsonIterateStringValuesAction action)
 
void iterate_json_string_values (text *json, 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

typedef void(* json_aelem_action)(void *state, bool isnull)

Definition at line 67 of file jsonapi.h.

typedef void(* json_ofield_action)(void *state, char *fname, bool isnull)

Definition at line 66 of file jsonapi.h.

typedef void(* json_scalar_action)(void *state, char *token, JsonTokenType tokentype)

Definition at line 68 of file jsonapi.h.

typedef void(* json_struct_action)(void *state)

Definition at line 65 of file jsonapi.h.

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

Definition at line 136 of file jsonapi.h.

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

Definition at line 139 of file jsonapi.h.

Enumeration Type Documentation

Enumerator
JSON_TOKEN_INVALID 
JSON_TOKEN_STRING 
JSON_TOKEN_NUMBER 
JSON_TOKEN_OBJECT_START 
JSON_TOKEN_OBJECT_END 
JSON_TOKEN_ARRAY_START 
JSON_TOKEN_ARRAY_END 
JSON_TOKEN_COMMA 
JSON_TOKEN_COLON 
JSON_TOKEN_TRUE 
JSON_TOKEN_FALSE 
JSON_TOKEN_NULL 
JSON_TOKEN_END 

Definition at line 20 of file jsonapi.h.

Function Documentation

bool IsValidJsonNumber ( const char *  str,
int  len 
)

Definition at line 192 of file json.c.

References JsonLexContext::input, JsonLexContext::input_length, and json_lex_number().

Referenced by datum_to_json(), hstore_to_json_loose(), and hstore_to_jsonb_loose().

193 {
194  bool numeric_error;
195  int total_len;
196  JsonLexContext dummy_lex;
197 
198  if (len <= 0)
199  return false;
200 
201  /*
202  * json_lex_number expects a leading '-' to have been eaten already.
203  *
204  * having to cast away the constness of str is ugly, but there's not much
205  * easy alternative.
206  */
207  if (*str == '-')
208  {
209  dummy_lex.input = (char *) str + 1;
210  dummy_lex.input_length = len - 1;
211  }
212  else
213  {
214  dummy_lex.input = (char *) str;
215  dummy_lex.input_length = len;
216  }
217 
218  json_lex_number(&dummy_lex, dummy_lex.input, &numeric_error, &total_len);
219 
220  return (!numeric_error) && (total_len == dummy_lex.input_length);
221 }
static void json_lex_number(JsonLexContext *lex, char *s, bool *num_err, int *total_len)
Definition: json.c:1027
int input_length
Definition: jsonapi.h:54
char * input
Definition: jsonapi.h:53
void iterate_json_string_values ( text json,
void *  action_state,
JsonIterateStringValuesAction  action 
)

Definition at line 4816 of file jsonfuncs.c.

References IterateJsonStringValuesState::action, IterateJsonStringValuesState::action_state, iterate_string_values_scalar(), IterateJsonStringValuesState::lex, makeJsonLexContext(), palloc0(), pg_parse_json(), JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by json_to_tsvector_byid().

4817 {
4818  JsonLexContext *lex = makeJsonLexContext(json, true);
4819  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
4821 
4822  state->lex = lex;
4823  state->action = action;
4824  state->action_state = action_state;
4825 
4826  sem->semstate = (void *) state;
4828 
4829  pg_parse_json(lex, sem);
4830 }
JsonIterateStringValuesAction action
Definition: jsonfuncs.c:60
json_scalar_action scalar
Definition: jsonapi.h:93
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: json.c:300
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:331
void * palloc0(Size size)
Definition: mcxt.c:878
Definition: regguts.h:298
static void iterate_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:4837
JsonLexContext * lex
Definition: jsonfuncs.c:59
void * semstate
Definition: jsonapi.h:84
void iterate_jsonb_string_values ( Jsonb jb,
void *  state,
JsonIterateStringValuesAction  action 
)

Definition at line 4794 of file jsonfuncs.c.

References jbvString, JsonbIteratorInit(), JsonbIteratorNext(), Jsonb::root, JsonbValue::type, JsonbValue::val, WJB_DONE, WJB_ELEM, and WJB_VALUE.

Referenced by jsonb_to_tsvector_byid().

4795 {
4796  JsonbIterator *it;
4797  JsonbValue v;
4798  JsonbIteratorToken type;
4799 
4800  it = JsonbIteratorInit(&jb->root);
4801 
4802  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
4803  {
4804  if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
4805  {
4806  action(state, v.val.string.val, v.val.string.len);
4807  }
4808  }
4809 }
char * val
Definition: jsonb.h:259
Definition: jsonb.h:22
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:218
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
Definition: regguts.h:298
enum jbvType type
Definition: jsonb.h:250
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25
int json_count_array_elements ( JsonLexContext lex)

Definition at line 366 of file json.c.

References JSON_PARSE_ARRAY_NEXT, JSON_PARSE_ARRAY_START, JSON_TOKEN_ARRAY_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_COMMA, lex_accept(), lex_expect(), JsonLexContext::lex_level, lex_peek(), NULL, parse_array_element(), and JsonLexContext::strval.

Referenced by get_array_start().

367 {
368  JsonLexContext copylex;
369  int count;
370 
371  /*
372  * It's safe to do this with a shallow copy because the lexical routines
373  * don't scribble on the input. They do scribble on the other pointers
374  * etc, so doing this with a copy makes that safe.
375  */
376  memcpy(&copylex, lex, sizeof(JsonLexContext));
377  copylex.strval = NULL; /* not interested in values here */
378  copylex.lex_level++;
379 
380  count = 0;
382  if (lex_peek(&copylex) != JSON_TOKEN_ARRAY_END)
383  {
384  do
385  {
386  count++;
388  }
389  while (lex_accept(&copylex, JSON_TOKEN_COMMA, NULL));
390  }
392 
393  return count;
394 }
static void lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
Definition: json.c:172
static bool lex_accept(JsonLexContext *lex, JsonTokenType token, char **lexeme)
Definition: json.c:138
int lex_level
Definition: jsonapi.h:59
static void parse_array_element(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:538
StringInfo strval
Definition: jsonapi.h:62
static JsonTokenType lex_peek(JsonLexContext *lex)
Definition: json.c:123
#define NULL
Definition: c.h:229
static JsonSemAction nullSemAction
Definition: json.c:109
JsonLexContext* makeJsonLexContext ( text json,
bool  need_escapes 
)

Definition at line 300 of file json.c.

References makeJsonLexContextCstringLen(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

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

301 {
303  VARSIZE_ANY_EXHDR(json),
304  need_escapes);
305 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
Definition: json.c:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
JsonLexContext* makeJsonLexContextCstringLen ( char *  json,
int  len,
bool  need_escapes 
)

Definition at line 308 of file json.c.

References JsonLexContext::input, JsonLexContext::input_length, JsonLexContext::line_number, JsonLexContext::line_start, makeStringInfo(), palloc0(), JsonLexContext::strval, and JsonLexContext::token_terminator.

Referenced by get_json_object_as_hash(), json_recv(), jsonb_from_cstring(), makeJsonLexContext(), and populate_array_json().

309 {
310  JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
311 
312  lex->input = lex->token_terminator = lex->line_start = json;
313  lex->line_number = 1;
314  lex->input_length = len;
315  if (need_escapes)
316  lex->strval = makeStringInfo();
317  return lex;
318 }
int line_number
Definition: jsonapi.h:60
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
char * line_start
Definition: jsonapi.h:61
int input_length
Definition: jsonapi.h:54
StringInfo strval
Definition: jsonapi.h:62
void * palloc0(Size size)
Definition: mcxt.c:878
char * token_terminator
Definition: jsonapi.h:56
char * input
Definition: jsonapi.h:53
void pg_parse_json ( JsonLexContext lex,
JsonSemAction sem 
)

Definition at line 331 of file json.c.

References json_lex(), JSON_PARSE_END, JSON_TOKEN_ARRAY_START, JSON_TOKEN_END, JSON_TOKEN_OBJECT_START, lex_expect(), lex_peek(), parse_array(), parse_object(), and parse_scalar().

Referenced by datum_to_jsonb(), each_worker(), elements_worker(), get_json_object_as_hash(), get_worker(), iterate_json_string_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().

332 {
333  JsonTokenType tok;
334 
335  /* get the initial token */
336  json_lex(lex);
337 
338  tok = lex_peek(lex);
339 
340  /* parse by recursive descent */
341  switch (tok)
342  {
344  parse_object(lex, sem);
345  break;
347  parse_array(lex, sem);
348  break;
349  default:
350  parse_scalar(lex, sem); /* json can be a bare scalar */
351  }
352 
354 
355 }
static void lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
Definition: json.c:172
static void parse_array(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:569
static JsonTokenType lex_peek(JsonLexContext *lex)
Definition: json.c:123
static void json_lex(JsonLexContext *lex)
Definition: json.c:613
static void parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:406
static void parse_object(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:488
JsonTokenType
Definition: jsonapi.h:20
text* transform_json_string_values ( text json,
void *  action_state,
JsonTransformStringValuesAction  transform_action 
)

Definition at line 4895 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, TransformJsonStringValuesState::lex, makeJsonLexContext(), makeStringInfo(), JsonSemAction::object_end, JsonSemAction::object_field_start, JsonSemAction::object_start, palloc0(), pg_parse_json(), 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().

4897 {
4898  JsonLexContext *lex = makeJsonLexContext(json, true);
4899  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
4901 
4902  state->lex = lex;
4903  state->strval = makeStringInfo();
4904  state->action = transform_action;
4905  state->action_state = action_state;
4906 
4907  sem->semstate = (void *) state;
4916 
4917  pg_parse_json(lex, sem);
4918 
4919  return cstring_to_text_with_len(state->strval->data, state->strval->len);
4920 }
json_struct_action array_end
Definition: jsonapi.h:88
json_struct_action object_end
Definition: jsonapi.h:86
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
json_struct_action object_start
Definition: jsonapi.h:85
static void transform_string_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:4956
json_scalar_action scalar
Definition: jsonapi.h:93
static void transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:4981
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: json.c:300
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:331
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:161
static void transform_string_values_object_end(void *state)
Definition: jsonfuncs.c:4935
static void transform_string_values_array_element_start(void *state, bool isnull)
Definition: jsonfuncs.c:4972
void * palloc0(Size size)
Definition: mcxt.c:878
json_aelem_action array_element_start
Definition: jsonapi.h:91
static void transform_string_values_object_start(void *state)
Definition: jsonfuncs.c:4928
json_struct_action array_start
Definition: jsonapi.h:87
Definition: regguts.h:298
static void transform_string_values_array_end(void *state)
Definition: jsonfuncs.c:4949
JsonTransformStringValuesAction action
Definition: jsonfuncs.c:70
static void transform_string_values_array_start(void *state)
Definition: jsonfuncs.c:4942
json_ofield_action object_field_start
Definition: jsonapi.h:89
void * semstate
Definition: jsonapi.h:84
Jsonb* transform_jsonb_string_values ( Jsonb jsonb,
void *  action_state,
JsonTransformStringValuesAction  transform_action 
)

Definition at line 4851 of file jsonfuncs.c.

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

4853 {
4854  JsonbIterator *it;
4855  JsonbValue v, *res = NULL;
4856  JsonbIteratorToken type;
4857  JsonbParseState *st = NULL;
4858  text *out;
4859  bool is_scalar = false;
4860 
4861  it = JsonbIteratorInit(&jsonb->root);
4862  is_scalar = it->isScalar;
4863 
4864  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
4865  {
4866  if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
4867  {
4868  out = transform_action(action_state, v.val.string.val, v.val.string.len);
4869  v.val.string.val = VARDATA_ANY(out);
4870  v.val.string.len = VARSIZE_ANY_EXHDR(out);
4871  res = pushJsonbValue(&st, type, type < WJB_BEGIN_ARRAY ? &v : NULL);
4872  }
4873  else
4874  {
4875  res = pushJsonbValue(&st, type, (type == WJB_KEY ||
4876  type == WJB_VALUE ||
4877  type == WJB_ELEM) ? &v : NULL);
4878  }
4879  }
4880 
4881  if (res->type == jbvArray)
4882  res->val.array.rawScalar = is_scalar;
4883 
4884  return JsonbValueToJsonb(res);
4885 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:79
char * val
Definition: jsonb.h:259
Definition: jsonb.h:22
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:517
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:218
bool isScalar
Definition: jsonb.h:330
#define NULL
Definition: c.h:229
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
enum jbvType type
Definition: jsonb.h:250
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:439
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25