PostgreSQL Source Code  git master
jsonpath.c File Reference
#include "postgres.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/json.h"
#include "utils/jsonpath.h"
Include dependency graph for jsonpath.c:

Go to the source code of this file.

Macros

#define read_byte(v, b, p)
 
#define read_int32(v, b, p)
 
#define read_int32_n(v, b, p, n)
 

Functions

static Datum jsonPathFromCstring (char *in, int len)
 
static char * jsonPathToCstring (StringInfo out, JsonPath *in, int estimated_len)
 
static int flattenJsonPathParseItem (StringInfo buf, JsonPathParseItem *item, int nestingLevel, bool insideArraySubscript)
 
static void alignStringInfoInt (StringInfo buf)
 
static int32 reserveSpaceForItemPointer (StringInfo buf)
 
static void printJsonPathItem (StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
 
static int operationPriority (JsonPathItemType op)
 
Datum jsonpath_in (PG_FUNCTION_ARGS)
 
Datum jsonpath_recv (PG_FUNCTION_ARGS)
 
Datum jsonpath_out (PG_FUNCTION_ARGS)
 
Datum jsonpath_send (PG_FUNCTION_ARGS)
 
const char * jspOperationName (JsonPathItemType type)
 
void jspInit (JsonPathItem *v, JsonPath *js)
 
void jspInitByBuffer (JsonPathItem *v, char *base, int32 pos)
 
void jspGetArg (JsonPathItem *v, JsonPathItem *a)
 
bool jspGetNext (JsonPathItem *v, JsonPathItem *a)
 
void jspGetLeftArg (JsonPathItem *v, JsonPathItem *a)
 
void jspGetRightArg (JsonPathItem *v, JsonPathItem *a)
 
bool jspGetBool (JsonPathItem *v)
 
Numeric jspGetNumeric (JsonPathItem *v)
 
char * jspGetString (JsonPathItem *v, int32 *len)
 
bool jspGetArraySubscript (JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
 

Macro Definition Documentation

◆ read_byte

#define read_byte (   v,
  b,
 
)
Value:
do { \
(v) = *(uint8*)((b) + (p)); \
(p) += 1; \
} while(0) \
unsigned char uint8
Definition: c.h:356

Definition at line 801 of file jsonpath.c.

Referenced by jspInitByBuffer().

◆ read_int32

#define read_int32 (   v,
  b,
 
)
Value:
do { \
(v) = *(uint32*)((b) + (p)); \
(p) += sizeof(int32); \
} while(0) \
signed int int32
Definition: c.h:346
unsigned int uint32
Definition: c.h:358

Definition at line 806 of file jsonpath.c.

Referenced by jspInitByBuffer().

◆ read_int32_n

#define read_int32_n (   v,
  b,
  p,
 
)
Value:
do { \
(v) = (void *)((b) + (p)); \
(p) += sizeof(int32) * (n); \
} while(0) \
signed int int32
Definition: c.h:346

Definition at line 811 of file jsonpath.c.

Referenced by jspInitByBuffer().

Function Documentation

◆ alignStringInfoInt()

static void alignStringInfoInt ( StringInfo  buf)
static

Definition at line 437 of file jsonpath.c.

References appendStringInfoCharMacro, INTALIGN, and StringInfoData::len.

Referenced by flattenJsonPathParseItem().

438 {
439  switch (INTALIGN(buf->len) - buf->len)
440  {
441  case 3:
443  /* FALLTHROUGH */
444  case 2:
446  /* FALLTHROUGH */
447  case 1:
449  /* FALLTHROUGH */
450  default:
451  break;
452  }
453 }
#define INTALIGN(LEN)
Definition: c.h:682
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:127

◆ flattenJsonPathParseItem()

static int flattenJsonPathParseItem ( StringInfo  buf,
JsonPathParseItem item,
int  nestingLevel,
bool  insideArraySubscript 
)
static

Definition at line 229 of file jsonpath.c.

References alignStringInfoInt(), JsonPathParseItem::anybounds, appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoSpaces(), arg, JsonPathParseItem::arg, JsonPathParseItem::args, JsonPathParseItem::array, JsonPathParseItem::boolean, CHECK_FOR_INTERRUPTS, check_stack_depth(), StringInfoData::data, elog, ereport, errcode(), errmsg(), ERROR, i, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, JSONPATH_HDRSZ, StringInfoData::len, JsonPathParseItem::like_regex, JsonPathParseItem::next, next, JsonPathParseItem::numeric, reserveSpaceForItemPointer(), JsonPathParseItem::string, JsonPathParseItem::type, JsonPathParseItem::value, and VARSIZE.

Referenced by jsonPathFromCstring().

