2424#include "utils/jsonpath.h"
2525#include "utils/varlena.h"
2626
27+ /* Special pseudo-ErrorData with zero sqlerrcode for existence queries. */
28+ ErrorData jperNotFound [1 ];
29+
30+
2731typedef struct JsonPathExecContext
2832{
2933 List * vars ;
@@ -755,12 +759,12 @@ executeComparison(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
755759 jspGetLeftArg (jsp , & elem );
756760 res = recursiveExecuteAndUnwrap (cxt , & elem , jb , & lseq );
757761 if (jperIsError (res ))
758- return jpbUnknown ;
762+ return jperReplace ( res , jpbUnknown ) ;
759763
760764 jspGetRightArg (jsp , & elem );
761765 res = recursiveExecuteAndUnwrap (cxt , & elem , jb , & rseq );
762766 if (jperIsError (res ))
763- return jpbUnknown ;
767+ return jperReplace ( res , jpbUnknown ) ;
764768
765769 while ((lval = JsonValueListNext (& lseq , & lseqit )))
766770 {
@@ -906,14 +910,16 @@ executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
906910 PG_CATCH ();
907911 {
908912 int errcode = geterrcode ();
913+ ErrorData * edata ;
909914
910915 if (ERRCODE_TO_CATEGORY (errcode ) != ERRCODE_DATA_EXCEPTION )
911916 PG_RE_THROW ();
912917
913- FlushErrorState ();
914918 MemoryContextSwitchTo (mcxt );
919+ edata = CopyErrorData ();
920+ FlushErrorState ();
915921
916- return jperMakeError ( errcode );
922+ return jperMakeErrorData ( edata );
917923 }
918924 PG_END_TRY ();
919925
@@ -940,7 +946,7 @@ executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp,
940946 jper = recursiveExecuteAndUnwrap (cxt , & elem , jb , & seq );
941947
942948 if (jperIsError (jper ))
943- return jperMakeError (ERRCODE_JSON_NUMBER_NOT_FOUND );
949+ return jperReplace ( jper , jperMakeError (ERRCODE_JSON_NUMBER_NOT_FOUND ) );
944950
945951 jper = jperNotFound ;
946952
@@ -1107,7 +1113,7 @@ executeStartsWithPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
11071113 jspGetRightArg (jsp , & elem );
11081114 res = recursiveExecute (cxt , & elem , jb , & rseq );
11091115 if (jperIsError (res ))
1110- return jpbUnknown ;
1116+ return jperReplace ( res , jpbUnknown ) ;
11111117
11121118 if (JsonValueListLength (& rseq ) != 1 )
11131119 return jpbUnknown ;
@@ -1123,7 +1129,7 @@ executeStartsWithPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
11231129 jspGetLeftArg (jsp , & elem );
11241130 res = recursiveExecuteAndUnwrap (cxt , & elem , jb , & lseq );
11251131 if (jperIsError (res ))
1126- return jpbUnknown ;
1132+ return jperReplace ( res , jpbUnknown ) ;
11271133
11281134 while ((whole = JsonValueListNext (& lseq , & lit )))
11291135 {
@@ -1190,7 +1196,7 @@ executeLikeRegexPredicate(JsonPathExecContext *cxt, JsonPathItem *jsp,
11901196 jspInitByBuffer (& elem , jsp -> base , jsp -> content .like_regex .expr );
11911197 res = recursiveExecuteAndUnwrap (cxt , & elem , jb , & seq );
11921198 if (jperIsError (res ))
1193- return jpbUnknown ;
1199+ return jperReplace ( res , jpbUnknown ) ;
11941200
11951201 while ((str = JsonValueListNext (& seq , & it )))
11961202 {
@@ -1371,7 +1377,7 @@ recursiveExecuteBool(JsonPathExecContext *cxt, JsonPathItem *jsp,
13711377 recursiveExecute (cxt , & arg , jb , & vals );
13721378
13731379 if (jperIsError (res ))
1374- return jpbUnknown ;
1380+ return jperReplace ( res , jpbUnknown ) ;
13751381
13761382 return JsonValueListIsEmpty (& vals ) ? jpbFalse : jpbTrue ;
13771383 }
@@ -1380,7 +1386,7 @@ recursiveExecuteBool(JsonPathExecContext *cxt, JsonPathItem *jsp,
13801386 JsonPathExecResult res = recursiveExecute (cxt , & arg , jb , NULL );
13811387
13821388 if (jperIsError (res ))
1383- return jpbUnknown ;
1389+ return jperReplace ( res , jpbUnknown ) ;
13841390
13851391 return res == jperOk ? jpbTrue : jpbFalse ;
13861392 }
@@ -2353,59 +2359,65 @@ makePassingVars(Jsonb *jb)
23532359static void
23542360throwJsonPathError (JsonPathExecResult res )
23552361{
2362+ int err ;
23562363 if (!jperIsError (res ))
23572364 return ;
23582365
2359- switch (jperGetError (res ))
2366+ if (jperIsErrorData (res ))
2367+ ThrowErrorData (jperGetErrorData (res ));
2368+
2369+ err = jperGetError (res );
2370+
2371+ switch (err )
23602372 {
23612373 case ERRCODE_JSON_ARRAY_NOT_FOUND :
23622374 ereport (ERROR ,
2363- (errcode (jperGetError ( res ) ),
2375+ (errcode (err ),
23642376 errmsg ("SQL/JSON array not found" )));
23652377 break ;
23662378 case ERRCODE_JSON_OBJECT_NOT_FOUND :
23672379 ereport (ERROR ,
2368- (errcode (jperGetError ( res ) ),
2380+ (errcode (err ),
23692381 errmsg ("SQL/JSON object not found" )));
23702382 break ;
23712383 case ERRCODE_JSON_MEMBER_NOT_FOUND :
23722384 ereport (ERROR ,
2373- (errcode (jperGetError ( res ) ),
2385+ (errcode (err ),
23742386 errmsg ("SQL/JSON member not found" )));
23752387 break ;
23762388 case ERRCODE_JSON_NUMBER_NOT_FOUND :
23772389 ereport (ERROR ,
2378- (errcode (jperGetError ( res ) ),
2390+ (errcode (err ),
23792391 errmsg ("SQL/JSON number not found" )));
23802392 break ;
23812393 case ERRCODE_JSON_SCALAR_REQUIRED :
23822394 ereport (ERROR ,
2383- (errcode (jperGetError ( res ) ),
2395+ (errcode (err ),
23842396 errmsg ("SQL/JSON scalar required" )));
23852397 break ;
23862398 case ERRCODE_SINGLETON_JSON_ITEM_REQUIRED :
23872399 ereport (ERROR ,
2388- (errcode (jperGetError ( res ) ),
2400+ (errcode (err ),
23892401 errmsg ("Singleton SQL/JSON item required" )));
23902402 break ;
23912403 case ERRCODE_NON_NUMERIC_JSON_ITEM :
23922404 ereport (ERROR ,
2393- (errcode (jperGetError ( res ) ),
2405+ (errcode (err ),
23942406 errmsg ("Non-numeric SQL/JSON item" )));
23952407 break ;
23962408 case ERRCODE_INVALID_JSON_SUBSCRIPT :
23972409 ereport (ERROR ,
2398- (errcode (jperGetError ( res ) ),
2410+ (errcode (err ),
23992411 errmsg ("Invalid SQL/JSON subscript" )));
24002412 break ;
24012413 case ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION :
24022414 ereport (ERROR ,
2403- (errcode (jperGetError ( res ) ),
2415+ (errcode (err ),
24042416 errmsg ("Invalid argument for SQL/JSON datetime function" )));
24052417 break ;
24062418 default :
24072419 ereport (ERROR ,
2408- (errcode (jperGetError ( res ) ),
2420+ (errcode (err ),
24092421 errmsg ("Unknown SQL/JSON error" )));
24102422 break ;
24112423 }
@@ -2428,7 +2440,10 @@ jsonb_jsonpath_exists(PG_FUNCTION_ARGS)
24282440 PG_FREE_IF_COPY (jp , 1 );
24292441
24302442 if (jperIsError (res ))
2443+ {
2444+ jperFree (res );
24312445 PG_RETURN_NULL ();
2446+ }
24322447
24332448 PG_RETURN_BOOL (res == jperOk );
24342449}
0 commit comments