PostgreSQL Source Code  git master
jsonpath.c File Reference
#include "postgres.h"
#include "catalog/pg_type.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
#include "nodes/nodeFuncs.h"
#include "utils/fmgrprotos.h"
#include "utils/formatting.h"
#include "utils/json.h"
#include "utils/jsonpath.h"
Include dependency graph for jsonpath.c:

Go to the source code of this file.

Data Structures

struct  JsonPathMutableContext
 

Macros

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

Enumerations

enum  JsonPathDatatypeStatus { jpdsNonDateTime , jpdsUnknownDateTime , jpdsDateTimeZoned , jpdsDateTimeNonZoned }
 

Functions

static Datum jsonPathFromCstring (char *in, int len, struct Node *escontext)
 
static char * jsonPathToCstring (StringInfo out, JsonPath *in, int estimated_len)
 
static bool flattenJsonPathParseItem (StringInfo buf, int *result, struct Node *escontext, 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)
 
static enum JsonPathDatatypeStatus jspIsMutableWalker (JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
 
bool jspIsMutable (JsonPath *path, List *varnames, List *varexprs)
 

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:504
int b
Definition: isn.c:70

Definition at line 954 of file jsonpath.c.

◆ read_int32

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

Definition at line 959 of file jsonpath.c.

◆ read_int32_n

#define read_int32_n (   v,
  b,
  p,
 
)
Value:
do { \
(v) = (void *)((b) + (p)); \
(p) += sizeof(int32) * (n); \
} while(0) \

Definition at line 964 of file jsonpath.c.

Enumeration Type Documentation

◆ JsonPathDatatypeStatus

Enumerator
jpdsNonDateTime 
jpdsUnknownDateTime 
jpdsDateTimeZoned 
jpdsDateTimeNonZoned 

Definition at line 1247 of file jsonpath.c.

1248 {
1249  jpdsNonDateTime, /* null, bool, numeric, string, array, object */
1250  jpdsUnknownDateTime, /* unknown datetime type */
1251  jpdsDateTimeZoned, /* timetz, timestamptz */
1252  jpdsDateTimeNonZoned, /* time, timestamp, date */
1253 };
@ jpdsDateTimeZoned
Definition: jsonpath.c:1251
@ jpdsNonDateTime
Definition: jsonpath.c:1249
@ jpdsDateTimeNonZoned
Definition: jsonpath.c:1252
@ jpdsUnknownDateTime
Definition: jsonpath.c:1250

Function Documentation

◆ alignStringInfoInt()

static void alignStringInfoInt ( StringInfo  buf)
static

Definition at line 484 of file jsonpath.c.

485 {
486  switch (INTALIGN(buf->len) - buf->len)
487  {
488  case 3:
490  /* FALLTHROUGH */
491  case 2:
493  /* FALLTHROUGH */
494  case 1:
496  /* FALLTHROUGH */
497  default:
498  break;
499  }
500 }
#define INTALIGN(LEN)
Definition: c.h:808
static char * buf
Definition: pg_test_fsync.c:73
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:204

References appendStringInfoCharMacro, buf, and INTALIGN.

Referenced by flattenJsonPathParseItem().

◆ flattenJsonPathParseItem()

static bool flattenJsonPathParseItem ( StringInfo  buf,
int *  result,
struct Node escontext,
JsonPathParseItem item,
int  nestingLevel,
bool  insideArraySubscript 
)
static

Definition at line 239 of file jsonpath.c.