231 {
232  /* position from beginning of jsonpath data */
233  int32 pos = buf->len - JSONPATH_HDRSZ;
234  int32 chld;
235  int32 next;
236  int argNestingLevel = 0;
237 
240 
241  appendStringInfoChar(buf, (char) (item->type));
242 
243  /*
244  * We align buffer to int32 because a series of int32 values often goes
245  * after the header, and we want to read them directly by dereferencing
246  * int32 pointer (see jspInitByBuffer()).
247  */
248  alignStringInfoInt(buf);
249 
250  /*
251  * Reserve space for next item pointer. Actual value will be recorded
252  * later, after next and children items processing.
253  */
254  next = reserveSpaceForItemPointer(buf);
255 
256  switch (item->type)
257  {
258  case jpiString:
259  case jpiVariable:
260  case jpiKey:
261  appendBinaryStringInfo(buf, (char *) &item->value.string.len,
262  sizeof(item->value.string.len));
263  appendBinaryStringInfo(buf, item->value.string.val,
264  item->value.string.len);
265  appendStringInfoChar(buf, '\0');
266  break;
267  case jpiNumeric:
268  appendBinaryStringInfo(buf, (char *) item->value.numeric,
269  VARSIZE(item->value.numeric));
270  break;
271  case jpiBool:
272  appendBinaryStringInfo(buf, (char *) &item->value.boolean,
273  sizeof(item->value.boolean));
274  break;
275  case jpiAnd:
276  case jpiOr:
277  case jpiEqual:
278  case jpiNotEqual:
279  case jpiLess:
280  case jpiGreater:
281  case jpiLessOrEqual:
282  case jpiGreaterOrEqual:
283  case jpiAdd:
284  case jpiSub:
285  case jpiMul:
286  case jpiDiv:
287  case jpiMod:
288  case jpiStartsWith:
289  {
290  /*
291  * First, reserve place for left/right arg's positions, then
292  * record both args and sets actual position in reserved
293  * places.
294  */
295  int32 left = reserveSpaceForItemPointer(buf);
296  int32 right = reserveSpaceForItemPointer(buf);
297 
298  chld = !item->value.args.left ? pos :
299  flattenJsonPathParseItem(buf, item->value.args.left,
300  nestingLevel + argNestingLevel,
301  insideArraySubscript);
302  *(int32 *) (buf->data + left) = chld - pos;
303 
304  chld = !item->value.args.right ? pos :
305  flattenJsonPathParseItem(buf, item->value.args.right,
306  nestingLevel + argNestingLevel,
307  insideArraySubscript);
308  *(int32 *) (buf->data + right) = chld - pos;
309  }
310  break;
311  case jpiLikeRegex:
312  {
313  int32 offs;
314 
316  (char *) &item->value.like_regex.flags,
317  sizeof(item->value.like_regex.flags));
318  offs = reserveSpaceForItemPointer(buf);
320  (char *) &item->value.like_regex.patternlen,
321  sizeof(item->value.like_regex.patternlen));
322  appendBinaryStringInfo(buf, item->value.like_regex.pattern,
323  item->value.like_regex.patternlen);
324  appendStringInfoChar(buf, '\0');
325 
326  chld = flattenJsonPathParseItem(buf, item->value.like_regex.expr,
327  nestingLevel,
328  insideArraySubscript);
329  *(int32 *) (buf->data + offs) = chld - pos;
330  }
331  break;
332  case jpiFilter:
333  argNestingLevel++;
334  /* FALLTHROUGH */
335  case jpiIsUnknown:
336  case jpiNot:
337  case jpiPlus:
338  case jpiMinus:
339  case jpiExists:
340  {
342 
343  chld = flattenJsonPathParseItem(buf, item->value.arg,
344  nestingLevel + argNestingLevel,
345  insideArraySubscript);
346  *(int32 *) (buf->data + arg) = chld - pos;
347  }
348  break;
349  case jpiNull:
350  break;
351  case jpiRoot:
352  break;
353  case jpiAnyArray:
354  case jpiAnyKey:
355  break;
356  case jpiCurrent:
357  if (nestingLevel <= 0)
358  ereport(ERROR,
359  (errcode(ERRCODE_SYNTAX_ERROR),
360  errmsg("@ is not allowed in root expressions")));
361  break;
362  case jpiLast:
363  if (!insideArraySubscript)
364  ereport(ERROR,
365  (errcode(ERRCODE_SYNTAX_ERROR),
366  errmsg("LAST is allowed only in array subscripts")));
367  break;
368  case jpiIndexArray:
369  {
370  int32 nelems = item->value.array.nelems;
371  int offset;
372  int i;
373 
374  appendBinaryStringInfo(buf, (char *) &nelems, sizeof(nelems));
375 
376  offset = buf->len;
377 
378  appendStringInfoSpaces(buf, sizeof(int32) * 2 * nelems);
379 
380  for (i = 0; i < nelems; i++)
381  {
382  int32 *ppos;
383  int32 topos;
384  int32 frompos =
386  item->value.array.elems[i].from,
387  nestingLevel, true) - pos;
388 
389  if (item->value.array.elems[i].to)
390  topos = flattenJsonPathParseItem(buf,
391  item->value.array.elems[i].to,
392  nestingLevel, true) - pos;
393  else
394  topos = 0;
395 
396  ppos = (int32 *) &buf->data[offset + i * 2 * sizeof(int32)];
397 
398  ppos[0] = frompos;
399  ppos[1] = topos;
400  }
401  }
402  break;
403  case jpiAny:
405  (char *) &item->value.anybounds.first,
406  sizeof(item->value.anybounds.first));
408  (char *) &item->value.anybounds.last,
409  sizeof(item->value.anybounds.last));
410  break;
411  case jpiType:
412  case jpiSize:
413  case jpiAbs:
414  case jpiFloor:
415  case jpiCeiling:
416  case jpiDouble:
417  case jpiKeyValue:
418  break;
419  default:
420  elog(ERROR, "unrecognized jsonpath item type: %d", item->type);
421  }
422 
423  if (item->next)
424  {
425  chld = flattenJsonPathParseItem(buf, item->next, nestingLevel,
426  insideArraySubscript) - pos;
427  *(int32 *) (buf->data + next) = chld;
428  }
429 
430  return pos;
431 }
struct JsonPathParseItem::@136::@137 args
struct JsonPathParseItem::@136::@141 string
static int32 next
Definition: blutils.c:213
Definition: jsonpath.h:50
#define VARSIZE(PTR)
Definition: postgres.h:303
JsonPathParseItem * arg
Definition: jsonpath.h:201
int errcode(int sqlerrcode)
Definition: elog.c:570
JsonPathParseItem * next
Definition: jsonpath.h:188
signed int int32
Definition: c.h:346
#define ERROR
Definition: elog.h:43
static void alignStringInfoInt(StringInfo buf)
Definition: jsonpath.c:437
struct JsonPathParseItem::@136::@139 anybounds
void check_stack_depth(void)
Definition: postgres.c:3262
struct JsonPathParseItem::@136::@138 array
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
union JsonPathParseItem::@136 value
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:193
JsonPathItemType type
Definition: jsonpath.h:187
Numeric numeric
Definition: jsonpath.h:230
#define JSONPATH_HDRSZ
Definition: jsonpath.h:30
static int flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item, int nestingLevel, bool insideArraySubscript)
Definition: jsonpath.c:229
static int32 reserveSpaceForItemPointer(StringInfo buf)
Definition: jsonpath.c:460
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
void * arg
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
struct JsonPathParseItem::@136::@140 like_regex
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ jsonpath_in()

