PostgreSQL Source Code  git master
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 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  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
}
 
enum  JsonToIndex {
  jtiKey = 0x01, jtiString = 0x02, jtiNumeric = 0x04, jtiBool = 0x08,
  jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool
}
 

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)
 
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)
 
char * JsonEncodeDateTime (char *buf, Datum value, Oid typid)
 

Typedef Documentation

◆ json_aelem_action

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

Definition at line 67 of file jsonapi.h.

◆ json_ofield_action

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

Definition at line 66 of file jsonapi.h.

◆ json_scalar_action

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

Definition at line 68 of file jsonapi.h.

◆ json_struct_action

typedef void(* json_struct_action) (void *state)

Definition at line 65 of file jsonapi.h.

◆ JsonIterateStringValuesAction

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

Definition at line 149 of file jsonapi.h.

◆ JsonLexContext

◆ JsonSemAction

◆ JsonToIndex

◆ JsonTransformStringValuesAction

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

Definition at line 152 of file jsonapi.h.

Enumeration Type Documentation

◆ JsonToIndex

Enumerator
jtiKey 
jtiString 
jtiNumeric 
jtiBool 
jtiAll 

Definition at line 139 of file jsonapi.h.

140 {
141  jtiKey = 0x01,
142  jtiString = 0x02,
143  jtiNumeric = 0x04,
144  jtiBool = 0x08,
146 } JsonToIndex;
JsonToIndex
Definition: jsonapi.h:139

◆ JsonTokenType

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

◆ IsValidJsonNumber()

bool IsValidJsonNumber ( const char *  str,
int  len 
)

Definition at line 193 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().

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

◆ iterate_json_values()

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

Definition at line 5088 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(), JsonSemAction::scalar, and JsonSemAction::semstate.

Referenced by json_to_tsvector_worker().

5090 {
5091  JsonLexContext *lex = makeJsonLexContext(json, true);
5092  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5094 
5095  state->lex = lex;
5096  state->action = action;
5097  state->action_state = action_state;
5098  state->flags = flags;
5099 
5100  sem->semstate = (void *) state;
5103 
5104  pg_parse_json(lex, sem);
5105 }
JsonIterateStringValuesAction action
Definition: jsonfuncs.c:60
static void iterate_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5112
json_scalar_action scalar
Definition: jsonapi.h:93
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: json.c:301
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:332
void * palloc0(Size size)
Definition: mcxt.c:955
Definition: regguts.h:298
JsonLexContext * lex
Definition: jsonfuncs.c:59
json_ofield_action object_field_start
Definition: jsonapi.h:89
static void iterate_values_object_field_start(void *state, char *fname, bool isnull)
Definition: jsonfuncs.c:5138
void * semstate
Definition: jsonapi.h:84

◆ iterate_jsonb_values()

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

Definition at line 5020 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, generate_unaccent_rules::type, JsonbValue::type, JsonbValue::val, val, WJB_DONE, WJB_ELEM, WJB_KEY, and WJB_VALUE.

Referenced by jsonb_to_tsvector_worker().

5022 {
5023  JsonbIterator *it;
5024  JsonbValue v;
5026 
5027  it = JsonbIteratorInit(&jb->root);
5028 
5029  /*
5030  * Just recursively iterating over jsonb and call callback on all
5031  * correspoding elements
5032  */
5033  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5034  {
5035  if (type == WJB_KEY)
5036  {
5037  if (flags & jtiKey)
5038  action(state, v.val.string.val, v.val.string.len);
5039 
5040  continue;
5041  }
5042  else if (!(type == WJB_VALUE || type == WJB_ELEM))
5043  {
5044  /* do not call callback for composite JsonbValue */
5045  continue;
5046  }
5047 
5048  /* JsonbValue is a value of object or element of array */
5049  switch (v.type)
5050  {
5051  case jbvString:
5052  if (flags & jtiString)
5053  action(state, v.val.string.val, v.val.string.len);
5054  break;
5055  case jbvNumeric:
5056  if (flags & jtiNumeric)
5057  {
5058  char *val;
5059 
5061  NumericGetDatum(v.val.numeric)));
5062 
5063  action(state, val, strlen(val));
5064  pfree(val);
5065  }
5066  break;
5067  case jbvBool:
5068  if (flags & jtiBool)
5069  {
5070  if (v.val.boolean)
5071  action(state, "true", 4);
5072  else
5073  action(state, "false", 5);
5074  }
5075  break;
5076  default:
5077  /* do not call callback for composite JsonbValue */
5078  break;
5079  }
5080  }
5081 }
char * val
Definition: jsonb.h:259
#define NumericGetDatum(X)
Definition: numeric.h:51
Definition: jsonb.h:234
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:652
Definition: jsonb.h:22
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:590
void pfree(void *pointer)
Definition: mcxt.c:1031
#define DatumGetCString(X)
Definition: postgres.h:551
Definition: jsonb.h:23
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
long val
Definition: informix.c:689
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25