242 {
243  /* position from beginning of jsonpath data */
244  int32 pos = buf->len - JSONPATH_HDRSZ;
245  int32 chld;
246  int32 next;
247  int argNestingLevel = 0;
248 
251 
252  appendStringInfoChar(buf, (char) (item->type));
253 
254  /*
255  * We align buffer to int32 because a series of int32 values often goes
256  * after the header, and we want to read them directly by dereferencing
257  * int32 pointer (see jspInitByBuffer()).
258  */
260 
261  /*
262  * Reserve space for next item pointer. Actual value will be recorded
263  * later, after next and children items processing.
264  */
266 
267  switch (item->type)
268  {
269  case jpiString:
270  case jpiVariable:
271  case jpiKey:
273  sizeof(item->value.string.len));
275  item->value.string.len);
276  appendStringInfoChar(buf, '\0');
277  break;
278  case jpiNumeric:
280  VARSIZE(item->value.numeric));
281  break;
282  case jpiBool:
284  sizeof(item->value.boolean));
285  break;
286  case jpiAnd:
287  case jpiOr:
288  case jpiEqual:
289  case jpiNotEqual:
290  case jpiLess:
291  case jpiGreater:
292  case jpiLessOrEqual:
293  case jpiGreaterOrEqual:
294  case jpiAdd:
295  case jpiSub:
296  case jpiMul:
297  case jpiDiv:
298  case jpiMod:
299  case jpiStartsWith:
300  case jpiDecimal:
301  {
302  /*
303  * First, reserve place for left/right arg's positions, then
304  * record both args and sets actual position in reserved
305  * places.
306  */
309 
310  if (!item->value.args.left)
311  chld = pos;
312  else if (!flattenJsonPathParseItem(buf, &chld, escontext,
313  item->value.args.left,
314  nestingLevel + argNestingLevel,
315  insideArraySubscript))
316  return false;
317  *(int32 *) (buf->data + left) = chld - pos;
318 
319  if (!item->value.args.right)
320  chld = pos;
321  else if (!flattenJsonPathParseItem(buf, &chld, escontext,
322  item->value.args.right,
323  nestingLevel + argNestingLevel,
324  insideArraySubscript))
325  return false;
326  *(int32 *) (buf->data + right) = chld - pos;
327  }
328  break;
329  case jpiLikeRegex:
330  {
331  int32 offs;
332 
334  &item->value.like_regex.flags,
335  sizeof(item->value.like_regex.flags));
338  &item->value.like_regex.patternlen,
339  sizeof(item->value.like_regex.patternlen));
341  item->value.like_regex.patternlen);
342  appendStringInfoChar(buf, '\0');
343 
344  if (!flattenJsonPathParseItem(buf, &chld, escontext,
345  item->value.like_regex.expr,
346  nestingLevel,
347  insideArraySubscript))
348  return false;
349  *(int32 *) (buf->data + offs) = chld - pos;
350  }
351  break;
352  case jpiFilter:
353  argNestingLevel++;
354  /* FALLTHROUGH */
355  case jpiIsUnknown:
356  case jpiNot:
357  case jpiPlus:
358  case jpiMinus:
359  case jpiExists:
360  case jpiDatetime:
361  case jpiTime:
362  case jpiTimeTz:
363  case jpiTimestamp:
364  case jpiTimestampTz:
365  {
367 
368  if (!item->value.arg)
369  chld = pos;
370  else if (!flattenJsonPathParseItem(buf, &chld, escontext,
371  item->value.arg,
372  nestingLevel + argNestingLevel,
373  insideArraySubscript))
374  return false;
375  *(int32 *) (buf->data + arg) = chld - pos;
376  }
377  break;
378  case jpiNull:
379  break;
380  case jpiRoot:
381  break;
382  case jpiAnyArray:
383  case jpiAnyKey:
384  break;
385  case jpiCurrent:
386  if (nestingLevel <= 0)
387  ereturn(escontext, false,
388  (errcode(ERRCODE_SYNTAX_ERROR),
389  errmsg("@ is not allowed in root expressions")));
390  break;
391  case jpiLast:
392  if (!insideArraySubscript)
393  ereturn(escontext, false,
394  (errcode(ERRCODE_SYNTAX_ERROR),
395  errmsg("LAST is allowed only in array subscripts")));
396  break;
397  case jpiIndexArray:
398  {
399  int32 nelems = item->value.array.nelems;
400  int offset;
401  int i;
402 
403  appendBinaryStringInfo(buf, &nelems, sizeof(nelems));
404 
405  offset = buf->len;
406 
407  appendStringInfoSpaces(buf, sizeof(int32) * 2 * nelems);
408 
409  for (i = 0; i < nelems; i++)
410  {
411  int32 *ppos;
412  int32 topos;
413  int32 frompos;
414 
415  if (!flattenJsonPathParseItem(buf, &frompos, escontext,
416  item->value.array.elems[i].from,
417  nestingLevel, true))
418  return false;
419  frompos -= pos;
420 
421  if (item->value.array.elems[i].to)
422  {
423  if (!flattenJsonPathParseItem(buf, &topos, escontext,
424  item->value.array.elems[i].to,
425  nestingLevel, true))
426  return false;
427  topos -= pos;
428  }
429  else
430  topos = 0;
431 
432  ppos = (int32 *) &buf->data[offset + i * 2 * sizeof(int32)];
433 
434  ppos[0] = frompos;
435  ppos[1] = topos;
436  }
437  }
438  break;
439  case jpiAny:
441  &item->value.anybounds.first,
442  sizeof(item->value.anybounds.first));
444  &item->value.anybounds.last,
445  sizeof(item->value.anybounds.last));
446  break;
447  case jpiType:
448  case jpiSize:
449  case jpiAbs:
450  case jpiFloor:
451  case jpiCeiling:
452  case jpiDouble:
453  case jpiKeyValue:
454  case jpiBigint:
455  case jpiBoolean:
456  case jpiDate:
457  case jpiInteger:
458  case jpiNumber:
459  case jpiStringFunc:
460  break;
461  default:
462  elog(ERROR, "unrecognized jsonpath item type: %d", item->type);
463  }
464 
465  if (item->next)
466  {
467  if (!flattenJsonPathParseItem(buf, &chld, escontext,
468  item->next, nestingLevel,
469  insideArraySubscript))
470  return false;
471  chld -= pos;
472  *(int32 *) (buf->data + next) = chld;
473  }
474 
475  if (result)
476  *result = pos;
477  return true;
478 }
static int32 next
Definition: blutils.c:221
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
int i
Definition: isn.c:73
static void alignStringInfoInt(StringInfo buf)
Definition: jsonpath.c:484
static bool flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext, JsonPathParseItem *item, int nestingLevel, bool insideArraySubscript)
Definition: jsonpath.c:239
static int32 reserveSpaceForItemPointer(StringInfo buf)
Definition: jsonpath.c:507
@ jpiAdd
Definition: jsonpath.h:78
@ jpiString
Definition: jsonpath.h:65
@ jpiAbs
Definition: jsonpath.h:97
@ jpiIndexArray
Definition: jsonpath.h:87
@ jpiAny
Definition: jsonpath.h:88
@ jpiDatetime
Definition: jsonpath.h:101
@ jpiBigint
Definition: jsonpath.h:107
@ jpiBool
Definition: jsonpath.h:67
@ jpiType
Definition: jsonpath.h:95
@ jpiFloor
Definition: jsonpath.h:98
@ jpiAnyArray
Definition: jsonpath.h:85
@ jpiExists
Definition: jsonpath.h:94
@ jpiSize
Definition: jsonpath.h:96
@ jpiSub
Definition: jsonpath.h:79
@ jpiNotEqual
Definition: jsonpath.h:73
@ jpiMul
Definition: jsonpath.h:80
@ jpiVariable
Definition: jsonpath.h:92
@ jpiTimeTz
Definition: jsonpath.h:115
@ jpiNot
Definition: jsonpath.h:70
@ jpiDate
Definition: jsonpath.h:109
@ jpiGreaterOrEqual
Definition: jsonpath.h:77
@ jpiPlus
Definition: jsonpath.h:83
@ jpiDouble
Definition: jsonpath.h:100
@ jpiGreater
Definition: jsonpath.h:75
@ jpiNumber
Definition: jsonpath.h:112
@ jpiAnd
Definition: jsonpath.h:68
@ jpiStartsWith
Definition: jsonpath.h:105
@ jpiOr
Definition: jsonpath.h:69
@ jpiMod
Definition: jsonpath.h:82
@ jpiTimestamp
Definition: jsonpath.h:116
@ jpiLikeRegex
Definition: jsonpath.h:106
@ jpiTimestampTz
Definition: jsonpath.h:117
@ jpiInteger
Definition: jsonpath.h:111
@ jpiRoot
Definition: jsonpath.h:91
@ jpiFilter
Definition: jsonpath.h:93
@ jpiNull
Definition: jsonpath.h:64
@ jpiLess
Definition: jsonpath.h:74
@ jpiCurrent
Definition: jsonpath.h:90
@ jpiEqual
Definition: jsonpath.h:72
@ jpiKey
Definition: jsonpath.h:89
@ jpiDiv
Definition: jsonpath.h:81
@ jpiTime
Definition: jsonpath.h:114
@ jpiLast
Definition: jsonpath.h:104
@ jpiMinus
Definition: jsonpath.h:84
@ jpiLessOrEqual
Definition: jsonpath.h:76
@ jpiCeiling
Definition: jsonpath.h:99
@ jpiIsUnknown
Definition: jsonpath.h:71
@ jpiKeyValue
Definition: jsonpath.h:102
@ jpiNumeric
Definition: jsonpath.h:66
@ jpiBoolean
Definition: jsonpath.h:108
@ jpiStringFunc
Definition: jsonpath.h:113
@ jpiDecimal
Definition: jsonpath.h:110
@ jpiAnyKey
Definition: jsonpath.h:86
#define JSONPATH_HDRSZ
Definition: jsonpath.h:32
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
void * arg
void check_stack_depth(void)
Definition: postgres.c:3531
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:212
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
JsonPathParseItem * arg
Definition: jsonpath.h:233
struct JsonPathParseItem::@144::@148 like_regex
struct JsonPathParseItem::@144::@146 array
struct JsonPathParseItem::@144::@149 string
struct JsonPathParseItem::@144::@147 anybounds
JsonPathParseItem * next
Definition: jsonpath.h:220
Numeric numeric
Definition: jsonpath.h:262
struct JsonPathParseItem::@144::@145 args
union JsonPathParseItem::@144 value
JsonPathItemType type
Definition: jsonpath.h:219
#define VARSIZE(PTR)
Definition: varatt.h:279

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