Datum jsonpath_in ( PG_FUNCTION_ARGS  )

Definition at line 93 of file jsonpath.c.

References jsonPathFromCstring(), and PG_GETARG_CSTRING.

94 {
95  char *in = PG_GETARG_CSTRING(0);
96  int len = strlen(in);
97 
98  return jsonPathFromCstring(in, len);
99 }
static Datum jsonPathFromCstring(char *in, int len)
Definition: jsonpath.c:168
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272

◆ jsonpath_out()

Datum jsonpath_out ( PG_FUNCTION_ARGS  )

Definition at line 129 of file jsonpath.c.

References jsonPathToCstring(), PG_GETARG_JSONPATH_P, PG_RETURN_CSTRING, and VARSIZE.

130 {
132 
134 }
#define VARSIZE(PTR)
Definition: postgres.h:303
static char * jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
Definition: jsonpath.c:203
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352

◆ jsonpath_recv()

Datum jsonpath_recv ( PG_FUNCTION_ARGS  )

Definition at line 110 of file jsonpath.c.

References buf, StringInfoData::cursor, elog, ERROR, JSONPATH_VERSION, jsonPathFromCstring(), StringInfoData::len, PG_GETARG_POINTER, pq_getmsgint(), pq_getmsgtext(), and generate_unaccent_rules::str.

111 {
113  int version = pq_getmsgint(buf, 1);
114  char *str;
115  int nbytes;
116 
117  if (version == JSONPATH_VERSION)
118  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
119  else
120  elog(ERROR, "unsupported jsonpath version number: %d", version);
121 
122  return jsonPathFromCstring(str, nbytes);
123 }
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:68
#define JSONPATH_VERSION
Definition: jsonpath.h:28
static Datum jsonPathFromCstring(char *in, int len)
Definition: jsonpath.c:168
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:548
#define elog(elevel,...)
Definition: elog.h:226
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417

◆ jsonpath_send()

Datum jsonpath_send ( PG_FUNCTION_ARGS  )

Definition at line 142 of file jsonpath.c.

References buf, StringInfoData::data, initStringInfo(), JSONPATH_VERSION, jsonPathToCstring(), StringInfoData::len, pfree(), PG_GETARG_JSONPATH_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint8(), pq_sendtext(), and VARSIZE.

143 {
146  StringInfoData jtext;
147  int version = JSONPATH_VERSION;
148 
149  initStringInfo(&jtext);
150  (void) jsonPathToCstring(&jtext, in, VARSIZE(in));
151 
152  pq_begintypsend(&buf);
153  pq_sendint8(&buf, version);
154  pq_sendtext(&buf, jtext.data, jtext.len);
155  pfree(jtext.data);
156 
158 }
#define VARSIZE(PTR)
Definition: postgres.h:303
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:174
static char * jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
Definition: jsonpath.c:203
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
void pfree(void *pointer)
Definition: mcxt.c:1031
static char * buf
Definition: pg_test_fsync.c:68
#define JSONPATH_VERSION
Definition: jsonpath.h:28
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:129

◆ jsonPathFromCstring()

static Datum jsonPathFromCstring ( char *  in,
int  len 
)
static

Definition at line 168 of file jsonpath.c.

References appendStringInfoSpaces(), buf, StringInfoData::data, enlargeStringInfo(), ereport, errcode(), errmsg(), ERROR, JsonPathParseResult::expr, flattenJsonPathParseItem(), JsonPath::header, initStringInfo(), JSONPATH_HDRSZ, JSONPATH_LAX, JSONPATH_VERSION, JsonPathParseResult::lax, StringInfoData::len, parsejsonpath(), PG_RETURN_JSONPATH_P, and SET_VARSIZE.

Referenced by jsonpath_in(), and jsonpath_recv().

169 {
170  JsonPathParseResult *jsonpath = parsejsonpath(in, len);
171  JsonPath *res;
173 
174  initStringInfo(&buf);
175  enlargeStringInfo(&buf, 4 * len /* estimation */ );
176 
178 
179  if (!jsonpath)
180  ereport(ERROR,
181  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
182  errmsg("invalid input syntax for type %s: \"%s\"", "jsonpath",
183  in)));
184 
185  flattenJsonPathParseItem(&buf, jsonpath->expr, 0, false);
186 
187  res = (JsonPath *) buf.data;
188  SET_VARSIZE(res, buf.len);
189  res->header = JSONPATH_VERSION;
190  if (jsonpath->lax)
191  res->header |= JSONPATH_LAX;
192 
194 }
JsonPathParseResult * parsejsonpath(const char *str, int len)
int errcode(int sqlerrcode)
Definition: elog.c:570
#define JSONPATH_LAX
Definition: jsonpath.h:29
JsonPathParseItem * expr
Definition: jsonpath.h:242
#define PG_RETURN_JSONPATH_P(p)
Definition: jsonpath.h:36
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:68
#define JSONPATH_VERSION
Definition: jsonpath.h:28
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:270
#define ereport(elevel, rest)
Definition: elog.h:141
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:193
#define JSONPATH_HDRSZ
Definition: jsonpath.h:30
static int flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item, int nestingLevel, bool insideArraySubscript)
Definition: jsonpath.c:229
int errmsg(const char *fmt,...)
Definition: elog.c:784
uint32 header
Definition: jsonpath.h:24
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ jsonPathToCstring()

