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 961 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:496

Definition at line 966 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 971 of file jsonpath.c.

Enumeration Type Documentation

◆ JsonPathDatatypeStatus

Enumerator
jpdsNonDateTime 
jpdsUnknownDateTime 
jpdsDateTimeZoned 
jpdsDateTimeNonZoned 

Definition at line 1254 of file jsonpath.c.

1255 {
1256  jpdsNonDateTime, /* null, bool, numeric, string, array, object */
1257  jpdsUnknownDateTime, /* unknown datetime type */
1258  jpdsDateTimeZoned, /* timetz, timestamptz */
1259  jpdsDateTimeNonZoned, /* time, timestamp, date */
1260 };
@ jpdsDateTimeZoned
Definition: jsonpath.c:1258
@ jpdsNonDateTime
Definition: jsonpath.c:1256
@ jpdsDateTimeNonZoned
Definition: jsonpath.c:1259
@ jpdsUnknownDateTime
Definition: jsonpath.c:1257

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:799
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:222
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
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:3564
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::@146::@150 like_regex
JsonPathParseItem * next
Definition: jsonpath.h:220
struct JsonPathParseItem::@146::@147 args
Numeric numeric
Definition: jsonpath.h:262
union JsonPathParseItem::@146 value
struct JsonPathParseItem::@146::@149 anybounds
struct JsonPathParseItem::@146::@148 array
struct JsonPathParseItem::@146::@151 string
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:1521
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:53
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:980
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 1081 of file jsonpath.c.

1082 {
1083  Assert(v->type == jpiNot ||
1084  v->type == jpiIsUnknown ||
1085  v->type == jpiPlus ||
1086  v->type == jpiMinus ||
1087  v->type == jpiFilter ||
1088  v->type == jpiExists ||
1089  v->type == jpiDatetime ||
1090  v->type == jpiTime ||
1091  v->type == jpiTimeTz ||
1092  v->type == jpiTimestamp ||
1093  v->type == jpiTimestampTz);
1094 
1095  jspInitByBuffer(a, v->base, v->content.arg);
1096 }
#define Assert(condition)
Definition: c.h:849
int a
Definition: isn.c:69
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:990
union JsonPathItem::@139 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 1238 of file jsonpath.c.

1240 {
1241  Assert(v->type == jpiIndexArray);
1242 
1243  jspInitByBuffer(from, v->base, v->content.array.elems[i].from);
1244 
1245  if (!v->content.array.elems[i].to)
1246  return false;
1247 
1248  jspInitByBuffer(to, v->base, v->content.array.elems[i].to);
1249 
1250  return true;
1251 }
struct JsonPathItem::@139::@141 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 1210 of file jsonpath.c.

1211 {
1212  Assert(v->type == jpiBool);
1213 
1214  return (bool) *v->content.value.data;
1215 }
struct JsonPathItem::@139::@143 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 1166 of file jsonpath.c.

1167 {
1168  Assert(v->type == jpiAnd ||
1169  v->type == jpiOr ||
1170  v->type == jpiEqual ||
1171  v->type == jpiNotEqual ||
1172  v->type == jpiLess ||
1173  v->type == jpiGreater ||
1174  v->type == jpiLessOrEqual ||
1175  v->type == jpiGreaterOrEqual ||
1176  v->type == jpiAdd ||
1177  v->type == jpiSub ||
1178  v->type == jpiMul ||
1179  v->type == jpiDiv ||
1180  v->type == jpiMod ||
1181  v->type == jpiStartsWith ||
1182  v->type == jpiDecimal);
1183 
1184  jspInitByBuffer(a, v->base, v->content.args.left);
1185 }
struct JsonPathItem::@139::@140 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 1099 of file jsonpath.c.

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

1219 {
1220  Assert(v->type == jpiNumeric);
1221 
1222  return (Numeric) v->content.value.data;
1223 }

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 1188 of file jsonpath.c.

1189 {
1190  Assert(v->type == jpiAnd ||
1191  v->type == jpiOr ||
1192  v->type == jpiEqual ||
1193  v->type == jpiNotEqual ||
1194  v->type == jpiLess ||
1195  v->type == jpiGreater ||
1196  v->type == jpiLessOrEqual ||
1197  v->type == jpiGreaterOrEqual ||
1198  v->type == jpiAdd ||
1199  v->type == jpiSub ||
1200  v->type == jpiMul ||
1201  v->type == jpiDiv ||
1202  v->type == jpiMod ||
1203  v->type == jpiStartsWith ||
1204  v->type == jpiDecimal);
1205 
1206  jspInitByBuffer(a, v->base, v->content.args.right);
1207 }

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 1226 of file jsonpath.c.

1227 {
1228  Assert(v->type == jpiKey ||
1229  v->type == jpiString ||
1230  v->type == jpiVariable);
1231 
1232  if (len)
1233  *len = v->content.value.datalen;
1234  return v->content.value.data;
1235 }

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 980 of file jsonpath.c.