◆ json_count_array_elements()

int json_count_array_elements ( JsonLexContext lex)

Definition at line 367 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(), parse_array_element(), and JsonLexContext::strval.

Referenced by get_array_start().

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

◆ JsonEncodeDateTime()

char* JsonEncodeDateTime ( char *  buf,
Datum  value,
Oid  typid 
)

Definition at line 1556 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_mday, pg_tm::tm_mon, pg_tm::tm_year, and USE_XSD_DATES.

Referenced by datum_to_json(), and datum_to_jsonb().

1557 {
1558  if (!buf)
1559  buf = palloc(MAXDATELEN + 1);
1560 
1561  switch (typid)
1562  {
1563  case DATEOID:
1564  {
1565  DateADT date;
1566  struct pg_tm tm;
1567 
1568  date = DatumGetDateADT(value);
1569 
1570  /* Same as date_out(), but forcing DateStyle */
1571  if (DATE_NOT_FINITE(date))
1572  EncodeSpecialDate(date, buf);
1573  else
1574  {
1576  &(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
1578  }
1579  }
1580  break;
1581  case TIMEOID:
1582  {
1583  TimeADT time = DatumGetTimeADT(value);
1584  struct pg_tm tt,
1585  *tm = &tt;
1586  fsec_t fsec;
1587 
1588  /* Same as time_out(), but forcing DateStyle */
1589  time2tm(time, tm, &fsec);
1590  EncodeTimeOnly(tm, fsec, false, 0, USE_XSD_DATES, buf);
1591  }
1592  break;
1593  case TIMETZOID:
1594  {
1596  struct pg_tm tt,
1597  *tm = &tt;
1598  fsec_t fsec;
1599  int tz;
1600 
1601  /* Same as timetz_out(), but forcing DateStyle */
1602  timetz2tm(time, tm, &fsec, &tz);
1603  EncodeTimeOnly(tm, fsec, true, tz, USE_XSD_DATES, buf);
1604  }
1605  break;
1606  case TIMESTAMPOID:
1607  {
1609  struct pg_tm tm;
1610  fsec_t fsec;
1611 
1612  timestamp = DatumGetTimestamp(value);
1613  /* Same as timestamp_out(), but forcing DateStyle */
1614  if (TIMESTAMP_NOT_FINITE(timestamp))
1615  EncodeSpecialTimestamp(timestamp, buf);
1616  else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
1617  EncodeDateTime(&tm, fsec, false, 0, NULL, USE_XSD_DATES, buf);
1618  else
1619  ereport(ERROR,
1620  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1621  errmsg("timestamp out of range")));
1622  }
1623  break;
1624  case TIMESTAMPTZOID:
1625  {
1627  struct pg_tm tm;
1628  int tz;
1629  fsec_t fsec;
1630  const char *tzn = NULL;
1631 
1632  timestamp = DatumGetTimestampTz(value);
1633  /* Same as timestamptz_out(), but forcing DateStyle */
1634  if (TIMESTAMP_NOT_FINITE(timestamp))
1635  EncodeSpecialTimestamp(timestamp, buf);
1636  else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
1637  EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf);
1638  else
1639  ereport(ERROR,
1640  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1641  errmsg("timestamp out of range")));
1642  }
1643  break;
1644  default:
1645  elog(ERROR, "unknown jsonb value datetime type oid %d", typid);
1646  return NULL;
1647  }
1648 
1649  return buf;
1650 }
#define MAXDATELEN
Definition: datetime.h:203
void EncodeDateOnly(struct pg_tm *tm, int style, char *str)
Definition: datetime.c:3873
#define DatumGetDateADT(X)
Definition: date.h:53
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:1758
#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:3958
int errcode(int sqlerrcode)
Definition: elog.c:575
int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec)
Definition: date.c:1279
long date
Definition: pgtypes_date.h:9
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1523
Definition: pgtime.h:25
static struct pg_tm tm
Definition: localtime.c:106
#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:3988
void EncodeSpecialDate(DateADT dt, char *str)
Definition: date.c:297
int32 fsec_t
Definition: timestamp.h:41
int64 TimeADT
Definition: date.h:25
#define ereport(elevel, rest)
Definition: elog.h:122
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:301
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:2142
static struct @131 value
#define USE_XSD_DATES
Definition: miscadmin.h:215
int tm_year
Definition: pgtime.h:32
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
#define elog
Definition: elog.h:219
Definition: date.h:27
#define DatumGetTimestamp(X)
Definition: timestamp.h:27

