PostgreSQL Source Code git master
Loading...
Searching...
No Matches
jsonpath.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * jsonpath.h
4 * Definitions for jsonpath datatype
5 *
6 * Copyright (c) 2019-2026, 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 *
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 */
118 jpiStrReplace, /* .replace() item method */
119 jpiStrLower, /* .lower() item method */
120 jpiStrUpper, /* .upper() item method */
121 jpiStrLtrim, /* .ltrim() item method */
122 jpiStrRtrim, /* .rtrim() item method */
123 jpiStrBtrim, /* .btrim() item method */
124 jpiStrInitcap, /* .initcap() item method */
125 jpiStrSplitPart, /* .split_part() item method */
127
128/* XQuery regex mode flags for LIKE_REGEX predicate */
129#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */
130#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */
131#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */
132#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */
133#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
134
135/*
136 * Support functions to parse/construct binary value.
137 * Unlike many other representation of expression the first/main
138 * node is not an operation but left operand of expression. That
139 * allows to implement cheap follow-path descending in jsonb
140 * structure and then execute operator with right operand
141 */
142
143typedef struct JsonPathItem
144{
146
147 /* position form base to next node */
149
150 /*
151 * pointer into JsonPath value to current node, all positions of current
152 * are relative to this base
153 */
154 char *base;
155
156 union
157 {
158 /* classic operator with two operands: and, or etc */
159 struct
160 {
164
165 /* any unary operation */
167
168 /* storage for jpiIndexArray: indexes of array */
169 struct
170 {
172 struct
173 {
178
179 /* jpiAny: levels */
180 struct
181 {
185
186 struct
187 {
188 char *data; /* for bool, numeric and string/key */
189 int32 datalen; /* filled only for string/key */
191
192 struct
193 {
195 char *pattern;
201
202#define jspHasNext(jsp) ((jsp)->nextPos > 0)
203
204extern void jspInit(JsonPathItem *v, JsonPath *js);
205extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
206extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
207extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
208extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
209extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
211extern bool jspGetBool(JsonPathItem *v);
212extern char *jspGetString(JsonPathItem *v, int32 *len);
214 JsonPathItem *to, int i);
215extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
216
217extern const char *jspOperationName(JsonPathItemType type);
218
219/*
220 * Parsing support data structures.
221 */
222
224
226{
228 JsonPathParseItem *next; /* next in path */
229
230 union
231 {
232
233 /* classic operator with two operands: and, or etc */
234 struct
235 {
239
240 /* any unary operation */
242
243 /* storage for jpiIndexArray: indexes of array */
244 struct
245 {
247 struct
248 {
253
254 /* jpiAny: levels */
255 struct
256 {
260
261 struct
262 {
264 char *pattern; /* could not be not null-terminated */
268
269 /* scalars */
272 struct
273 {
275 char *val; /* could not be not null-terminated */
278};
279
285
286extern JsonPathParseResult *parsejsonpath(const char *str, int len,
287 struct Node *escontext);
288
290 struct Node *escontext);
291
292/*
293 * Struct for details about external variables passed into jsonpath executor
294 */
295typedef struct JsonPathVariable
296{
297 char *name;
298 int namelen; /* strlen(name) as cache for GetJsonPathVar() */
302 bool isnull;
304
305
306/* SQL/JSON query functions */
307extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars);
309 bool *empty, bool *error, List *vars,
310 const char *column_name);
311extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
312 bool *error, List *vars,
313 const char *column_name);
314
315/* For JSON_TABLE() */
317
318#endif
#define PGDLLIMPORT
Definition c.h:1421
#define FLEXIBLE_ARRAY_MEMBER
Definition c.h:558
int32_t int32
Definition c.h:620
uint32_t uint32
Definition c.h:624
uint32 result
#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:73
int i
Definition isn.c:77
@ jbvNumeric
Definition jsonb.h:232
@ jbvBool
Definition jsonb.h:233
@ jbvNull
Definition jsonb.h:230
@ jbvString
Definition jsonb.h:231
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:1381
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1263
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1167
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition jsonpath.c:1068
bool jspGetBool(JsonPathItem *v)
Definition jsonpath.c:1311
void jspInit(JsonPathItem *v, JsonPath *js)
Definition jsonpath.c:1058
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:1327
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
Numeric jspGetNumeric(JsonPathItem *v)
Definition jsonpath.c:1319
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition jsonpath.c:1339
static JsonPath * DatumGetJsonPathPCopy(Datum d)
Definition jsonpath.h:41
const char * jspOperationName(JsonPathItemType type)
Definition jsonpath.c:905
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1188
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)
static JsonPath * DatumGetJsonPathP(Datum d)
Definition jsonpath.h:35
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition jsonpath.c:1287
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
@ 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
@ 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
@ 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
const void size_t len
const void * data
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
JsonWrapper
Definition primnodes.h:1777
static void error(void)
struct JsonPathItem::@152::@155 anybounds
uint32 first
Definition jsonpath.h:182
int32 datalen
Definition jsonpath.h:189
int32 nelems
Definition jsonpath.h:171
uint32 flags
Definition jsonpath.h:197
union JsonPathItem::@152 content
char * base
Definition jsonpath.h:154
struct JsonPathItem::@152::@157 like_regex
int32 nextPos
Definition jsonpath.h:148
JsonPathItemType type
Definition jsonpath.h:145
struct JsonPathItem::@152::@154::@158 * elems
char * data
Definition jsonpath.h:188
uint32 last
Definition jsonpath.h:183
struct JsonPathItem::@152::@153 args
struct JsonPathItem::@152::@154 array
int32 right
Definition jsonpath.h:162
int32 patternlen
Definition jsonpath.h:196
char * pattern
Definition jsonpath.h:195
struct JsonPathItem::@152::@156 value
struct JsonPathParseItem::@159::@164 string
JsonPathParseItem * arg
Definition jsonpath.h:241
JsonPathParseItem * from
Definition jsonpath.h:249
JsonPathParseItem * expr
Definition jsonpath.h:263
JsonPathParseItem * left
Definition jsonpath.h:236
JsonPathParseItem * right
Definition jsonpath.h:237
JsonPathParseItem * next
Definition jsonpath.h:228
struct JsonPathParseItem::@159::@160 args
union JsonPathParseItem::@159 value
JsonPathParseItem * to
Definition jsonpath.h:250
struct JsonPathParseItem::@159::@163 like_regex
struct JsonPathParseItem::@159::@161::@165 * elems
JsonPathItemType type
Definition jsonpath.h:227
struct JsonPathParseItem::@159::@162 anybounds
struct JsonPathParseItem::@159::@161 array
JsonPathParseItem * expr
Definition jsonpath.h:282
int32 vl_len_
Definition jsonpath.h:25
uint32 header
Definition jsonpath.h:26
Definition pg_list.h:54
Definition nodes.h:135
const char * type