PostgreSQL Source Code  git master
jsonpath_exec.c File Reference
#include "postgres.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "miscadmin.h"
#include "regex/regex.h"
#include "utils/builtins.h"
#include "utils/datetime.h"
#include "utils/datum.h"
#include "utils/formatting.h"
#include "utils/float.h"
#include "utils/guc.h"
#include "utils/json.h"
#include "utils/jsonpath.h"
#include "utils/date.h"
#include "utils/timestamp.h"
#include "utils/varlena.h"
Include dependency graph for jsonpath_exec.c:

Go to the source code of this file.

Data Structures

struct  JsonBaseObjectInfo
 
struct  JsonPathExecContext
 
struct  JsonLikeRegexContext
 
struct  JsonValueList
 
struct  JsonValueListIterator
 

Macros

#define jperIsError(jper)   ((jper) == jperError)
 
#define jspStrictAbsenseOfErrors(cxt)   (!(cxt)->laxMode)
 
#define jspAutoUnwrap(cxt)   ((cxt)->laxMode)
 
#define jspAutoWrap(cxt)   ((cxt)->laxMode)
 
#define jspIgnoreStructuralErrors(cxt)   ((cxt)->ignoreStructuralErrors)
 
#define jspThrowErrors(cxt)   ((cxt)->throwErrors)
 
#define RETURN_ERROR(throw_error)
 

Typedefs

typedef struct JsonBaseObjectInfo JsonBaseObjectInfo
 
typedef struct JsonPathExecContext JsonPathExecContext
 
typedef struct JsonLikeRegexContext JsonLikeRegexContext
 
typedef enum JsonPathBool JsonPathBool
 
typedef enum JsonPathExecResult JsonPathExecResult
 
typedef struct JsonValueList JsonValueList
 
typedef struct JsonValueListIterator JsonValueListIterator
 
typedef JsonPathBool(* JsonPathPredicateCallback) (JsonPathItem *jsp, JsonbValue *larg, JsonbValue *rarg, void *param)
 
typedef Numeric(* BinaryArithmFunc) (Numeric num1, Numeric num2, bool *error)
 

Enumerations

enum  JsonPathBool { jpbFalse = 0, jpbTrue = 1, jpbUnknown = 2 }
 
enum  JsonPathExecResult { jperOk = 0, jperNotFound = 1, jperError = 2 }
 

Functions