◆ makeJsonLexContext()

JsonLexContext* makeJsonLexContext ( text json,
bool  need_escapes 
)

Definition at line 301 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_values(), json_array_length(), json_in(), json_object_keys(), json_strip_nulls(), json_typeof(), populate_recordset_worker(), and transform_json_string_values().

302 {
304  VARSIZE_ANY_EXHDR(json),
305  need_escapes);
306 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
JsonLexContext * makeJsonLexContextCstringLen(char *json, int len, bool need_escapes)
Definition: json.c:309
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ makeJsonLexContextCstringLen()

JsonLexContext* makeJsonLexContextCstringLen ( char *  json,
int  len,
bool  need_escapes 
)

Definition at line 309 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().

310 {
311  JsonLexContext *lex = palloc0(sizeof(JsonLexContext));
312 
313  lex->input = lex->token_terminator = lex->line_start = json;
314  lex->line_number = 1;
315  lex->input_length = len;
316  if (need_escapes)
317  lex->strval = makeStringInfo();
318  return lex;
319 }
int line_number
Definition: jsonapi.h:60
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
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:955
char * token_terminator
Definition: jsonapi.h:56
char * input
Definition: jsonapi.h:53

◆ parse_jsonb_index_flags()

uint32 parse_jsonb_index_flags ( Jsonb jb)

Definition at line 4952 of file jsonfuncs.c.

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

4953 {
4954  JsonbIterator *it;
4955  JsonbValue v;
4957  uint32 flags = 0;
4958 
4959  it = JsonbIteratorInit(&jb->root);
4960 
4961  type = JsonbIteratorNext(&it, &v, false);
4962 
4963  /*
4964  * We iterate over array (scalar internally is represented as array, so,
4965  * we will accept it too) to check all its elements. Flag names are
4966  * chosen the same as jsonb_typeof uses.
4967  */
4968  if (type != WJB_BEGIN_ARRAY)
4969  ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4970  errmsg("wrong flag type, only arrays and scalars are allowed")));
4971 
4972  while ((type = JsonbIteratorNext(&it, &v, false)) == WJB_ELEM)
4973  {
4974  if (v.type != jbvString)
4975  ereport(ERROR,
4976  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4977  errmsg("flag array element is not a string"),
4978  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"")));
4979 
4980  if (v.val.string.len == 3 &&
4981  pg_strncasecmp(v.val.string.val, "all", 3) == 0)
4982  flags |= jtiAll;
4983  else if (v.val.string.len == 3 &&
4984  pg_strncasecmp(v.val.string.val, "key", 3) == 0)
4985  flags |= jtiKey;
4986  else if (v.val.string.len == 6 &&
4987  pg_strncasecmp(v.val.string.val, "string", 5) == 0)
4988  flags |= jtiString;
4989  else if (v.val.string.len == 7 &&
4990  pg_strncasecmp(v.val.string.val, "numeric", 7) == 0)
4991  flags |= jtiNumeric;
4992  else if (v.val.string.len == 7 &&
4993  pg_strncasecmp(v.val.string.val, "boolean", 7) == 0)
4994  flags |= jtiBool;
4995  else
4996  ereport(ERROR,
4997  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4998  errmsg("wrong flag in flag array: \"%s\"",
4999  pnstrdup(v.val.string.val, v.val.string.len)),
5000  errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"")));
5001  }
5002 
5003  /* expect end of array now */
5004  if (type != WJB_END_ARRAY)
5005  elog(ERROR, "unexpected end of flag array");
5006 
5007  /* get final WJB_DONE and free iterator */
5008  type = JsonbIteratorNext(&it, &v, false);
5009  if (type != WJB_DONE)
5010  elog(ERROR, "unexpected end of flag array");
5011 
5012  return flags;
5013 }
int errhint(const char *fmt,...)
Definition: elog.c:987
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1172
char * val
Definition: jsonb.h:259
Definition: jsonb.h:22
int errcode(int sqlerrcode)
Definition: elog.c:575
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define ERROR
Definition: elog.h:43
unsigned int uint32
Definition: c.h:325
#define ereport(elevel, rest)
Definition: elog.h:122
JsonbIteratorToken
Definition: jsonb.h:20
JsonbContainer root
Definition: jsonb.h:218
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
enum jbvType type
Definition: jsonb.h:250
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25