Referenced by jsonPathFromCstring().

◆ jsonpath_in()

Datum jsonpath_in ( PG_FUNCTION_ARGS  )

Definition at line 98 of file jsonpath.c.

99 {
100  char *in = PG_GETARG_CSTRING(0);
101  int len = strlen(in);
102 
103  return jsonPathFromCstring(in, len, fcinfo->context);
104 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
static Datum jsonPathFromCstring(char *in, int len, struct Node *escontext)
Definition: jsonpath.c:173
const void size_t len

References jsonPathFromCstring(), len, and PG_GETARG_CSTRING.

Referenced by makeJsonTablePathScan().

◆ jsonpath_out()

Datum jsonpath_out ( PG_FUNCTION_ARGS  )

Definition at line 134 of file jsonpath.c.

135 {
137 
139 }
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
static char * jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
Definition: jsonpath.c:213
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:46

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

◆ jsonpath_recv()

Datum jsonpath_recv ( PG_FUNCTION_ARGS  )

Definition at line 115 of file jsonpath.c.

116 {
118  int version = pq_getmsgint(buf, 1);
119  char *str;
120  int nbytes;
121 
122  if (version == JSONPATH_VERSION)
123  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
124  else
125  elog(ERROR, "unsupported jsonpath version number: %d", version);
126 
127  return jsonPathFromCstring(str, nbytes, NULL);
128 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
const char * str
#define JSONPATH_VERSION
Definition: jsonpath.h:30
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
StringInfoData * StringInfo
Definition: stringinfo.h:54

References buf, elog, ERROR, JSONPATH_VERSION, jsonPathFromCstring(), PG_GETARG_POINTER, pq_getmsgint(), pq_getmsgtext(), and str.

◆ jsonpath_send()

Datum jsonpath_send ( PG_FUNCTION_ARGS  )

Definition at line 147 of file jsonpath.c.

148 {
151  StringInfoData jtext;
152  int version = JSONPATH_VERSION;
153 
154  initStringInfo(&jtext);
155  (void) jsonPathToCstring(&jtext, in, VARSIZE(in));
156 
158  pq_sendint8(&buf, version);
159  pq_sendtext(&buf, jtext.data, jtext.len);
160  pfree(jtext.data);
161 
163 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pfree(void *pointer)
Definition: mcxt.c:1520
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:128
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

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.

◆ jsonPathFromCstring()

static Datum jsonPathFromCstring ( char *  in,
int  len,
struct Node escontext 
)
static

Definition at line 173 of file jsonpath.c.

174 {
175  JsonPathParseResult *jsonpath = parsejsonpath(in, len, escontext);
176  JsonPath *res;
178 
179  if (SOFT_ERROR_OCCURRED(escontext))
180  return (Datum) 0;
181 
182  if (!jsonpath)
183  ereturn(escontext, (Datum) 0,
184  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
185  errmsg("invalid input syntax for type %s: \"%s\"", "jsonpath",
186  in)));
187 
189  enlargeStringInfo(&buf, 4 * len /* estimation */ );
190 
192 
193  if (!flattenJsonPathParseItem(&buf, NULL, escontext,
194  jsonpath->expr, 0, false))
195  return (Datum) 0;
196 
197  res = (JsonPath *) buf.data;
198  SET_VARSIZE(res, buf.len);
199  res->header = JSONPATH_VERSION;
200  if (jsonpath->lax)
201  res->header |= JSONPATH_LAX;
202 
204 }
#define PG_RETURN_JSONPATH_P(p)
Definition: jsonpath.h:48
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
#define JSONPATH_LAX
Definition: jsonpath.h:31
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52
uintptr_t Datum
Definition: postgres.h:64
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:289
JsonPathParseItem * expr
Definition: jsonpath.h:274
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References appendStringInfoSpaces(), buf, enlargeStringInfo(), ereturn, errcode(), errmsg(), JsonPathParseResult::expr, flattenJsonPathParseItem(), initStringInfo(), JSONPATH_HDRSZ, JSONPATH_LAX, JSONPATH_VERSION, JsonPathParseResult::lax, len, parsejsonpath(), PG_RETURN_JSONPATH_P, res, SET_VARSIZE, and SOFT_ERROR_OCCURRED.

Referenced by jsonpath_in(), and jsonpath_recv().

◆ jsonPathToCstring()

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

Definition at line 213 of file jsonpath.c.

214 {
216  JsonPathItem v;
217 
218  if (!out)
219  {
220  out = &buf;
221  initStringInfo(out);
222  }
223  enlargeStringInfo(out, estimated_len);
224 
225  if (!(in->header & JSONPATH_LAX))
226  appendStringInfoString(out, "strict ");
227 
228  jspInit(&v, in);
229  printJsonPathItem(out, &v, false, true);
230 
231  return out->data;
232 }
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:973
static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
Definition: jsonpath.c:521
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
uint32 header
Definition: jsonpath.h:26

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

Referenced by jsonpath_out(), and jsonpath_send().

◆ jspGetArg()

void jspGetArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 1074 of file jsonpath.c.

1075 {
1076  Assert(v->type == jpiNot ||
1077  v->type == jpiIsUnknown ||
1078  v->type == jpiPlus ||
1079  v->type == jpiMinus ||
1080  v->type == jpiFilter ||
1081  v->type == jpiExists ||
1082  v->type == jpiDatetime ||
1083  v->type == jpiTime ||
1084  v->type == jpiTimeTz ||
1085  v->type == jpiTimestamp ||
1086  v->type == jpiTimestampTz);
1087 
1088  jspInitByBuffer(a, v->base, v->content.arg);
1089 }
#define Assert(condition)
Definition: c.h:858
int a
Definition: isn.c:69
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:983
union JsonPathItem::@137 content
char * base
Definition: jsonpath.h:146
int32 arg
Definition: jsonpath.h:158
JsonPathItemType type
Definition: jsonpath.h:137

References a, JsonPathItem::arg, Assert, JsonPathItem::base, JsonPathItem::content, jpiDatetime, jpiExists, jpiFilter, jpiIsUnknown, jpiMinus, jpiNot, jpiPlus, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jspInitByBuffer(), and JsonPathItem::type.

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

◆ jspGetArraySubscript()

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

Definition at line 1231 of file jsonpath.c.

1233 {
1234  Assert(v->type == jpiIndexArray);
1235 
1236  jspInitByBuffer(from, v->base, v->content.array.elems[i].from);
1237 
1238  if (!v->content.array.elems[i].to)
1239  return false;
1240 
1241  jspInitByBuffer(to, v->base, v->content.array.elems[i].to);
1242 
1243  return true;
1244 }
struct JsonPathItem::@137::@139 array

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

Referenced by executeItemOptUnwrapTarget(), and printJsonPathItem().

◆ jspGetBool()

bool jspGetBool ( JsonPathItem v)

Definition at line 1203 of file jsonpath.c.

1204 {
1205  Assert(v->type == jpiBool);
1206 
1207  return (bool) *v->content.value.data;
1208 }
struct JsonPathItem::@137::@141 value

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

Referenced by getJsonPathItem(), and printJsonPathItem().

◆ jspGetLeftArg()

void jspGetLeftArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 1159 of file jsonpath.c.

1160 {
1161  Assert(v->type == jpiAnd ||
1162  v->type == jpiOr ||
1163  v->type == jpiEqual ||
1164  v->type == jpiNotEqual ||
1165  v->type == jpiLess ||
1166  v->type == jpiGreater ||
1167  v->type == jpiLessOrEqual ||
1168  v->type == jpiGreaterOrEqual ||
1169  v->type == jpiAdd ||
1170  v->type == jpiSub ||
1171  v->type == jpiMul ||
1172  v->type == jpiDiv ||
1173  v->type == jpiMod ||
1174  v->type == jpiStartsWith ||
1175  v->type == jpiDecimal);
1176 
1177  jspInitByBuffer(a, v->base, v->content.args.left);
1178 }
struct JsonPathItem::@137::@138 args

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

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

◆ jspGetNext()

bool jspGetNext ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 1092 of file jsonpath.c.

1093 {
1094  if (jspHasNext(v))
1095  {
1096  Assert(v->type == jpiNull ||
1097  v->type == jpiString ||
1098  v->type == jpiNumeric ||
1099  v->type == jpiBool ||
1100  v->type == jpiAnd ||
1101  v->type == jpiOr ||
1102  v->type == jpiNot ||
1103  v->type == jpiIsUnknown ||
1104  v->type == jpiEqual ||
1105  v->type == jpiNotEqual ||
1106  v->type == jpiLess ||
1107  v->type == jpiGreater ||
1108  v->type == jpiLessOrEqual ||
1109  v->type == jpiGreaterOrEqual ||
1110  v->type == jpiAdd ||
1111  v->type == jpiSub ||
1112  v->type == jpiMul ||
1113  v->type == jpiDiv ||
1114  v->type == jpiMod ||
1115  v->type == jpiPlus ||
1116  v->type == jpiMinus ||
1117  v->type == jpiAnyArray ||
1118  v->type == jpiAnyKey ||
1119  v->type == jpiIndexArray ||
1120  v->type == jpiAny ||
1121  v->type == jpiKey ||
1122  v->type == jpiCurrent ||
1123  v->type == jpiRoot ||
1124  v->type == jpiVariable ||
1125  v->type == jpiFilter ||
1126  v->type == jpiExists ||
1127  v->type == jpiType ||
1128  v->type == jpiSize ||
1129  v->type == jpiAbs ||
1130  v->type == jpiFloor ||
1131  v->type == jpiCeiling ||
1132  v->type == jpiDouble ||
1133  v->type == jpiDatetime ||
1134  v->type == jpiKeyValue ||
1135  v->type == jpiLast ||
1136  v->type == jpiStartsWith ||
1137  v->type == jpiLikeRegex ||
1138  v->type == jpiBigint ||
1139  v->type == jpiBoolean ||
1140  v->type == jpiDate ||
1141  v->type == jpiDecimal ||
1142  v->type == jpiInteger ||
1143  v->type == jpiNumber ||
1144  v->type == jpiStringFunc ||
1145  v->type == jpiTime ||
1146  v->type == jpiTimeTz ||
1147  v->type == jpiTimestamp ||
1148  v->type == jpiTimestampTz);
1149 
1150  if (a)
1151  jspInitByBuffer(a, v->base, v->nextPos);
1152  return true;
1153  }
1154 
1155  return false;
1156 }
#define jspHasNext(jsp)
Definition: jsonpath.h:194
int32 nextPos
Definition: jsonpath.h:140

References a, Assert, JsonPathItem::base, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBigint, jpiBool, jpiBoolean, jpiCeiling, jpiCurrent, jpiDate, jpiDatetime, jpiDecimal, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiInteger, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumber, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, jspHasNext, jspInitByBuffer(), JsonPathItem::nextPos, and JsonPathItem::type.

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

◆ jspGetNumeric()

Numeric jspGetNumeric ( JsonPathItem v)

Definition at line 1211 of file jsonpath.c.

1212 {
1213  Assert(v->type == jpiNumeric);
1214 
1215  return (Numeric) v->content.value.data;
1216 }

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

Referenced by executeDateTimeMethod(), executeItemOptUnwrapTarget(), getJsonPathItem(), and printJsonPathItem().

◆ jspGetRightArg()

void jspGetRightArg ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 1181 of file jsonpath.c.

1182 {
1183  Assert(v->type == jpiAnd ||
1184  v->type == jpiOr ||
1185  v->type == jpiEqual ||
1186  v->type == jpiNotEqual ||
1187  v->type == jpiLess ||
1188  v->type == jpiGreater ||
1189  v->type == jpiLessOrEqual ||
1190  v->type == jpiGreaterOrEqual ||
1191  v->type == jpiAdd ||
1192  v->type == jpiSub ||
1193  v->type == jpiMul ||
1194  v->type == jpiDiv ||
1195  v->type == jpiMod ||
1196  v->type == jpiStartsWith ||
1197  v->type == jpiDecimal);
1198 
1199  jspInitByBuffer(a, v->base, v->content.args.right);
1200 }

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

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

◆ jspGetString()

char* jspGetString ( JsonPathItem v,
int32 len 
)

Definition at line 1219 of file jsonpath.c.

1220 {
1221  Assert(v->type == jpiKey ||
1222  v->type == jpiString ||
1223  v->type == jpiVariable);
1224 
1225  if (len)
1226  *len = v->content.value.datalen;
1227  return v->content.value.data;
1228 }

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

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

◆ jspInit()

void jspInit ( JsonPathItem v,
JsonPath js 
)

Definition at line 973 of file jsonpath.c.

974 {
976  jspInitByBuffer(v, js->data, 0);
977 }
char data[FLEXIBLE_ARRAY_MEMBER]
Definition: jsonpath.h:27

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

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

◆ jspInitByBuffer()

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

Definition at line 983 of file jsonpath.c.

984 {
985  v->base = base + pos;
986 
987  read_byte(v->type, base, pos);
988  pos = INTALIGN((uintptr_t) (base + pos)) - (uintptr_t) base;
989  read_int32(v->nextPos, base, pos);
990 
991  switch (v->type)
992  {
993  case jpiNull:
994  case jpiRoot:
995  case jpiCurrent:
996  case jpiAnyArray:
997  case jpiAnyKey:
998  case jpiType:
999  case jpiSize:
1000  case jpiAbs:
1001  case jpiFloor:
1002  case jpiCeiling:
1003  case jpiDouble:
1004  case jpiKeyValue:
1005  case jpiLast:
1006  case jpiBigint:
1007  case jpiBoolean:
1008  case jpiDate:
1009  case jpiInteger:
1010  case jpiNumber:
1011  case jpiStringFunc:
1012  break;
1013  case jpiString:
1014  case jpiKey:
1015  case jpiVariable:
1016  read_int32(v->content.value.datalen, base, pos);
1017  /* FALLTHROUGH */
1018  case jpiNumeric:
1019  case jpiBool:
1020  v->content.value.data = base + pos;
1021  break;
1022  case jpiAnd:
1023  case jpiOr:
1024  case jpiEqual:
1025  case jpiNotEqual:
1026  case jpiLess:
1027  case jpiGreater:
1028  case jpiLessOrEqual:
1029  case jpiGreaterOrEqual:
1030  case jpiAdd:
1031  case jpiSub:
1032  case jpiMul:
1033  case jpiDiv:
1034  case jpiMod:
1035  case jpiStartsWith:
1036  case jpiDecimal:
1037  read_int32(v->content.args.left, base, pos);
1038  read_int32(v->content.args.right, base, pos);
1039  break;
1040  case jpiNot:
1041  case jpiIsUnknown:
1042  case jpiExists:
1043  case jpiPlus:
1044  case jpiMinus:
1045  case jpiFilter:
1046  case jpiDatetime:
1047  case jpiTime:
1048  case jpiTimeTz:
1049  case jpiTimestamp:
1050  case jpiTimestampTz:
1051  read_int32(v->content.arg, base, pos);
1052  break;
1053  case jpiIndexArray:
1054  read_int32(v->content.array.nelems, base, pos);
1055  read_int32_n(v->content.array.elems, base, pos,
1056  v->content.array.nelems * 2);
1057  break;
1058  case jpiAny:
1059  read_int32(v->content.anybounds.first, base, pos);
1060  read_int32(v->content.anybounds.last, base, pos);
1061  break;
1062  case jpiLikeRegex:
1063  read_int32(v->content.like_regex.flags, base, pos);
1064  read_int32(v->content.like_regex.expr, base, pos);
1065  read_int32(v->content.like_regex.patternlen, base, pos);
1066  v->content.like_regex.pattern = base + pos;
1067  break;
1068  default:
1069  elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
1070  }
1071 }
#define read_byte(v, b, p)
Definition: jsonpath.c:954
#define read_int32_n(v, b, p, n)
Definition: jsonpath.c:964
#define read_int32(v, b, p)
Definition: jsonpath.c:959
struct JsonPathItem::@137::@142 like_regex
struct JsonPathItem::@137::@140 anybounds

References JsonPathItem::anybounds, JsonPathItem::arg, JsonPathItem::args, JsonPathItem::array, JsonPathItem::base, JsonPathItem::content, elog, ERROR, INTALIGN, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBigint, jpiBool, jpiBoolean, jpiCeiling, jpiCurrent, jpiDate, jpiDatetime, jpiDecimal, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiInteger, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumber, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, 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().

◆ jspIsMutable()

bool jspIsMutable ( JsonPath path,
List varnames,
List varexprs 
)

Definition at line 1273 of file jsonpath.c.

1274 {
1275  struct JsonPathMutableContext cxt;
1276  JsonPathItem jpi;
1277 
1278  cxt.varnames = varnames;
1279  cxt.varexprs = varexprs;
1280  cxt.current = jpdsNonDateTime;
1281  cxt.lax = (path->header & JSONPATH_LAX) != 0;
1282  cxt.mutable = false;
1283 
1284  jspInit(&jpi, path);
1285  (void) jspIsMutableWalker(&jpi, &cxt);
1286 
1287  return cxt.mutable;
1288 }
static enum JsonPathDatatypeStatus jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
Definition: jsonpath.c:1294

References JsonPathMutableContext::current, JsonPath::header, jpdsNonDateTime, JSONPATH_LAX, jspInit(), jspIsMutableWalker(), JsonPathMutableContext::lax, JsonPathMutableContext::mutable, JsonPathMutableContext::varexprs, and JsonPathMutableContext::varnames.

Referenced by contain_mutable_functions_walker().

◆ jspIsMutableWalker()

static enum JsonPathDatatypeStatus jspIsMutableWalker ( JsonPathItem jpi,
struct JsonPathMutableContext cxt 
)
static

Definition at line 1273 of file jsonpath.c.

1295 {
1298 
1299  while (!cxt->mutable)
1300  {
1301  JsonPathItem arg;
1302  enum JsonPathDatatypeStatus leftStatus;
1303  enum JsonPathDatatypeStatus rightStatus;
1304 
1305  switch (jpi->type)
1306  {
1307  case jpiRoot:
1308  Assert(status == jpdsNonDateTime);
1309  break;
1310 
1311  case jpiCurrent:
1312  Assert(status == jpdsNonDateTime);
1313  status = cxt->current;
1314  break;
1315 
1316  case jpiFilter:
1317  {
1318  enum JsonPathDatatypeStatus prevStatus = cxt->current;
1319 
1320  cxt->current = status;
1321  jspGetArg(jpi, &arg);
1322  jspIsMutableWalker(&arg, cxt);
1323 
1324  cxt->current = prevStatus;
1325  break;
1326  }
1327 
1328  case jpiVariable:
1329  {
1330  int32 len;
1331  const char *name = jspGetString(jpi, &len);
1332  ListCell *lc1;
1333  ListCell *lc2;
1334 
1335  Assert(status == jpdsNonDateTime);
1336 
1337  forboth(lc1, cxt->varnames, lc2, cxt->varexprs)
1338  {
1339  String *varname = lfirst_node(String, lc1);
1340  Node *varexpr = lfirst(lc2);
1341 
1342  if (strncmp(varname->sval, name, len))
1343  continue;
1344 
1345  switch (exprType(varexpr))
1346  {
1347  case DATEOID:
1348  case TIMEOID:
1349  case TIMESTAMPOID:
1350  status = jpdsDateTimeNonZoned;
1351  break;
1352 
1353  case TIMETZOID:
1354  case TIMESTAMPTZOID:
1355  status = jpdsDateTimeZoned;
1356  break;
1357 
1358  default:
1359  status = jpdsNonDateTime;
1360  break;
1361  }
1362 
1363  break;
1364  }
1365  break;
1366  }
1367 
1368  case jpiEqual:
1369  case jpiNotEqual:
1370  case jpiLess:
1371  case jpiGreater:
1372  case jpiLessOrEqual:
1373  case jpiGreaterOrEqual:
1374  Assert(status == jpdsNonDateTime);
1375  jspGetLeftArg(jpi, &arg);
1376  leftStatus = jspIsMutableWalker(&arg, cxt);
1377 
1378  jspGetRightArg(jpi, &arg);
1379  rightStatus = jspIsMutableWalker(&arg, cxt);
1380 
1381  /*
1382  * Comparison of datetime type with different timezone status
1383  * is mutable.
1384  */
1385  if (leftStatus != jpdsNonDateTime &&
1386  rightStatus != jpdsNonDateTime &&
1387  (leftStatus == jpdsUnknownDateTime ||
1388  rightStatus == jpdsUnknownDateTime ||
1389  leftStatus != rightStatus))
1390  cxt->mutable = true;
1391  break;
1392 
1393  case jpiNot:
1394  case jpiIsUnknown:
1395  case jpiExists:
1396  case jpiPlus:
1397  case jpiMinus:
1398  Assert(status == jpdsNonDateTime);
1399  jspGetArg(jpi, &arg);
1400  jspIsMutableWalker(&arg, cxt);
1401  break;
1402 
1403  case jpiAnd:
1404  case jpiOr:
1405  case jpiAdd:
1406  case jpiSub:
1407  case jpiMul:
1408  case jpiDiv:
1409  case jpiMod:
1410  case jpiStartsWith:
1411  Assert(status == jpdsNonDateTime);
1412  jspGetLeftArg(jpi, &arg);
1413  jspIsMutableWalker(&arg, cxt);
1414  jspGetRightArg(jpi, &arg);
1415  jspIsMutableWalker(&arg, cxt);
1416  break;
1417 
1418  case jpiIndexArray:
1419  for (int i = 0; i < jpi->content.array.nelems; i++)
1420  {
1421  JsonPathItem from;
1422  JsonPathItem to;
1423 
1424  if (jspGetArraySubscript(jpi, &from, &to, i))
1425  jspIsMutableWalker(&to, cxt);
1426 
1427  jspIsMutableWalker(&from, cxt);
1428  }
1429  /* FALLTHROUGH */
1430 
1431  case jpiAnyArray:
1432  if (!cxt->lax)
1433  status = jpdsNonDateTime;
1434  break;
1435 
1436  case jpiAny:
1437  if (jpi->content.anybounds.first > 0)
1438  status = jpdsNonDateTime;
1439  break;
1440 
1441  case jpiDatetime:
1442  if (jpi->content.arg)
1443  {
1444  char *template;
1445 
1446  jspGetArg(jpi, &arg);
1447  if (arg.type != jpiString)
1448  {
1449  status = jpdsNonDateTime;
1450  break; /* there will be runtime error */
1451  }
1452 
1453  template = jspGetString(&arg, NULL);
1454  if (datetime_format_has_tz(template))
1455  status = jpdsDateTimeZoned;
1456  else
1457  status = jpdsDateTimeNonZoned;
1458  }
1459  else
1460  {
1461  status = jpdsUnknownDateTime;
1462  }
1463  break;
1464 
1465  case jpiLikeRegex:
1466  Assert(status == jpdsNonDateTime);
1467  jspInitByBuffer(&arg, jpi->base, jpi->content.like_regex.expr);
1468  jspIsMutableWalker(&arg, cxt);
1469  break;
1470 
1471  /* literals */
1472  case jpiNull:
1473  case jpiString:
1474  case jpiNumeric:
1475  case jpiBool:
1476  break;
1477  /* accessors */
1478  case jpiKey:
1479  case jpiAnyKey:
1480  /* special items */
1481  case jpiSubscript:
1482  case jpiLast:
1483  /* item methods */
1484  case jpiType:
1485  case jpiSize:
1486  case jpiAbs:
1487  case jpiFloor:
1488  case jpiCeiling:
1489  case jpiDouble:
1490  case jpiKeyValue:
1491  case jpiBigint:
1492  case jpiBoolean:
1493  case jpiDecimal:
1494  case jpiInteger:
1495  case jpiNumber:
1496  case jpiStringFunc:
1497  status = jpdsNonDateTime;
1498  break;
1499 
1500  case jpiTime:
1501  case jpiDate:
1502  case jpiTimestamp:
1503  status = jpdsDateTimeNonZoned;
1504  cxt->mutable = true;
1505  break;
1506 
1507  case jpiTimeTz:
1508  case jpiTimestampTz:
1509  status = jpdsDateTimeNonZoned;
1510  cxt->mutable = true;
1511  break;
1512 
1513  }
1514 
1515  if (!jspGetNext(jpi, &next))
1516  break;
1517 
1518  jpi = &next;
1519  }
1520 
1521  return status;
1522 }
bool datetime_format_has_tz(const char *fmt_str)
Definition: formatting.c:4618
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1159
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1074
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1231
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1092
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1181
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1219
JsonPathDatatypeStatus
Definition: jsonpath.c:1248
@ jpiSubscript
Definition: jsonpath.h:103
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:518
enum JsonPathDatatypeStatus current
Definition: jsonpath.c:1260
Definition: nodes.h:129
Definition: value.h:64
char * sval
Definition: value.h:68
const char * name

Referenced by jspIsMutable().

◆ jspOperationName()

const char* jspOperationName ( JsonPathItemType  type)

Definition at line 836 of file jsonpath.c.

837 {
838  switch (type)
839  {
840  case jpiAnd:
841  return "&&";
842  case jpiOr:
843  return "||";
844  case jpiEqual:
845  return "==";
846  case jpiNotEqual:
847  return "!=";
848  case jpiLess:
849  return "<";
850  case jpiGreater:
851  return ">";
852  case jpiLessOrEqual:
853  return "<=";
854  case jpiGreaterOrEqual:
855  return ">=";
856  case jpiAdd:
857  case jpiPlus:
858  return "+";
859  case jpiSub:
860  case jpiMinus:
861  return "-";
862  case jpiMul:
863  return "*";
864  case jpiDiv:
865  return "/";
866  case jpiMod:
867  return "%";
868  case jpiType:
869  return "type";
870  case jpiSize:
871  return "size";
872  case jpiAbs:
873  return "abs";
874  case jpiFloor:
875  return "floor";
876  case jpiCeiling:
877  return "ceiling";
878  case jpiDouble:
879  return "double";
880  case jpiDatetime:
881  return "datetime";
882  case jpiKeyValue:
883  return "keyvalue";
884  case jpiStartsWith:
885  return "starts with";
886  case jpiLikeRegex:
887  return "like_regex";
888  case jpiBigint:
889  return "bigint";
890  case jpiBoolean:
891  return "boolean";
892  case jpiDate:
893  return "date";
894  case jpiDecimal:
895  return "decimal";
896  case jpiInteger:
897  return "integer";
898  case jpiNumber:
899  return "number";
900  case jpiStringFunc:
901  return "string";
902  case jpiTime:
903  return "time";
904  case jpiTimeTz:
905  return "time_tz";
906  case jpiTimestamp:
907  return "timestamp";
908  case jpiTimestampTz:
909  return "timestamp_tz";
910  default:
911  elog(ERROR, "unrecognized jsonpath item type: %d", type);
912  return NULL;
913  }
914 }
const char * type

References elog, ERROR, jpiAbs, jpiAdd, jpiAnd, jpiBigint, jpiBoolean, jpiCeiling, jpiDate, jpiDatetime, jpiDecimal, jpiDiv, jpiDouble, jpiEqual, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiInteger, jpiKeyValue, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNotEqual, jpiNumber, jpiOr, jpiPlus, jpiSize, jpiStartsWith, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, and type.

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

◆ operationPriority()

static int operationPriority ( JsonPathItemType  op)
static

Definition at line 917 of file jsonpath.c.

918 {
919  switch (op)
920  {
921  case jpiOr:
922  return 0;
923  case jpiAnd:
924  return 1;
925  case jpiEqual:
926  case jpiNotEqual:
927  case jpiLess:
928  case jpiGreater:
929  case jpiLessOrEqual:
930  case jpiGreaterOrEqual:
931  case jpiStartsWith:
932  return 2;
933  case jpiAdd:
934  case jpiSub:
935  return 3;
936  case jpiMul:
937  case jpiDiv:
938  case jpiMod:
939  return 4;
940  case jpiPlus:
941  case jpiMinus:
942  return 5;
943  default:
944  return 6;
945  }
946 }

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

Referenced by printJsonPathItem().

◆ printJsonPathItem()

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

Definition at line 521 of file jsonpath.c.

523 {
524  JsonPathItem elem;
525  int i;
526 
529 
530  switch (v->type)
531  {
532  case jpiNull:
533  appendStringInfoString(buf, "null");
534  break;
535  case jpiString:
536  escape_json(buf, jspGetString(v, NULL));
537  break;
538  case jpiNumeric:
539  if (jspHasNext(v))
544  if (jspHasNext(v))
546  break;
547  case jpiBool:
548  if (jspGetBool(v))
549  appendStringInfoString(buf, "true");
550  else
551  appendStringInfoString(buf, "false");
552  break;
553  case jpiAnd:
554  case jpiOr:
555  case jpiEqual:
556  case jpiNotEqual:
557  case jpiLess:
558  case jpiGreater:
559  case jpiLessOrEqual:
560  case jpiGreaterOrEqual:
561  case jpiAdd:
562  case jpiSub:
563  case jpiMul:
564  case jpiDiv:
565  case jpiMod:
566  case jpiStartsWith:
567  if (printBracketes)
569  jspGetLeftArg(v, &elem);
570  printJsonPathItem(buf, &elem, false,
571  operationPriority(elem.type) <=
572  operationPriority(v->type));
576  jspGetRightArg(v, &elem);
577  printJsonPathItem(buf, &elem, false,
578  operationPriority(elem.type) <=
579  operationPriority(v->type));
580  if (printBracketes)
582  break;
583  case jpiNot:
585  jspGetArg(v, &elem);
586  printJsonPathItem(buf, &elem, false, false);
588  break;
589  case jpiIsUnknown:
591  jspGetArg(v, &elem);
592  printJsonPathItem(buf, &elem, false, false);
593  appendStringInfoString(buf, ") is unknown");
594  break;
595  case jpiPlus:
596  case jpiMinus:
597  if (printBracketes)
599  appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
600  jspGetArg(v, &elem);
601  printJsonPathItem(buf, &elem, false,
602  operationPriority(elem.type) <=
603  operationPriority(v->type));
604  if (printBracketes)
606  break;
607  case jpiAnyArray:
608  appendStringInfoString(buf, "[*]");
609  break;
610  case jpiAnyKey:
611  if (inKey)
614  break;
615  case jpiIndexArray:
617  for (i = 0; i < v->content.array.nelems; i++)
618  {
619  JsonPathItem from;
620  JsonPathItem to;
621  bool range = jspGetArraySubscript(v, &from, &to, i);
622 
623  if (i)
625 
626  printJsonPathItem(buf, &from, false, false);
627 
628  if (range)
629  {
630  appendStringInfoString(buf, " to ");
631  printJsonPathItem(buf, &to, false, false);
632  }
633  }
635  break;
636  case jpiAny:
637  if (inKey)
639 
640  if (v->content.anybounds.first == 0 &&
641  v->content.anybounds.last == PG_UINT32_MAX)
643  else if (v->content.anybounds.first == v->content.anybounds.last)
644  {
645  if (v->content.anybounds.first == PG_UINT32_MAX)
646  appendStringInfoString(buf, "**{last}");
647  else
648  appendStringInfo(buf, "**{%u}",
649  v->content.anybounds.first);
650  }
651  else if (v->content.anybounds.first == PG_UINT32_MAX)
652  appendStringInfo(buf, "**{last to %u}",
653  v->content.anybounds.last);
654  else if (v->content.anybounds.last == PG_UINT32_MAX)
655  appendStringInfo(buf, "**{%u to last}",
656  v->content.anybounds.first);
657  else
658  appendStringInfo(buf, "**{%u to %u}",
659  v->content.anybounds.first,
660  v->content.anybounds.last);
661  break;
662  case jpiKey:
663  if (inKey)
665  escape_json(buf, jspGetString(v, NULL));
666  break;
667  case jpiCurrent:
668  Assert(!inKey);
670  break;
671  case jpiRoot:
672  Assert(!inKey);
674  break;
675  case jpiVariable:
677  escape_json(buf, jspGetString(v, NULL));
678  break;
679  case jpiFilter:
681  jspGetArg(v, &elem);
682  printJsonPathItem(buf, &elem, false, false);
684  break;
685  case jpiExists:
686  appendStringInfoString(buf, "exists (");
687  jspGetArg(v, &elem);
688  printJsonPathItem(buf, &elem, false, false);
690  break;
691  case jpiType:
692  appendStringInfoString(buf, ".type()");
693  break;
694  case jpiSize:
695  appendStringInfoString(buf, ".size()");
696  break;
697  case jpiAbs:
698  appendStringInfoString(buf, ".abs()");
699  break;
700  case jpiFloor:
701  appendStringInfoString(buf, ".floor()");
702  break;
703  case jpiCeiling:
704  appendStringInfoString(buf, ".ceiling()");
705  break;
706  case jpiDouble:
707  appendStringInfoString(buf, ".double()");
708  break;
709  case jpiDatetime:
710  appendStringInfoString(buf, ".datetime(");
711  if (v->content.arg)
712  {
713  jspGetArg(v, &elem);
714  printJsonPathItem(buf, &elem, false, false);
715  }
717  break;
718  case jpiKeyValue:
719  appendStringInfoString(buf, ".keyvalue()");
720  break;
721  case jpiLast:
722  appendStringInfoString(buf, "last");
723  break;
724  case jpiLikeRegex:
725  if (printBracketes)
727 
728  jspInitByBuffer(&elem, v->base, v->content.like_regex.expr);
729  printJsonPathItem(buf, &elem, false,
730  operationPriority(elem.type) <=
731  operationPriority(v->type));
732 
733  appendStringInfoString(buf, " like_regex ");
734 
735  escape_json(buf, v->content.like_regex.pattern);
736 
737  if (v->content.like_regex.flags)
738  {
739  appendStringInfoString(buf, " flag \"");
740 
741  if (v->content.like_regex.flags & JSP_REGEX_ICASE)
743  if (v->content.like_regex.flags & JSP_REGEX_DOTALL)
745  if (v->content.like_regex.flags & JSP_REGEX_MLINE)
747  if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
749  if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
751 
753  }
754 
755  if (printBracketes)
757  break;
758  case jpiBigint:
759  appendStringInfoString(buf, ".bigint()");
760  break;
761  case jpiBoolean:
762  appendStringInfoString(buf, ".boolean()");
763  break;
764  case jpiDate:
765  appendStringInfoString(buf, ".date()");
766  break;
767  case jpiDecimal:
768  appendStringInfoString(buf, ".decimal(");
769  if (v->content.args.left)
770  {
771  jspGetLeftArg(v, &elem);
772  printJsonPathItem(buf, &elem, false, false);
773  }
774  if (v->content.args.right)
775  {
777  jspGetRightArg(v, &elem);
778  printJsonPathItem(buf, &elem, false, false);
779  }
781  break;
782  case jpiInteger:
783  appendStringInfoString(buf, ".integer()");
784  break;
785  case jpiNumber:
786  appendStringInfoString(buf, ".number()");
787  break;
788  case jpiStringFunc:
789  appendStringInfoString(buf, ".string()");
790  break;
791  case jpiTime:
792  appendStringInfoString(buf, ".time(");
793  if (v->content.arg)
794  {
795  jspGetArg(v, &elem);
796  printJsonPathItem(buf, &elem, false, false);
797  }
799  break;
800  case jpiTimeTz:
801  appendStringInfoString(buf, ".time_tz(");
802  if (v->content.arg)
803  {
804  jspGetArg(v, &elem);
805  printJsonPathItem(buf, &elem, false, false);
806  }
808  break;
809  case jpiTimestamp:
810  appendStringInfoString(buf, ".timestamp(");
811  if (v->content.arg)
812  {
813  jspGetArg(v, &elem);
814  printJsonPathItem(buf, &elem, false, false);
815  }
817  break;
818  case jpiTimestampTz:
819  appendStringInfoString(buf, ".timestamp_tz(");
820  if (v->content.arg)
821  {
822  jspGetArg(v, &elem);
823  printJsonPathItem(buf, &elem, false, false);
824  }
826  break;
827  default:
828  elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
829  }
830 
831  if (jspGetNext(v, &elem))
832  printJsonPathItem(buf, &elem, true, true);
833 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:807
#define PG_UINT32_MAX
Definition: c.h:590
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1549
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1203
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:836
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1211
static int operationPriority(JsonPathItemType op)
Definition: jsonpath.c:917
#define JSP_REGEX_WSPACE
Definition: jsonpath.h:124
#define JSP_REGEX_MLINE
Definition: jsonpath.h:123
#define JSP_REGEX_ICASE
Definition: jsonpath.h:121
#define JSP_REGEX_DOTALL
Definition: jsonpath.h:122
#define JSP_REGEX_QUOTE
Definition: jsonpath.h:125
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:73
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97

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

Referenced by jsonPathToCstring().

◆ reserveSpaceForItemPointer()

static int32 reserveSpaceForItemPointer ( StringInfo  buf)
static

Definition at line 507 of file jsonpath.c.

508 {
509  int32 pos = buf->len;
510  int32 ptr = 0;
511 
512  appendBinaryStringInfo(buf, &ptr, sizeof(ptr));
513 
514  return pos;
515 }

References appendBinaryStringInfo(), and buf.

Referenced by flattenJsonPathParseItem().