static JsonPathExecResult executeJsonPath (JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
 
static JsonPathExecResult executeItem (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
 
static JsonPathExecResult executeItemOptUnwrapTarget (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)
 
static JsonPathExecResult executeItemUnwrapTargetArray (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
 
static JsonPathExecResult executeNextItem (JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
 
static JsonPathExecResult executeItemOptUnwrapResult (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
 
static JsonPathExecResult executeItemOptUnwrapResultNoThrow (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
 
static JsonPathBool executeBoolItem (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
 
static JsonPathBool executeNestedBoolItem (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
 
static JsonPathExecResult executeAnyItem (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
 
static JsonPathBool executePredicate (JsonPathExecContext *cxt, JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, bool unwrapRightArg, JsonPathPredicateCallback exec, void *param)
 
static JsonPathExecResult executeBinaryArithmExpr (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
 
static JsonPathExecResult executeUnaryArithmExpr (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, PGFunction func, JsonValueList *found)
 
static JsonPathBool executeStartsWith (JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, void *param)
 
static JsonPathBool executeLikeRegex (JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, void *param)
 
static JsonPathExecResult executeNumericItemMethod (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, JsonValueList *found)
 
static JsonPathExecResult executeDateTimeMethod (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
 
static JsonPathExecResult executeKeyValueMethod (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
 
static JsonPathExecResult appendBoolResult (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonValueList *found, JsonPathBool res)
 
static void getJsonPathItem (JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)
 
static void getJsonPathVariable (JsonPathExecContext *cxt, JsonPathItem *variable, Jsonb *vars, JsonbValue *value)
 
static int JsonbArraySize (JsonbValue *jb)
 
static JsonPathBool executeComparison (JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)
 
static JsonPathBool compareItems (int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)
 
static int compareNumeric (Numeric a, Numeric b)
 
static JsonbValuecopyJsonbValue (JsonbValue *src)
 
static JsonPathExecResult getArrayIndex (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)
 
static JsonBaseObjectInfo setBaseObject (JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
 
static void JsonValueListAppend (JsonValueList *jvl, JsonbValue *jbv)
 
static int JsonValueListLength (const JsonValueList *jvl)
 
static bool JsonValueListIsEmpty (JsonValueList *jvl)
 
static JsonbValueJsonValueListHead (JsonValueList *jvl)
 
static ListJsonValueListGetList (JsonValueList *jvl)
 
static void JsonValueListInitIterator (const JsonValueList *jvl, JsonValueListIterator *it)
 
static JsonbValueJsonValueListNext (const JsonValueList *jvl, JsonValueListIterator *it)
 
static int JsonbType (JsonbValue *jb)
 
static JsonbValueJsonbInitBinary (JsonbValue *jbv, Jsonb *jb)
 
static JsonbValuegetScalar (JsonbValue *scalar, enum jbvType type)
 
static JsonbValuewrapItemsInArray (const JsonValueList *items)
 
static int compareDatetime (Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *have_error)
 
static Datum jsonb_path_exists_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_exists (PG_FUNCTION_ARGS)
 
Datum jsonb_path_exists_tz (PG_FUNCTION_ARGS)
 
Datum jsonb_path_exists_opr (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_match_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_match (PG_FUNCTION_ARGS)
 
Datum jsonb_path_match_tz (PG_FUNCTION_ARGS)
 
Datum jsonb_path_match_opr (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_tz (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_array_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query_array (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_array_tz (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_first_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query_first (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_first_tz (PG_FUNCTION_ARGS)
 
static int binaryCompareStrings (const char *s1, int len1, const char *s2, int len2)
 
static int compareStrings (const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
 

Macro Definition Documentation

◆ jperIsError

◆ jspAutoUnwrap

#define jspAutoUnwrap (   cxt)    ((cxt)->laxMode)

◆ jspAutoWrap

#define jspAutoWrap (   cxt)    ((cxt)->laxMode)

Definition at line 158 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspIgnoreStructuralErrors

#define jspIgnoreStructuralErrors (   cxt)    ((cxt)->ignoreStructuralErrors)

Definition at line 159 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspStrictAbsenseOfErrors

#define jspStrictAbsenseOfErrors (   cxt)    (!(cxt)->laxMode)

Definition at line 156 of file jsonpath_exec.c.

Referenced by executeBoolItem(), executeJsonPath(), and executePredicate().

◆ jspThrowErrors

#define jspThrowErrors (   cxt)    ((cxt)->throwErrors)

◆ RETURN_ERROR

#define RETURN_ERROR (   throw_error)
Value:
do { \
if (jspThrowErrors(cxt)) \
throw_error; \
else \
return jperError; \
} while (0)
#define jspThrowErrors(cxt)

Definition at line 163 of file jsonpath_exec.c.

Referenced by executeBinaryArithmExpr(), executeDateTimeMethod(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), executeNumericItemMethod(), executeUnaryArithmExpr(), and getArrayIndex().

Typedef Documentation

◆ BinaryArithmFunc

typedef Numeric(* BinaryArithmFunc) (Numeric num1, Numeric num2, bool *error)

Definition at line 175 of file jsonpath_exec.c.

◆ JsonBaseObjectInfo

◆ JsonLikeRegexContext

◆ JsonPathBool

typedef enum JsonPathBool JsonPathBool

◆ JsonPathExecContext

◆ JsonPathExecResult

◆ JsonPathPredicateCallback

typedef JsonPathBool(* JsonPathPredicateCallback) (JsonPathItem *jsp, JsonbValue *larg, JsonbValue *rarg, void *param)

Definition at line 171 of file jsonpath_exec.c.

◆ JsonValueList

typedef struct JsonValueList JsonValueList

◆ JsonValueListIterator

Enumeration Type Documentation

◆ JsonPathBool

Enumerator
jpbFalse 
jpbTrue 
jpbUnknown 

Definition at line 122 of file jsonpath_exec.c.

123 {
124  jpbFalse = 0,
125  jpbTrue = 1,
126  jpbUnknown = 2
127 } JsonPathBool;
JsonPathBool

◆ JsonPathExecResult

Enumerator
jperOk 
jperNotFound 
jperError 

Definition at line 130 of file jsonpath_exec.c.

131 {
132  jperOk = 0,
133  jperNotFound = 1,
134  jperError = 2
JsonPathExecResult

Function Documentation

◆ appendBoolResult()

static JsonPathExecResult appendBoolResult ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonValueList found,
JsonPathBool  res 
)
static

Definition at line 2036 of file jsonpath_exec.c.

References executeNextItem(), jbvBool, jbvNull, jpbTrue, jpbUnknown, jperOk, jspGetNext(), next, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

2038 {
2040  JsonbValue jbv;
2041 
2042  if (!jspGetNext(jsp, &next) && !found)
2043  return jperOk; /* found singleton boolean value */
2044 
2045  if (res == jpbUnknown)
2046  {
2047  jbv.type = jbvNull;
2048  }
2049  else
2050  {
2051  jbv.type = jbvBool;
2052  jbv.val.boolean = res == jpbTrue;
2053  }
2054 
2055  return executeNextItem(cxt, jsp, &next, &jbv, found, true);
2056 }
static int32 next
Definition: blutils.c:215
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Definition: jsonb.h:236
enum jbvType type
Definition: jsonb.h:263
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)

◆ binaryCompareStrings()

static int binaryCompareStrings ( const char *  s1,
int  len1,
const char *  s2,
int  len2 
)
static

Definition at line 2170 of file jsonpath_exec.c.

References cmp(), and Min.

Referenced by compareStrings().

2172 {
2173  int cmp;
2174 
2175  cmp = memcmp(s1, s2, Min(len1, len2));
2176 
2177  if (cmp != 0)
2178  return cmp;
2179 
2180  if (len1 == len2)
2181  return 0;
2182 
2183  return len1 < len2 ? -1 : 1;
2184 }
#define Min(x, y)
Definition: c.h:904
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ compareDatetime()

static int compareDatetime ( Datum  val1,
Oid  typid1,
Datum  val2,
Oid  typid2,
bool  useTz,
bool have_error 
)
static

Definition at line 2579 of file jsonpath_exec.c.

References date2timestamp_opt_error(), date2timestamptz_opt_error(), date_cmp(), DatumGetDateADT, DatumGetInt32, DatumGetTimestamp, DirectFunctionCall1, DirectFunctionCall2, elog, ereport, errcode(), errhint(), errmsg(), ERROR, time_cmp(), time_timetz(), timestamp2timestamptz_opt_error(), timestamp_cmp(), TimestampGetDatum, TimestampTzGetDatum, and timetz_cmp().

Referenced by compareItems().

2581 {
2582  PGFunction cmpfunc = NULL;
2583 
2584  switch (typid1)
2585  {
2586  case DATEOID:
2587  switch (typid2)
2588  {
2589  case DATEOID:
2590  cmpfunc = date_cmp;
2591 
2592  break;
2593 
2594  case TIMESTAMPOID:
2595  val1 = TimestampGetDatum(date2timestamp_opt_error(DatumGetDateADT(val1), have_error));
2596  if (have_error && *have_error)
2597  return 0;
2598  cmpfunc = timestamp_cmp;
2599 
2600  break;
2601 
2602  case TIMESTAMPTZOID:
2603  if (!useTz)
2604  ereport(ERROR,
2605  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2606  errmsg("cannot convert value from %s to %s without timezone usage",
2607  "date", "timestamptz"),
2608  errhint("use *_tz() function for timezone support")));
2610  if (have_error && *have_error)
2611  return 0;
2612  cmpfunc = timestamp_cmp;
2613 
2614  break;
2615 
2616  case TIMEOID:
2617  case TIMETZOID:
2618  *have_error = true;
2619  return 0;
2620  }
2621  break;
2622 
2623  case TIMEOID:
2624  switch (typid2)
2625  {
2626  case TIMEOID:
2627  cmpfunc = time_cmp;
2628 
2629  break;
2630 
2631  case TIMETZOID:
2632  if (!useTz)
2633  ereport(ERROR,
2634  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2635  errmsg("cannot convert value from %s to %s without timezone usage",
2636  "time", "timetz"),
2637  errhint("use *_tz() function for timezone support")));
2638  val1 = DirectFunctionCall1(time_timetz, val1);
2639  cmpfunc = timetz_cmp;
2640 
2641  break;
2642 
2643  case DATEOID:
2644  case TIMESTAMPOID:
2645  case TIMESTAMPTZOID:
2646  *have_error = true;
2647  return 0;
2648  }
2649  break;
2650 
2651  case TIMETZOID:
2652  switch (typid2)
2653  {
2654  case TIMEOID:
2655  if (!useTz)
2656  ereport(ERROR,
2657  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2658  errmsg("cannot convert value from %s to %s without timezone usage",
2659  "time", "timetz"),
2660  errhint("use *_tz() function for timezone support")));
2661  val2 = DirectFunctionCall1(time_timetz, val2);
2662  cmpfunc = timetz_cmp;
2663 
2664  break;
2665 
2666  case TIMETZOID:
2667  cmpfunc = timetz_cmp;
2668 
2669  break;
2670 
2671  case DATEOID:
2672  case TIMESTAMPOID:
2673  case TIMESTAMPTZOID:
2674  *have_error = true;
2675  return 0;
2676  }
2677  break;
2678 
2679  case TIMESTAMPOID:
2680  switch (typid2)
2681  {
2682  case DATEOID:
2683  val2 = TimestampGetDatum(date2timestamp_opt_error(DatumGetDateADT(val2), have_error));
2684  if (have_error && *have_error)
2685  return 0;
2686  cmpfunc = timestamp_cmp;
2687 
2688  break;
2689 
2690  case TIMESTAMPOID:
2691  cmpfunc = timestamp_cmp;
2692 
2693  break;
2694 
2695  case TIMESTAMPTZOID:
2696  if (!useTz)
2697  ereport(ERROR,
2698  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2699  errmsg("cannot convert value from %s to %s without timezone usage",
2700  "timestamp", "timestamptz"),
2701  errhint("use *_tz() function for timezone support")));
2703  if (have_error && *have_error)
2704  return 0;
2705  cmpfunc = timestamp_cmp;
2706 
2707  break;
2708 
2709  case TIMEOID:
2710  case TIMETZOID:
2711  *have_error = true;
2712  return 0;
2713  }
2714  break;
2715 
2716  case TIMESTAMPTZOID:
2717  switch (typid2)
2718  {
2719  case DATEOID:
2720  if (!useTz)
2721  ereport(ERROR,
2722  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2723  errmsg("cannot convert value from %s to %s without timezone usage",
2724  "date", "timestamptz"),
2725  errhint("use *_tz() function for timezone support")));
2727  if (have_error && *have_error)
2728  return 0;
2729  cmpfunc = timestamp_cmp;
2730 
2731  break;
2732 
2733  case TIMESTAMPOID:
2734  if (!useTz)
2735  ereport(ERROR,
2736  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2737  errmsg("cannot convert value from %s to %s without timezone usage",
2738  "timestamp", "timestamptz"),
2739  errhint("use *_tz() function for timezone support")));
2741  if (have_error && *have_error)
2742  return 0;
2743  cmpfunc = timestamp_cmp;
2744 
2745  break;
2746 
2747  case TIMESTAMPTZOID:
2748  cmpfunc = timestamp_cmp;
2749 
2750  break;
2751 
2752  case TIMEOID:
2753  case TIMETZOID:
2754  *have_error = true;
2755  return 0;
2756  }
2757  break;
2758 
2759  default:
2760  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %d",
2761  typid1);
2762  }
2763 
2764  if (*have_error)
2765  return 0;
2766 
2767  if (!cmpfunc)
2768  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %d",
2769  typid2);
2770 
2771  *have_error = false;
2772 
2773  return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2));
2774 }
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2267
Datum(* PGFunction)(FunctionCallInfo fcinfo)
Definition: fmgr.h:40
TimestampTz timestamp2timestamptz_opt_error(Timestamp timestamp, bool *have_error)
Definition: timestamp.c:5198
#define DatumGetDateADT(X)
Definition: date.h:53
int errhint(const char *fmt,...)
Definition: elog.c:974
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition: timestamp.c:2119
Timestamp date2timestamp_opt_error(DateADT dateVal, bool *have_error)
Definition: date.c:561
int errcode(int sqlerrcode)
Definition: elog.c:570
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1523
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
#define ereport(elevel, rest)
Definition: elog.h:141
#define TimestampGetDatum(X)
Definition: timestamp.h:31
Datum date_cmp(PG_FUNCTION_ARGS)
Definition: date.c:428
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2559
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619
#define DatumGetTimestamp(X)
Definition: timestamp.h:27
TimestampTz date2timestamptz_opt_error(DateADT dateVal, bool *have_error)
Definition: date.c:614

◆ compareItems()

static JsonPathBool compareItems ( int32  op,
JsonbValue jb1,
JsonbValue jb2,
bool  useTz 
)
static

Definition at line 2258 of file jsonpath_exec.c.

References cmp(), compareDatetime(), compareNumeric(), compareStrings(), elog, ERROR, jbvArray, jbvBinary, jbvBool, jbvDatetime, jbvNull, jbvNumeric, jbvObject, jbvString, jpbFalse, jpbTrue, jpbUnknown, jpiEqual, jpiGreater, jpiGreaterOrEqual, jpiLess, jpiLessOrEqual, jpiNotEqual, JsonbValue::type, and JsonbValue::val.

Referenced by executeComparison().

2259 {
2260  int cmp;
2261  bool res;
2262 
2263  if (jb1->type != jb2->type)
2264  {
2265  if (jb1->type == jbvNull || jb2->type == jbvNull)
2266 
2267  /*
2268  * Equality and order comparison of nulls to non-nulls returns
2269  * always false, but inequality comparison returns true.
2270  */
2271  return op == jpiNotEqual ? jpbTrue : jpbFalse;
2272 
2273  /* Non-null items of different types are not comparable. */
2274  return jpbUnknown;
2275  }
2276 
2277  switch (jb1->type)
2278  {
2279  case jbvNull:
2280  cmp = 0;
2281  break;
2282  case jbvBool:
2283  cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
2284  jb1->val.boolean ? 1 : -1;
2285  break;
2286  case jbvNumeric:
2287  cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
2288  break;
2289  case jbvString:
2290  if (op == jpiEqual)
2291  return jb1->val.string.len != jb2->val.string.len ||
2292  memcmp(jb1->val.string.val,
2293  jb2->val.string.val,
2294  jb1->val.string.len) ? jpbFalse : jpbTrue;
2295 
2296  cmp = compareStrings(jb1->val.string.val, jb1->val.string.len,
2297  jb2->val.string.val, jb2->val.string.len);
2298  break;
2299  case jbvDatetime:
2300  {
2301  bool have_error = false;
2302 
2303  cmp = compareDatetime(jb1->val.datetime.value,
2304  jb1->val.datetime.typid,
2305  jb2->val.datetime.value,
2306  jb2->val.datetime.typid,
2307  useTz,
2308  &have_error);
2309 
2310  if (have_error)
2311  return jpbUnknown;
2312  }
2313  break;
2314 
2315  case jbvBinary:
2316  case jbvArray:
2317  case jbvObject:
2318  return jpbUnknown; /* non-scalars are not comparable */
2319 
2320  default:
2321  elog(ERROR, "invalid jsonb value type %d", jb1->type);
2322  }
2323 
2324  switch (op)
2325  {
2326  case jpiEqual:
2327  res = (cmp == 0);
2328  break;
2329  case jpiNotEqual:
2330  res = (cmp != 0);
2331  break;
2332  case jpiLess:
2333  res = (cmp < 0);
2334  break;
2335  case jpiGreater:
2336  res = (cmp > 0);
2337  break;
2338  case jpiLessOrEqual:
2339  res = (cmp <= 0);
2340  break;
2341  case jpiGreaterOrEqual:
2342  res = (cmp >= 0);
2343  break;
2344  default:
2345  elog(ERROR, "unrecognized jsonpath operation: %d", op);
2346  return jpbUnknown;
2347  }
2348 
2349  return res ? jpbTrue : jpbFalse;
2350 }
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Definition: jsonb.h:236
static int compareNumeric(Numeric a, Numeric b)
static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *have_error)
static int compareStrings(const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
#define ERROR
Definition: elog.h:43
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:226
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ compareNumeric()

static int compareNumeric ( Numeric  a,
Numeric  b 
)
static

Definition at line 2354 of file jsonpath_exec.c.

References DatumGetInt32, DirectFunctionCall2, numeric_cmp(), and NumericGetDatum.

Referenced by compareItems().

2355 {
2357  NumericGetDatum(a),
2358  NumericGetDatum(b)));
2359 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2046
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ compareStrings()

static int compareStrings ( const char *  mbstr1,
int  mblen1,
const char *  mbstr2,
int  mblen2 
)
static

Definition at line 2191 of file jsonpath_exec.c.

References binaryCompareStrings(), cmp(), GetDatabaseEncoding(), pfree(), pg_server_to_any(), PG_SQL_ASCII, and PG_UTF8.

Referenced by compareItems().

2193 {
2194  if (GetDatabaseEncoding() == PG_SQL_ASCII ||
2196  {
2197  /*
2198  * It's known property of UTF-8 strings that their per-byte comparison
2199  * result matches codepoints comparison result. ASCII can be
2200  * considered as special case of UTF-8.
2201  */
2202  return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2);
2203  }
2204  else
2205  {
2206  char *utf8str1,
2207  *utf8str2;
2208  int cmp,
2209  utf8len1,
2210  utf8len2;
2211 
2212  /*
2213  * We have to convert other encodings to UTF-8 first, then compare.
2214  * Input strings may be not null-terminated and pg_server_to_any() may
2215  * return them "as is". So, use strlen() only if there is real
2216  * conversion.
2217  */
2218  utf8str1 = pg_server_to_any(mbstr1, mblen1, PG_UTF8);
2219  utf8str2 = pg_server_to_any(mbstr2, mblen2, PG_UTF8);
2220  utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1);
2221  utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2);
2222 
2223  cmp = binaryCompareStrings(utf8str1, utf8len1, utf8str2, utf8len2);
2224 
2225  /*
2226  * If pg_server_to_any() did no real conversion, then we actually
2227  * compared original strings. So, we already done.
2228  */
2229  if (mbstr1 == utf8str1 && mbstr2 == utf8str2)
2230  return cmp;
2231 
2232  /* Free memory if needed */
2233  if (mbstr1 != utf8str1)
2234  pfree(utf8str1);
2235  if (mbstr2 != utf8str2)
2236  pfree(utf8str2);
2237 
2238  /*
2239  * When all Unicode codepoints are equal, return result of binary
2240  * comparison. In some edge cases, same characters may have different
2241  * representations in encoding. Then our behavior could diverge from
2242  * standard. However, that allow us to do simple binary comparison
2243  * for "==" operator, which is performance critical in typical cases.
2244  * In future to implement strict standard conformance, we can do
2245  * normalization of input JSON strings.
2246  */
2247  if (cmp == 0)
2248  return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2);
2249  else
2250  return cmp;
2251  }
2252 }
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:654
void pfree(void *pointer)
Definition: mcxt.c:1056
int GetDatabaseEncoding(void)
Definition: mbutils.c:1046
static int binaryCompareStrings(const char *s1, int len1, const char *s2, int len2)
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ copyJsonbValue()

static JsonbValue * copyJsonbValue ( JsonbValue src)
static

Definition at line 2362 of file jsonpath_exec.c.

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

2363 {
2364  JsonbValue *dst = palloc(sizeof(*dst));
2365 
2366  *dst = *src;
2367 
2368  return dst;
2369 }
void * palloc(Size size)
Definition: mcxt.c:949

◆ executeAnyItem()

static JsonPathExecResult executeAnyItem ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbContainer jbc,
JsonValueList found,
uint32  level,
uint32  first,
uint32  last,
bool  ignoreStructuralErrors,
bool  unwrapNext 
)
static

Definition at line 1380 of file jsonpath_exec.c.

References Assert, check_stack_depth(), copyJsonbValue(), executeItemOptUnwrapTarget(), JsonPathExecContext::ignoreStructuralErrors, jbvBinary, jperIsError, jperNotFound, jperOk, JsonbIteratorInit(), JsonbIteratorNext(), JsonValueListAppend(), PG_UINT32_MAX, JsonbValue::type, JsonbValue::val, WJB_DONE, WJB_ELEM, WJB_KEY, and WJB_VALUE.

Referenced by executeItemOptUnwrapTarget(), and executeItemUnwrapTargetArray().

1383 {
1385  JsonbIterator *it;
1386  int32 r;
1387  JsonbValue v;
1388 
1390 
1391  if (level > last)
1392  return res;
1393 
1394  it = JsonbIteratorInit(jbc);
1395 
1396  /*
1397  * Recursively iterate over jsonb objects/arrays
1398  */
1399  while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1400  {
1401  if (r == WJB_KEY)
1402  {
1403  r = JsonbIteratorNext(&it, &v, true);
1404  Assert(r == WJB_VALUE);
1405  }
1406 
1407  if (r == WJB_VALUE || r == WJB_ELEM)
1408  {
1409 
1410  if (level >= first ||
1411  (first == PG_UINT32_MAX && last == PG_UINT32_MAX &&
1412  v.type != jbvBinary)) /* leaves only requested */
1413  {
1414  /* check expression */
1415  if (jsp)
1416  {
1417  if (ignoreStructuralErrors)
1418  {
1419  bool savedIgnoreStructuralErrors;
1420 
1421  savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors;
1422  cxt->ignoreStructuralErrors = true;
1423  res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext);
1424  cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors;
1425  }
1426  else
1427  res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext);
1428 
1429  if (jperIsError(res))
1430  break;
1431 
1432  if (res == jperOk && !found)
1433  break;
1434  }
1435  else if (found)
1436  JsonValueListAppend(found, copyJsonbValue(&v));
1437  else
1438  return jperOk;
1439  }
1440 
1441  if (level < last && v.type == jbvBinary)
1442  {
1443  res = executeAnyItem
1444  (cxt, jsp, v.val.binary.data, found,
1445  level + 1, first, last,
1446  ignoreStructuralErrors, unwrapNext);
1447 
1448  if (jperIsError(res))
1449  break;
1450 
1451  if (res == jperOk && found == NULL)
1452  break;
1453  }
1454  }
1455  }
1456 
1457  return res;
1458 }
#define jperIsError(jper)
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
#define PG_UINT32_MAX
Definition: c.h:442
signed int int32
Definition: c.h:346
static JsonbValue * copyJsonbValue(JsonbValue *src)
static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
JsonPathExecResult
void check_stack_depth(void)
Definition: postgres.c:3262
Definition: jsonb.h:23
static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
enum jbvType type
Definition: jsonb.h:263
static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795
Definition: jsonb.h:25

◆ executeBinaryArithmExpr()

static JsonPathExecResult executeBinaryArithmExpr ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
BinaryArithmFunc  func,
JsonValueList found 
)
static

Definition at line 1551 of file jsonpath_exec.c.

References ereport, errcode(), errmsg(), ERROR, error(), executeItemOptUnwrapResult(), executeNextItem(), getScalar(), jbvNumeric, jperError, jperIsError, jperOk, JsonValueListHead(), JsonValueListLength(), jspGetLeftArg(), jspGetNext(), jspGetRightArg(), jspOperationName(), jspThrowErrors, palloc(), RETURN_ERROR, JsonPathItem::type, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

1554 {
1555  JsonPathExecResult jper;
1556  JsonPathItem elem;
1557  JsonValueList lseq = {0};
1558  JsonValueList rseq = {0};
1559  JsonbValue *lval;
1560  JsonbValue *rval;
1561  Numeric res;
1562 
1563  jspGetLeftArg(jsp, &elem);
1564 
1565  /*
1566  * XXX: By standard only operands of multiplicative expressions are
1567  * unwrapped. We extend it to other binary arithmetic expressions too.
1568  */
1569  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &lseq);
1570  if (jperIsError(jper))
1571  return jper;
1572 
1573  jspGetRightArg(jsp, &elem);
1574 
1575  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &rseq);
1576  if (jperIsError(jper))
1577  return jper;
1578 
1579  if (JsonValueListLength(&lseq) != 1 ||
1580  !(lval = getScalar(JsonValueListHead(&lseq), jbvNumeric)))
1582  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
1583  errmsg("left operand of jsonpath operator %s is not a single numeric value",
1584  jspOperationName(jsp->type)))));
1585 
1586  if (JsonValueListLength(&rseq) != 1 ||
1587  !(rval = getScalar(JsonValueListHead(&rseq), jbvNumeric)))
1589  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
1590  errmsg("right operand of jsonpath operator %s is not a single numeric value",
1591  jspOperationName(jsp->type)))));
1592 
1593  if (jspThrowErrors(cxt))
1594  {
1595  res = func(lval->val.numeric, rval->val.numeric, NULL);
1596  }
1597  else
1598  {
1599  bool error = false;
1600 
1601  res = func(lval->val.numeric, rval->val.numeric, &error);
1602 
1603  if (error)
1604  return jperError;
1605  }
1606 
1607  if (!jspGetNext(jsp, &elem) && !found)
1608  return jperOk;
1609 
1610  lval = palloc(sizeof(*lval));
1611  lval->type = jbvNumeric;
1612  lval->val.numeric = res;
1613 
1614  return executeNextItem(cxt, jsp, &elem, lval, found, false);
1615 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
static void error(void)
Definition: sql-dyntest.c:147
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:570
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static int JsonValueListLength(const JsonValueList *jvl)
#define ERROR
Definition: elog.h:43
JsonPathExecResult
#define jspThrowErrors(cxt)
#define ereport(elevel, rest)
Definition: elog.h:141
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1013
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:992
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
static JsonbValue * JsonValueListHead(JsonValueList *jvl)