static char * jsonPathToCstring ( StringInfo  out,
JsonPath in,
int  estimated_len 
)
static

Definition at line 203 of file jsonpath.c.

References appendBinaryStringInfo(), buf, StringInfoData::data, enlargeStringInfo(), JsonPath::header, initStringInfo(), JSONPATH_LAX, jspInit(), and printJsonPathItem().

Referenced by jsonpath_out(), and jsonpath_send().

204 {
206  JsonPathItem v;
207 
208  if (!out)
209  {
210  out = &buf;
211  initStringInfo(out);
212  }
213  enlargeStringInfo(out, estimated_len);
214 
215  if (!(in->header & JSONPATH_LAX))
216  appendBinaryStringInfo(out, "strict ", 7);
217 
218  jspInit(&v, in);
219  printJsonPathItem(out, &v, false, true);
220 
221  return out->data;
222 }
#define JSONPATH_LAX
Definition: jsonpath.h:29
static char * buf
Definition: pg_test_fsync.c:68
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:270
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:820
uint32 header
Definition: jsonpath.h:24
static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
Definition: jsonpath.c:474
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ jspGetArg()

void jspGetArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 909 of file jsonpath.c.

References JsonPathItem::arg, Assert, JsonPathItem::base, JsonPathItem::content, jpiExists, jpiFilter, jpiIsUnknown, jpiMinus, jpiNot, jpiPlus, jspInitByBuffer(), and JsonPathItem::type.

Referenced by executeBoolItem(), executeItemOptUnwrapTarget(), executeUnaryArithmExpr(), extract_jsp_bool_expr(), extract_jsp_path_expr_nodes(), and printJsonPathItem().

910 {
911  Assert(v->type == jpiFilter ||
912  v->type == jpiNot ||
913  v->type == jpiIsUnknown ||
914  v->type == jpiExists ||
915  v->type == jpiPlus ||
916  v->type == jpiMinus);
917 
918  jspInitByBuffer(a, v->base, v->content.arg);
919 }
char * base
Definition: jsonpath.h:115
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
int32 arg
Definition: jsonpath.h:127
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106

◆ jspGetArraySubscript()

bool jspGetArraySubscript ( JsonPathItem v,
JsonPathItem from,
JsonPathItem to,
int  i 
)

Definition at line 1046 of file jsonpath.c.

References JsonPathItem::array, Assert, JsonPathItem::base, JsonPathItem::content, jpiIndexArray, jspInitByBuffer(), and JsonPathItem::type.

Referenced by executeItemOptUnwrapTarget(), and printJsonPathItem().

1048 {
1049  Assert(v->type == jpiIndexArray);
1050 
1051  jspInitByBuffer(from, v->base, v->content.array.elems[i].from);
1052 
1053  if (!v->content.array.elems[i].to)
1054  return false;
1055 
1056  jspInitByBuffer(to, v->base, v->content.array.elems[i].to);
1057 
1058  return true;
1059 }
char * base
Definition: jsonpath.h:115
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
struct JsonPathItem::@129::@131 array
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
int i

◆ jspGetBool()

bool jspGetBool ( JsonPathItem v)

Definition at line 1018 of file jsonpath.c.

References Assert, JsonPathItem::content, jpiBool, JsonPathItem::type, and JsonPathItem::value.

Referenced by getJsonPathItem(), and printJsonPathItem().

1019 {
1020  Assert(v->type == jpiBool);
1021 
1022  return (bool) *v->content.value.data;
1023 }
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
struct JsonPathItem::@129::@133 value

◆ jspGetLeftArg()

void jspGetLeftArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 976 of file jsonpath.c.

References JsonPathItem::args, Assert, JsonPathItem::base, JsonPathItem::content, jpiAdd, jpiAnd, jpiDiv, jpiEqual, jpiGreater, jpiGreaterOrEqual, jpiLess, jpiLessOrEqual, jpiMod, jpiMul, jpiNotEqual, jpiOr, jpiStartsWith, jpiSub, jspInitByBuffer(), and JsonPathItem::type.

Referenced by executeBinaryArithmExpr(), executeBoolItem(), extract_jsp_bool_expr(), and printJsonPathItem().

977 {
978  Assert(v->type == jpiAnd ||
979  v->type == jpiOr ||
980  v->type == jpiEqual ||
981  v->type == jpiNotEqual ||
982  v->type == jpiLess ||
983  v->type == jpiGreater ||
984  v->type == jpiLessOrEqual ||
985  v->type == jpiGreaterOrEqual ||
986  v->type == jpiAdd ||
987  v->type == jpiSub ||
988  v->type == jpiMul ||
989  v->type == jpiDiv ||
990  v->type == jpiMod ||
991  v->type == jpiStartsWith);
992 
993  jspInitByBuffer(a, v->base, v->content.args.left);
994 }
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:115
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
struct JsonPathItem::@129::@130 args
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106

◆ jspGetNext()

bool jspGetNext ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 922 of file jsonpath.c.

References Assert, JsonPathItem::base, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, jspHasNext, jspInitByBuffer(), JsonPathItem::nextPos, and JsonPathItem::type.

Referenced by appendBoolResult(), executeBinaryArithmExpr(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), executeNextItem(), executeNumericItemMethod(), executeUnaryArithmExpr(), extract_jsp_path_expr_nodes(), and printJsonPathItem().

