PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 charjsonPathToCstring (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 charjspOperationName (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)
 
charjspGetString (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) \
uint8_t uint8
Definition c.h:622
int b
Definition isn.c:74

Definition at line 1039 of file jsonpath.c.

1039 { \
1040 (v) = *(uint8*)((b) + (p)); \
1041 (p) += 1; \
1042} while(0) \
1043

◆ read_int32

#define read_int32 (   v,
  b,
 
)
Value:
do { \
(v) = *(uint32*)((b) + (p)); \
(p) += sizeof(int32); \
} while(0) \
int32_t int32
Definition c.h:620
uint32_t uint32
Definition c.h:624

Definition at line 1044 of file jsonpath.c.

1044 { \
1045 (v) = *(uint32*)((b) + (p)); \
1046 (p) += sizeof(int32); \
1047} while(0) \
1048

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

1049 { \
1050 (v) = (void *)((b) + (p)); \
1051 (p) += sizeof(int32) * (n); \
1052} while(0) \
1053

Enumeration Type Documentation

◆ JsonPathDatatypeStatus

Enumerator
jpdsNonDateTime 
jpdsUnknownDateTime 
jpdsDateTimeZoned 
jpdsDateTimeNonZoned 

Definition at line 1355 of file jsonpath.c.

1356{
1357 jpdsNonDateTime, /* null, bool, numeric, string, array, object */
1358 jpdsUnknownDateTime, /* unknown datetime type */
1359 jpdsDateTimeZoned, /* timetz, timestamptz */
1360 jpdsDateTimeNonZoned, /* time, timestamp, date */
1361};
@ jpdsDateTimeZoned
Definition jsonpath.c:1359
@ jpdsNonDateTime
Definition jsonpath.c:1357
@ jpdsDateTimeNonZoned
Definition jsonpath.c:1360
@ jpdsUnknownDateTime
Definition jsonpath.c:1358

Function Documentation

◆ alignStringInfoInt()

static void alignStringInfoInt ( StringInfo  buf)
static

Definition at line 492 of file jsonpath.c.

493{
494 switch (INTALIGN(buf->len) - buf->len)
495 {
496 case 3:
499 case 2:
502 case 1:
505 default:
506 break;
507 }
508}
#define INTALIGN(LEN)
Definition c.h:893
#define pg_fallthrough
Definition c.h:161
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define appendStringInfoCharMacro(str, ch)
Definition stringinfo.h:231