◆ executeBoolItem()

static JsonPathBool executeBoolItem ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
bool  canHaveNext 
)
static

Definition at line 1226 of file jsonpath_exec.c.

References JsonPathItem::base, JsonPathItem::content, elog, ERROR, executeComparison(), executeItemOptUnwrapResultNoThrow(), executeLikeRegex(), executePredicate(), executeStartsWith(), jpbFalse, jpbTrue, jpbUnknown, jperIsError, jperOk, jpiAnd, jpiEqual, jpiExists, jpiGreater, jpiGreaterOrEqual, jpiIsUnknown, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiNot, jpiNotEqual, jpiOr, jpiStartsWith, JsonValueListIsEmpty(), jspGetArg(), jspGetLeftArg(), jspGetRightArg(), jspHasNext, jspInitByBuffer(), jspStrictAbsenseOfErrors, JsonPathItem::like_regex, and JsonPathItem::type.

Referenced by executeItemOptUnwrapTarget(), and executeNestedBoolItem().

1228 {
1229  JsonPathItem larg;
1230  JsonPathItem rarg;
1231  JsonPathBool res;
1232  JsonPathBool res2;
1233 
1234  if (!canHaveNext && jspHasNext(jsp))
1235  elog(ERROR, "boolean jsonpath item cannot have next item");
1236 
1237  switch (jsp->type)
1238  {
1239  case jpiAnd:
1240  jspGetLeftArg(jsp, &larg);
1241  res = executeBoolItem(cxt, &larg, jb, false);
1242 
1243  if (res == jpbFalse)
1244  return jpbFalse;
1245 
1246  /*
1247  * SQL/JSON says that we should check second arg in case of
1248  * jperError
1249  */
1250 
1251  jspGetRightArg(jsp, &rarg);
1252  res2 = executeBoolItem(cxt, &rarg, jb, false);
1253 
1254  return res2 == jpbTrue ? res : res2;
1255 
1256  case jpiOr:
1257  jspGetLeftArg(jsp, &larg);
1258  res = executeBoolItem(cxt, &larg, jb, false);
1259 
1260  if (res == jpbTrue)
1261  return jpbTrue;
1262 
1263  jspGetRightArg(jsp, &rarg);
1264  res2 = executeBoolItem(cxt, &rarg, jb, false);
1265 
1266  return res2 == jpbFalse ? res : res2;
1267 
1268  case jpiNot:
1269  jspGetArg(jsp, &larg);
1270 
1271  res = executeBoolItem(cxt, &larg, jb, false);
1272 
1273  if (res == jpbUnknown)
1274  return jpbUnknown;
1275 
1276  return res == jpbTrue ? jpbFalse : jpbTrue;
1277 
1278  case jpiIsUnknown:
1279  jspGetArg(jsp, &larg);
1280  res = executeBoolItem(cxt, &larg, jb, false);
1281  return res == jpbUnknown ? jpbTrue : jpbFalse;
1282 
1283  case jpiEqual:
1284  case jpiNotEqual:
1285  case jpiLess:
1286  case jpiGreater:
1287  case jpiLessOrEqual:
1288  case jpiGreaterOrEqual:
1289  jspGetLeftArg(jsp, &larg);
1290  jspGetRightArg(jsp, &rarg);
1291  return executePredicate(cxt, jsp, &larg, &rarg, jb, true,
1292  executeComparison, cxt);
1293 
1294  case jpiStartsWith: /* 'whole STARTS WITH initial' */
1295  jspGetLeftArg(jsp, &larg); /* 'whole' */
1296  jspGetRightArg(jsp, &rarg); /* 'initial' */
1297  return executePredicate(cxt, jsp, &larg, &rarg, jb, false,
1298  executeStartsWith, NULL);
1299 
1300  case jpiLikeRegex: /* 'expr LIKE_REGEX pattern FLAGS flags' */
1301  {
1302  /*
1303  * 'expr' is a sequence-returning expression. 'pattern' is a
1304  * regex string literal. SQL/JSON standard requires XQuery
1305  * regexes, but we use Postgres regexes here. 'flags' is a
1306  * string literal converted to integer flags at compile-time.
1307  */
1308  JsonLikeRegexContext lrcxt = {0};
1309 
1310  jspInitByBuffer(&larg, jsp->base,
1311  jsp->content.like_regex.expr);
1312 
1313  return executePredicate(cxt, jsp, &larg, NULL, jb, false,
1314  executeLikeRegex, &lrcxt);
1315  }
1316 
1317  case jpiExists:
1318  jspGetArg(jsp, &larg);
1319 
1320  if (jspStrictAbsenseOfErrors(cxt))
1321  {
1322  /*
1323  * In strict mode we must get a complete list of values to
1324  * check that there are no errors at all.
1325  */
1326  JsonValueList vals = {0};
1327  JsonPathExecResult res =
1328  executeItemOptUnwrapResultNoThrow(cxt, &larg, jb,
1329  false, &vals);
1330 
1331  if (jperIsError(res))
1332  return jpbUnknown;
1333 
1334  return JsonValueListIsEmpty(&vals) ? jpbFalse : jpbTrue;
1335  }
1336  else
1337  {
1338  JsonPathExecResult res =
1339  executeItemOptUnwrapResultNoThrow(cxt, &larg, jb,
1340  false, NULL);
1341 
1342  if (jperIsError(res))
1343  return jpbUnknown;
1344 
1345  return res == jperOk ? jpbTrue : jpbFalse;
1346  }
1347 
1348  default:
1349  elog(ERROR, "invalid boolean jsonpath item type: %d", jsp->type);
1350  return jpbUnknown;
1351  }
1352 }
#define jperIsError(jper)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
Definition: jsonpath.h:50
char * base
Definition: jsonpath.h:116
static bool JsonValueListIsEmpty(JsonValueList *jvl)
#define jspHasNext(jsp)
Definition: jsonpath.h:164
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:843
JsonPathBool
static JsonPathBool executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, void *param)
#define ERROR
Definition: elog.h:43
JsonPathExecResult
union JsonPathItem::@130 content
static JsonPathBool executePredicate(JsonPathExecContext *cxt, JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, bool unwrapRightArg, JsonPathPredicateCallback exec, void *param)
static JsonPathBool executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, void *param)
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1013
static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:992
JsonPathItemType type
Definition: jsonpath.h:107
struct JsonPathItem::@130::@135 like_regex
#define elog(elevel,...)
Definition: elog.h:226
static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)
#define jspStrictAbsenseOfErrors(cxt)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:923

◆ executeComparison()

static JsonPathBool executeComparison ( JsonPathItem cmp,
JsonbValue lv,
JsonbValue rv,
void *  p 
)
static

Definition at line 2159 of file jsonpath_exec.c.

References compareItems(), JsonPathItem::type, and JsonPathExecContext::useTz.

Referenced by executeBoolItem().

2160 {
2162 
2163  return compareItems(cmp->type, lv, rv, cxt->useTz);
2164 }
static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)
JsonPathItemType type
Definition: jsonpath.h:107

◆ executeDateTimeMethod()

static JsonPathExecResult executeDateTimeMethod ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
JsonValueList found 
)
static

Definition at line 1779 of file jsonpath_exec.c.

References JsonPathItem::arg, JsonPathItem::content, cstring_to_text(), cstring_to_text_with_len(), elog, ereport, errcode(), errhint(), errmsg(), ERROR, executeNextItem(), getScalar(), i, jbvDatetime, jbvString, jperError, jperIsError, jperNotFound, jperOk, jpiString, jspGetArg(), jspGetNext(), jspGetString(), jspOperationName(), jspThrowErrors, lengthof, MemoryContextSwitchTo(), palloc(), parse_datetime(), pfree(), RETURN_ERROR, TopMemoryContext, JsonPathItem::type, JsonbValue::type, JsonbValue::val, and value.

Referenced by executeItemOptUnwrapTarget().

1781 {
1782  JsonbValue jbvbuf;
1783  Datum value;
1784  text *datetime;
1785  Oid typid;
1786  int32 typmod = -1;
1787  int tz = 0;
1788  bool hasNext;
1790  JsonPathItem elem;
1791 
1792  if (!(jb = getScalar(jb, jbvString)))
1794  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION),
1795  errmsg("jsonpath item method .%s() can only be applied to a string",
1796  jspOperationName(jsp->type)))));
1797 
1798  datetime = cstring_to_text_with_len(jb->val.string.val,
1799  jb->val.string.len);
1800 
1801  if (jsp->content.arg)
1802  {
1803  text *template;
1804  char *template_str;
1805  int template_len;
1806  bool have_error = false;
1807 
1808  jspGetArg(jsp, &elem);
1809 
1810  if (elem.type != jpiString)
1811  elog(ERROR, "invalid jsonpath item type for .datetime() argument");
1812 
1813  template_str = jspGetString(&elem, &template_len);
1814 
1815  template = cstring_to_text_with_len(template_str,
1816  template_len);
1817 
1818  value = parse_datetime(datetime, template, true,
1819  &typid, &typmod, &tz,
1820  jspThrowErrors(cxt) ? NULL : &have_error);
1821 
1822  if (have_error)
1823  res = jperError;
1824  else
1825  res = jperOk;
1826  }
1827  else
1828  {
1829  /*
1830  * According to SQL/JSON standard enumerate ISO formats for: date,
1831  * timetz, time, timestamptz, timestamp.
1832  */
1833  static const char *fmt_str[] =
1834  {
1835  "yyyy-mm-dd",
1836  "HH24:MI:SS TZH:TZM",
1837  "HH24:MI:SS TZH",
1838  "HH24:MI:SS",
1839  "yyyy-mm-dd HH24:MI:SS TZH:TZM",
1840  "yyyy-mm-dd HH24:MI:SS TZH",
1841  "yyyy-mm-dd HH24:MI:SS"
1842  };
1843 
1844  /* cache for format texts */
1845  static text *fmt_txt[lengthof(fmt_str)] = {0};
1846  int i;
1847 
1848  /* loop until datetime format fits */
1849  for (i = 0; i < lengthof(fmt_str); i++)
1850  {
1851  bool have_error = false;
1852 
1853  if (!fmt_txt[i])
1854  {
1855  MemoryContext oldcxt =
1857 
1858  fmt_txt[i] = cstring_to_text(fmt_str[i]);
1859  MemoryContextSwitchTo(oldcxt);
1860  }
1861 
1862  value = parse_datetime(datetime, fmt_txt[i], true,
1863  &typid, &typmod, &tz,
1864  &have_error);
1865 
1866  if (!have_error)
1867  {
1868  res = jperOk;
1869  break;
1870  }
1871  }
1872 
1873  if (res == jperNotFound)
1875  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION),
1876  errmsg("datetime format is not unrecognized"),
1877  errhint("use datetime template argument for explicit format specification"))));
1878  }
1879 
1880  pfree(datetime);
1881 
1882  if (jperIsError(res))
1883  return res;
1884 
1885  hasNext = jspGetNext(jsp, &elem);
1886 
1887  if (!hasNext && !found)
1888  return res;
1889 
1890  jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
1891 
1892  jb->type = jbvDatetime;
1893  jb->val.datetime.value = value;
1894  jb->val.datetime.typid = typid;
1895  jb->val.datetime.typmod = typmod;
1896  jb->val.datetime.tz = tz;
1897 
1898  return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
1899 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
int errhint(const char *fmt,...)
Definition: elog.c:974
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:570
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
#define lengthof(array)
Definition: c.h:662
unsigned int Oid
Definition: postgres_ext.h:31
int32 arg
Definition: jsonpath.h:128
Datum parse_datetime(text *date_txt, text *fmt, bool strict, Oid *typid, int32 *typmod, int *tz, bool *have_error)
Definition: formatting.c:4126
signed int int32
Definition: c.h:346
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
JsonPathExecResult
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
union JsonPathItem::@130 content
#define jspThrowErrors(cxt)
#define ereport(elevel, rest)
Definition: elog.h:141
MemoryContext TopMemoryContext
Definition: mcxt.c:44
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
uintptr_t Datum
Definition: postgres.h:367
text * cstring_to_text(const char *s)
Definition: varlena.c:171
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: c.h:549
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:923
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1050

