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-2024, 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 
23 typedef 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 
34 static inline JsonPath *
36 {
37  return (JsonPath *) PG_DETOAST_DATUM(d);
38 }
39 
40 static 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  */
62 typedef 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 
135 typedef 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  {
155  } args;
156 
157  /* any unary operation */
159 
160  /* storage for jpiIndexArray: indexes of array */
161  struct
162  {
164  struct
165  {
168  } *elems;
169  } array;
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 */
182  } value;
183 
184  struct
185  {
187  char *pattern;
193 
194 #define jspHasNext(jsp) ((jsp)->nextPos > 0)
195 
196 extern void jspInit(JsonPathItem *v, JsonPath *js);
197 extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
198 extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
199 extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
200 extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
201 extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
203 extern bool jspGetBool(JsonPathItem *v);
204 extern char *jspGetString(JsonPathItem *v, int32 *len);
205 extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
206  JsonPathItem *to, int i);
207 extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
208 
210 
211 /*
212  * Parsing support data structures.
213  */
214 
215 typedef struct JsonPathParseItem JsonPathParseItem;
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  {
230  } args;
231 
232  /* any unary operation */
234 
235  /* storage for jpiIndexArray: indexes of array */
236  struct
237  {
238  int nelems;
239  struct
240  {
243  } *elems;
244  } array;
245 
246  /* jpiAny: levels */
247  struct
248  {
252 
253  struct
254  {
256  char *pattern; /* could not be not null-terminated */
260 
261  /* scalars */
263  bool boolean;
264  struct
265  {
267  char *val; /* could not be not null-terminated */
269  } value;
270 };
271 
272 typedef struct JsonPathParseResult
273 {
275  bool lax;
277 
278 extern JsonPathParseResult *parsejsonpath(const char *str, int len,
279  struct Node *escontext);
280 
281 extern bool jspConvertRegexFlags(uint32 xflags, int *result,
282  struct Node *escontext);
283 
284 
285 /*
286  * Evaluation of jsonpath
287  */
288 
289 /* External variable passed into jsonpath. */
290 typedef struct JsonPathVariable
291 {
292  char *name;
296  bool isnull;
298 
299 
300 /* SQL/JSON item */
301 extern bool JsonPathExists(Datum jb, JsonPath *path, bool *error, List *vars);
302 extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
303  bool *empty, bool *error, List *vars);
304 extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
305  bool *error, List *vars);
306 
308 
309 #endif
unsigned int uint32
Definition: c.h:506
#define PGDLLIMPORT
Definition: c.h:1316
signed int int32
Definition: c.h:494
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:398
#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:69
int i
Definition: isn.c:73
@ 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 jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
Definition: jsonpath.c:1273
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1159
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1074
Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper, bool *empty, bool *error, List *vars)
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:983
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1203
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:973
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:836
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1211
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1231
struct JsonPathVariable JsonPathVariable
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1092
static JsonPath * DatumGetJsonPathP(Datum d)
Definition: jsonpath.h:35
bool JsonPathExists(Datum jb, JsonPath *path, bool *error, List *vars)
struct JsonPathParseResult JsonPathParseResult
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1181
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1219
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
JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars)
static JsonPath * DatumGetJsonPathPCopy(Datum d)
Definition: jsonpath.h:41
const void size_t len
const void * data
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
JsonWrapper
Definition: primnodes.h:1715
static void error(void)
Definition: sql-dyntest.c:147
uint32 first
Definition: jsonpath.h:174
int32 datalen
Definition: jsonpath.h:181
union JsonPathItem::@137 content
struct JsonPathItem::@137::@141 value
int32 nelems
Definition: jsonpath.h:163
uint32 flags
Definition: jsonpath.h:189
int32 to
Definition: jsonpath.h:167
int32 from
Definition: jsonpath.h:166
struct JsonPathItem::@137::@139 array
struct JsonPathItem::@137::@139::@143 * elems
int32 left
Definition: jsonpath.h:153
char * base
Definition: jsonpath.h:146
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::@137::@142 like_regex
struct JsonPathItem::@137::@140 anybounds
struct JsonPathItem::@137::@138 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::@144::@148 like_regex
struct JsonPathParseItem::@144::@146 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::@144::@149 string
struct JsonPathParseItem::@144::@147 anybounds
JsonPathParseItem * next
Definition: jsonpath.h:220
Numeric numeric
Definition: jsonpath.h:262
struct JsonPathParseItem::@144::@145 args
struct JsonPathParseItem::@144::@146::@150 * elems
JsonPathParseItem * to
Definition: jsonpath.h:242
union JsonPathParseItem::@144 value
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:281
const char * type