◆ pg_parse_json()

void pg_parse_json ( JsonLexContext lex,
JsonSemAction sem 
)

Definition at line 332 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_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().

333 {
334  JsonTokenType tok;
335 
336  /* get the initial token */
337  json_lex(lex);
338 
339  tok = lex_peek(lex);
340 
341  /* parse by recursive descent */
342  switch (tok)
343  {
345  parse_object(lex, sem);
346  break;
348  parse_array(lex, sem);
349  break;
350  default:
351  parse_scalar(lex, sem); /* json can be a bare scalar */
352  }
353 
355 
356 }
static void lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token)
Definition: json.c:173
static void parse_array(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:570
static JsonTokenType lex_peek(JsonLexContext *lex)
Definition: json.c:124
static void json_lex(JsonLexContext *lex)
Definition: json.c:614
static void parse_scalar(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:407
static void parse_object(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:489
JsonTokenType
Definition: jsonapi.h:20

◆ transform_json_string_values()

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

Definition at line 5202 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(), 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().

5204 {
5205  JsonLexContext *lex = makeJsonLexContext(json, true);
5206  JsonSemAction *sem = palloc0(sizeof(JsonSemAction));
5208 
5209  state->lex = lex;
5210  state->strval = makeStringInfo();
5211  state->action = transform_action;
5212  state->action_state = action_state;
5213 
5214  sem->semstate = (void *) state;
5223 
5224  pg_parse_json(lex, sem);
5225 
5226  return cstring_to_text_with_len(state->strval->data, state->strval->len);
5227 }
json_struct_action array_end
Definition: jsonapi.h:88
json_struct_action object_end
Definition: jsonapi.h:86
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
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:5267
json_scalar_action scalar
Definition: jsonapi.h:93
static void transform_string_values_scalar(void *state, char *token, JsonTokenType tokentype)
Definition: jsonfuncs.c:5292
JsonLexContext * makeJsonLexContext(text *json, bool need_escapes)
Definition: json.c:301
void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem)
Definition: json.c:332
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:5243
static void transform_string_values_array_element_start(void *state, bool isnull)
Definition: jsonfuncs.c:5283
void * palloc0(Size size)
Definition: mcxt.c:955
json_aelem_action array_element_start
Definition: jsonapi.h:91
static void transform_string_values_object_start(void *state)
Definition: jsonfuncs.c:5235
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:5259
JsonTransformStringValuesAction action
Definition: jsonfuncs.c:72
static void transform_string_values_array_start(void *state)
Definition: jsonfuncs.c:5251
json_ofield_action object_field_start
Definition: jsonapi.h:89
void * semstate
Definition: jsonapi.h:84

◆ transform_jsonb_string_values()

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

Definition at line 5157 of file jsonfuncs.c.

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

5159 {
5160  JsonbIterator *it;
5161  JsonbValue v,
5162  *res = NULL;
5164  JsonbParseState *st = NULL;
5165  text *out;
5166  bool is_scalar = false;
5167 
5168  it = JsonbIteratorInit(&jsonb->root);
5169  is_scalar = it->isScalar;
5170 
5171  while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)
5172  {
5173  if ((type == WJB_VALUE || type == WJB_ELEM) && v.type == jbvString)
5174  {
5175  out = transform_action(action_state, v.val.string.val, v.val.string.len);
5176  v.val.string.val = VARDATA_ANY(out);
5177  v.val.string.len = VARSIZE_ANY_EXHDR(out);
5178  res = pushJsonbValue(&st, type, type < WJB_BEGIN_ARRAY ? &v : NULL);
5179  }
5180  else
5181  {
5182  res = pushJsonbValue(&st, type, (type == WJB_KEY ||
5183  type == WJB_VALUE ||
5184  type == WJB_ELEM) ? &v : NULL);
5185  }
5186  }
5187 
5188  if (res->type == jbvArray)
5189  res->val.array.rawScalar = is_scalar;
5190 
5191  return JsonbValueToJsonb(res);
5192 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
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
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:718
enum jbvType type
Definition: jsonb.h:250
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:516
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:754
Definition: jsonb.h:25