References appendStringInfoCharMacro, buf, INTALIGN, and pg_fallthrough.

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);
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:
294 case jpiAdd:
295 case jpiSub:
296 case jpiMul:
297 case jpiDiv:
298 case jpiMod:
299 case jpiStartsWith:
300 case jpiDecimal:
301 case jpiStrReplace:
302 case jpiStrSplitPart:
303 {
304 /*
305 * First, reserve place for left/right arg's positions, then
306 * record both args and sets actual position in reserved
307 * places.
308 */
311
312 if (!item->value.args.left)
313 chld = pos;
314 else if (!flattenJsonPathParseItem(buf, &chld, escontext,
315 item->value.args.left,
316 nestingLevel + argNestingLevel,
318 return false;
319 *(int32 *) (buf->data + left) = chld - pos;
320
321 if (!item->value.args.right)
322 chld = pos;
323 else if (!flattenJsonPathParseItem(buf, &chld, escontext,
324 item->value.args.right,
325 nestingLevel + argNestingLevel,
327 return false;
328 *(int32 *) (buf->data + right) = chld - pos;
329 }
330 break;
331 case jpiLikeRegex:
332 {
333 int32 offs;
334
336 &item->value.like_regex.flags,
337 sizeof(item->value.like_regex.flags));
341 sizeof(item->value.like_regex.patternlen));
345
346 if (!flattenJsonPathParseItem(buf, &chld, escontext,
347 item->value.like_regex.expr,
348 nestingLevel,
350 return false;
351 *(int32 *) (buf->data + offs) = chld - pos;
352 }
353 break;
354 case jpiFilter:
357 case jpiIsUnknown:
358 case jpiNot:
359 case jpiPlus:
360 case jpiMinus:
361 case jpiExists:
362 case jpiDatetime:
363 case jpiTime:
364 case jpiTimeTz:
365 case jpiTimestamp:
366 case jpiTimestampTz:
367 case jpiStrLtrim:
368 case jpiStrRtrim:
369 case jpiStrBtrim:
370 {
372
373 if (!item->value.arg)
374 chld = pos;
375 else if (!flattenJsonPathParseItem(buf, &chld, escontext,
376 item->value.arg,
377 nestingLevel + argNestingLevel,
379 return false;
380 *(int32 *) (buf->data + arg) = chld - pos;
381 }
382 break;
383 case jpiNull:
384 break;
385 case jpiRoot:
386 break;
387 case jpiAnyArray:
388 case jpiAnyKey:
389 break;
390 case jpiCurrent:
391 if (nestingLevel <= 0)
392 ereturn(escontext, false,
394 errmsg("@ is not allowed in root expressions")));
395 break;
396 case jpiLast:
398 ereturn(escontext, false,
400 errmsg("LAST is allowed only in array subscripts")));
401 break;
402 case jpiIndexArray:
403 {
404 int32 nelems = item->value.array.nelems;
405 int offset;
406 int i;
407
408 appendBinaryStringInfo(buf, &nelems, sizeof(nelems));
409
410 offset = buf->len;
411
412 appendStringInfoSpaces(buf, sizeof(int32) * 2 * nelems);
413
414 for (i = 0; i < nelems; i++)
415 {
416 int32 *ppos;
417 int32 topos;
419
420 if (!flattenJsonPathParseItem(buf, &frompos, escontext,
421 item->value.array.elems[i].from,
422 nestingLevel, true))
423 return false;
424 frompos -= pos;
425
426 if (item->value.array.elems[i].to)
427 {
428 if (!flattenJsonPathParseItem(buf, &topos, escontext,
429 item->value.array.elems[i].to,
430 nestingLevel, true))
431 return false;
432 topos -= pos;
433 }
434 else
435 topos = 0;
436
437 ppos = (int32 *) &buf->data[offset + i * 2 * sizeof(int32)];
438
439 ppos[0] = frompos;
440 ppos[1] = topos;
441 }
442 }
443 break;
444 case jpiAny:
446 &item->value.anybounds.first,
447 sizeof(item->value.anybounds.first));
449 &item->value.anybounds.last,
450 sizeof(item->value.anybounds.last));
451 break;
452 case jpiType:
453 case jpiSize:
454 case jpiAbs:
455 case jpiFloor:
456 case jpiCeiling:
457 case jpiDouble:
458 case jpiKeyValue:
459 case jpiBigint:
460 case jpiBoolean:
461 case jpiDate:
462 case jpiInteger:
463 case jpiNumber:
464 case jpiStringFunc:
465 case jpiStrLower:
466 case jpiStrUpper:
467 case jpiStrInitcap:
468 break;
469 default:
470 elog(ERROR, "unrecognized jsonpath item type: %d", item->type);
471 }
472
473 if (item->next)
474 {
475 if (!flattenJsonPathParseItem(buf, &chld, escontext,
476 item->next, nestingLevel,
478 return false;
479 chld -= pos;
480 *(int32 *) (buf->data + next) = chld;
481 }
482
483 if (result)
484 *result = pos;
485 return true;
486}
static int32 next
Definition blutils.c:225
uint32 result
Datum arg
Definition elog.c:1322
int errcode(int sqlerrcode)
Definition elog.c:874
#define ereturn(context, dummy_value,...)
Definition elog.h:280
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
int i
Definition isn.c:77
static void alignStringInfoInt(StringInfo buf)
Definition jsonpath.c:492
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:515
@ 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
@ jpiStrRtrim
Definition jsonpath.h:122
@ jpiBigint
Definition jsonpath.h:107
@ jpiBool
Definition jsonpath.h:67
@ jpiType
Definition jsonpath.h:95
@ jpiStrUpper
Definition jsonpath.h:120
@ jpiFloor
Definition jsonpath.h:98
@ jpiStrBtrim
Definition jsonpath.h:123
@ jpiAnyArray
Definition jsonpath.h:85
@ jpiExists
Definition jsonpath.h:94
@ jpiSize
Definition jsonpath.h:96
@ jpiStrReplace
Definition jsonpath.h:118
@ 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
@ jpiStrInitcap
Definition jsonpath.h:124
@ jpiDouble
Definition jsonpath.h:100
@ jpiGreater
Definition jsonpath.h:75
@ jpiNumber
Definition jsonpath.h:112
@ jpiStrLtrim
Definition jsonpath.h:121
@ 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
@ jpiStrSplitPart
Definition jsonpath.h:125
@ 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
@ jpiStrLower
Definition jsonpath.h:119
@ 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:125
static char * errmsg
static int fb(int x)
void check_stack_depth(void)
Definition stack_depth.c:95
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition stringinfo.c:281
void appendStringInfoSpaces(StringInfo str, int count)
Definition stringinfo.c:260
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
JsonPathParseItem * arg
Definition jsonpath.h:241
struct JsonPathParseItem::@165::@166 args
struct JsonPathParseItem::@165::@168 anybounds
JsonPathParseItem * expr
Definition jsonpath.h:263
JsonPathParseItem * left
Definition jsonpath.h:236
JsonPathParseItem * right
Definition jsonpath.h:237
struct JsonPathParseItem::@165::@167 array
struct JsonPathParseItem::@165::@169 like_regex
JsonPathParseItem * next
Definition jsonpath.h:228
struct JsonPathParseItem::@165::@170 string
struct JsonPathParseItem::@165::@167::@171 * elems
union JsonPathParseItem::@165 value
JsonPathItemType type
Definition jsonpath.h:227
static Size VARSIZE(const void *PTR)
Definition varatt.h:298

References alignStringInfoInt(), JsonPathParseItem::anybounds, appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoSpaces(), arg, JsonPathParseItem::arg, JsonPathParseItem::args, JsonPathParseItem::array, JsonPathParseItem::boolean, buf, CHECK_FOR_INTERRUPTS, check_stack_depth(), JsonPathParseItem::elems, elog, ereturn, errcode(), errmsg, ERROR, JsonPathParseItem::expr, fb(), JsonPathParseItem::first, JsonPathParseItem::flags, flattenJsonPathParseItem(), 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, jpiStrBtrim, jpiString, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, JSONPATH_HDRSZ, JsonPathParseItem::last, JsonPathParseItem::left, JsonPathParseItem::len, JsonPathParseItem::like_regex, JsonPathParseItem::nelems, next, JsonPathParseItem::next, JsonPathParseItem::numeric, JsonPathParseItem::pattern, JsonPathParseItem::patternlen, pg_fallthrough, reserveSpaceForItemPointer(), result, JsonPathParseItem::right, JsonPathParseItem::string, JsonPathParseItem::type, JsonPathParseItem::val, JsonPathParseItem::value, and VARSIZE().

Referenced by flattenJsonPathParseItem(), and 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:278
static Datum jsonPathFromCstring(char *in, int len, struct Node *escontext)
Definition jsonpath.c:173
const void size_t len

References fb(), 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:364
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 fb(), 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:277
const char * str
#define JSONPATH_VERSION
Definition jsonpath.h:30
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition pqformat.c:414
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition pqformat.c:545
struct StringInfoData * StringInfo
Definition string.h:15

References buf, elog, ERROR, fb(), 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{
152 int version = JSONPATH_VERSION;
153
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:373
void pfree(void *pointer)
Definition mcxt.c:1616
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition pqformat.c:325
bytea * pq_endtypsend(StringInfo buf)
Definition pqformat.c:345
static void pq_sendint8(StringInfo buf, uint8 i)
Definition pqformat.h:128
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

References buf, fb(), initStringInfo(), JSONPATH_VERSION, jsonPathToCstring(), 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{
176 JsonPath *res;
178
179 if (SOFT_ERROR_OCCURRED(escontext))
180 return (Datum) 0;
181
182 if (!jsonpath)
183 ereturn(escontext, (Datum) 0,
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);
200 if (jsonpath->lax)
201 res->header |= JSONPATH_LAX;
202
204}
#define PG_RETURN_JSONPATH_P(p)
Definition jsonpath.h:48
#define JSONPATH_LAX
Definition jsonpath.h:31
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
#define SOFT_ERROR_OCCURRED(escontext)
Definition miscnodes.h:53
uint64_t Datum
Definition postgres.h:70
void enlargeStringInfo(StringInfo str, int needed)
Definition stringinfo.c:337
char data[FLEXIBLE_ARRAY_MEMBER]
Definition jsonpath.h:27
uint32 header
Definition jsonpath.h:26
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432

References appendStringInfoSpaces(), buf, JsonPath::data, enlargeStringInfo(), ereturn, errcode(), errmsg, fb(), flattenJsonPathParseItem(), JsonPath::header, initStringInfo(), JSONPATH_HDRSZ, JSONPATH_LAX, JSONPATH_VERSION, len, parsejsonpath(), PG_RETURN_JSONPATH_P, 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 }
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:1058
static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
Definition jsonpath.c:529
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230

References appendStringInfoString(), buf, StringInfoData::data, enlargeStringInfo(), fb(), 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 1167 of file jsonpath.c.

1168{
1169 Assert(v->type == jpiNot ||
1170 v->type == jpiIsUnknown ||
1171 v->type == jpiPlus ||
1172 v->type == jpiMinus ||
1173 v->type == jpiFilter ||
1174 v->type == jpiExists ||
1175 v->type == jpiDatetime ||
1176 v->type == jpiTime ||
1177 v->type == jpiTimeTz ||
1178 v->type == jpiTimestamp ||
1179 v->type == jpiTimestampTz ||
1180 v->type == jpiStrLtrim ||
1181 v->type == jpiStrRtrim ||
1182 v->type == jpiStrBtrim);
1183
1184 jspInitByBuffer(a, v->base, v->content.arg);
1185}
#define Assert(condition)
Definition c.h:943
int a
Definition isn.c:73
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition jsonpath.c:1068
char * base
Definition jsonpath.h:154
JsonPathItemType type
Definition jsonpath.h:145
union JsonPathItem::@158 content

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

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

◆ jspGetArraySubscript()

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

Definition at line 1339 of file jsonpath.c.

1341{
1342 Assert(v->type == jpiIndexArray);
1343
1344 jspInitByBuffer(from, v->base, v->content.array.elems[i].from);
1345
1346 if (!v->content.array.elems[i].to)
1347 return false;
1348
1349 jspInitByBuffer(to, v->base, v->content.array.elems[i].to);
1350
1351 return true;
1352}
struct JsonPathItem::@158::@160 array
struct JsonPathItem::@158::@160::@164 * elems

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

Referenced by executeItemOptUnwrapTarget(), jspIsMutableWalker(), and printJsonPathItem().

◆ jspGetBool()

bool jspGetBool ( JsonPathItem v)

Definition at line 1311 of file jsonpath.c.

1312{
1313 Assert(v->type == jpiBool);
1314
1315 return (bool) *v->content.value.data;
1316}
struct JsonPathItem::@158::@162 value
char * data
Definition jsonpath.h:188

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

Referenced by getJsonPathItem(), and printJsonPathItem().

◆ jspGetLeftArg()

void jspGetLeftArg ( JsonPathItem v,
JsonPathItem a 
)

◆ jspGetNext()

bool jspGetNext ( JsonPathItem v,
JsonPathItem a 
)

Definition at line 1188 of file jsonpath.c.

1189{
1190 if (jspHasNext(v))
1191 {
1192 Assert(v->type == jpiNull ||
1193 v->type == jpiString ||
1194 v->type == jpiNumeric ||
1195 v->type == jpiBool ||
1196 v->type == jpiAnd ||
1197 v->type == jpiOr ||
1198 v->type == jpiNot ||
1199 v->type == jpiIsUnknown ||
1200 v->type == jpiEqual ||
1201 v->type == jpiNotEqual ||
1202 v->type == jpiLess ||
1203 v->type == jpiGreater ||
1204 v->type == jpiLessOrEqual ||
1205 v->type == jpiGreaterOrEqual ||
1206 v->type == jpiAdd ||
1207 v->type == jpiSub ||
1208 v->type == jpiMul ||
1209 v->type == jpiDiv ||
1210 v->type == jpiMod ||
1211 v->type == jpiPlus ||
1212 v->type == jpiMinus ||
1213 v->type == jpiAnyArray ||
1214 v->type == jpiAnyKey ||
1215 v->type == jpiIndexArray ||
1216 v->type == jpiAny ||
1217 v->type == jpiKey ||
1218 v->type == jpiCurrent ||
1219 v->type == jpiRoot ||
1220 v->type == jpiVariable ||
1221 v->type == jpiFilter ||
1222 v->type == jpiExists ||
1223 v->type == jpiType ||
1224 v->type == jpiSize ||
1225 v->type == jpiAbs ||
1226 v->type == jpiFloor ||
1227 v->type == jpiCeiling ||
1228 v->type == jpiDouble ||
1229 v->type == jpiDatetime ||
1230 v->type == jpiKeyValue ||
1231 v->type == jpiLast ||
1232 v->type == jpiStartsWith ||
1233 v->type == jpiLikeRegex ||
1234 v->type == jpiBigint ||
1235 v->type == jpiBoolean ||
1236 v->type == jpiDate ||
1237 v->type == jpiDecimal ||
1238 v->type == jpiInteger ||
1239 v->type == jpiNumber ||
1240 v->type == jpiStringFunc ||
1241 v->type == jpiTime ||
1242 v->type == jpiTimeTz ||
1243 v->type == jpiTimestamp ||
1244 v->type == jpiTimestampTz ||
1245 v->type == jpiStrReplace ||
1246 v->type == jpiStrLower ||
1247 v->type == jpiStrUpper ||
1248 v->type == jpiStrLtrim ||
1249 v->type == jpiStrRtrim ||
1250 v->type == jpiStrBtrim ||
1251 v->type == jpiStrInitcap ||
1252 v->type == jpiStrSplitPart);
1253
1254 if (a)
1255 jspInitByBuffer(a, v->base, v->nextPos);
1256 return true;
1257 }
1258
1259 return false;
1260}
#define jspHasNext(jsp)
Definition jsonpath.h:202
int32 nextPos
Definition jsonpath.h:148

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, jpiStrBtrim, jpiString, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, jspHasNext, jspInitByBuffer(), JsonPathItem::nextPos, and JsonPathItem::type.

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

◆ jspGetNumeric()

◆ jspGetRightArg()

◆ jspGetString()

◆ jspInit()

void jspInit ( JsonPathItem v,
JsonPath js 
)

◆ jspInitByBuffer()

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

Definition at line 1068 of file jsonpath.c.

1069{
1070 v->base = base + pos;
1071
1072 read_byte(v->type, base, pos);
1073 pos = INTALIGN((uintptr_t) (base + pos)) - (uintptr_t) base;
1074 read_int32(v->nextPos, base, pos);
1075
1076 switch (v->type)
1077 {
1078 case jpiNull:
1079 case jpiRoot:
1080 case jpiCurrent:
1081 case jpiAnyArray:
1082 case jpiAnyKey:
1083 case jpiType:
1084 case jpiSize:
1085 case jpiAbs:
1086 case jpiFloor:
1087 case jpiCeiling:
1088 case jpiDouble:
1089 case jpiKeyValue:
1090 case jpiLast:
1091 case jpiBigint:
1092 case jpiBoolean:
1093 case jpiDate:
1094 case jpiInteger:
1095 case jpiNumber:
1096 case jpiStringFunc:
1097 case jpiStrLower:
1098 case jpiStrUpper:
1099 case jpiStrInitcap:
1100 break;
1101 case jpiString:
1102 case jpiKey:
1103 case jpiVariable:
1104 read_int32(v->content.value.datalen, base, pos);
1106 case jpiNumeric:
1107 case jpiBool:
1108 v->content.value.data = base + pos;
1109 break;
1110 case jpiAnd:
1111 case jpiOr:
1112 case jpiEqual:
1113 case jpiNotEqual:
1114 case jpiLess:
1115 case jpiGreater:
1116 case jpiLessOrEqual:
1117 case jpiGreaterOrEqual:
1118 case jpiAdd:
1119 case jpiSub:
1120 case jpiMul:
1121 case jpiDiv:
1122 case jpiMod:
1123 case jpiStartsWith:
1124 case jpiDecimal:
1125 case jpiStrReplace:
1126 case jpiStrSplitPart:
1127 read_int32(v->content.args.left, base, pos);
1128 read_int32(v->content.args.right, base, pos);
1129 break;
1130 case jpiNot:
1131 case jpiIsUnknown:
1132 case jpiExists:
1133 case jpiPlus:
1134 case jpiMinus:
1135 case jpiFilter:
1136 case jpiDatetime:
1137 case jpiTime:
1138 case jpiTimeTz:
1139 case jpiTimestamp:
1140 case jpiTimestampTz:
1141 case jpiStrLtrim:
1142 case jpiStrRtrim:
1143 case jpiStrBtrim:
1144 read_int32(v->content.arg, base, pos);
1145 break;
1146 case jpiIndexArray:
1147 read_int32(v->content.array.nelems, base, pos);
1148 read_int32_n(v->content.array.elems, base, pos,
1149 v->content.array.nelems * 2);
1150 break;
1151 case jpiAny:
1152 read_int32(v->content.anybounds.first, base, pos);
1153 read_int32(v->content.anybounds.last, base, pos);
1154 break;
1155 case jpiLikeRegex:
1156 read_int32(v->content.like_regex.flags, base, pos);
1157 read_int32(v->content.like_regex.expr, base, pos);
1158 read_int32(v->content.like_regex.patternlen, base, pos);
1159 v->content.like_regex.pattern = base + pos;
1160 break;
1161 default:
1162 elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
1163 }
1164}
#define read_byte(v, b, p)
Definition jsonpath.c:1039
#define read_int32_n(v, b, p, n)
Definition jsonpath.c:1049
#define read_int32(v, b, p)
Definition jsonpath.c:1044
uint32 first
Definition jsonpath.h:182
int32 nelems
Definition jsonpath.h:171
struct JsonPathItem::@158::@163 like_regex
uint32 flags
Definition jsonpath.h:197
uint32 last
Definition jsonpath.h:183
struct JsonPathItem::@158::@161 anybounds
int32 patternlen
Definition jsonpath.h:196
char * pattern
Definition jsonpath.h:195

References JsonPathItem::anybounds, JsonPathItem::arg, JsonPathItem::args, JsonPathItem::array, JsonPathItem::base, JsonPathItem::content, JsonPathItem::data, JsonPathItem::datalen, JsonPathItem::elems, elog, ERROR, JsonPathItem::expr, fb(), JsonPathItem::first, JsonPathItem::flags, 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, jpiStrBtrim, jpiString, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, JsonPathItem::last, JsonPathItem::left, JsonPathItem::like_regex, JsonPathItem::nelems, JsonPathItem::nextPos, JsonPathItem::pattern, JsonPathItem::patternlen, pg_fallthrough, read_byte, read_int32, read_int32_n, JsonPathItem::right, JsonPathItem::type, and JsonPathItem::value.

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

◆ jspIsMutable()

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

Definition at line 1381 of file jsonpath.c.

1382{
1383 struct JsonPathMutableContext cxt;
1385
1386 cxt.varnames = varnames;
1387 cxt.varexprs = varexprs;
1388 cxt.current = jpdsNonDateTime;
1389 cxt.lax = (path->header & JSONPATH_LAX) != 0;
1390 cxt.mutable = false;
1391
1392 jspInit(&jpi, path);
1393 (void) jspIsMutableWalker(&jpi, &cxt);
1394
1395 return cxt.mutable;
1396}
static enum JsonPathDatatypeStatus jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
Definition jsonpath.c:1402

References JsonPathMutableContext::current, fb(), 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 1402 of file jsonpath.c.

1403{
1406
1407 while (!cxt->mutable)
1408 {
1412
1413 switch (jpi->type)
1414 {
1415 case jpiRoot:
1416 Assert(status == jpdsNonDateTime);
1417 break;
1418
1419 case jpiCurrent:
1420 Assert(status == jpdsNonDateTime);
1421 status = cxt->current;
1422 break;
1423
1424 case jpiFilter:
1425 {
1427
1428 cxt->current = status;
1429 jspGetArg(jpi, &arg);
1430 jspIsMutableWalker(&arg, cxt);
1431
1432 cxt->current = prevStatus;
1433 break;
1434 }
1435
1436 case jpiVariable:
1437 {
1438 int32 len;
1439 const char *name = jspGetString(jpi, &len);
1440 ListCell *lc1;
1441 ListCell *lc2;
1442
1443 Assert(status == jpdsNonDateTime);
1444
1445 forboth(lc1, cxt->varnames, lc2, cxt->varexprs)
1446 {
1447 String *varname = lfirst_node(String, lc1);
1448 Node *varexpr = lfirst(lc2);
1449
1450 if (strncmp(varname->sval, name, len))
1451 continue;
1452
1453 switch (exprType(varexpr))
1454 {
1455 case DATEOID:
1456 case TIMEOID:
1457 case TIMESTAMPOID:
1458 status = jpdsDateTimeNonZoned;
1459 break;
1460
1461 case TIMETZOID:
1462 case TIMESTAMPTZOID:
1463 status = jpdsDateTimeZoned;
1464 break;
1465
1466 default:
1467 status = jpdsNonDateTime;
1468 break;
1469 }
1470
1471 break;
1472 }
1473 break;
1474 }
1475
1476 case jpiEqual:
1477 case jpiNotEqual:
1478 case jpiLess:
1479 case jpiGreater:
1480 case jpiLessOrEqual:
1481 case jpiGreaterOrEqual:
1482 Assert(status == jpdsNonDateTime);
1485
1488
1489 /*
1490 * Comparison of datetime type with different timezone status
1491 * is mutable.
1492 */
1493 if (leftStatus != jpdsNonDateTime &&
1498 cxt->mutable = true;
1499 break;
1500
1501 case jpiNot:
1502 case jpiIsUnknown:
1503 case jpiExists:
1504 case jpiPlus:
1505 case jpiMinus:
1506 Assert(status == jpdsNonDateTime);
1507 jspGetArg(jpi, &arg);
1508 jspIsMutableWalker(&arg, cxt);
1509 break;
1510
1511 case jpiAnd:
1512 case jpiOr:
1513 case jpiAdd:
1514 case jpiSub:
1515 case jpiMul:
1516 case jpiDiv:
1517 case jpiMod:
1518 case jpiStartsWith:
1519 Assert(status == jpdsNonDateTime);
1521 jspIsMutableWalker(&arg, cxt);
1523 jspIsMutableWalker(&arg, cxt);
1524 break;
1525
1526 case jpiIndexArray:
1527 for (int i = 0; i < jpi->content.array.nelems; i++)
1528 {
1529 JsonPathItem from;
1530 JsonPathItem to;
1531
1532 if (jspGetArraySubscript(jpi, &from, &to, i))
1533 jspIsMutableWalker(&to, cxt);
1534
1535 jspIsMutableWalker(&from, cxt);
1536 }
1538
1539 case jpiAnyArray:
1540 if (!cxt->lax)
1541 status = jpdsNonDateTime;
1542 break;
1543
1544 case jpiAny:
1545 if (jpi->content.anybounds.first > 0)
1546 status = jpdsNonDateTime;
1547 break;
1548
1549 case jpiDatetime:
1550 if (jpi->content.arg)
1551 {
1552 char *template;
1553
1554 jspGetArg(jpi, &arg);
1555 if (arg.type != jpiString)
1556 {
1557 status = jpdsNonDateTime;
1558 break; /* there will be runtime error */
1559 }
1560
1561 template = jspGetString(&arg, NULL);
1562 if (datetime_format_has_tz(template))
1563 status = jpdsDateTimeZoned;
1564 else
1565 status = jpdsDateTimeNonZoned;
1566 }
1567 else
1568 {
1569 status = jpdsUnknownDateTime;
1570 }
1571 break;
1572
1573 case jpiLikeRegex:
1574 Assert(status == jpdsNonDateTime);
1575 jspInitByBuffer(&arg, jpi->base, jpi->content.like_regex.expr);
1576 jspIsMutableWalker(&arg, cxt);
1577 break;
1578
1579 /* literals */
1580 case jpiNull:
1581 case jpiString:
1582 case jpiNumeric:
1583 case jpiBool:
1584 break;
1585 /* accessors */
1586 case jpiKey:
1587 case jpiAnyKey:
1588 /* special items */
1589 case jpiSubscript:
1590 case jpiLast:
1591 /* item methods */
1592 case jpiType:
1593 case jpiSize:
1594 case jpiAbs:
1595 case jpiFloor:
1596 case jpiCeiling:
1597 case jpiDouble:
1598 case jpiKeyValue:
1599 case jpiBigint:
1600 case jpiBoolean:
1601 case jpiDecimal:
1602 case jpiInteger:
1603 case jpiNumber:
1604 case jpiStringFunc:
1605 case jpiStrReplace:
1606 case jpiStrLower:
1607 case jpiStrUpper:
1608 case jpiStrLtrim:
1609 case jpiStrRtrim:
1610 case jpiStrBtrim:
1611 case jpiStrInitcap:
1612 case jpiStrSplitPart:
1613 status = jpdsNonDateTime;
1614 break;
1615
1616 case jpiTime:
1617 case jpiDate:
1618 case jpiTimestamp:
1619 status = jpdsDateTimeNonZoned;
1620 cxt->mutable = true;
1621 break;
1622
1623 case jpiTimeTz:
1624 case jpiTimestampTz:
1625 status = jpdsDateTimeNonZoned;
1626 cxt->mutable = true;
1627 break;
1628
1629 }
1630
1631 if (!jspGetNext(jpi, &next))
1632 break;
1633
1634 jpi = &next;
1635 }
1636
1637 return status;
1638}
bool datetime_format_has_tz(const char *fmt_str)
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1263
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1167
char * jspGetString(JsonPathItem *v, int32 *len)
Definition jsonpath.c:1327
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition jsonpath.c:1339
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1188
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1287
JsonPathDatatypeStatus
Definition jsonpath.c:1356
@ 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:550
enum JsonPathDatatypeStatus current
Definition jsonpath.c:1368
Definition nodes.h:135
Definition value.h:64
char * sval
Definition value.h:68
const char * name

References arg, Assert, JsonPathMutableContext::current, datetime_format_has_tz(), exprType(), fb(), forboth, i, jpdsDateTimeNonZoned, jpdsDateTimeZoned, jpdsNonDateTime, jpdsUnknownDateTime, 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, jpiStrBtrim, jpiString, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, jpiSub, jpiSubscript, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, jspGetArg(), jspGetArraySubscript(), jspGetLeftArg(), jspGetNext(), jspGetRightArg(), jspGetString(), jspInitByBuffer(), jspIsMutableWalker(), JsonPathMutableContext::lax, len, lfirst, lfirst_node, JsonPathMutableContext::mutable, name, next, pg_fallthrough, String::sval, JsonPathMutableContext::varexprs, and JsonPathMutableContext::varnames.

Referenced by jspIsMutable(), and jspIsMutableWalker().

◆ jspOperationName()

const char * jspOperationName ( JsonPathItemType  type)

Definition at line 905 of file jsonpath.c.

906{
907 switch (type)
908 {
909 case jpiAnd:
910 return "&&";
911 case jpiOr:
912 return "||";
913 case jpiEqual:
914 return "==";
915 case jpiNotEqual:
916 return "!=";
917 case jpiLess:
918 return "<";
919 case jpiGreater:
920 return ">";
921 case jpiLessOrEqual:
922 return "<=";
924 return ">=";
925 case jpiAdd:
926 case jpiPlus:
927 return "+";
928 case jpiSub:
929 case jpiMinus:
930 return "-";
931 case jpiMul:
932 return "*";
933 case jpiDiv:
934 return "/";
935 case jpiMod:
936 return "%";
937 case jpiType:
938 return "type";
939 case jpiSize:
940 return "size";
941 case jpiAbs:
942 return "abs";
943 case jpiFloor:
944 return "floor";
945 case jpiCeiling:
946 return "ceiling";
947 case jpiDouble:
948 return "double";
949 case jpiDatetime:
950 return "datetime";
951 case jpiKeyValue:
952 return "keyvalue";
953 case jpiStartsWith:
954 return "starts with";
955 case jpiLikeRegex:
956 return "like_regex";
957 case jpiBigint:
958 return "bigint";
959 case jpiBoolean:
960 return "boolean";
961 case jpiDate:
962 return "date";
963 case jpiDecimal:
964 return "decimal";
965 case jpiInteger:
966 return "integer";
967 case jpiNumber:
968 return "number";
969 case jpiStringFunc:
970 return "string";
971 case jpiTime:
972 return "time";
973 case jpiTimeTz:
974 return "time_tz";
975 case jpiTimestamp:
976 return "timestamp";
977 case jpiTimestampTz:
978 return "timestamp_tz";
979 case jpiStrReplace:
980 return "replace";
981 case jpiStrLower:
982 return "lower";
983 case jpiStrUpper:
984 return "upper";
985 case jpiStrLtrim:
986 return "ltrim";
987 case jpiStrRtrim:
988 return "rtrim";
989 case jpiStrBtrim:
990 return "btrim";
991 case jpiStrInitcap:
992 return "initcap";
993 case jpiStrSplitPart:
994 return "split_part";
995 default:
996 elog(ERROR, "unrecognized jsonpath item type: %d", type);
997 return NULL;
998 }
999}
const char * type

References elog, ERROR, fb(), 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, jpiStrBtrim, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, and type.

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

◆ operationPriority()

static int operationPriority ( JsonPathItemType  op)
static

Definition at line 1002 of file jsonpath.c.

1003{
1004 switch (op)
1005 {
1006 case jpiOr:
1007 return 0;
1008 case jpiAnd:
1009 return 1;
1010 case jpiEqual:
1011 case jpiNotEqual:
1012 case jpiLess:
1013 case jpiGreater:
1014 case jpiLessOrEqual:
1015 case jpiGreaterOrEqual:
1016 case jpiStartsWith:
1017 return 2;
1018 case jpiAdd:
1019 case jpiSub:
1020 return 3;
1021 case jpiMul:
1022 case jpiDiv:
1023 case jpiMod:
1024 return 4;
1025 case jpiPlus:
1026 case jpiMinus:
1027 return 5;
1028 default:
1029 return 6;
1030 }
1031}

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

531{
532 JsonPathItem elem;
533 int i;
534 int32 len;
535 char *str;
536
539
540 switch (v->type)
541 {
542 case jpiNull:
544 break;
545 case jpiString:
546 str = jspGetString(v, &len);
548 break;
549 case jpiNumeric:
550 if (jspHasNext(v))
555 if (jspHasNext(v))
557 break;
558 case jpiBool:
559 if (jspGetBool(v))
561 else
562 appendStringInfoString(buf, "false");
563 break;
564 case jpiAnd:
565 case jpiOr:
566 case jpiEqual:
567 case jpiNotEqual:
568 case jpiLess:
569 case jpiGreater:
570 case jpiLessOrEqual:
572 case jpiAdd:
573 case jpiSub:
574 case jpiMul:
575 case jpiDiv:
576 case jpiMod:
577 case jpiStartsWith:
578 if (printBracketes)
580 jspGetLeftArg(v, &elem);
581 printJsonPathItem(buf, &elem, false,
582 operationPriority(elem.type) <=
587 jspGetRightArg(v, &elem);
588 printJsonPathItem(buf, &elem, false,
589 operationPriority(elem.type) <=
591 if (printBracketes)
593 break;
594 case jpiNot:
596 jspGetArg(v, &elem);
597 printJsonPathItem(buf, &elem, false, false);
599 break;
600 case jpiIsUnknown:
602 jspGetArg(v, &elem);
603 printJsonPathItem(buf, &elem, false, false);
604 appendStringInfoString(buf, ") is unknown");
605 break;
606 case jpiPlus:
607 case jpiMinus:
608 if (printBracketes)
610 appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-');
611 jspGetArg(v, &elem);
612 printJsonPathItem(buf, &elem, false,
613 operationPriority(elem.type) <=
615 if (printBracketes)
617 break;
618 case jpiAnyArray:
620 break;
621 case jpiAnyKey:
622 if (inKey)
625 break;
626 case jpiIndexArray:
628 for (i = 0; i < v->content.array.nelems; i++)
629 {
630 JsonPathItem from;
631 JsonPathItem to;
632 bool range = jspGetArraySubscript(v, &from, &to, i);
633
634 if (i)
636
637 printJsonPathItem(buf, &from, false, false);
638
639 if (range)
640 {
642 printJsonPathItem(buf, &to, false, false);
643 }
644 }
646 break;
647 case jpiAny:
648 if (inKey)
650
651 if (v->content.anybounds.first == 0 &&
654 else if (v->content.anybounds.first == v->content.anybounds.last)
655 {
657 appendStringInfoString(buf, "**{last}");
658 else
659 appendStringInfo(buf, "**{%u}",
661 }
662 else if (v->content.anybounds.first == PG_UINT32_MAX)
663 appendStringInfo(buf, "**{last to %u}",
665 else if (v->content.anybounds.last == PG_UINT32_MAX)
666 appendStringInfo(buf, "**{%u to last}",
668 else
669 appendStringInfo(buf, "**{%u to %u}",
672 break;
673 case jpiKey:
674 if (inKey)
676 str = jspGetString(v, &len);
678 break;
679 case jpiCurrent:
680 Assert(!inKey);
682 break;
683 case jpiRoot:
684 Assert(!inKey);
686 break;
687 case jpiVariable:
689 str = jspGetString(v, &len);
691 break;
692 case jpiFilter:
694 jspGetArg(v, &elem);
695 printJsonPathItem(buf, &elem, false, false);
697 break;
698 case jpiExists:
699 appendStringInfoString(buf, "exists (");
700 jspGetArg(v, &elem);
701 printJsonPathItem(buf, &elem, false, false);
703 break;
704 case jpiType:
705 appendStringInfoString(buf, ".type()");
706 break;
707 case jpiSize:
708 appendStringInfoString(buf, ".size()");
709 break;
710 case jpiAbs:
711 appendStringInfoString(buf, ".abs()");
712 break;
713 case jpiFloor:
714 appendStringInfoString(buf, ".floor()");
715 break;
716 case jpiCeiling:
717 appendStringInfoString(buf, ".ceiling()");
718 break;
719 case jpiDouble:
720 appendStringInfoString(buf, ".double()");
721 break;
722 case jpiDatetime:
723 appendStringInfoString(buf, ".datetime(");
724 if (v->content.arg)
725 {
726 jspGetArg(v, &elem);
727 printJsonPathItem(buf, &elem, false, false);
728 }
730 break;
731 case jpiKeyValue:
732 appendStringInfoString(buf, ".keyvalue()");
733 break;
734 case jpiLast:
736 break;
737 case jpiLikeRegex:
738 if (printBracketes)
740
742 printJsonPathItem(buf, &elem, false,
743 operationPriority(elem.type) <=
745
746 appendStringInfoString(buf, " like_regex ");
747
751
752 if (v->content.like_regex.flags)
753 {
754 appendStringInfoString(buf, " flag \"");
755
766
768 }
769
770 if (printBracketes)
772 break;
773 case jpiBigint:
774 appendStringInfoString(buf, ".bigint()");
775 break;
776 case jpiBoolean:
777 appendStringInfoString(buf, ".boolean()");
778 break;
779 case jpiDate:
780 appendStringInfoString(buf, ".date()");
781 break;
782 case jpiDecimal:
783 appendStringInfoString(buf, ".decimal(");
784 if (v->content.args.left)
785 {
786 jspGetLeftArg(v, &elem);
787 printJsonPathItem(buf, &elem, false, false);
788 }
789 if (v->content.args.right)
790 {
792 jspGetRightArg(v, &elem);
793 printJsonPathItem(buf, &elem, false, false);
794 }
796 break;
797 case jpiInteger:
798 appendStringInfoString(buf, ".integer()");
799 break;
800 case jpiNumber:
801 appendStringInfoString(buf, ".number()");
802 break;
803 case jpiStringFunc:
804 appendStringInfoString(buf, ".string()");
805 break;
806 case jpiTime:
807 appendStringInfoString(buf, ".time(");
808 if (v->content.arg)
809 {
810 jspGetArg(v, &elem);
811 printJsonPathItem(buf, &elem, false, false);
812 }
814 break;
815 case jpiTimeTz:
816 appendStringInfoString(buf, ".time_tz(");
817 if (v->content.arg)
818 {
819 jspGetArg(v, &elem);
820 printJsonPathItem(buf, &elem, false, false);
821 }
823 break;
824 case jpiTimestamp:
825 appendStringInfoString(buf, ".timestamp(");
826 if (v->content.arg)
827 {
828 jspGetArg(v, &elem);
829 printJsonPathItem(buf, &elem, false, false);
830 }
832 break;
833 case jpiTimestampTz:
834 appendStringInfoString(buf, ".timestamp_tz(");
835 if (v->content.arg)
836 {
837 jspGetArg(v, &elem);
838 printJsonPathItem(buf, &elem, false, false);
839 }
841 break;
842 case jpiStrReplace:
843 appendStringInfoString(buf, ".replace(");
844 jspGetLeftArg(v, &elem);
845 printJsonPathItem(buf, &elem, false, false);
847 jspGetRightArg(v, &elem);
848 printJsonPathItem(buf, &elem, false, false);
850 break;
851 case jpiStrLower:
852 appendStringInfoString(buf, ".lower()");
853 break;
854 case jpiStrUpper:
855 appendStringInfoString(buf, ".upper()");
856 break;
857 case jpiStrSplitPart:
858 appendStringInfoString(buf, ".split_part(");
859 jspGetLeftArg(v, &elem);
860 printJsonPathItem(buf, &elem, false, false);
862 jspGetRightArg(v, &elem);
863 printJsonPathItem(buf, &elem, false, false);
865 break;
866 case jpiStrLtrim:
867 appendStringInfoString(buf, ".ltrim(");
868 if (v->content.arg)
869 {
870 jspGetArg(v, &elem);
871 printJsonPathItem(buf, &elem, false, false);
872 }
874 break;
875 case jpiStrRtrim:
876 appendStringInfoString(buf, ".rtrim(");
877 if (v->content.arg)
878 {
879 jspGetArg(v, &elem);
880 printJsonPathItem(buf, &elem, false, false);
881 }
883 break;
884 case jpiStrBtrim:
885 appendStringInfoString(buf, ".btrim(");
886 if (v->content.arg)
887 {
888 jspGetArg(v, &elem);
889 printJsonPathItem(buf, &elem, false, false);
890 }
892 break;
893 case jpiStrInitcap:
894 appendStringInfoString(buf, ".initcap()");
895 break;
896 default:
897 elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
898 }
899
900 if (jspGetNext(v, &elem))
901 printJsonPathItem(buf, &elem, true, true);
902}
Datum numeric_out(PG_FUNCTION_ARGS)
Definition numeric.c:799
#define PG_UINT32_MAX
Definition c.h:674
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:684
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition json.c:1601
bool jspGetBool(JsonPathItem *v)
Definition jsonpath.c:1311
Numeric jspGetNumeric(JsonPathItem *v)
Definition jsonpath.c:1319
const char * jspOperationName(JsonPathItemType type)
Definition jsonpath.c:905
static int operationPriority(JsonPathItemType op)
Definition jsonpath.c:1002
#define JSP_REGEX_WSPACE
Definition jsonpath.h:132
#define JSP_REGEX_MLINE
Definition jsonpath.h:131
#define JSP_REGEX_ICASE
Definition jsonpath.h:129
#define JSP_REGEX_DOTALL
Definition jsonpath.h:130
#define JSP_REGEX_QUOTE
Definition jsonpath.h:133
static Datum NumericGetDatum(Numeric X)
Definition numeric.h:76
static char * DatumGetCString(Datum X)
Definition postgres.h:355
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145

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(), JsonPathItem::expr, fb(), JsonPathItem::first, JsonPathItem::flags, 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, jpiStrBtrim, jpiString, jpiStringFunc, jpiStrInitcap, jpiStrLower, jpiStrLtrim, jpiStrReplace, jpiStrRtrim, jpiStrSplitPart, jpiStrUpper, 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::last, JsonPathItem::left, len, JsonPathItem::like_regex, JsonPathItem::nelems, numeric_out(), NumericGetDatum(), operationPriority(), JsonPathItem::pattern, JsonPathItem::patternlen, PG_UINT32_MAX, printJsonPathItem(), range(), JsonPathItem::right, str, and JsonPathItem::type.

Referenced by jsonPathToCstring(), and printJsonPathItem().

◆ reserveSpaceForItemPointer()

static int32 reserveSpaceForItemPointer ( StringInfo  buf)
static

Definition at line 515 of file jsonpath.c.

516{
517 int32 pos = buf->len;
518 int32 ptr = 0;
519
520 appendBinaryStringInfo(buf, &ptr, sizeof(ptr));
521
522 return pos;
523}

References appendBinaryStringInfo(), and buf.

Referenced by flattenJsonPathParseItem().