923 {
924  if (jspHasNext(v))
925  {
926  Assert(v->type == jpiString ||
927  v->type == jpiNumeric ||
928  v->type == jpiBool ||
929  v->type == jpiNull ||
930  v->type == jpiKey ||
931  v->type == jpiAny ||
932  v->type == jpiAnyArray ||
933  v->type == jpiAnyKey ||
934  v->type == jpiIndexArray ||
935  v->type == jpiFilter ||
936  v->type == jpiCurrent ||
937  v->type == jpiExists ||
938  v->type == jpiRoot ||
939  v->type == jpiVariable ||
940  v->type == jpiLast ||
941  v->type == jpiAdd ||
942  v->type == jpiSub ||
943  v->type == jpiMul ||
944  v->type == jpiDiv ||
945  v->type == jpiMod ||
946  v->type == jpiPlus ||
947  v->type == jpiMinus ||
948  v->type == jpiEqual ||
949  v->type == jpiNotEqual ||
950  v->type == jpiGreater ||
951  v->type == jpiGreaterOrEqual ||
952  v->type == jpiLess ||
953  v->type == jpiLessOrEqual ||
954  v->type == jpiAnd ||
955  v->type == jpiOr ||
956  v->type == jpiNot ||
957  v->type == jpiIsUnknown ||
958  v->type == jpiType ||
959  v->type == jpiSize ||
960  v->type == jpiAbs ||
961  v->type == jpiFloor ||
962  v->type == jpiCeiling ||
963  v->type == jpiDouble ||
964  v->type == jpiKeyValue ||
965  v->type == jpiStartsWith);
966 
967  if (a)
968  jspInitByBuffer(a, v->base, v->nextPos);
969  return true;
970  }
971 
972  return false;
973 }
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:115
#define jspHasNext(jsp)
Definition: jsonpath.h:163
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
int32 nextPos
Definition: jsonpath.h:109

◆ jspGetNumeric()

Numeric jspGetNumeric ( JsonPathItem v)

Definition at line 1026 of file jsonpath.c.

References Assert, JsonPathItem::content, jpiNumeric, JsonPathItem::type, and JsonPathItem::value.

Referenced by getJsonPathItem(), and printJsonPathItem().

1027 {
1028  Assert(v->type == jpiNumeric);
1029 
1030  return (Numeric) v->content.value.data;
1031 }
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
struct JsonPathItem::@129::@133 value

◆ jspGetRightArg()

void jspGetRightArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 997 of file jsonpath.c.

References JsonPathItem::args, Assert, JsonPathItem::base, JsonPathItem::content, jpiAdd, jpiAnd, jpiDiv, jpiEqual, jpiGreater, jpiGreaterOrEqual, jpiLess, jpiLessOrEqual, jpiMod, jpiMul, jpiNotEqual, jpiOr, jpiStartsWith, jpiSub, jspInitByBuffer(), and JsonPathItem::type.

Referenced by executeBinaryArithmExpr(), executeBoolItem(), extract_jsp_bool_expr(), and printJsonPathItem().

998 {
999  Assert(v->type == jpiAnd ||
1000  v->type == jpiOr ||
1001  v->type == jpiEqual ||
1002  v->type == jpiNotEqual ||
1003  v->type == jpiLess ||
1004  v->type == jpiGreater ||
1005  v->type == jpiLessOrEqual ||
1006  v->type == jpiGreaterOrEqual ||
1007  v->type == jpiAdd ||
1008  v->type == jpiSub ||
1009  v->type == jpiMul ||
1010  v->type == jpiDiv ||
1011  v->type == jpiMod ||
1012  v->type == jpiStartsWith);
1013 
1014  jspInitByBuffer(a, v->base, v->content.args.right);
1015 }
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:115
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
struct JsonPathItem::@129::@130 args
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106

◆ jspGetString()

char* jspGetString ( JsonPathItem v,
int32 len 
)

Definition at line 1034 of file jsonpath.c.

References Assert, JsonPathItem::content, jpiKey, jpiString, jpiVariable, JsonPathItem::type, and JsonPathItem::value.

Referenced by executeItemOptUnwrapTarget(), getJsonPathItem(), getJsonPathVariable(), jsonb_ops__add_path_item(), jsonb_path_ops__add_path_item(), and printJsonPathItem().

1035 {
1036  Assert(v->type == jpiKey ||
1037  v->type == jpiString ||
1038  v->type == jpiVariable);
1039 
1040  if (len)
1041  *len = v->content.value.datalen;
1042  return v->content.value.data;
1043 }
union JsonPathItem::@129 content
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
struct JsonPathItem::@129::@133 value

◆ jspInit()

void jspInit ( JsonPathItem v,
JsonPath js 
)

Definition at line 820 of file jsonpath.c.

References Assert, JsonPath::data, JsonPath::header, JSONPATH_LAX, JSONPATH_VERSION, and jspInitByBuffer().

Referenced by executeJsonPath(), extract_jsp_query(), and jsonPathToCstring().

821 {
823  jspInitByBuffer(v, js->data, 0);
824 }
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
#define JSONPATH_LAX
Definition: jsonpath.h:29
#define JSONPATH_VERSION
Definition: jsonpath.h:28
#define Assert(condition)
Definition: c.h:732
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonpath.h:25
uint32 header
Definition: jsonpath.h:24

◆ jspInitByBuffer()

void jspInitByBuffer ( JsonPathItem v,
char *  base,
int32  pos 
)

Definition at line 830 of file jsonpath.c.

References JsonPathItem::anybounds, JsonPathItem::arg, JsonPathItem::args, JsonPathItem::array, JsonPathItem::base, JsonPathItem::content, elog, ERROR, INTALIGN, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, JsonPathItem::like_regex, JsonPathItem::nextPos, read_byte, read_int32, read_int32_n, JsonPathItem::type, and JsonPathItem::value.

