PostgreSQL Source Code git master
jsonpath.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * jsonpath.h
4 * Definitions for jsonpath datatype
5 *
6 * Copyright (c) 2019-2025, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/include/utils/jsonpath.h
10 *
11 *-------------------------------------------------------------------------
12 */
13
14#ifndef JSONPATH_H
15#define JSONPATH_H
16
17#include "executor/tablefunc.h"
18#include "fmgr.h"
19#include "nodes/pg_list.h"
20#include "nodes/primnodes.h"
21#include "utils/jsonb.h"
22
23typedef struct
24{
25 int32 vl_len_; /* varlena header (do not touch directly!) */
26 uint32 header; /* version and flags (see below) */
28} JsonPath;
29
30#define JSONPATH_VERSION (0x01)
31#define JSONPATH_LAX (0x80000000)
32#define JSONPATH_HDRSZ (offsetof(JsonPath, data))
33
34static inline JsonPath *
36{
37 return (JsonPath *) PG_DETOAST_DATUM(d);
38}
39
40static inline JsonPath *
42{
43 return (JsonPath *) PG_DETOAST_DATUM_COPY(d);
44}
45
46#define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x))
47#define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
48#define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p)
49
50#define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)
51
52/*
53 * All node's type of jsonpath expression
54 *
55 * These become part of the on-disk representation of the jsonpath type.
56 * Therefore, to preserve pg_upgradability, the order must not be changed, and
57 * new values must be added at the end.
58 *
59 * It is recommended that switch cases etc. in other parts of the code also
60 * use this order, to maintain some consistency.
61 */
62typedef enum JsonPathItemType
63{
64 jpiNull = jbvNull, /* NULL literal */
65 jpiString = jbvString, /* string literal */
66 jpiNumeric = jbvNumeric, /* numeric literal */
67 jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */
68 jpiAnd, /* predicate && predicate */
69 jpiOr, /* predicate || predicate */
70 jpiNot, /* ! predicate */
71 jpiIsUnknown, /* (predicate) IS UNKNOWN */
72 jpiEqual, /* expr == expr */
73 jpiNotEqual, /* expr != expr */
74 jpiLess, /* expr < expr */
75 jpiGreater, /* expr > expr */
76 jpiLessOrEqual, /* expr <= expr */
77 jpiGreaterOrEqual, /* expr >= expr */
78 jpiAdd, /* expr + expr */
79 jpiSub, /* expr - expr */
80 jpiMul, /* expr * expr */
81 jpiDiv, /* expr / expr */
82 jpiMod, /* expr % expr */
83 jpiPlus, /* + expr */
84 jpiMinus, /* - expr */
85 jpiAnyArray, /* [*] */
86 jpiAnyKey, /* .* */
87 jpiIndexArray, /* [subscript, ...] */
88 jpiAny, /* .** */
89 jpiKey, /* .key */
90 jpiCurrent, /* @ */
91 jpiRoot, /* $ */
92 jpiVariable, /* $variable */
93 jpiFilter, /* ? (predicate) */
94 jpiExists, /* EXISTS (expr) predicate */
95 jpiType, /* .type() item method */
96 jpiSize, /* .size() item method */
97 jpiAbs, /* .abs() item method */
98 jpiFloor, /* .floor() item method */
99 jpiCeiling, /* .ceiling() item method */
100 jpiDouble, /* .double() item method */
101 jpiDatetime, /* .datetime() item method */
102 jpiKeyValue, /* .keyvalue() item method */
103 jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */
104 jpiLast, /* LAST array subscript */
105 jpiStartsWith, /* STARTS WITH predicate */
106 jpiLikeRegex, /* LIKE_REGEX predicate */
107 jpiBigint, /* .bigint() item method */
108 jpiBoolean, /* .boolean() item method */
109 jpiDate, /* .date() item method */
110 jpiDecimal, /* .decimal() item method */
111 jpiInteger, /* .integer() item method */
112 jpiNumber, /* .number() item method */
113 jpiStringFunc, /* .string() item method */
114 jpiTime, /* .time() item method */
115 jpiTimeTz, /* .time_tz() item method */
116 jpiTimestamp, /* .timestamp() item method */
117 jpiTimestampTz, /* .timestamp_tz() item method */
119
120/* XQuery regex mode flags for LIKE_REGEX predicate */
121#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */
122#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */
123#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */
124#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */
125#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
126
127/*
128 * Support functions to parse/construct binary value.
129 * Unlike many other representation of expression the first/main
130 * node is not an operation but left operand of expression. That
131 * allows to implement cheap follow-path descending in jsonb
132 * structure and then execute operator with right operand
133 */
134
135typedef struct JsonPathItem
136{
138
139 /* position form base to next node */
141
142 /*
143 * pointer into JsonPath value to current node, all positions of current
144 * are relative to this base
145 */
146 char *base;
147
148 union
149 {
150 /* classic operator with two operands: and, or etc */
151 struct
152 {
156
157 /* any unary operation */
159
160 /* storage for jpiIndexArray: indexes of array */
161 struct
162 {
164 struct
165 {
170
171 /* jpiAny: levels */
172 struct
173 {
177
178 struct
179 {
180 char *data; /* for bool, numeric and string/key */
181 int32 datalen; /* filled only for string/key */
183
184 struct
185 {
187 char *pattern;
193
194#define jspHasNext(jsp) ((jsp)->nextPos > 0)
195
196extern void jspInit(JsonPathItem *v, JsonPath *js);
197extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
198extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
199extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
200extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
201extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
203extern bool jspGetBool(JsonPathItem *v);
204extern char *jspGetString(JsonPathItem *v, int32 *len);
206 JsonPathItem *to, int i);
207extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
208
209extern const char *jspOperationName(JsonPathItemType type);
210
211/*
212 * Parsing support data structures.
213 */
214
216
218{
220 JsonPathParseItem *next; /* next in path */
221
222 union
223 {
224
225 /* classic operator with two operands: and, or etc */
226 struct
227 {
231
232 /* any unary operation */
234
235 /* storage for jpiIndexArray: indexes of array */
236 struct
237 {
239 struct
240 {
245
246 /* jpiAny: levels */
247 struct
248 {
252
253 struct
254 {
256 char *pattern; /* could not be not null-terminated */
260
261 /* scalars */
264 struct
265 {
267 char *val; /* could not be not null-terminated */
270};
271
273{
275 bool lax;
277
278extern JsonPathParseResult *parsejsonpath(const char *str, int len,
279 struct Node *escontext);
280
281extern bool jspConvertRegexFlags(uint32 xflags, int *result,
282 struct Node *escontext);
283
284/*
285 * Struct for details about external variables passed into jsonpath executor
286 */
287typedef struct JsonPathVariable
288{
289 char *name;
290 int namelen; /* strlen(name) as cache for GetJsonPathVar() */
294 bool isnull;
296
297
298/* SQL/JSON query functions */
299extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars);
300extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
301 bool *empty, bool *error, List *vars,
302 const char *column_name);
303extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
304 bool *error, List *vars,
305 const char *column_name);
306
307/* For JSON_TABLE() */
309
310#endif
#define PGDLLIMPORT
Definition: c.h:1277
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:420
int32_t int32
Definition: c.h:484
uint32_t uint32
Definition: c.h:488
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:242
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:240
const char * str
int a
Definition: isn.c:68
int i
Definition: isn.c:72
@ jbvNumeric
Definition: jsonb.h:230
@ jbvBool
Definition: jsonb.h:231
@ jbvNull
Definition: jsonb.h:228
@ jbvString
Definition: jsonb.h:229
PGDLLIMPORT const TableFuncRoutine JsonbTableRoutine
bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars)
bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
Definition: jsonpath.c:1280
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1166
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1081
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:990
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1210
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:980
Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty, bool *error, List *vars, const char *column_name)
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1226
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1218
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1238
struct JsonPathVariable JsonPathVariable
static JsonPath * DatumGetJsonPathPCopy(Datum d)
Definition: jsonpath.h:41
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:843
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1099
JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars, const char *column_name)
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
struct JsonPathParseResult JsonPathParseResult
static JsonPath * DatumGetJsonPathP(Datum d)
Definition: jsonpath.h:35
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1188
struct JsonPathItem JsonPathItem
JsonPathItemType
Definition: jsonpath.h:63
@ 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
@ jpiSubscript
Definition: jsonpath.h:103
@ 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
const void size_t len
const void * data
uintptr_t Datum
Definition: postgres.h:69
unsigned int Oid
Definition: postgres_ext.h:32
JsonWrapper
Definition: primnodes.h:1780
static void error(void)
Definition: sql-dyntest.c:147
uint32 first
Definition: jsonpath.h:174
int32 datalen
Definition: jsonpath.h:181
struct JsonPathItem::@144::@149 like_regex
int32 nelems
Definition: jsonpath.h:163
struct JsonPathItem::@144::@147 anybounds
uint32 flags
Definition: jsonpath.h:189
int32 to
Definition: jsonpath.h:167
int32 from
Definition: jsonpath.h:166
int32 left
Definition: jsonpath.h:153
union JsonPathItem::@144 content
struct JsonPathItem::@144::@146 array
char * base
Definition: jsonpath.h:146
struct JsonPathItem::@144::@146::@150 * elems
int32 nextPos
Definition: jsonpath.h:140
int32 arg
Definition: jsonpath.h:158
JsonPathItemType type
Definition: jsonpath.h:137
char * data
Definition: jsonpath.h:180
uint32 last
Definition: jsonpath.h:175
struct JsonPathItem::@144::@148 value
struct JsonPathItem::@144::@145 args
int32 right
Definition: jsonpath.h:154
int32 patternlen
Definition: jsonpath.h:188
char * pattern
Definition: jsonpath.h:187
int32 expr
Definition: jsonpath.h:186
JsonPathParseItem * arg
Definition: jsonpath.h:233
struct JsonPathParseItem::@151::@153 array
JsonPathParseItem * from
Definition: jsonpath.h:241
JsonPathParseItem * expr
Definition: jsonpath.h:255
JsonPathParseItem * left
Definition: jsonpath.h:228
JsonPathParseItem * right
Definition: jsonpath.h:229
struct JsonPathParseItem::@151::@155 like_regex
JsonPathParseItem * next
Definition: jsonpath.h:220
union JsonPathParseItem::@151 value
Numeric numeric
Definition: jsonpath.h:262
struct JsonPathParseItem::@151::@154 anybounds
struct JsonPathParseItem::@151::@152 args
JsonPathParseItem * to
Definition: jsonpath.h:242
struct JsonPathParseItem::@151::@153::@157 * elems
struct JsonPathParseItem::@151::@156 string
JsonPathItemType type
Definition: jsonpath.h:219
uint32 patternlen
Definition: jsonpath.h:257
JsonPathParseItem * expr
Definition: jsonpath.h:274
int32 vl_len_
Definition: jsonpath.h:25
uint32 header
Definition: jsonpath.h:26
Definition: pg_list.h:54
Definition: nodes.h:129
Definition: regcomp.c:282
const char * type