◆ executeItem()

static JsonPathExecResult executeItem ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
JsonValueList found 
)
static

Definition at line 600 of file jsonpath_exec.c.

References executeItemOptUnwrapTarget(), and jspAutoUnwrap.

Referenced by executeItemOptUnwrapResult(), executeJsonPath(), executeNextItem(), and getArrayIndex().

602 {
603  return executeItemOptUnwrapTarget(cxt, jsp, jb, found, jspAutoUnwrap(cxt));
604 }
static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)
#define jspAutoUnwrap(cxt)

◆ executeItemOptUnwrapResult()

static JsonPathExecResult executeItemOptUnwrapResult ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
bool  unwrap,
JsonValueList found 
)
static

Definition at line 1174 of file jsonpath_exec.c.

References Assert, executeItem(), executeItemUnwrapTargetArray(), jbvArray, jperIsError, jperOk, JsonbType(), JsonValueListAppend(), JsonValueListInitIterator(), JsonValueListNext(), jspAutoUnwrap, and JsonbValue::type.

Referenced by executeBinaryArithmExpr(), executeItemOptUnwrapResultNoThrow(), and executeUnaryArithmExpr().

1177 {
1178  if (unwrap && jspAutoUnwrap(cxt))
1179  {
1180  JsonValueList seq = {0};
1182  JsonPathExecResult res = executeItem(cxt, jsp, jb, &seq);
1183  JsonbValue *item;
1184 
1185  if (jperIsError(res))
1186  return res;
1187 
1188  JsonValueListInitIterator(&seq, &it);
1189  while ((item = JsonValueListNext(&seq, &it)))
1190  {
1191  Assert(item->type != jbvArray);
1192 
1193  if (JsonbType(item) == jbvArray)
1194  executeItemUnwrapTargetArray(cxt, NULL, item, found, false);
1195  else
1196  JsonValueListAppend(found, item);
1197  }
1198 
1199  return jperOk;
1200  }
1201 
1202  return executeItem(cxt, jsp, jb, found);
1203 }
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
#define jperIsError(jper)
static int JsonbType(JsonbValue *jb)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
JsonPathExecResult
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263
#define jspAutoUnwrap(cxt)

◆ executeItemOptUnwrapResultNoThrow()

static JsonPathExecResult executeItemOptUnwrapResultNoThrow ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
bool  unwrap,
JsonValueList found 
)
static

Definition at line 1209 of file jsonpath_exec.c.

References executeItemOptUnwrapResult(), and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

1213 {
1214  JsonPathExecResult res;
1215  bool throwErrors = cxt->throwErrors;
1216 
1217  cxt->throwErrors = false;
1218  res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found);
1219  cxt->throwErrors = throwErrors;
1220 
1221  return res;
1222 }
JsonPathExecResult
static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)

◆ executeItemOptUnwrapTarget()

static JsonPathExecResult executeItemOptUnwrapTarget ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
JsonValueList found,
bool  unwrap 
)
static

Definition at line 612 of file jsonpath_exec.c.

References JsonPathItem::anybounds, appendBoolResult(), JsonPathItem::array, Assert, JsonPathExecContext::baseObject, CHECK_FOR_INTERRUPTS, check_stack_depth(), JsonPathItem::content, JsonPathExecContext::current, DatumGetCString, DatumGetNumeric, DirectFunctionCall1, elog, ereport, errcode(), errmsg(), ERROR, executeAnyItem(), executeBinaryArithmExpr(), executeBoolItem(), executeDateTimeMethod(), executeItemUnwrapTargetArray(), executeKeyValueMethod(), executeNestedBoolItem(), executeNextItem(), executeNumericItemMethod(), executeUnaryArithmExpr(), findJsonbValueFromContainer(), float8_numeric(), Float8GetDatum(), float8in_internal_opt_error(), getArrayIndex(), getIthJsonbValueFromContainer(), getJsonPathItem(), i, JsonPathExecContext::ignoreStructuralErrors, JsonPathExecContext::innermostArraySize, Int32GetDatum, int4_numeric(), isinf(), JB_FOBJECT, jbvArray, jbvBinary, jbvNumeric, jbvObject, jbvString, jpbTrue, jperError, jperIsError, jperNotFound, jperOk, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDatetime, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, JsonbArraySize(), JsonbType(), JsonbTypeName(), jspAutoUnwrap, jspAutoWrap, jspGetArg(), jspGetArraySubscript(), jspGetNext(), jspGetString(), jspHasNext, jspIgnoreStructuralErrors, jspOperationName(), jspThrowErrors, sort-test::key, numeric_abs(), numeric_add_opt_error(), numeric_ceil(), numeric_div_opt_error(), numeric_floor(), numeric_mod_opt_error(), numeric_mul_opt_error(), numeric_out(), numeric_sub_opt_error(), numeric_uminus(), NumericGetDatum, palloc(), pfree(), pnstrdup(), pstrdup(), range(), RETURN_ERROR, JsonPathExecContext::root, setBaseObject(), JsonPathItem::type, JsonbValue::type, JsonbValue::val, and val.

Referenced by executeAnyItem(), and executeItem().

