7272#include "utils/jsonpath.h"
7373
7474
75+ /* Context for jsonpath encoding. */
76+ typedef struct JsonPathEncodingContext
77+ {
78+ StringInfo buf ; /* output buffer */
79+ bool ext ; /* PG extensions are enabled? */
80+ } JsonPathEncodingContext ;
81+
7582static Datum jsonPathFromCstring (char * in , int len );
7683static char * jsonPathToCstring (StringInfo out , JsonPath * in ,
7784 int estimated_len );
78- static int flattenJsonPathParseItem (StringInfo buf , JsonPathParseItem * item ,
79- int nestingLevel , bool insideArraySubscript );
85+ static int flattenJsonPathParseItem (JsonPathEncodingContext * cxt ,
86+ JsonPathParseItem * item ,
87+ int nestingLevel ,
88+ bool insideArraySubscript );
8089static void alignStringInfoInt (StringInfo buf );
8190static int32 reserveSpaceForItemPointer (StringInfo buf );
8291static void printJsonPathItem (StringInfo buf , JsonPathItem * v , bool inKey ,
@@ -167,6 +176,7 @@ jsonpath_send(PG_FUNCTION_ARGS)
167176static Datum
168177jsonPathFromCstring (char * in , int len )
169178{
179+ JsonPathEncodingContext cxt ;
170180 JsonPathParseResult * jsonpath = parsejsonpath (in , len );
171181 JsonPath * res ;
172182 StringInfoData buf ;
@@ -182,13 +192,18 @@ jsonPathFromCstring(char *in, int len)
182192 errmsg ("invalid input syntax for type %s: \"%s\"" , "jsonpath" ,
183193 in )));
184194
185- flattenJsonPathParseItem (& buf , jsonpath -> expr , 0 , false);
195+ cxt .buf = & buf ;
196+ cxt .ext = jsonpath -> ext ;
197+
198+ flattenJsonPathParseItem (& cxt , jsonpath -> expr , 0 , false);
186199
187200 res = (JsonPath * ) buf .data ;
188201 SET_VARSIZE (res , buf .len );
189202 res -> header = JSONPATH_VERSION ;
190203 if (jsonpath -> lax )
191204 res -> header |= JSONPATH_LAX ;
205+ if (jsonpath -> ext )
206+ res -> header |= JSONPATH_EXT ;
192207
193208 PG_RETURN_JSONPATH_P (res );
194209}
@@ -212,6 +227,8 @@ jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
212227 }
213228 enlargeStringInfo (out , estimated_len );
214229
230+ if (in -> header & JSONPATH_EXT )
231+ appendBinaryStringInfo (out , "pg " , 3 );
215232 if (!(in -> header & JSONPATH_LAX ))
216233 appendBinaryStringInfo (out , "strict " , 7 );
217234
@@ -221,14 +238,27 @@ jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
221238 return out -> data ;
222239}
223240
241+ static void
242+ checkJsonPathExtensionsEnabled (JsonPathEncodingContext * cxt ,
243+ JsonPathItemType type )
244+ {
245+ if (!cxt -> ext )
246+ ereport (ERROR ,
247+ (errcode (ERRCODE_INVALID_TEXT_REPRESENTATION ),
248+ errmsg ("%s contains extended operators that were not enabled" , "jsonpath" ),
249+ errhint ("use \"%s\" modifier at the start of %s string to enable extensions" ,
250+ "pg" , "jsonpath" )));
251+ }
252+
224253/*
225254 * Recursive function converting given jsonpath parse item and all its
226255 * children into a binary representation.
227256 */
228257static int
229- flattenJsonPathParseItem (StringInfo buf , JsonPathParseItem * item ,
258+ flattenJsonPathParseItem (JsonPathEncodingContext * cxt , JsonPathParseItem * item ,
230259 int nestingLevel , bool insideArraySubscript )
231260{
261+ StringInfo buf = cxt -> buf ;
232262 /* position from beginning of jsonpath data */
233263 int32 pos = buf -> len - JSONPATH_HDRSZ ;
234264 int32 chld ;
@@ -296,13 +326,13 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
296326 int32 right = reserveSpaceForItemPointer (buf );
297327
298328 chld = !item -> value .args .left ? pos :
299- flattenJsonPathParseItem (buf , item -> value .args .left ,
329+ flattenJsonPathParseItem (cxt , item -> value .args .left ,
300330 nestingLevel + argNestingLevel ,
301331 insideArraySubscript );
302332 * (int32 * ) (buf -> data + left ) = chld - pos ;
303333
304334 chld = !item -> value .args .right ? pos :
305- flattenJsonPathParseItem (buf , item -> value .args .right ,
335+ flattenJsonPathParseItem (cxt , item -> value .args .right ,
306336 nestingLevel + argNestingLevel ,
307337 insideArraySubscript );
308338 * (int32 * ) (buf -> data + right ) = chld - pos ;
@@ -323,7 +353,7 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
323353 item -> value .like_regex .patternlen );
324354 appendStringInfoChar (buf , '\0' );
325355
326- chld = flattenJsonPathParseItem (buf , item -> value .like_regex .expr ,
356+ chld = flattenJsonPathParseItem (cxt , item -> value .like_regex .expr ,
327357 nestingLevel ,
328358 insideArraySubscript );
329359 * (int32 * ) (buf -> data + offs ) = chld - pos ;
@@ -342,7 +372,7 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
342372 int32 arg = reserveSpaceForItemPointer (buf );
343373
344374 chld = !item -> value .arg ? pos :
345- flattenJsonPathParseItem (buf , item -> value .arg ,
375+ flattenJsonPathParseItem (cxt , item -> value .arg ,
346376 nestingLevel + argNestingLevel ,
347377 insideArraySubscript );
348378 * (int32 * ) (buf -> data + arg ) = chld - pos ;
@@ -384,12 +414,12 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
384414 int32 * ppos ;
385415 int32 topos ;
386416 int32 frompos =
387- flattenJsonPathParseItem (buf ,
417+ flattenJsonPathParseItem (cxt ,
388418 item -> value .array .elems [i ].from ,
389419 nestingLevel , true) - pos ;
390420
391421 if (item -> value .array .elems [i ].to )
392- topos = flattenJsonPathParseItem (buf ,
422+ topos = flattenJsonPathParseItem (cxt ,
393423 item -> value .array .elems [i ].to ,
394424 nestingLevel , true) - pos ;
395425 else
@@ -424,7 +454,7 @@ flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item,
424454
425455 if (item -> next )
426456 {
427- chld = flattenJsonPathParseItem (buf , item -> next , nestingLevel ,
457+ chld = flattenJsonPathParseItem (cxt , item -> next , nestingLevel ,
428458 insideArraySubscript ) - pos ;
429459 * (int32 * ) (buf -> data + next ) = chld ;
430460 }
@@ -832,7 +862,7 @@ operationPriority(JsonPathItemType op)
832862void
833863jspInit (JsonPathItem * v , JsonPath * js )
834864{
835- Assert ((js -> header & ~ JSONPATH_LAX ) == JSONPATH_VERSION );
865+ Assert ((js -> header & JSONPATH_VERSION_MASK ) == JSONPATH_VERSION );
836866 jspInitByBuffer (v , js -> data , 0 );
837867}
838868
0 commit comments