Referenced by executeBoolItem(), jspGetArg(), jspGetArraySubscript(), jspGetLeftArg(), jspGetNext(), jspGetRightArg(), jspInit(), and printJsonPathItem().

831 {
832  v->base = base + pos;
833 
834  read_byte(v->type, base, pos);
835  pos = INTALIGN((uintptr_t) (base + pos)) - (uintptr_t) base;
836  read_int32(v->nextPos, base, pos);
837 
838  switch (v->type)
839  {
840  case jpiNull:
841  case jpiRoot:
842  case jpiCurrent:
843  case jpiAnyArray:
844  case jpiAnyKey:
845  case jpiType:
846  case jpiSize:
847  case jpiAbs:
848  case jpiFloor:
849  case jpiCeiling:
850  case jpiDouble:
851  case jpiKeyValue:
852  case jpiLast:
853  break;
854  case jpiKey:
855  case jpiString:
856  case jpiVariable:
857  read_int32(v->content.value.datalen, base, pos);
858  /* FALLTHROUGH */
859  case jpiNumeric:
860  case jpiBool:
861  v->content.value.data = base + pos;
862  break;
863  case jpiAnd:
864  case jpiOr:
865  case jpiAdd:
866  case jpiSub:
867  case jpiMul:
868  case jpiDiv:
869  case jpiMod:
870  case jpiEqual:
871  case jpiNotEqual:
872  case jpiLess:
873  case jpiGreater:
874  case jpiLessOrEqual:
875  case jpiGreaterOrEqual:
876  case jpiStartsWith:
877  read_int32(v->content.args.left, base, pos);
878  read_int32(v->content.args.right, base, pos);
879  break;
880  case jpiLikeRegex:
881  read_int32(v->content.like_regex.flags, base, pos);
882  read_int32(v->content.like_regex.expr, base, pos);
883  read_int32(v->content.like_regex.patternlen, base, pos);
884  v->content.like_regex.pattern = base + pos;
885  break;
886  case jpiNot:
887  case jpiExists:
888  case jpiIsUnknown:
889  case jpiPlus:
890  case jpiMinus:
891  case jpiFilter:
892  read_int32(v->content.arg, base, pos);
893  break;
894  case jpiIndexArray:
895  read_int32(v->content.array.nelems, base, pos);
896  read_int32_n(v->content.array.elems, base, pos,
897  v->content.array.nelems * 2);
898  break;
899  case jpiAny:
900  read_int32(v->content.anybounds.first, base, pos);
901  read_int32(v->content.anybounds.last, base, pos);
902  break;
903  default:
904  elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
905  }
906 }
#define read_int32(v, b, p)
Definition: jsonpath.c:806
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:115
#define INTALIGN(LEN)
Definition: c.h:682
int32 arg
Definition: jsonpath.h:127
#define ERROR
Definition: elog.h:43
struct JsonPathItem::@129::@131 array
struct JsonPathItem::@129::@130 args
struct JsonPathItem::@129::@132 anybounds
struct JsonPathItem::@129::@134 like_regex
union JsonPathItem::@129 content
#define read_int32_n(v, b, p, n)
Definition: jsonpath.c:811
JsonPathItemType type
Definition: jsonpath.h:106
#define elog(elevel,...)
Definition: elog.h:226
#define read_byte(v, b, p)
Definition: jsonpath.c:801
struct JsonPathItem::@129::@133 value
int32 nextPos
Definition: jsonpath.h:109

◆ jspOperationName()

const char* jspOperationName ( JsonPathItemType  type)

Definition at line 707 of file jsonpath.c.

References elog, ERROR, jpiAbs, jpiAdd, jpiAnd, jpiCeiling, jpiDiv, jpiDouble, jpiEqual, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiKeyValue, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNotEqual, jpiOr, jpiPlus, jpiSize, jpiStartsWith, jpiSub, and jpiType.

Referenced by executeBinaryArithmExpr(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), executeNumericItemMethod(), executeUnaryArithmExpr(), and printJsonPathItem().

708 {
709  switch (type)
710  {
711  case jpiAnd:
712  return "&&";
713  case jpiOr:
714  return "||";
715  case jpiEqual:
716  return "==";
717  case jpiNotEqual:
718  return "!=";
719  case jpiLess:
720  return "<";
721  case jpiGreater:
722  return ">";
723  case jpiLessOrEqual:
724  return "<=";
725  case jpiGreaterOrEqual:
726  return ">=";
727  case jpiPlus:
728  case jpiAdd:
729  return "+";
730  case jpiMinus:
731  case jpiSub:
732  return "-";
733  case jpiMul:
734  return "*";
735  case jpiDiv:
736  return "/";
737  case jpiMod:
738  return "%";
739  case jpiStartsWith:
740  return "starts with";
741  case jpiLikeRegex:
742  return "like_regex";
743  case jpiType:
744  return "type";
745  case jpiSize:
746  return "size";
747  case jpiKeyValue:
748  return "keyvalue";
749  case jpiDouble:
750  return "double";
751  case jpiAbs:
752  return "abs";
753  case jpiFloor:
754  return "floor";
755  case jpiCeiling:
756  return "ceiling";
757  default:
758  elog(ERROR, "unrecognized jsonpath item type: %d", type);
759  return NULL;
760  }
761 }
Definition: jsonpath.h:50
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:226

◆ operationPriority()

static int operationPriority ( JsonPathItemType  op)
static

Definition at line 764 of file jsonpath.c.

References jpiAdd, jpiAnd, jpiDiv, jpiEqual, jpiGreater, jpiGreaterOrEqual, jpiLess, jpiLessOrEqual, jpiMinus, jpiMod, jpiMul, jpiNotEqual, jpiOr, jpiPlus, jpiStartsWith, and jpiSub.