614 {
615  JsonPathItem elem;
617  JsonBaseObjectInfo baseObject;
618 
621 
622  switch (jsp->type)
623  {
624  /* all boolean item types: */
625  case jpiAnd:
626  case jpiOr:
627  case jpiNot:
628  case jpiIsUnknown:
629  case jpiEqual:
630  case jpiNotEqual:
631  case jpiLess:
632  case jpiGreater:
633  case jpiLessOrEqual:
634  case jpiGreaterOrEqual:
635  case jpiExists:
636  case jpiStartsWith:
637  case jpiLikeRegex:
638  {
639  JsonPathBool st = executeBoolItem(cxt, jsp, jb, true);
640 
641  res = appendBoolResult(cxt, jsp, found, st);
642  break;
643  }
644 
645  case jpiKey:
646  if (JsonbType(jb) == jbvObject)
647  {
648  JsonbValue *v;
649  JsonbValue key;
650 
651  key.type = jbvString;
652  key.val.string.val = jspGetString(jsp, &key.val.string.len);
653 
654  v = findJsonbValueFromContainer(jb->val.binary.data,
655  JB_FOBJECT, &key);
656 
657  if (v != NULL)
658  {
659  res = executeNextItem(cxt, jsp, NULL,
660  v, found, false);
661 
662  /* free value if it was not added to found list */
663  if (jspHasNext(jsp) || !found)
664  pfree(v);
665  }
666  else if (!jspIgnoreStructuralErrors(cxt))
667  {
668  Assert(found);
669 
670  if (!jspThrowErrors(cxt))
671  return jperError;
672 
673  ereport(ERROR,
674  (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \
675  errmsg("JSON object does not contain key \"%s\"",
676  pnstrdup(key.val.string.val,
677  key.val.string.len))));
678  }
679  }
680  else if (unwrap && JsonbType(jb) == jbvArray)
681  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
682  else if (!jspIgnoreStructuralErrors(cxt))
683  {
684  Assert(found);
686  (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND),
687  errmsg("jsonpath member accessor can only be applied to an object"))));
688  }
689  break;
690 
691  case jpiRoot:
692  jb = cxt->root;
693  baseObject = setBaseObject(cxt, jb, 0);
694  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
695  cxt->baseObject = baseObject;
696  break;
697 
698  case jpiCurrent:
699  res = executeNextItem(cxt, jsp, NULL, cxt->current,
700  found, true);
701  break;
702 
703  case jpiAnyArray:
704  if (JsonbType(jb) == jbvArray)
705  {
706  bool hasNext = jspGetNext(jsp, &elem);
707 
708  res = executeItemUnwrapTargetArray(cxt, hasNext ? &elem : NULL,
709  jb, found, jspAutoUnwrap(cxt));
710  }
711  else if (jspAutoWrap(cxt))
712  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
713  else if (!jspIgnoreStructuralErrors(cxt))
715  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
716  errmsg("jsonpath wildcard array accessor can only be applied to an array"))));
717  break;
718 
719  case jpiIndexArray:
720  if (JsonbType(jb) == jbvArray || jspAutoWrap(cxt))
721  {
722  int innermostArraySize = cxt->innermostArraySize;
723  int i;
724  int size = JsonbArraySize(jb);
725  bool singleton = size < 0;
726  bool hasNext = jspGetNext(jsp, &elem);
727 
728  if (singleton)
729  size = 1;
730 
731  cxt->innermostArraySize = size; /* for LAST evaluation */
732 
733  for (i = 0; i < jsp->content.array.nelems; i++)
734  {
735  JsonPathItem from;
736  JsonPathItem to;
737  int32 index;
738  int32 index_from;
739  int32 index_to;
740  bool range = jspGetArraySubscript(jsp, &from,
741  &to, i);
742 
743  res = getArrayIndex(cxt, &from, jb, &index_from);
744 
745  if (jperIsError(res))
746  break;
747 
748  if (range)
749  {
750  res = getArrayIndex(cxt, &to, jb, &index_to);
751 
752  if (jperIsError(res))
753  break;
754  }
755  else
756  index_to = index_from;
757 
758  if (!jspIgnoreStructuralErrors(cxt) &&
759  (index_from < 0 ||
760  index_from > index_to ||
761  index_to >= size))
763  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
764  errmsg("jsonpath array subscript is out of bounds"))));
765 
766  if (index_from < 0)
767  index_from = 0;
768 
769  if (index_to >= size)
770  index_to = size - 1;
771 
772  res = jperNotFound;
773 
774  for (index = index_from; index <= index_to; index++)
775  {
776  JsonbValue *v;
777  bool copy;
778 
779  if (singleton)
780  {
781  v = jb;
782  copy = true;
783  }
784  else
785  {
786  v = getIthJsonbValueFromContainer(jb->val.binary.data,
787  (uint32) index);
788 
789  if (v == NULL)
790  continue;
791 
792  copy = false;
793  }
794 
795  if (!hasNext && !found)
796  return jperOk;
797 
798  res = executeNextItem(cxt, jsp, &elem, v, found,
799  copy);
800 
801  if (jperIsError(res))
802  break;
803 
804  if (res == jperOk && !found)
805  break;
806  }
807 
808  if (jperIsError(res))
809  break;
810 
811  if (res == jperOk && !found)
812  break;
813  }
814 
815  cxt->innermostArraySize = innermostArraySize;
816  }
817  else if (!jspIgnoreStructuralErrors(cxt))
818  {
820  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
821  errmsg("jsonpath array accessor can only be applied to an array"))));
822  }
823  break;
824 
825  case jpiLast:
826  {
827  JsonbValue tmpjbv;
828  JsonbValue *lastjbv;
829  int last;
830  bool hasNext = jspGetNext(jsp, &elem);
831 
832  if (cxt->innermostArraySize < 0)
833  elog(ERROR, "evaluating jsonpath LAST outside of array subscript");
834 
835  if (!hasNext && !found)
836  {
837  res = jperOk;
838  break;
839  }
840 
841  last = cxt->innermostArraySize - 1;
842 
843  lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv));
844 
845  lastjbv->type = jbvNumeric;
846  lastjbv->val.numeric =
848  Int32GetDatum(last)));
849 
850  res = executeNextItem(cxt, jsp, &elem,
851  lastjbv, found, hasNext);
852  }
853  break;
854 
855  case jpiAnyKey:
856  if (JsonbType(jb) == jbvObject)
857  {
858  bool hasNext = jspGetNext(jsp, &elem);
859 
860  if (jb->type != jbvBinary)
861  elog(ERROR, "invalid jsonb object type: %d", jb->type);
862 
863  return executeAnyItem
864  (cxt, hasNext ? &elem : NULL,
865  jb->val.binary.data, found, 1, 1, 1,
866  false, jspAutoUnwrap(cxt));
867  }
868  else if (unwrap && JsonbType(jb) == jbvArray)
869  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
870  else if (!jspIgnoreStructuralErrors(cxt))
871  {
872  Assert(found);
874  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
875  errmsg("jsonpath wildcard member accessor can only be applied to an object"))));
876  }
877  break;
878 
879  case jpiAdd:
880  return executeBinaryArithmExpr(cxt, jsp, jb,
881  numeric_add_opt_error, found);
882 
883  case jpiSub:
884  return executeBinaryArithmExpr(cxt, jsp, jb,
885  numeric_sub_opt_error, found);
886 
887  case jpiMul:
888  return executeBinaryArithmExpr(cxt, jsp, jb,
889  numeric_mul_opt_error, found);
890 
891  case jpiDiv:
892  return executeBinaryArithmExpr(cxt, jsp, jb,
893  numeric_div_opt_error, found);
894 
895  case jpiMod:
896  return executeBinaryArithmExpr(cxt, jsp, jb,
897  numeric_mod_opt_error, found);
898 
899  case jpiPlus:
900  return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found);
901 
902  case jpiMinus:
903  return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus,
904  found);
905 
906  case jpiFilter:
907  {
908  JsonPathBool st;
909 
910  if (unwrap && JsonbType(jb) == jbvArray)
911  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
912  false);
913 
914  jspGetArg(jsp, &elem);
915  st = executeNestedBoolItem(cxt, &elem, jb);
916  if (st != jpbTrue)
917  res = jperNotFound;
918  else
919  res = executeNextItem(cxt, jsp, NULL,
920  jb, found, true);
921  break;
922  }
923 
924  case jpiAny:
925  {
926  bool hasNext = jspGetNext(jsp, &elem);
927 
928  /* first try without any intermediate steps */
929  if (jsp->content.anybounds.first == 0)
930  {
931  bool savedIgnoreStructuralErrors;
932 
933  savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors;
934  cxt->ignoreStructuralErrors = true;
935  res = executeNextItem(cxt, jsp, &elem,
936  jb, found, true);
937  cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors;
938 
939  if (res == jperOk && !found)
940  break;
941  }
942 
943  if (jb->type == jbvBinary)
944  res = executeAnyItem
945  (cxt, hasNext ? &elem : NULL,
946  jb->val.binary.data, found,
947  1,
948  jsp->content.anybounds.first,
949  jsp->content.anybounds.last,
950  true, jspAutoUnwrap(cxt));
951  break;
952  }
953 
954  case jpiNull:
955  case jpiBool:
956  case jpiNumeric:
957  case jpiString:
958  case jpiVariable:
959  {
960  JsonbValue vbuf;
961  JsonbValue *v;
962  bool hasNext = jspGetNext(jsp, &elem);
963 
964  if (!hasNext && !found)
965  {
966  res = jperOk; /* skip evaluation */
967  break;
968  }
969 
970  v = hasNext ? &vbuf : palloc(sizeof(*v));
971 
972  baseObject = cxt->baseObject;
973  getJsonPathItem(cxt, jsp, v);
974 
975  res = executeNextItem(cxt, jsp, &elem,
976  v, found, hasNext);
977  cxt->baseObject = baseObject;
978  }
979  break;
980 
981  case jpiType:
982  {
983  JsonbValue *jbv = palloc(sizeof(*jbv));
984 
985  jbv->type = jbvString;
986  jbv->val.string.val = pstrdup(JsonbTypeName(jb));
987  jbv->val.string.len = strlen(jbv->val.string.val);
988 
989  res = executeNextItem(cxt, jsp, NULL, jbv,
990  found, false);
991  }
992  break;
993 
994  case jpiSize:
995  {
996  int size = JsonbArraySize(jb);
997 
998  if (size < 0)
999  {
1000  if (!jspAutoWrap(cxt))
1001  {
1002  if (!jspIgnoreStructuralErrors(cxt))
1004  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
1005  errmsg("jsonpath item method .%s() can only be applied to an array",
1006  jspOperationName(jsp->type)))));
1007  break;
1008  }
1009 
1010  size = 1;
1011  }
1012 
1013  jb = palloc(sizeof(*jb));
1014 
1015  jb->type = jbvNumeric;
1016  jb->val.numeric =
1018  Int32GetDatum(size)));
1019 
1020  res = executeNextItem(cxt, jsp, NULL, jb, found, false);
1021  }
1022  break;
1023 
1024  case jpiAbs:
1025  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs,
1026  found);
1027 
1028  case jpiFloor:
1029  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor,
1030  found);
1031 
1032  case jpiCeiling:
1033  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil,
1034  found);
1035 
1036  case jpiDouble:
1037  {
1038  JsonbValue jbv;
1039 
1040  if (unwrap && JsonbType(jb) == jbvArray)
1041  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1042  false);
1043 
1044  if (jb->type == jbvNumeric)
1045  {
1047  NumericGetDatum(jb->val.numeric)));
1048  bool have_error = false;
1049 
1050  (void) float8in_internal_opt_error(tmp,
1051  NULL,
1052  "double precision",
1053  tmp,
1054  &have_error);
1055 
1056  if (have_error)
1058  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1059  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1060  jspOperationName(jsp->type)))));
1061  res = jperOk;
1062  }
1063  else if (jb->type == jbvString)
1064  {
1065  /* cast string as double */
1066  double val;
1067  char *tmp = pnstrdup(jb->val.string.val,
1068  jb->val.string.len);
1069  bool have_error = false;
1070 
1071  val = float8in_internal_opt_error(tmp,
1072  NULL,
1073  "double precision",
1074  tmp,
1075  &have_error);
1076 
1077  if (have_error || isinf(val))
1079  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1080  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1081  jspOperationName(jsp->type)))));
1082 
1083  jb = &jbv;
1084  jb->type = jbvNumeric;
1086  Float8GetDatum(val)));
1087  res = jperOk;
1088  }
1089 
1090  if (res == jperNotFound)
1092  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1093  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1094  jspOperationName(jsp->type)))));
1095 
1096  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1097  }
1098  break;
1099 
1100  case jpiDatetime:
1101  if (unwrap && JsonbType(jb) == jbvArray)
1102  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1103 
1104  return executeDateTimeMethod(cxt, jsp, jb, found);
1105 
1106  case jpiKeyValue:
1107  if (unwrap && JsonbType(jb) == jbvArray)
1108  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1109 
1110  return executeKeyValueMethod(cxt, jsp, jb, found);
1111 
1112  default:
1113  elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
1114  }
1115 
1116  return res;
1117 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
#define jspIgnoreStructuralErrors(cxt)
static int JsonbType(JsonbValue *jb)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
Definition: jsonpath.h:50
static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
struct JsonPathItem::@130::@133 anybounds
static JsonPathExecResult executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, PGFunction func, JsonValueList *found)
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2428
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2600
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:655
#define jspHasNext(jsp)
Definition: jsonpath.h:164
int errcode(int sqlerrcode)
Definition: elog.c:570
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:98
Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2540
JsonPathBool
signed int int32
Definition: c.h:346
static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1723
Definition: type.h:89
static void getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)
static JsonPathExecResult executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, JsonValueList *found)
void pfree(void *pointer)
Definition: mcxt.c:1056
Datum numeric_uminus(PG_FUNCTION_ARGS)
Definition: numeric.c:1129
Datum numeric_abs(PG_FUNCTION_ARGS)
Definition: numeric.c:1101
#define ERROR
Definition: elog.h:43
static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
#define DatumGetCString(X)
Definition: postgres.h:566
JsonPathExecResult
int isinf(double x)
const char * JsonbTypeName(JsonbValue *jbv)
Definition: jsonb.c:191
void check_stack_depth(void)
Definition: postgres.c:3262
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
union JsonPathItem::@130 content
unsigned int uint32
Definition: c.h:358
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
#define jspThrowErrors(cxt)
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbValue * root
Definition: jsonpath_exec.c:96
Datum numeric_floor(PG_FUNCTION_ARGS)
Definition: numeric.c:1354
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
Datum int4_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3193
Datum float8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3383
Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2720
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition: jsonb_util.c:460
#define DatumGetNumeric(X)
Definition: numeric.h:49
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1062
#define Assert(condition)
Definition: c.h:732
#define JB_FOBJECT
Definition: jsonb.h:210
JsonPathItemType type
Definition: jsonpath.h:107
JsonbValue * current
Definition: jsonpath_exec.c:97
#define jspAutoWrap(cxt)
static JsonPathExecResult executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
enum jbvType type
Definition: jsonb.h:263
static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonValueList *found, JsonPathBool res)
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
Datum numeric_ceil(PG_FUNCTION_ARGS)
Definition: numeric.c:1329
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2484
#define elog(elevel,...)
Definition: elog.h:226
int i
#define jspAutoUnwrap(cxt)
double float8in_internal_opt_error(char *num, char **endptr_p, const char *type_name, const char *orig_string, bool *have_error)
Definition: float.c:372
static JsonPathExecResult executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:336
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:923
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1050
long val
Definition: informix.c:684
struct JsonPathItem::@130::@132 array
static int JsonbArraySize(JsonbValue *jb)

◆ executeItemUnwrapTargetArray()

static JsonPathExecResult executeItemUnwrapTargetArray ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
JsonValueList found,
bool  unwrapElements 
)
static

Definition at line 1123 of file jsonpath_exec.c.

References Assert, elog, ERROR, executeAnyItem(), jbvArray, jbvBinary, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapResult(), executeItemOptUnwrapTarget(), and executeNumericItemMethod().

1126 {
1127  if (jb->type != jbvBinary)
1128  {
1129  Assert(jb->type != jbvArray);
1130  elog(ERROR, "invalid jsonb array value type: %d", jb->type);
1131  }
1132 
1133  return executeAnyItem
1134  (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
1135  false, unwrapElements);
1136 }
char * val
Definition: jsonb.h:272
#define ERROR
Definition: elog.h:43
static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:226

◆ executeJsonPath()

static JsonPathExecResult executeJsonPath ( JsonPath path,
Jsonb vars,
Jsonb json,
bool  throwErrors,
JsonValueList result,
bool  useTz 
)
static

Definition at line 540 of file jsonpath_exec.c.

References Assert, JsonPathExecContext::baseObject, JsonPathExecContext::current, ereport, errcode(), errdetail(), errmsg(), ERROR, executeItem(), JsonPath::header, JsonBaseObjectInfo::id, JsonPathExecContext::ignoreStructuralErrors, JsonPathExecContext::innermostArraySize, JsonBaseObjectInfo::jbc, jperIsError, jperNotFound, jperOk, JsonbExtractScalar(), JsonbInitBinary(), JsonContainerIsObject, JSONPATH_LAX, JsonValueListIsEmpty(), jspInit(), jspStrictAbsenseOfErrors, JsonPathExecContext::lastGeneratedObjectId, JsonPathExecContext::laxMode, JsonPathExecContext::root, Jsonb::root, JsonPathExecContext::throwErrors, JsonPathExecContext::useTz, and JsonPathExecContext::vars.

Referenced by jsonb_path_exists_internal(), jsonb_path_match_internal(), jsonb_path_query_array_internal(), jsonb_path_query_first_internal(), and jsonb_path_query_internal().

542 {
544  JsonPathExecResult res;
545  JsonPathItem jsp;
546  JsonbValue jbv;
547 
548  jspInit(&jsp, path);
549 
550  if (!JsonbExtractScalar(&json->root, &jbv))
551  JsonbInitBinary(&jbv, json);
552 
553  if (vars && !JsonContainerIsObject(&vars->root))
554  {
555  ereport(ERROR,
556  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
557  errmsg("\"vars\" argument is not an object"),
558  errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object.")));
559  }
560 
561  cxt.vars = vars;
562  cxt.laxMode = (path->header & JSONPATH_LAX) != 0;
564  cxt.root = &jbv;
565  cxt.current = &jbv;
566  cxt.baseObject.jbc = NULL;
567  cxt.baseObject.id = 0;
568  cxt.lastGeneratedObjectId = vars ? 2 : 1;
569  cxt.innermostArraySize = -1;
570  cxt.throwErrors = throwErrors;
571  cxt.useTz = useTz;
572 
573  if (jspStrictAbsenseOfErrors(&cxt) && !result)
574  {
575  /*
576  * In strict mode we must get a complete list of values to check that
577  * there are no errors at all.
578  */
579  JsonValueList vals = {0};
580 
581  res = executeItem(&cxt, &jsp, &jbv, &vals);
582 
583  if (jperIsError(res))
584  return res;
585 
586  return JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk;
587  }
588 
589  res = executeItem(&cxt, &jsp, &jbv, result);
590 
591  Assert(!throwErrors || !jperIsError(res));
592 
593  return res;
594 }
#define jperIsError(jper)
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1895
static bool JsonValueListIsEmpty(JsonValueList *jvl)
int errcode(int sqlerrcode)
Definition: elog.c:570
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:98
#define JSONPATH_LAX
Definition: jsonpath.h:29
#define ERROR
Definition: elog.h:43
JsonPathExecResult
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbValue * root
Definition: jsonpath_exec.c:96
JsonbContainer root
Definition: jsonb.h:223
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
JsonbContainer * jbc
Definition: jsonpath_exec.c:86
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:732
JsonbValue * current
Definition: jsonpath_exec.c:97
int errmsg(const char *fmt,...)
Definition: elog.c:784
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:833
uint32 header
Definition: jsonpath.h:24
#define jspStrictAbsenseOfErrors(cxt)

◆ executeKeyValueMethod()

static JsonPathExecResult executeKeyValueMethod ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
JsonValueList found 
)
static

Definition at line 1925 of file jsonpath_exec.c.

References Assert, JsonPathExecContext::baseObject, DatumGetNumeric, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, executeNextItem(), JsonBaseObjectInfo::id, Int64GetDatum(), int8_numeric(), JsonBaseObjectInfo::jbc, jbvBinary, jbvNumeric, jbvObject, jbvString, jperIsError, jperNotFound, jperOk, JsonbInitBinary(), JsonbIteratorInit(), JsonbIteratorNext(), JsonbType(), JsonbValueToJsonb(), JsonContainerSize, jspGetNext(), jspOperationName(), sort-test::key, JsonPathExecContext::lastGeneratedObjectId, next, pushJsonbValue(), RETURN_ERROR, setBaseObject(), JsonPathItem::type, JsonbValue::type, JsonbValue::val, val, WJB_BEGIN_OBJECT, WJB_DONE, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

