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-2022, 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 "fmgr.h"
18 #include "executor/tablefunc.h"
19 #include "nodes/pg_list.h"
20 #include "nodes/primnodes.h"
21 #include "utils/jsonb.h"
22 #include "utils/jsonfuncs.h"
23 
24 typedef struct
25 {
26  int32 vl_len_; /* varlena header (do not touch directly!) */
27  uint32 header; /* version and flags (see below) */
29 } JsonPath;
30 
31 #define JSONPATH_VERSION (0x01)
32 #define JSONPATH_LAX (0x80000000)
33 #define JSONPATH_HDRSZ (offsetof(JsonPath, data))
34 
35 #define DatumGetJsonPathP(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM(d)))
36 #define DatumGetJsonPathPCopy(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM_COPY(d)))
37 #define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x))
38 #define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
39 #define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p)
40 
41 #define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)
42 
43 /*
44  * All node's type of jsonpath expression
45  */
46 typedef enum JsonPathItemType
47 {
48  jpiNull = jbvNull, /* NULL literal */
49  jpiString = jbvString, /* string literal */
50  jpiNumeric = jbvNumeric, /* numeric literal */
51  jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */
52  jpiAnd, /* predicate && predicate */
53  jpiOr, /* predicate || predicate */
54  jpiNot, /* ! predicate */
55  jpiIsUnknown, /* (predicate) IS UNKNOWN */
56  jpiEqual, /* expr == expr */
57  jpiNotEqual, /* expr != expr */
58  jpiLess, /* expr < expr */
59  jpiGreater, /* expr > expr */
60  jpiLessOrEqual, /* expr <= expr */
61  jpiGreaterOrEqual, /* expr >= expr */
62  jpiAdd, /* expr + expr */
63  jpiSub, /* expr - expr */
64  jpiMul, /* expr * expr */
65  jpiDiv, /* expr / expr */
66  jpiMod, /* expr % expr */
67  jpiPlus, /* + expr */
68  jpiMinus, /* - expr */
69  jpiAnyArray, /* [*] */
70  jpiAnyKey, /* .* */
71  jpiIndexArray, /* [subscript, ...] */
72  jpiAny, /* .** */
73  jpiKey, /* .key */
74  jpiCurrent, /* @ */
75  jpiRoot, /* $ */
76  jpiVariable, /* $variable */
77  jpiFilter, /* ? (predicate) */
78  jpiExists, /* EXISTS (expr) predicate */
79  jpiType, /* .type() item method */
80  jpiSize, /* .size() item method */
81  jpiAbs, /* .abs() item method */
82  jpiFloor, /* .floor() item method */
83  jpiCeiling, /* .ceiling() item method */
84  jpiDouble, /* .double() item method */
85  jpiDatetime, /* .datetime() item method */
86  jpiKeyValue, /* .keyvalue() item method */
87  jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */
88  jpiLast, /* LAST array subscript */
89  jpiStartsWith, /* STARTS WITH predicate */
90  jpiLikeRegex, /* LIKE_REGEX predicate */
92 
93 /* XQuery regex mode flags for LIKE_REGEX predicate */
94 #define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */
95 #define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */
96 #define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */
97 #define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */
98 #define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
99 
100 /*
101  * Support functions to parse/construct binary value.
102  * Unlike many other representation of expression the first/main
103  * node is not an operation but left operand of expression. That
104  * allows to implement cheap follow-path descending in jsonb
105  * structure and then execute operator with right operand
106  */
107 
108 typedef struct JsonPathItem
109 {
111 
112  /* position form base to next node */
114 
115  /*
116  * pointer into JsonPath value to current node, all positions of current
117  * are relative to this base
118  */
119  char *base;
120 
121  union
122  {
123  /* classic operator with two operands: and, or etc */
124  struct
125  {
128  } args;
129 
130  /* any unary operation */
132 
133  /* storage for jpiIndexArray: indexes of array */
134  struct
135  {
137  struct
138  {
141  } *elems;
142  } array;
143 
144  /* jpiAny: levels */
145  struct
146  {
150 
151  struct
152  {
153  char *data; /* for bool, numeric and string/key */
154  int32 datalen; /* filled only for string/key */
155  } value;
156 
157  struct
158  {
160  char *pattern;
166 
167 #define jspHasNext(jsp) ((jsp)->nextPos > 0)
168 
169 extern void jspInit(JsonPathItem *v, JsonPath *js);
170 extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
171 extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
172 extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
173 extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
174 extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
176 extern bool jspGetBool(JsonPathItem *v);
177 extern char *jspGetString(JsonPathItem *v, int32 *len);
178 extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
179  JsonPathItem *to, int i);
180 extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
181 
183 
184 /*
185  * Parsing support data structures.
186  */
187 
188 typedef struct JsonPathParseItem JsonPathParseItem;
189 
191 {
193  JsonPathParseItem *next; /* next in path */
194 
195  union
196  {
197 
198  /* classic operator with two operands: and, or etc */
199  struct
200  {
203  } args;
204 
205  /* any unary operation */
207 
208  /* storage for jpiIndexArray: indexes of array */
209  struct
210  {
211  int nelems;
212  struct
213  {
216  } *elems;
217  } array;
218 
219  /* jpiAny: levels */
220  struct
221  {
225 
226  struct
227  {
229  char *pattern; /* could not be not null-terminated */
233 
234  /* scalars */
236  bool boolean;
237  struct
238  {
240  char *val; /* could not be not null-terminated */
242  } value;
243 };
244 
245 typedef struct JsonPathParseResult
246 {
248  bool lax;
250 
251 extern JsonPathParseResult *parsejsonpath(const char *str, int len);
252 
253 extern int jspConvertRegexFlags(uint32 xflags);
254 
255 /*
256  * Evaluation of jsonpath
257  */
258 
259 /* External variable passed into jsonpath. */
261 {
262  char *name;
266  struct ExprState *estate;
267  MemoryContext mcxt; /* memory context for cached value */
269  bool isnull;
270  bool evaluated;
272 
273 /* SQL/JSON item */
274 extern void JsonItemFromDatum(Datum val, Oid typid, int32 typmod,
275  JsonbValue *res);
276 
277 extern bool JsonPathExists(Datum jb, JsonPath *path, List *vars, bool *error);
278 extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
279  bool *empty, bool *error, List *vars);
280 extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
281  bool *error, List *vars);
282 
283 extern int EvalJsonPathVar(void *vars, char *varName, int varNameLen,
284  JsonbValue *val, JsonbValue *baseObject);
285 
287 
288 #endif
unsigned int uint32
Definition: c.h:441
#define PGDLLIMPORT
Definition: c.h:1331
signed int int32
Definition: c.h:429
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:350
long val
Definition: informix.c:664
int a
Definition: isn.c:69
int i
Definition: isn.c:73
@ jbvNumeric
Definition: jsonb.h:238
@ jbvBool
Definition: jsonb.h:239
@ jbvNull
Definition: jsonb.h:236
@ jbvString
Definition: jsonb.h:237
PGDLLIMPORT const TableFuncRoutine JsonbTableRoutine
bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
Definition: jsonpath.c:1321
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:998
int jspConvertRegexFlags(uint32 xflags)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:929
void JsonItemFromDatum(Datum val, Oid typid, int32 typmod, JsonbValue *res)
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:849
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1040
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:839
int EvalJsonPathVar(void *vars, char *varName, int varNameLen, JsonbValue *val, JsonbValue *baseObject)
struct JsonPathVariableEvalContext JsonPathVariableEvalContext
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:724
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1048
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1068
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:943
JsonPathParseResult * parsejsonpath(const char *str, int len)
struct JsonPathParseResult JsonPathParseResult
bool JsonPathExists(Datum jb, JsonPath *path, List *vars, bool *error)
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1019
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1056
struct JsonPathItem JsonPathItem
JsonPathItemType
Definition: jsonpath.h:47
@ jpiAdd
Definition: jsonpath.h:62
@ jpiString
Definition: jsonpath.h:49
@ jpiAbs
Definition: jsonpath.h:81
@ jpiIndexArray
Definition: jsonpath.h:71
@ jpiAny
Definition: jsonpath.h:72
@ jpiDatetime
Definition: jsonpath.h:85
@ jpiBool
Definition: jsonpath.h:51
@ jpiType
Definition: jsonpath.h:79
@ jpiFloor
Definition: jsonpath.h:82
@ jpiAnyArray
Definition: jsonpath.h:69
@ jpiExists
Definition: jsonpath.h:78
@ jpiSize
Definition: jsonpath.h:80
@ jpiSub
Definition: jsonpath.h:63
@ jpiSubscript
Definition: jsonpath.h:87
@ jpiNotEqual
Definition: jsonpath.h:57
@ jpiMul
Definition: jsonpath.h:64
@ jpiVariable
Definition: jsonpath.h:76
@ jpiNot
Definition: jsonpath.h:54
@ jpiGreaterOrEqual
Definition: jsonpath.h:61
@ jpiPlus
Definition: jsonpath.h:67
@ jpiDouble
Definition: jsonpath.h:84
@ jpiGreater
Definition: jsonpath.h:59
@ jpiAnd
Definition: jsonpath.h:52
@ jpiStartsWith
Definition: jsonpath.h:89
@ jpiOr
Definition: jsonpath.h:53
@ jpiMod
Definition: jsonpath.h:66
@ jpiLikeRegex
Definition: jsonpath.h:90
@ jpiRoot
Definition: jsonpath.h:75
@ jpiFilter
Definition: jsonpath.h:77
@ jpiNull
Definition: jsonpath.h:48
@ jpiLess
Definition: jsonpath.h:58
@ jpiCurrent
Definition: jsonpath.h:74
@ jpiEqual
Definition: jsonpath.h:56
@ jpiKey
Definition: jsonpath.h:73
@ jpiDiv
Definition: jsonpath.h:65
@ jpiLast
Definition: jsonpath.h:88
@ jpiMinus
Definition: jsonpath.h:68
@ jpiLessOrEqual
Definition: jsonpath.h:60
@ jpiCeiling
Definition: jsonpath.h:83
@ jpiIsUnknown
Definition: jsonpath.h:55
@ jpiKeyValue
Definition: jsonpath.h:86
@ jpiNumeric
Definition: jsonpath.h:50
@ jpiAnyKey
Definition: jsonpath.h:70
JsonbValue * JsonPathValue(Datum jb, JsonPath *jp, bool *empty, bool *error, List *vars)
const void size_t len
const void * data
uintptr_t Datum
Definition: postgres.h:411
unsigned int Oid
Definition: postgres_ext.h:31
JsonWrapper
Definition: primnodes.h:1306
static void error(void)
Definition: sql-dyntest.c:147
uint32 first
Definition: jsonpath.h:147
int32 datalen
Definition: jsonpath.h:154
struct JsonPathItem::@136::@140 value
int32 nelems
Definition: jsonpath.h:136
uint32 flags
Definition: jsonpath.h:162
int32 to
Definition: jsonpath.h:140
int32 from
Definition: jsonpath.h:139
int32 left
Definition: jsonpath.h:126
char * base
Definition: jsonpath.h:119
int32 nextPos
Definition: jsonpath.h:113
struct JsonPathItem::@136::@138::@142 * elems
struct JsonPathItem::@136::@141 like_regex
int32 arg
Definition: jsonpath.h:131
JsonPathItemType type
Definition: jsonpath.h:110
char * data
Definition: jsonpath.h:153
uint32 last
Definition: jsonpath.h:148
struct JsonPathItem::@136::@137 args
struct JsonPathItem::@136::@139 anybounds
struct JsonPathItem::@136::@138 array
union JsonPathItem::@136 content
int32 right
Definition: jsonpath.h:127
int32 patternlen
Definition: jsonpath.h:161
char * pattern
Definition: jsonpath.h:160
int32 expr
Definition: jsonpath.h:159
struct JsonPathParseItem::@143::@144 args
JsonPathParseItem * arg
Definition: jsonpath.h:206
struct JsonPathParseItem::@143::@145::@149 * elems
struct JsonPathParseItem::@143::@146 anybounds
JsonPathParseItem * from
Definition: jsonpath.h:214
JsonPathParseItem * expr
Definition: jsonpath.h:228
JsonPathParseItem * left
Definition: jsonpath.h:201
JsonPathParseItem * right
Definition: jsonpath.h:202
JsonPathParseItem * next
Definition: jsonpath.h:193
struct JsonPathParseItem::@143::@148 string
Numeric numeric
Definition: jsonpath.h:235
JsonPathParseItem * to
Definition: jsonpath.h:215
struct JsonPathParseItem::@143::@145 array
struct JsonPathParseItem::@143::@147 like_regex
JsonPathItemType type
Definition: jsonpath.h:192
uint32 patternlen
Definition: jsonpath.h:230
union JsonPathParseItem::@143 value
JsonPathParseItem * expr
Definition: jsonpath.h:247
struct ExprState * estate
Definition: jsonpath.h:266
struct ExprContext * econtext
Definition: jsonpath.h:265
int32 vl_len_
Definition: jsonpath.h:26
uint32 header
Definition: jsonpath.h:27
Definition: pg_list.h:51
Definition: regcomp.c:238