Referenced by printJsonPathItem().

765 {
766  switch (op)
767  {
768  case jpiOr:
769  return 0;
770  case jpiAnd:
771  return 1;
772  case jpiEqual:
773  case jpiNotEqual:
774  case jpiLess:
775  case jpiGreater:
776  case jpiLessOrEqual:
777  case jpiGreaterOrEqual:
778  case jpiStartsWith:
779  return 2;
780  case jpiAdd:
781  case jpiSub:
782  return 3;
783  case jpiMul:
784  case jpiDiv:
785  case jpiMod:
786  return 4;
787  case jpiPlus:
788  case jpiMinus:
789  return 5;
790  default:
791  return 6;
792  }
793 }
Definition: jsonpath.h:50

◆ printJsonPathItem()

static void printJsonPathItem ( StringInfo  buf,
JsonPathItem v,
bool  inKey,
bool  printBracketes 
)
static

Definition at line 474 of file jsonpath.c.

References JsonPathItem::anybounds, appendBinaryStringInfo(), appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), JsonPathItem::array, Assert, JsonPathItem::base, CHECK_FOR_INTERRUPTS, check_stack_depth(), JsonPathItem::content, DatumGetCString, DirectFunctionCall1, elog, ERROR, escape_json(), i, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, JSP_REGEX_ICASE, JSP_REGEX_MLINE, JSP_REGEX_QUOTE, JSP_REGEX_SLINE, JSP_REGEX_WSPACE, jspGetArg(), jspGetArraySubscript(), jspGetBool(), jspGetLeftArg(), jspGetNext(), jspGetNumeric(), jspGetRightArg(), jspGetString(), jspInitByBuffer(), jspOperationName(), JsonPathItem::like_regex, numeric_out(), NumericGetDatum, operationPriority(), PG_UINT32_MAX, range(), and JsonPathItem::type.

Referenced by jsonPathToCstring().