Referenced by executeItemOptUnwrapTarget().

1927 {
1930  JsonbContainer *jbc;
1931  JsonbValue key;
1932  JsonbValue val;
1933  JsonbValue idval;
1934  JsonbValue keystr;
1935  JsonbValue valstr;
1936  JsonbValue idstr;
1937  JsonbIterator *it;
1938  JsonbIteratorToken tok;
1939  int64 id;
1940  bool hasNext;
1941 
1942  if (JsonbType(jb) != jbvObject || jb->type != jbvBinary)
1944  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
1945  errmsg("jsonpath item method .%s() can only be applied to an object",
1946  jspOperationName(jsp->type)))));
1947 
1948  jbc = jb->val.binary.data;
1949 
1950  if (!JsonContainerSize(jbc))
1951  return jperNotFound; /* no key-value pairs */
1952 
1953  hasNext = jspGetNext(jsp, &next);
1954 
1955  keystr.type = jbvString;
1956  keystr.val.string.val = "key";
1957  keystr.val.string.len = 3;
1958 
1959  valstr.type = jbvString;
1960  valstr.val.string.val = "value";
1961  valstr.val.string.len = 5;
1962 
1963  idstr.type = jbvString;
1964  idstr.val.string.val = "id";
1965  idstr.val.string.len = 2;
1966 
1967  /* construct object id from its base object and offset inside that */
1968  id = jb->type != jbvBinary ? 0 :
1969  (int64) ((char *) jbc - (char *) cxt->baseObject.jbc);
1970  id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
1971 
1972  idval.type = jbvNumeric;
1974  Int64GetDatum(id)));
1975 
1976  it = JsonbIteratorInit(jbc);
1977 
1978  while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
1979  {
1980  JsonBaseObjectInfo baseObject;
1981  JsonbValue obj;
1982  JsonbParseState *ps;
1983  JsonbValue *keyval;
1984  Jsonb *jsonb;
1985 
1986  if (tok != WJB_KEY)
1987  continue;
1988 
1989  res = jperOk;
1990 
1991  if (!hasNext && !found)
1992  break;
1993 
1994  tok = JsonbIteratorNext(&it, &val, true);
1995  Assert(tok == WJB_VALUE);
1996 
1997  ps = NULL;
1998  pushJsonbValue(&ps, WJB_BEGIN_OBJECT, NULL);
1999 
2000  pushJsonbValue(&ps, WJB_KEY, &keystr);
2001  pushJsonbValue(&ps, WJB_VALUE, &key);
2002 
2003  pushJsonbValue(&ps, WJB_KEY, &valstr);
2004  pushJsonbValue(&ps, WJB_VALUE, &val);
2005 
2006  pushJsonbValue(&ps, WJB_KEY, &idstr);
2007  pushJsonbValue(&ps, WJB_VALUE, &idval);
2008 
2009  keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
2010 
2011  jsonb = JsonbValueToJsonb(keyval);
2012 
2013  JsonbInitBinary(&obj, jsonb);
2014 
2015  baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++);
2016 
2017  res = executeNextItem(cxt, jsp, &next, &obj, found, true);
2018 
2019  cxt->baseObject = baseObject;
2020 
2021  if (jperIsError(res))
2022  return res;
2023 
2024  if (res == jperOk && !found)
2025  break;
2026  }
2027 
2028  return res;
2029 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
static int JsonbType(JsonbValue *jb)
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
static int32 next
Definition: blutils.c:215
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
Definition: jsonb.h:22
int errcode(int sqlerrcode)
Definition: elog.c:570
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3285
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:98
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
#define ERROR
Definition: elog.h:43
JsonPathExecResult
#define JsonContainerSize(jc)
Definition: jsonb.h:214
Definition: jsonb.h:23
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbIteratorToken
Definition: jsonb.h:20
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
JsonbContainer * jbc
Definition: jsonpath_exec.c:86
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define Assert(condition)
Definition: c.h:732
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:759
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
long val
Definition: informix.c:684
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:795

◆ executeLikeRegex()

static JsonPathBool executeLikeRegex ( JsonPathItem jsp,
JsonbValue str,
JsonbValue rarg,
void *  param 
)
static

Definition at line 1713 of file jsonpath_exec.c.

References JsonLikeRegexContext::cflags, JsonPathItem::content, cstring_to_text_with_len(), getScalar(), jbvString, jpbFalse, jpbTrue, jpbUnknown, jspConvertRegexFlags(), JsonPathItem::like_regex, RE_compile_and_execute(), JsonLikeRegexContext::regex, and JsonbValue::val.

Referenced by executeBoolItem().

1715 {
1716  JsonLikeRegexContext *cxt = param;
1717 
1718  if (!(str = getScalar(str, jbvString)))
1719  return jpbUnknown;
1720 
1721  /* Cache regex text and converted flags. */
1722  if (!cxt->regex)
1723  {
1724  cxt->regex =
1726  jsp->content.like_regex.patternlen);
1727  cxt->cflags = jspConvertRegexFlags(jsp->content.like_regex.flags);
1728  }
1729 
1730  if (RE_compile_and_execute(cxt->regex, str->val.string.val,
1731  str->val.string.len,
1732  cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
1733  return jpbTrue;
1734 
1735  return jpbFalse;
1736 }
char * val
Definition: jsonb.h:272
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
Definition: regexp.c:343
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
union JsonPathItem::@130 content
int jspConvertRegexFlags(uint32 xflags)
struct JsonPathItem::@130::@135 like_regex

◆ executeNestedBoolItem()

static JsonPathBool executeNestedBoolItem ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb 
)
static

Definition at line 1359 of file jsonpath_exec.c.

References JsonPathExecContext::current, and executeBoolItem().

Referenced by executeItemOptUnwrapTarget().

1361 {
1362  JsonbValue *prev;
1363  JsonPathBool res;
1364 
1365  prev = cxt->current;
1366  cxt->current = jb;
1367  res = executeBoolItem(cxt, jsp, jb, false);
1368  cxt->current = prev;
1369 
1370  return res;
1371 }
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
JsonPathBool
JsonbValue * current
Definition: jsonpath_exec.c:97

◆ executeNextItem()

static JsonPathExecResult executeNextItem ( JsonPathExecContext cxt,
JsonPathItem cur,
JsonPathItem next,
JsonbValue v,
JsonValueList found,
bool  copy 
)
static

Definition at line 1143 of file jsonpath_exec.c.

References copyJsonbValue(), executeItem(), jperOk, JsonValueListAppend(), jspGetNext(), and jspHasNext.

Referenced by appendBoolResult(), executeBinaryArithmExpr(), executeDateTimeMethod(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), executeNumericItemMethod(), and executeUnaryArithmExpr().

1146 {
1147  JsonPathItem elem;
1148  bool hasNext;
1149 
1150  if (!cur)
1151  hasNext = next != NULL;
1152  else if (next)
1153  hasNext = jspHasNext(cur);
1154  else
1155  {
1156  next = &elem;
1157  hasNext = jspGetNext(cur, next);
1158  }
1159 
1160  if (hasNext)
1161  return executeItem(cxt, next, v, found);
1162 
1163  if (found)
1164  JsonValueListAppend(found, copy ? copyJsonbValue(v) : v);
1165 
1166  return jperOk;
1167 }
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
#define jspHasNext(jsp)
Definition: jsonpath.h:164
static JsonbValue * copyJsonbValue(JsonbValue *src)
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)

◆ executeNumericItemMethod()

static JsonPathExecResult executeNumericItemMethod ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
bool  unwrap,
PGFunction  func,
JsonValueList found 
)
static

Definition at line 1743 of file jsonpath_exec.c.

References DatumGetNumeric, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, executeItemUnwrapTargetArray(), executeNextItem(), getScalar(), jbvArray, jbvNumeric, jperOk, JsonbType(), jspGetNext(), jspOperationName(), next, NumericGetDatum, palloc(), RETURN_ERROR, JsonPathItem::type, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

1746 {
1748  Datum datum;
1749 
1750  if (unwrap && JsonbType(jb) == jbvArray)
1751  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1752 
1753  if (!(jb = getScalar(jb, jbvNumeric)))
1755  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1756  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1757  jspOperationName(jsp->type)))));
1758 
1759  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
1760 
1761  if (!jspGetNext(jsp, &next) && !found)
1762  return jperOk;
1763 
1764  jb = palloc(sizeof(*jb));
1765  jb->type = jbvNumeric;
1766  jb->val.numeric = DatumGetNumeric(datum);
1767 
1768  return executeNextItem(cxt, jsp, &next, jb, found, false);
1769 }
#define RETURN_ERROR(throw_error)
static int JsonbType(JsonbValue *jb)
static int32 next
Definition: blutils.c:215
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
int errcode(int sqlerrcode)
Definition: elog.c:570
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
#define ereport(elevel, rest)
Definition: elog.h:141
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
uintptr_t Datum
Definition: postgres.h:367
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)

◆ executePredicate()

static JsonPathBool executePredicate ( JsonPathExecContext cxt,
JsonPathItem pred,
JsonPathItem larg,
JsonPathItem rarg,
JsonbValue jb,
bool  unwrapRightArg,
JsonPathPredicateCallback  exec,
void *  param 
)
static

Definition at line 1471 of file jsonpath_exec.c.

References error(), executeItemOptUnwrapResultNoThrow(), jpbFalse, jpbTrue, jpbUnknown, jperIsError, JsonValueListInitIterator(), JsonValueListNext(), and jspStrictAbsenseOfErrors.

Referenced by executeBoolItem().

1475 {
1476  JsonPathExecResult res;
1477  JsonValueListIterator lseqit;
1478  JsonValueList lseq = {0};
1479  JsonValueList rseq = {0};
1480  JsonbValue *lval;
1481  bool error = false;
1482  bool found = false;
1483 
1484  /* Left argument is always auto-unwrapped. */
1485  res = executeItemOptUnwrapResultNoThrow(cxt, larg, jb, true, &lseq);
1486  if (jperIsError(res))
1487  return jpbUnknown;
1488 
1489  if (rarg)
1490  {
1491  /* Right argument is conditionally auto-unwrapped. */
1492  res = executeItemOptUnwrapResultNoThrow(cxt, rarg, jb,
1493  unwrapRightArg, &rseq);
1494  if (jperIsError(res))
1495  return jpbUnknown;
1496  }
1497 
1498  JsonValueListInitIterator(&lseq, &lseqit);
1499  while ((lval = JsonValueListNext(&lseq, &lseqit)))
1500  {
1501  JsonValueListIterator rseqit;
1502  JsonbValue *rval;
1503  bool first = true;
1504 
1505  JsonValueListInitIterator(&rseq, &rseqit);
1506  if (rarg)
1507  rval = JsonValueListNext(&rseq, &rseqit);
1508  else
1509  rval = NULL;
1510 
1511  /* Loop over right arg sequence or do single pass otherwise */
1512  while (rarg ? (rval != NULL) : first)
1513  {
1514  JsonPathBool res = exec(pred, lval, rval, param);
1515 
1516  if (res == jpbUnknown)
1517  {
1518  if (jspStrictAbsenseOfErrors(cxt))
1519  return jpbUnknown;
1520 
1521  error = true;
1522  }
1523  else if (res == jpbTrue)
1524  {
1525  if (!jspStrictAbsenseOfErrors(cxt))
1526  return jpbTrue;
1527 
1528  found = true;
1529  }
1530 
1531  first = false;
1532  if (rarg)
1533  rval = JsonValueListNext(&rseq, &rseqit);
1534  }
1535  }
1536 
1537  if (found) /* possible only in strict mode */
1538  return jpbTrue;
1539 
1540  if (error) /* possible only in lax mode */
1541  return jpbUnknown;
1542 
1543  return jpbFalse;
1544 }
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
#define jperIsError(jper)
static void error(void)
Definition: sql-dyntest.c:147
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
JsonPathBool
JsonPathExecResult
static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
Definition: type.h:109
#define jspStrictAbsenseOfErrors(cxt)

◆ executeStartsWith()

static JsonPathBool executeStartsWith ( JsonPathItem jsp,
JsonbValue whole,
JsonbValue initial,
void *  param 
)
static

Definition at line 1689 of file jsonpath_exec.c.

References getScalar(), jbvString, jpbFalse, jpbTrue, jpbUnknown, and JsonbValue::val.

Referenced by executeBoolItem().

1691 {
1692  if (!(whole = getScalar(whole, jbvString)))
1693  return jpbUnknown; /* error */
1694 
1695  if (!(initial = getScalar(initial, jbvString)))
1696  return jpbUnknown; /* error */
1697 
1698  if (whole->val.string.len >= initial->val.string.len &&
1699  !memcmp(whole->val.string.val,
1700  initial->val.string.val,
1701  initial->val.string.len))
1702  return jpbTrue;
1703 
1704  return jpbFalse;
1705 }
char * val
Definition: jsonb.h:272
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)

◆ executeUnaryArithmExpr()

static JsonPathExecResult executeUnaryArithmExpr ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
PGFunction  func,
JsonValueList found 
)
static

Definition at line 1622 of file jsonpath_exec.c.

References DatumGetNumeric, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, executeItemOptUnwrapResult(), executeNextItem(), getScalar(), jbvNumeric, jperIsError, jperNotFound, jperOk, JsonValueListInitIterator(), JsonValueListNext(), jspGetArg(), jspGetNext(), jspOperationName(), NumericGetDatum, RETURN_ERROR, JsonPathItem::type, JsonbValue::val, and val.