981 {
983  jspInitByBuffer(v, js->data, 0);
984 }
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 990 of file jsonpath.c.

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

1281 {
1282  struct JsonPathMutableContext cxt;
1283  JsonPathItem jpi;
1284 
1285  cxt.varnames = varnames;
1286  cxt.varexprs = varexprs;
1287  cxt.current = jpdsNonDateTime;
1288  cxt.lax = (path->header & JSONPATH_LAX) != 0;
1289  cxt.mutable = false;
1290 
1291  jspInit(&jpi, path);
1292  (void) jspIsMutableWalker(&jpi, &cxt);
1293 
1294  return cxt.mutable;
1295 }
static enum JsonPathDatatypeStatus jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
Definition: jsonpath.c:1301

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 1280 of file jsonpath.c.

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

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

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

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  int32 len;
527  char *str;
528 
531 
532  switch (v->type)
533  {
534  case jpiNull:
535  appendStringInfoString(buf, "null");
536  break;
537  case jpiString:
538  str = jspGetString(v, &len);
540  break;
541  case jpiNumeric:
542  if (jspHasNext(v))
547  if (jspHasNext(v))
549  break;
550  case jpiBool:
551  if (jspGetBool(v))
552  appendStringInfoString(buf, "true");
553  else
554  appendStringInfoString(buf, "false");
555  break;
556  case jpiAnd:
557  case jpiOr:
558  case jpiEqual:
559  case jpiNotEqual:
560  case jpiLess:
561  case jpiGreater:
562  case jpiLessOrEqual:
563  case jpiGreaterOrEqual:
564  case jpiAdd:
565  case jpiSub:
566  case jpiMul:
567  case jpiDiv:
568  case jpiMod:
569  case jpiStartsWith:
570  if (printBracketes)
572  jspGetLeftArg(v, &elem);
573  printJsonPathItem(buf, &elem, false,
574  operationPriority(elem.type) <=
575  operationPriority(v->type));
579  jspGetRightArg(v, &elem);
580  printJsonPathItem(buf, &elem, false,
581  operationPriority(elem.type) <=
582  operationPriority(v->type));
583  if (printBracketes)
585  break;
586  case jpiNot:
588  jspGetArg(v, &elem);
589  printJsonPathItem(buf, &elem, false, false);
591  break;
592  case jpiIsUnknown:
594  jspGetArg(v, &elem);
595  printJsonPathItem(buf, &elem, false, false);
596  appendStringInfoString(buf, ") is unknown");
597  break;
598  case jpiPlus:
599  case jpiMinus:
600  if (printBracketes)
602  appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
603  jspGetArg(v, &elem);
604  printJsonPathItem(buf, &elem, false,
605  operationPriority(elem.type) <=
606  operationPriority(v->type));
607  if (printBracketes)
609  break;
610  case jpiAnyArray:
611  appendStringInfoString(buf, "[*]");
612  break;
613  case jpiAnyKey:
614  if (inKey)
617  break;
618  case jpiIndexArray:
620  for (i = 0; i < v->content.array.nelems; i++)
621  {
622  JsonPathItem from;
623  JsonPathItem to;
624  bool range = jspGetArraySubscript(v, &from, &to, i);
625 
626  if (i)
628 
629  printJsonPathItem(buf, &from, false, false);
630 
631  if (range)
632  {
633  appendStringInfoString(buf, " to ");
634  printJsonPathItem(buf, &to, false, false);
635  }
636  }
638  break;
639  case jpiAny:
640  if (inKey)
642 
643  if (v->content.anybounds.first == 0 &&
644  v->content.anybounds.last == PG_UINT32_MAX)
646  else if (v->content.anybounds.first == v->content.anybounds.last)
647  {
648  if (v->content.anybounds.first == PG_UINT32_MAX)
649  appendStringInfoString(buf, "**{last}");
650  else
651  appendStringInfo(buf, "**{%u}",
652  v->content.anybounds.first);
653  }
654  else if (v->content.anybounds.first == PG_UINT32_MAX)
655  appendStringInfo(buf, "**{last to %u}",
656  v->content.anybounds.last);
657  else if (v->content.anybounds.last == PG_UINT32_MAX)
658  appendStringInfo(buf, "**{%u to last}",
659  v->content.anybounds.first);
660  else
661  appendStringInfo(buf, "**{%u to %u}",
662  v->content.anybounds.first,
663  v->content.anybounds.last);
664  break;
665  case jpiKey:
666  if (inKey)
668  str = jspGetString(v, &len);
670  break;
671  case jpiCurrent:
672  Assert(!inKey);
674  break;
675  case jpiRoot:
676  Assert(!inKey);
678  break;
679  case jpiVariable:
681  str = jspGetString(v, &len);
683  break;
684  case jpiFilter:
686  jspGetArg(v, &elem);
687  printJsonPathItem(buf, &elem, false, false);
689  break;
690  case jpiExists:
691  appendStringInfoString(buf, "exists (");
692  jspGetArg(v, &elem);
693  printJsonPathItem(buf, &elem, false, false);
695  break;
696  case jpiType:
697  appendStringInfoString(buf, ".type()");
698  break;
699  case jpiSize:
700  appendStringInfoString(buf, ".size()");
701  break;
702  case jpiAbs:
703  appendStringInfoString(buf, ".abs()");
704  break;
705  case jpiFloor:
706  appendStringInfoString(buf, ".floor()");
707  break;
708  case jpiCeiling:
709  appendStringInfoString(buf, ".ceiling()");
710  break;
711  case jpiDouble:
712  appendStringInfoString(buf, ".double()");
713  break;
714  case jpiDatetime:
715  appendStringInfoString(buf, ".datetime(");
716  if (v->content.arg)
717  {
718  jspGetArg(v, &elem);
719  printJsonPathItem(buf, &elem, false, false);
720  }
722  break;
723  case jpiKeyValue:
724  appendStringInfoString(buf, ".keyvalue()");
725  break;
726  case jpiLast:
727  appendStringInfoString(buf, "last");
728  break;
729  case jpiLikeRegex:
730  if (printBracketes)
732 
733  jspInitByBuffer(&elem, v->base, v->content.like_regex.expr);
734  printJsonPathItem(buf, &elem, false,
735  operationPriority(elem.type) <=
736  operationPriority(v->type));
737 
738  appendStringInfoString(buf, " like_regex ");
739 
741  v->content.like_regex.pattern,
742  v->content.like_regex.patternlen);
743 
744  if (v->content.like_regex.flags)
745  {
746  appendStringInfoString(buf, " flag \"");
747 
748  if (v->content.like_regex.flags & JSP_REGEX_ICASE)
750  if (v->content.like_regex.flags & JSP_REGEX_DOTALL)
752  if (v->content.like_regex.flags & JSP_REGEX_MLINE)
754  if (v->content.like_regex.flags & JSP_REGEX_WSPACE)
756  if (v->content.like_regex.flags & JSP_REGEX_QUOTE)
758 
760  }
761 
762  if (printBracketes)
764  break;
765  case jpiBigint:
766  appendStringInfoString(buf, ".bigint()");
767  break;
768  case jpiBoolean:
769  appendStringInfoString(buf, ".boolean()");
770  break;
771  case jpiDate:
772  appendStringInfoString(buf, ".date()");
773  break;
774  case jpiDecimal:
775  appendStringInfoString(buf, ".decimal(");
776  if (v->content.args.left)
777  {
778  jspGetLeftArg(v, &elem);
779  printJsonPathItem(buf, &elem, false, false);
780  }
781  if (v->content.args.right)
782  {
784  jspGetRightArg(v, &elem);
785  printJsonPathItem(buf, &elem, false, false);
786  }
788  break;
789  case jpiInteger:
790  appendStringInfoString(buf, ".integer()");
791  break;
792  case jpiNumber:
793  appendStringInfoString(buf, ".number()");
794  break;
795  case jpiStringFunc:
796  appendStringInfoString(buf, ".string()");
797  break;
798  case jpiTime:
799  appendStringInfoString(buf, ".time(");
800  if (v->content.arg)
801  {
802  jspGetArg(v, &elem);
803  printJsonPathItem(buf, &elem, false, false);
804  }
806  break;
807  case jpiTimeTz:
808  appendStringInfoString(buf, ".time_tz(");
809  if (v->content.arg)
810  {
811  jspGetArg(v, &elem);
812  printJsonPathItem(buf, &elem, false, false);
813  }
815  break;
816  case jpiTimestamp:
817  appendStringInfoString(buf, ".timestamp(");
818  if (v->content.arg)
819  {
820  jspGetArg(v, &elem);
821  printJsonPathItem(buf, &elem, false, false);
822  }
824  break;
825  case jpiTimestampTz:
826  appendStringInfoString(buf, ".timestamp_tz(");
827  if (v->content.arg)
828  {
829  jspGetArg(v, &elem);
830  printJsonPathItem(buf, &elem, false, false);
831  }
833  break;
834  default:
835  elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
836  }
837 
838  if (jspGetNext(v, &elem))
839  printJsonPathItem(buf, &elem, true, true);
840 }
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:815
#define PG_UINT32_MAX
Definition: c.h:581
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition: json.c:1631
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1210
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:843
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1218
static int operationPriority(JsonPathItemType op)
Definition: jsonpath.c:924
#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_with_len(), 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(), len, JsonPathItem::like_regex, numeric_out(), NumericGetDatum(), operationPriority(), PG_UINT32_MAX, range(), str, 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().