476 {
477  JsonPathItem elem;
478  int i;
479 
482 
483  switch (v->type)
484  {
485  case jpiNull:
486  appendStringInfoString(buf, "null");
487  break;
488  case jpiKey:
489  if (inKey)
490  appendStringInfoChar(buf, '.');
491  escape_json(buf, jspGetString(v, NULL));
492  break;
493  case jpiString:
494  escape_json(buf, jspGetString(v, NULL));
495  break;
496  case jpiVariable:
497  appendStringInfoChar(buf, '$');
498  escape_json(buf, jspGetString(v, NULL));
499  break;
500  case jpiNumeric:
504  break;
505  case jpiBool:
506  if (jspGetBool(v))
507  appendBinaryStringInfo(buf, "true", 4);
508  else
509  appendBinaryStringInfo(buf, "false", 5);
510  break;
511  case jpiAnd:
512  case jpiOr:
513  case jpiEqual:
514  case jpiNotEqual:
515  case jpiLess:
516  case jpiGreater:
517  case jpiLessOrEqual:
518  case jpiGreaterOrEqual:
519  case jpiAdd:
520  case jpiSub:
521  case jpiMul:
522  case jpiDiv:
523  case jpiMod:
524  case jpiStartsWith:
525  if (printBracketes)
526  appendStringInfoChar(buf, '(');
527  jspGetLeftArg(v, &elem);
528  printJsonPathItem(buf, &elem, false,
529  operationPriority(elem.type) <=
530  operationPriority(v->type));
531  appendStringInfoChar(buf, ' ');
533  appendStringInfoChar(buf, ' ');
534  jspGetRightArg(v, &elem);
535  printJsonPathItem(buf, &elem, false,
536  operationPriority(elem.type) <=
537  operationPriority(v->type));
538  if (printBracketes)
539  appendStringInfoChar(buf, ')');
540  break;
541  case jpiLikeRegex:
542  if (printBracketes)
543  appendStringInfoChar(buf, '(');
544 
545  jspInitByBuffer(&elem, v->base, v->content.like_regex.expr);
546  printJsonPathItem(buf, &elem, false,
547  operationPriority(elem.type) <=
548  operationPriority(v->type));
549 
550  appendBinaryStringInfo(buf, " like_regex ", 12);
551 
552  escape_json(buf, v->content.like_regex.pattern);
553 
554  if (v->content.like_regex.flags)
555  {
556  appendBinaryStringInfo(buf, " flag \"", 7);
557 
558  if (v->content.like_regex.flags & JSP_REGEX_ICASE)
559  appendStringInfoChar(buf, 'i');
560  if (v->content.like_regex.flags & JSP_REGEX_SLINE)
561  appendStringInfoChar(buf, 's');
562  if (v->content.like_regex.flags & JSP_REGEX_MLINE)
563  appendStringInfoChar(buf, 'm');
564  if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
565  appendStringInfoChar(buf, 'x');
566  if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
567  appendStringInfoChar(buf, 'q');
568 
569  appendStringInfoChar(buf, '"');
570  }
571 
572  if (printBracketes)
573  appendStringInfoChar(buf, ')');
574  break;
575  case jpiPlus:
576  case jpiMinus:
577  if (printBracketes)
578  appendStringInfoChar(buf, '(');
579  appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
580  jspGetArg(v, &elem);
581  printJsonPathItem(buf, &elem, false,
582  operationPriority(elem.type) <=
583  operationPriority(v->type));
584  if (printBracketes)
585  appendStringInfoChar(buf, ')');
586  break;
587  case jpiFilter:
588  appendBinaryStringInfo(buf, "?(", 2);
589  jspGetArg(v, &elem);
590  printJsonPathItem(buf, &elem, false, false);
591  appendStringInfoChar(buf, ')');
592  break;
593  case jpiNot:
594  appendBinaryStringInfo(buf, "!(", 2);
595  jspGetArg(v, &elem);
596  printJsonPathItem(buf, &elem, false, false);
597  appendStringInfoChar(buf, ')');
598  break;
599  case jpiIsUnknown:
600  appendStringInfoChar(buf, '(');
601  jspGetArg(v, &elem);
602  printJsonPathItem(buf, &elem, false, false);
603  appendBinaryStringInfo(buf, ") is unknown", 12);
604  break;
605  case jpiExists:
606  appendBinaryStringInfo(buf, "exists (", 8);
607  jspGetArg(v, &elem);
608  printJsonPathItem(buf, &elem, false, false);
609  appendStringInfoChar(buf, ')');
610  break;
611  case jpiCurrent:
612  Assert(!inKey);
613  appendStringInfoChar(buf, '@');
614  break;
615  case jpiRoot:
616  Assert(!inKey);
617  appendStringInfoChar(buf, '$');
618  break;
619  case jpiLast:
620  appendBinaryStringInfo(buf, "last", 4);
621  break;
622  case jpiAnyArray:
623  appendBinaryStringInfo(buf, "[*]", 3);
624  break;
625  case jpiAnyKey:
626  if (inKey)
627  appendStringInfoChar(buf, '.');
628  appendStringInfoChar(buf, '*');
629  break;
630  case jpiIndexArray:
631  appendStringInfoChar(buf, '[');
632  for (i = 0; i < v->content.array.nelems; i++)
633  {
634  JsonPathItem from;
635  JsonPathItem to;
636  bool range = jspGetArraySubscript(v, &from, &to, i);
637 
638  if (i)
639  appendStringInfoChar(buf, ',');
640 
641  printJsonPathItem(buf, &from, false, false);
642 
643  if (range)
644  {
645  appendBinaryStringInfo(buf, " to ", 4);
646  printJsonPathItem(buf, &to, false, false);
647  }
648  }
649  appendStringInfoChar(buf, ']');
650  break;
651  case jpiAny:
652  if (inKey)
653  appendStringInfoChar(buf, '.');
654 
655  if (v->content.anybounds.first == 0 &&
656  v->content.anybounds.last == PG_UINT32_MAX)
657  appendBinaryStringInfo(buf, "**", 2);
658  else if (v->content.anybounds.first == v->content.anybounds.last)
659  {
660  if (v->content.anybounds.first == PG_UINT32_MAX)
661  appendStringInfo(buf, "**{last}");
662  else
663  appendStringInfo(buf, "**{%u}",
664  v->content.anybounds.first);
665  }
666  else if (v->content.anybounds.first == PG_UINT32_MAX)
667  appendStringInfo(buf, "**{last to %u}",
668  v->content.anybounds.last);
669  else if (v->content.anybounds.last == PG_UINT32_MAX)
670  appendStringInfo(buf, "**{%u to last}",
671  v->content.anybounds.first);
672  else
673  appendStringInfo(buf, "**{%u to %u}",
674  v->content.anybounds.first,
675  v->content.anybounds.last);
676  break;
677  case jpiType:
678  appendBinaryStringInfo(buf, ".type()", 7);
679  break;
680  case jpiSize:
681  appendBinaryStringInfo(buf, ".size()", 7);
682  break;
683  case jpiAbs:
684  appendBinaryStringInfo(buf, ".abs()", 6);
685  break;
686  case jpiFloor:
687  appendBinaryStringInfo(buf, ".floor()", 8);
688  break;
689  case jpiCeiling:
690  appendBinaryStringInfo(buf, ".ceiling()", 10);
691  break;
692  case jpiDouble:
693  appendBinaryStringInfo(buf, ".double()", 9);
694  break;
695  case jpiKeyValue:
696  appendBinaryStringInfo(buf, ".keyvalue()", 11);
697  break;
698  default:
699  elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
700  }
701 
702  if (jspGetNext(v, &elem))
703  printJsonPathItem(buf, &elem, true, true);
704 }
void escape_json(StringInfo buf, const char *str)
Definition: json.c:2463
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:922
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:115
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:655
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:830
#define JSP_REGEX_ICASE
Definition: jsonpath.h:90
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:616
#define PG_UINT32_MAX
Definition: c.h:442
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ERROR
Definition: elog.h:43
#define JSP_REGEX_MLINE
Definition: jsonpath.h:92
#define DatumGetCString(X)
Definition: postgres.h:566
#define JSP_REGEX_WSPACE
Definition: jsonpath.h:93
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
void check_stack_depth(void)
Definition: postgres.c:3262
struct JsonPathItem::@129::@131 array
#define JSP_REGEX_QUOTE
Definition: jsonpath.h:94
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
struct JsonPathItem::@129::@132 anybounds
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
struct JsonPathItem::@129::@134 like_regex
union JsonPathItem::@129 content
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:707
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:997
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1018
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1046
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:976
#define Assert(condition)
Definition: c.h:732
JsonPathItemType type
Definition: jsonpath.h:106
static int operationPriority(JsonPathItemType op)
Definition: jsonpath.c:764
#define elog(elevel,...)
Definition: elog.h:226
int i
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
Definition: jsonpath.c:474
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:909
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1034
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214
#define JSP_REGEX_SLINE
Definition: jsonpath.h:91
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1026

◆ reserveSpaceForItemPointer()

static int32 reserveSpaceForItemPointer ( StringInfo  buf)
static

Definition at line 460 of file jsonpath.c.

References appendBinaryStringInfo(), and StringInfoData::len.

Referenced by flattenJsonPathParseItem().

461 {
462  int32 pos = buf->len;
463  int32 ptr = 0;
464 
465  appendBinaryStringInfo(buf, (char *) &ptr, sizeof(ptr));
466 
467  return pos;
468 }
signed int int32
Definition: c.h:346
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214