Referenced by executeItemOptUnwrapTarget().

1624 {
1625  JsonPathExecResult jper;
1626  JsonPathExecResult jper2;
1627  JsonPathItem elem;
1628  JsonValueList seq = {0};
1630  JsonbValue *val;
1631  bool hasNext;
1632 
1633  jspGetArg(jsp, &elem);
1634  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &seq);
1635 
1636  if (jperIsError(jper))
1637  return jper;
1638 
1639  jper = jperNotFound;
1640 
1641  hasNext = jspGetNext(jsp, &elem);
1642 
1643  JsonValueListInitIterator(&seq, &it);
1644  while ((val = JsonValueListNext(&seq, &it)))
1645  {
1646  if ((val = getScalar(val, jbvNumeric)))
1647  {
1648  if (!found && !hasNext)
1649  return jperOk;
1650  }
1651  else
1652  {
1653  if (!found && !hasNext)
1654  continue; /* skip non-numerics processing */
1655 
1657  (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),
1658  errmsg("operand of unary jsonpath operator %s is not a numeric value",
1659  jspOperationName(jsp->type)))));
1660  }
1661 
1662  if (func)
1663  val->val.numeric =
1665  NumericGetDatum(val->val.numeric)));
1666 
1667  jper2 = executeNextItem(cxt, jsp, &elem, val, found, false);
1668 
1669  if (jperIsError(jper2))
1670  return jper2;
1671 
1672  if (jper2 == jperOk)
1673  {
1674  if (!found)
1675  return jperOk;
1676  jper = jperOk;
1677  }
1678  }
1679 
1680  return jper;
1681 }
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
int errcode(int sqlerrcode)
Definition: elog.c:570
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
#define ERROR
Definition: elog.h:43
JsonPathExecResult
#define ereport(elevel, rest)
Definition: elog.h:141
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonPathItemType type
Definition: jsonpath.h:107
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:923
long val
Definition: informix.c:684

◆ getArrayIndex()

static JsonPathExecResult getArrayIndex ( JsonPathExecContext cxt,
JsonPathItem jsp,
JsonbValue jb,
int32 index 
)
static

Definition at line 2376 of file jsonpath_exec.c.

References DatumGetNumeric, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, executeItem(), getScalar(), Int32GetDatum, jbvNumeric, jperIsError, jperOk, JsonValueListHead(), JsonValueListLength(), numeric_int4_opt_error(), numeric_trunc(), NumericGetDatum, RETURN_ERROR, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

2378 {
2379  JsonbValue *jbv;
2380  JsonValueList found = {0};
2381  JsonPathExecResult res = executeItem(cxt, jsp, jb, &found);
2382  Datum numeric_index;
2383  bool have_error = false;
2384 
2385  if (jperIsError(res))
2386  return res;
2387 
2388  if (JsonValueListLength(&found) != 1 ||
2389  !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric)))
2391  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2392  errmsg("jsonpath array subscript is not a single numeric value"))));
2393 
2394  numeric_index = DirectFunctionCall2(numeric_trunc,
2395  NumericGetDatum(jbv->val.numeric),
2396  Int32GetDatum(0));
2397 
2398  *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index),
2399  &have_error);
2400 
2401  if (have_error)
2403  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2404  errmsg("jsonpath array subscript is out of integer range"))));
2405 
2406  return jperOk;
2407 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
Datum numeric_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:1282
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
int errcode(int sqlerrcode)
Definition: elog.c:570
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static int JsonValueListLength(const JsonValueList *jvl)
Definition: type.h:89
#define ERROR
Definition: elog.h:43
JsonPathExecResult
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
#define ereport(elevel, rest)
Definition: elog.h:141
int32 numeric_int4_opt_error(Numeric num, bool *have_error)
Definition: numeric.c:3211
uintptr_t Datum
Definition: postgres.h:367
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:784
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ getJsonPathItem()

static void getJsonPathItem ( JsonPathExecContext cxt,
JsonPathItem item,
JsonbValue value 
)
static

Definition at line 2064 of file jsonpath_exec.c.

References elog, ERROR, getJsonPathVariable(), jbvBool, jbvNull, jbvNumeric, jbvString, jpiBool, jpiNull, jpiNumeric, jpiString, jpiVariable, jspGetBool(), jspGetNumeric(), jspGetString(), JsonPathItem::type, JsonbValue::type, JsonbValue::val, and JsonPathExecContext::vars.

Referenced by executeItemOptUnwrapTarget().

2066 {
2067  switch (item->type)
2068  {
2069  case jpiNull:
2070  value->type = jbvNull;
2071  break;
2072  case jpiBool:
2073  value->type = jbvBool;
2074  value->val.boolean = jspGetBool(item);
2075  break;
2076  case jpiNumeric:
2077  value->type = jbvNumeric;
2078  value->val.numeric = jspGetNumeric(item);
2079  break;
2080  case jpiString:
2081  value->type = jbvString;
2082  value->val.string.val = jspGetString(item,
2083  &value->val.string.len);
2084  break;
2085  case jpiVariable:
2086  getJsonPathVariable(cxt, item, cxt->vars, value);
2087  return;
2088  default:
2089  elog(ERROR, "unexpected jsonpath item type");
2090  }
2091 }
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Definition: jsonb.h:236
#define ERROR
Definition: elog.h:43
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1034
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
static void getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, Jsonb *vars, JsonbValue *value)
#define elog(elevel,...)
Definition: elog.h:226
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1050
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1042

◆ getJsonPathVariable()

static void getJsonPathVariable ( JsonPathExecContext cxt,
JsonPathItem variable,
Jsonb vars,
JsonbValue value 
)
static

Definition at line 2097 of file jsonpath_exec.c.

References Assert, ereport, errcode(), errmsg(), ERROR, findJsonbValueFromContainer(), JB_FOBJECT, jbvNull, jbvString, jpiVariable, JsonbInitBinary(), jspGetString(), pfree(), pnstrdup(), Jsonb::root, setBaseObject(), JsonPathItem::type, JsonbValue::type, and JsonbValue::val.

Referenced by getJsonPathItem().

