PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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) \
uint8_t uint8
Definition: c.h:500
int b
Definition: isn.c:74

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) \
int32_t int32
Definition: c.h:498
uint32_t uint32
Definition: c.h:502

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:779
static char * buf
Definition: pg_test_fsync.c:72
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:231

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);
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 {
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));
339 sizeof(item->value.like_regex.patternlen));
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:224
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereturn(context, dummy_value,...)
Definition: elog.h:278
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: isn.c:77
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:123
void * arg
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:233
struct JsonPathParseItem::@154::@157 anybounds
JsonPathParseItem * expr
Definition: jsonpath.h:255
JsonPathParseItem * left
Definition: jsonpath.h:228
JsonPathParseItem * right
Definition: jsonpath.h:229
struct JsonPathParseItem::@154::@156 array
JsonPathParseItem * next
Definition: jsonpath.h:220
Numeric numeric
Definition: jsonpath.h:262
struct JsonPathParseItem::@154::@158 like_regex
struct JsonPathParseItem::@154::@156::@160 * elems
struct JsonPathParseItem::@154::@155 args
struct JsonPathParseItem::@154::@159 string
JsonPathItemType type
Definition: jsonpath.h:219
uint32 patternlen
Definition: jsonpath.h:257
union JsonPathParseItem::@154 value
#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(), JsonPathParseItem::elems, elog, ereturn, errcode(), errmsg(), ERROR, JsonPathParseItem::expr, 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, jpiString, jpiStringFunc, 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, reserveSpaceForItemPointer(), 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: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:2147
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:97

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);
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
uintptr_t Datum
Definition: postgres.h:69
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:337
JsonPathParseItem * expr
Definition: jsonpath.h:274
uint32 header
Definition: jsonpath.h:26
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References appendStringInfoSpaces(), buf, enlargeStringInfo(), ereturn, errcode(), errmsg(), JsonPathParseResult::expr, flattenJsonPathParseItem(), JsonPath::header, initStringInfo(), JSONPATH_HDRSZ, JSONPATH_LAX, JSONPATH_VERSION, JsonPathParseResult::lax, 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 }
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:230

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}
Assert(PointerIsAligned(start, uint64))
int a
Definition: isn.c:73
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:990
char * base
Definition: jsonpath.h:146
int32 arg
Definition: jsonpath.h:158
JsonPathItemType type
Definition: jsonpath.h:137
union JsonPathItem::@147 content

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(), jspIsMutableWalker(), 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::@147::@149::@153 * elems
struct JsonPathItem::@147::@149 array

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

1211{
1212 Assert(v->type == jpiBool);
1213
1214 return (bool) *v->content.value.data;
1215}
struct JsonPathItem::@147::@151 value
char * data
Definition: jsonpath.h:180

References Assert(), JsonPathItem::content, JsonPathItem::data, 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
1185}
int32 left
Definition: jsonpath.h:153
struct JsonPathItem::@147::@148 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(), JsonPathItem::left, and JsonPathItem::type.

Referenced by executeBinaryArithmExpr(), executeBoolItem(), executeItemOptUnwrapTarget(), extract_jsp_bool_expr(), jspIsMutableWalker(), 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(), jspIsMutableWalker(), and printJsonPathItem().

◆ jspGetNumeric()

◆ jspGetRightArg()

void jspGetRightArg ( JsonPathItem v,
JsonPathItem a 
)

◆ jspGetString()

◆ 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
uint32 first
Definition: jsonpath.h:174
int32 nelems
Definition: jsonpath.h:163
uint32 flags
Definition: jsonpath.h:189
uint32 last
Definition: jsonpath.h:175
struct JsonPathItem::@147::@150 anybounds
struct JsonPathItem::@147::@152 like_regex
int32 patternlen
Definition: jsonpath.h:188
char * pattern
Definition: jsonpath.h:187
int32 expr
Definition: jsonpath.h:186

References JsonPathItem::anybounds, JsonPathItem::arg, JsonPathItem::args, JsonPathItem::array, JsonPathItem::base, JsonPathItem::content, JsonPathItem::data, JsonPathItem::datalen, JsonPathItem::elems, elog, ERROR, JsonPathItem::expr, 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, jpiString, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, JsonPathItem::last, JsonPathItem::left, JsonPathItem::like_regex, JsonPathItem::nelems, JsonPathItem::nextPos, JsonPathItem::pattern, JsonPathItem::patternlen, 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 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 1301 of file jsonpath.c.

1302{
1305
1306 while (!cxt->mutable)
1307 {
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);
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:4365
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1166
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1081
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1226
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
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:135
Definition: value.h:64
char * sval
Definition: value.h:68
const char * name

References JsonPathItem::anybounds, arg, JsonPathItem::arg, JsonPathItem::array, Assert(), JsonPathItem::base, JsonPathItem::content, JsonPathMutableContext::current, datetime_format_has_tz(), JsonPathItem::expr, exprType(), JsonPathItem::first, 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, jpiString, jpiStringFunc, jpiSub, jpiSubscript, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, jspGetArg(), jspGetArraySubscript(), jspGetLeftArg(), jspGetNext(), jspGetRightArg(), jspGetString(), jspInitByBuffer(), jspIsMutableWalker(), JsonPathMutableContext::lax, len, lfirst, lfirst_node, JsonPathItem::like_regex, JsonPathMutableContext::mutable, name, JsonPathItem::nelems, next, String::sval, JsonPathItem::type, JsonPathMutableContext::varexprs, and JsonPathMutableContext::varnames.

Referenced by jspIsMutable(), and jspIsMutableWalker().

◆ 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 "<=";
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:
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:
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))
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:
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) <=
579 jspGetRightArg(v, &elem);
580 printJsonPathItem(buf, &elem, false,
581 operationPriority(elem.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) <=
607 if (printBracketes)
609 break;
610 case jpiAnyArray:
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 {
634 printJsonPathItem(buf, &to, false, false);
635 }
636 }
638 break;
639 case jpiAny:
640 if (inKey)
642
643 if (v->content.anybounds.first == 0 &&
646 else if (v->content.anybounds.first == v->content.anybounds.last)
647 {
649 appendStringInfoString(buf, "**{last}");
650 else
651 appendStringInfo(buf, "**{%u}",
653 }
654 else if (v->content.anybounds.first == PG_UINT32_MAX)
655 appendStringInfo(buf, "**{last to %u}",
657 else if (v->content.anybounds.last == PG_UINT32_MAX)
658 appendStringInfo(buf, "**{%u to last}",
660 else
661 appendStringInfo(buf, "**{%u to %u}",
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:
728 break;
729 case jpiLikeRegex:
730 if (printBracketes)
732
734 printJsonPathItem(buf, &elem, false,
735 operationPriority(elem.type) <=
737
738 appendStringInfoString(buf, " like_regex ");
739
743
744 if (v->content.like_regex.flags)
745 {
746 appendStringInfoString(buf, " flag \"");
747
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:816
#define PG_UINT32_MAX
Definition: c.h:561
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
void escape_json_with_len(StringInfo buf, const char *str, int len)
Definition: json.c:1631
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1210
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1218
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:843
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:340
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: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, 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, jpiString, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, JSP_REGEX_DOTALL, JSP_REGEX_ICASE, JSP_REGEX_MLINE, JSP_REGEX_QUOTE, JSP_REGEX_WSPACE, jspGetArg(), jspGetArraySubscript(), jspGetBool(), jspGetLeftArg(), jspGetNext(), jspGetNumeric(), jspGetRightArg(), jspGetString(), jspHasNext, jspInitByBuffer(), jspOperationName(), JsonPathItem::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 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().