2099 {
2100  char *varName;
2101  int varNameLength;
2102  JsonbValue tmp;
2103  JsonbValue *v;
2104 
2105  if (!vars)
2106  {
2107  value->type = jbvNull;
2108  return;
2109  }
2110 
2111  Assert(variable->type == jpiVariable);
2112  varName = jspGetString(variable, &varNameLength);
2113  tmp.type = jbvString;
2114  tmp.val.string.val = varName;
2115  tmp.val.string.len = varNameLength;
2116 
2117  v = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
2118 
2119  if (v)
2120  {
2121  *value = *v;
2122  pfree(v);
2123  }
2124  else
2125  {
2126  ereport(ERROR,
2127  (errcode(ERRCODE_UNDEFINED_OBJECT),
2128  errmsg("could not find jsonpath variable \"%s\"",
2129  pnstrdup(varName, varNameLength))));
2130  }
2131 
2132  JsonbInitBinary(&tmp, vars);
2133  setBaseObject(cxt, &tmp, 1);
2134 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
JsonbContainer root
Definition: jsonb.h:223
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:732
#define JB_FOBJECT
Definition: jsonb.h:210
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:784
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:336
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1050

◆ getScalar()

static JsonbValue * getScalar ( JsonbValue scalar,
enum jbvType  type 
)
static

Definition at line 2548 of file jsonpath_exec.c.

References Assert, jbvBinary, JsonContainerIsScalar, JsonbValue::type, and JsonbValue::val.

Referenced by executeBinaryArithmExpr(), executeDateTimeMethod(), executeLikeRegex(), executeNumericItemMethod(), executeStartsWith(), executeUnaryArithmExpr(), and getArrayIndex().

2549 {
2550  /* Scalars should be always extracted during jsonpath execution. */
2551  Assert(scalar->type != jbvBinary ||
2552  !JsonContainerIsScalar(scalar->val.binary.data));
2553 
2554  return scalar->type == type ? scalar : NULL;
2555 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263

◆ jsonb_path_exists()

Datum jsonb_path_exists ( PG_FUNCTION_ARGS  )

Definition at line 299 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

300 {
301  return jsonb_path_exists_internal(fcinfo, false);
302 }
static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_exists_internal()

static Datum jsonb_path_exists_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 273 of file jsonpath_exec.c.

References executeJsonPath(), jperIsError, jperOk, PG_FREE_IF_COPY, PG_GETARG_BOOL, PG_GETARG_JSONB_P, PG_GETARG_JSONPATH_P, PG_NARGS, PG_RETURN_BOOL, and PG_RETURN_NULL.

Referenced by jsonb_path_exists(), jsonb_path_exists_opr(), and jsonb_path_exists_tz().

274 {
275  Jsonb *jb = PG_GETARG_JSONB_P(0);
277  JsonPathExecResult res;
278  Jsonb *vars = NULL;
279  bool silent = true;
280 
281  if (PG_NARGS() == 4)
282  {
283  vars = PG_GETARG_JSONB_P(2);
284  silent = PG_GETARG_BOOL(3);
285  }
286 
287  res = executeJsonPath(jp, vars, jb, !silent, NULL, tz);
288 
289  PG_FREE_IF_COPY(jb, 0);
290  PG_FREE_IF_COPY(jp, 1);
291 
292  if (jperIsError(res))
293  PG_RETURN_NULL();
294 
295  PG_RETURN_BOOL(res == jperOk);
296 }
#define jperIsError(jper)
Definition: jsonb.h:220
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
JsonPathExecResult
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define PG_NARGS()
Definition: fmgr.h:198
Definition: regcomp.c:224
#define PG_RETURN_NULL()
Definition: fmgr.h:335
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_path_exists_opr()

Datum jsonb_path_exists_opr ( PG_FUNCTION_ARGS  )

Definition at line 316 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

317 {
318  /* just call the other one -- it can handle both cases */
319  return jsonb_path_exists_internal(fcinfo, false);
320 }
static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_exists_tz()

Datum jsonb_path_exists_tz ( PG_FUNCTION_ARGS  )

Definition at line 305 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

306 {
307  return jsonb_path_exists_internal(fcinfo, true);
308 }
static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_match()

Datum jsonb_path_match ( PG_FUNCTION_ARGS  )

Definition at line 367 of file jsonpath_exec.c.

References jsonb_path_match_internal().

368 {
369  return jsonb_path_match_internal(fcinfo, false);
370 }
static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_match_internal()

static Datum jsonb_path_match_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 328 of file jsonpath_exec.c.

References ereport, errcode(), errmsg(), ERROR, executeJsonPath(), jbvBool, jbvNull, JsonValueListHead(), JsonValueListLength(), PG_FREE_IF_COPY, PG_GETARG_BOOL, PG_GETARG_JSONB_P, PG_GETARG_JSONPATH_P, PG_NARGS, PG_RETURN_BOOL, PG_RETURN_NULL, JsonbValue::type, and JsonbValue::val.

Referenced by jsonb_path_match(), jsonb_path_match_opr(), and jsonb_path_match_tz().

329 {
330  Jsonb *jb = PG_GETARG_JSONB_P(0);
332  JsonValueList found = {0};
333  Jsonb *vars = NULL;
334  bool silent = true;
335 
336  if (PG_NARGS() == 4)
337  {
338  vars = PG_GETARG_JSONB_P(2);
339  silent = PG_GETARG_BOOL(3);
340  }
341 
342  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
343 
344  PG_FREE_IF_COPY(jb, 0);
345  PG_FREE_IF_COPY(jp, 1);
346 
347  if (JsonValueListLength(&found) == 1)
348  {
349  JsonbValue *jbv = JsonValueListHead(&found);
350 
351  if (jbv->type == jbvBool)
352  PG_RETURN_BOOL(jbv->val.boolean);
353 
354  if (jbv->type == jbvNull)
355  PG_RETURN_NULL();
356  }
357 
358  if (!silent)
359  ereport(ERROR,
360  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
361  errmsg("single boolean result is expected")));
362 
363  PG_RETURN_NULL();
364 }
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
int errcode(int sqlerrcode)
Definition: elog.c:570
Definition: jsonb.h:236
static int JsonValueListLength(const JsonValueList *jvl)
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define ERROR
Definition: elog.h:43
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
#define ereport(elevel, rest)
Definition: elog.h:141
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define PG_NARGS()
Definition: fmgr.h:198
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: regcomp.c:224
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define PG_RETURN_NULL()
Definition: fmgr.h:335
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_path_match_opr()

Datum jsonb_path_match_opr ( PG_FUNCTION_ARGS  )

Definition at line 384 of file jsonpath_exec.c.

References jsonb_path_match_internal().

385 {
386  /* just call the other one -- it can handle both cases */
387  return jsonb_path_match_internal(fcinfo, false);
388 }
static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_match_tz()

Datum jsonb_path_match_tz ( PG_FUNCTION_ARGS  )

Definition at line 373 of file jsonpath_exec.c.

References jsonb_path_match_internal().

374 {
375  return jsonb_path_match_internal(fcinfo, true);
376 }
static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query()

Datum jsonb_path_query ( PG_FUNCTION_ARGS  )

Definition at line 442 of file jsonpath_exec.c.

References jsonb_path_query_internal().

443 {
444  return jsonb_path_query_internal(fcinfo, false);
445 }
static Datum jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query_array()

Datum jsonb_path_query_array ( PG_FUNCTION_ARGS  )

Definition at line 473 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

474 {
475  return jsonb_path_query_array_internal(fcinfo, false);
476 }
static Datum jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query_array_internal()

static Datum jsonb_path_query_array_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 459 of file jsonpath_exec.c.

References executeJsonPath(), JsonbValueToJsonb(), PG_GETARG_BOOL, PG_GETARG_JSONB_P, PG_GETARG_JSONPATH_P, PG_RETURN_JSONB_P, and wrapItemsInArray().

Referenced by jsonb_path_query_array(), and jsonb_path_query_array_tz().

460 {
461  Jsonb *jb = PG_GETARG_JSONB_P(0);
463  JsonValueList found = {0};
465  bool silent = PG_GETARG_BOOL(3);
466 
467  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
468 
470 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
static JsonbValue * wrapItemsInArray(const JsonValueList *items)
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:76
Definition: regcomp.c:224
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_path_query_array_tz()

Datum jsonb_path_query_array_tz ( PG_FUNCTION_ARGS  )

Definition at line 479 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

480 {
481  return jsonb_path_query_array_internal(fcinfo, true);
482 }
static Datum jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query_first()

Datum jsonb_path_query_first ( PG_FUNCTION_ARGS  )

Definition at line 507 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

508 {
509  return jsonb_path_query_first_internal(fcinfo, false);
510 }
static Datum jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query_first_internal()

static Datum jsonb_path_query_first_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 490 of file jsonpath_exec.c.

References executeJsonPath(), JsonbValueToJsonb(), JsonValueListHead(), JsonValueListLength(), PG_GETARG_BOOL, PG_GETARG_JSONB_P, PG_GETARG_JSONPATH_P, PG_RETURN_JSONB_P, and PG_RETURN_NULL.

Referenced by jsonb_path_query_first(), and jsonb_path_query_first_tz().

491 {
492  Jsonb *jb = PG_GETARG_JSONB_P(0);
494  JsonValueList found = {0};
496  bool silent = PG_GETARG_BOOL(3);
497 
498  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
499 
500  if (JsonValueListLength(&found) >= 1)
502  else
503  PG_RETURN_NULL();
504 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
static int JsonValueListLength(const JsonValueList *jvl)
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:34
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:76
Definition: regcomp.c:224
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define PG_RETURN_NULL()
Definition: fmgr.h:335
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:74

◆ jsonb_path_query_first_tz()

Datum jsonb_path_query_first_tz ( PG_FUNCTION_ARGS  )

Definition at line 513 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

514 {
515  return jsonb_path_query_first_internal(fcinfo, true);
516 }
static Datum jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)

◆ jsonb_path_query_internal()

static Datum jsonb_path_query_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 396 of file jsonpath_exec.c.

References executeJsonPath(), JsonbPGetDatum, JsonbValueToJsonb(), JsonValueListGetList(), lfirst, list_delete_first(), list_head(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, PG_GETARG_BOOL, PG_GETARG_JSONB_P_COPY, PG_GETARG_JSONPATH_P_COPY, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, and FuncCallContext::user_fctx.

Referenced by jsonb_path_query(), and jsonb_path_query_tz().

397 {
398  FuncCallContext *funcctx;
399  List *found;
400  JsonbValue *v;
401  ListCell *c;
402 
403  if (SRF_IS_FIRSTCALL())
404  {
405  JsonPath *jp;
406  Jsonb *jb;
407  MemoryContext oldcontext;
408  Jsonb *vars;
409  bool silent;
410  JsonValueList found = {0};
411 
412  funcctx = SRF_FIRSTCALL_INIT();
413  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
414 
415  jb = PG_GETARG_JSONB_P_COPY(0);
417  vars = PG_GETARG_JSONB_P_COPY(2);
418  silent = PG_GETARG_BOOL(3);
419 
420  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
421 
422  funcctx->user_fctx = JsonValueListGetList(&found);
423 
424  MemoryContextSwitchTo(oldcontext);
425  }
426 
427  funcctx = SRF_PERCALL_SETUP();
428  found = funcctx->user_fctx;
429 
430  c = list_head(found);
431 
432  if (c == NULL)
433  SRF_RETURN_DONE(funcctx);
434 
435  v = lfirst(c);
436  funcctx->user_fctx = list_delete_first(found);
437 
439 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:84
Definition: jsonb.h:220
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:283
#define JsonbPGetDatum(p)
Definition: jsonb.h:73
#define PG_GETARG_JSONB_P_COPY(x)
Definition: jsonb.h:75
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:287
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:289
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
static List * JsonValueListGetList(JsonValueList *jvl)
#define PG_GETARG_JSONPATH_P_COPY(x)
Definition: jsonpath.h:35
char * c
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define lfirst(lc)
Definition: pg_list.h:190
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:102
void * user_fctx
Definition: funcapi.h:83
Definition: regcomp.c:224
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:861
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:307
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:285

◆ jsonb_path_query_tz()

Datum jsonb_path_query_tz ( PG_FUNCTION_ARGS  )

Definition at line 448 of file jsonpath_exec.c.

References jsonb_path_query_internal().

449 {
450  return jsonb_path_query_internal(fcinfo, true);
451 }
static Datum jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)

◆ JsonbArraySize()

static int JsonbArraySize ( JsonbValue jb)
static

Definition at line 2142 of file jsonpath_exec.c.

References Assert, JsonBaseObjectInfo::jbc, jbvArray, jbvBinary, JsonContainerIsArray, JsonContainerIsScalar, JsonContainerSize, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

2143 {
2144  Assert(jb->type != jbvArray);
2145 
2146  if (jb->type == jbvBinary)
2147  {
2148  JsonbContainer *jbc = jb->val.binary.data;
2149 
2150  if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
2151  return JsonContainerSize(jbc);
2152  }
2153 
2154  return -1;
2155 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define JsonContainerSize(jc)
Definition: jsonb.h:214
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263

◆ JsonbInitBinary()

static JsonbValue * JsonbInitBinary ( JsonbValue jbv,
Jsonb jb 
)
static

Definition at line 2511 of file jsonpath_exec.c.

References jbvBinary, Jsonb::root, JsonbValue::type, JsonbValue::val, and VARSIZE_ANY_EXHDR.

Referenced by executeJsonPath(), executeKeyValueMethod(), and getJsonPathVariable().

2512 {
2513  jbv->type = jbvBinary;
2514  jbv->val.binary.data = &jb->root;
2515  jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb);
2516 
2517  return jbv;
2518 }
char * val
Definition: jsonb.h:272
JsonbContainer root
Definition: jsonb.h:223
enum jbvType type
Definition: jsonb.h:263
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ JsonbType()

static int JsonbType ( JsonbValue jb)
static

Definition at line 2524 of file jsonpath_exec.c.

References Assert, elog, ERROR, JsonbContainer::header, JsonBaseObjectInfo::jbc, jbvArray, jbvBinary, jbvObject, JsonContainerIsArray, JsonContainerIsObject, JsonContainerIsScalar, JsonbValue::type, generate_unaccent_rules::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapResult(), executeItemOptUnwrapTarget(), executeKeyValueMethod(), and executeNumericItemMethod().

2525 {
2526  int type = jb->type;
2527 
2528  if (jb->type == jbvBinary)
2529  {
2530  JsonbContainer *jbc = (void *) jb->val.binary.data;
2531 
2532  /* Scalars should be always extracted during jsonpath execution. */
2534 
2535  if (JsonContainerIsObject(jbc))
2536  type = jbvObject;
2537  else if (JsonContainerIsArray(jbc))
2538  type = jbvArray;
2539  else
2540  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
2541  }
2542 
2543  return type;
2544 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define ERROR
Definition: elog.h:43
#define JsonContainerIsArray(jc)
Definition: jsonb.h:217
uint32 header
Definition: jsonb.h:200
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
#define Assert(condition)
Definition: c.h:732
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:226

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 2423 of file jsonpath_exec.c.

References lappend(), JsonValueList::list, list_make2, and JsonValueList::singleton.

Referenced by executeAnyItem(), executeItemOptUnwrapResult(), and executeNextItem().

2424 {
2425  if (jvl->singleton)
2426  {
2427  jvl->list = list_make2(jvl->singleton, jbv);
2428  jvl->singleton = NULL;
2429  }
2430  else if (!jvl->list)
2431  jvl->singleton = jbv;
2432  else
2433  jvl->list = lappend(jvl->list, jbv);
2434 }
#define list_make2(x1, x2)
Definition: pg_list.h:229
List * lappend(List *list, void *datum)
Definition: list.c:322
JsonbValue * singleton

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 2455 of file jsonpath_exec.c.

References JsonValueList::list, list_make1, and JsonValueList::singleton.

Referenced by jsonb_path_query_internal().

2456 {
2457  if (jvl->singleton)
2458  return list_make1(jvl->singleton);
2459 
2460  return jvl->list;
2461 }
#define list_make1(x1)
Definition: pg_list.h:227
JsonbValue * singleton

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

Definition at line 2449 of file jsonpath_exec.c.

References linitial, JsonValueList::list, and JsonValueList::singleton.

Referenced by executeBinaryArithmExpr(), getArrayIndex(), jsonb_path_match_internal(), and jsonb_path_query_first_internal().

2450 {
2451  return jvl->singleton ? jvl->singleton : linitial(jvl->list);
2452 }
#define linitial(l)
Definition: pg_list.h:195
JsonbValue * singleton

◆ JsonValueListInitIterator()

static void JsonValueListInitIterator ( const JsonValueList jvl,
JsonValueListIterator it 
)
static

Definition at line 2464 of file jsonpath_exec.c.

References linitial, JsonValueList::list, JsonValueListIterator::list, list_second_cell(), JsonValueListIterator::next, NIL, JsonValueList::singleton, and JsonValueListIterator::value.

Referenced by executeItemOptUnwrapResult(), executePredicate(), executeUnaryArithmExpr(), and wrapItemsInArray().

2465 {
2466  if (jvl->singleton)
2467  {
2468  it->value = jvl->singleton;
2469  it->list = NIL;
2470  it->next = NULL;
2471  }
2472  else if (jvl->list != NIL)
2473  {
2474  it->value = (JsonbValue *) linitial(jvl->list);
2475  it->list = jvl->list;
2476  it->next = list_second_cell(jvl->list);
2477  }
2478  else
2479  {
2480  it->value = NULL;
2481  it->list = NIL;
2482  it->next = NULL;
2483  }
2484 }
#define NIL
Definition: pg_list.h:65
#define linitial(l)
Definition: pg_list.h:195
static ListCell * list_second_cell(const List *l)
Definition: pg_list.h:139
JsonbValue * singleton

◆ JsonValueListIsEmpty()

static bool JsonValueListIsEmpty ( JsonValueList jvl)
static

Definition at line 2443 of file jsonpath_exec.c.

References JsonValueList::list, list_length(), and JsonValueList::singleton.

Referenced by executeBoolItem(), and executeJsonPath().

2444 {
2445  return !jvl->singleton && list_length(jvl->list) <= 0;
2446 }
JsonbValue * singleton
static int list_length(const List *l)
Definition: pg_list.h:169

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

Definition at line 2437 of file jsonpath_exec.c.

References JsonValueList::list, list_length(), and JsonValueList::singleton.

Referenced by executeBinaryArithmExpr(), getArrayIndex(), jsonb_path_match_internal(), and jsonb_path_query_first_internal().

2438 {
2439  return jvl->singleton ? 1 : list_length(jvl->list);
2440 }
JsonbValue * singleton
static int list_length(const List *l)
Definition: pg_list.h:169

◆ JsonValueListNext()

static JsonbValue * JsonValueListNext ( const JsonValueList jvl,
JsonValueListIterator it 
)
static

Definition at line 2490 of file jsonpath_exec.c.

References lfirst, JsonValueListIterator::list, lnext(), JsonValueListIterator::next, and JsonValueListIterator::value.

Referenced by executeItemOptUnwrapResult(), executePredicate(), executeUnaryArithmExpr(), and wrapItemsInArray().

2491 {
2492  JsonbValue *result = it->value;
2493 
2494  if (it->next)
2495  {
2496  it->value = lfirst(it->next);
2497  it->next = lnext(it->list, it->next);
2498  }
2499  else
2500  {
2501  it->value = NULL;
2502  }
2503 
2504  return result;
2505 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
#define lfirst(lc)
Definition: pg_list.h:190

◆ setBaseObject()

static JsonBaseObjectInfo setBaseObject ( JsonPathExecContext cxt,
JsonbValue jbv,
int32  id 
)
static

Definition at line 2411 of file jsonpath_exec.c.

References JsonPathExecContext::baseObject, JsonBaseObjectInfo::id, JsonBaseObjectInfo::jbc, jbvBinary, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget(), executeKeyValueMethod(), and getJsonPathVariable().

2412 {
2413  JsonBaseObjectInfo baseObject = cxt->baseObject;
2414 
2415  cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
2416  (JsonbContainer *) jbv->val.binary.data;
2417  cxt->baseObject.id = id;
2418 
2419  return baseObject;
2420 }
char * val
Definition: jsonb.h:272
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:98
JsonbContainer * jbc
Definition: jsonpath_exec.c:86
enum jbvType type
Definition: jsonb.h:263

◆ wrapItemsInArray()

static JsonbValue * wrapItemsInArray ( const JsonValueList items)
static

Definition at line 2559 of file jsonpath_exec.c.

References JsonValueListInitIterator(), JsonValueListNext(), pushJsonbValue(), WJB_BEGIN_ARRAY, WJB_ELEM, and WJB_END_ARRAY.

Referenced by jsonb_path_query_array_internal().

2560 {
2561  JsonbParseState *ps = NULL;
2563  JsonbValue *jbv;
2564 
2565  pushJsonbValue(&ps, WJB_BEGIN_ARRAY, NULL);
2566 
2567  JsonValueListInitIterator(items, &it);
2568  while ((jbv = JsonValueListNext(items, &it)))
2569  pushJsonbValue(&ps, WJB_ELEM, jbv);
2570 
2571  return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
2572 }
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:558
Definition: jsonb.h:25