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/date.h"
#include "utils/datetime.h"
#include "utils/datum.h"
#include "utils/float.h"
#include "utils/formatting.h"
#include "utils/guc.h"
#include "utils/json.h"
#include "utils/jsonpath.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)
 
static void checkTimezoneIsUsedForCast (bool useTz, const char *type1, const char *type2)
 
static Datum castTimeToTimeTz (Datum time, bool useTz)
 
static int cmpDateToTimestamp (DateADT date1, Timestamp ts2, bool useTz)
 
static int cmpDateToTimestampTz (DateADT date1, TimestampTz tstz2, bool useTz)
 
static int cmpTimestampToTimestampTz (Timestamp ts1, TimestampTz tstz2, bool useTz)
 

Macro Definition Documentation

◆ jperIsError

◆ jspAutoUnwrap

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

◆ jspAutoWrap

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

Definition at line 157 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspIgnoreStructuralErrors

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

Definition at line 158 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspStrictAbsenseOfErrors

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

Definition at line 155 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 162 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 174 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 170 of file jsonpath_exec.c.

◆ JsonValueList

typedef struct JsonValueList JsonValueList

◆ JsonValueListIterator

Enumeration Type Documentation

◆ JsonPathBool

Enumerator
jpbFalse 
jpbTrue 
jpbUnknown 

Definition at line 121 of file jsonpath_exec.c.

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

◆ JsonPathExecResult

Enumerator
jperOk 
jperNotFound 
jperError 

Definition at line 129 of file jsonpath_exec.c.

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

Function Documentation

◆ appendBoolResult()

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

Definition at line 2046 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

2048 {
2050  JsonbValue jbv;
2051 
2052  if (!jspGetNext(jsp, &next) && !found)
2053  return jperOk; /* found singleton boolean value */
2054 
2055  if (res == jpbUnknown)
2056  {
2057  jbv.type = jbvNull;
2058  }
2059  else
2060  {
2061  jbv.type = jbvBool;
2062  jbv.val.boolean = res == jpbTrue;
2063  }
2064 
2065  return executeNextItem(cxt, jsp, &next, &jbv, found, true);
2066 }
static int32 next
Definition: blutils.c:219
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 2180 of file jsonpath_exec.c.

References cmp(), and Min.

Referenced by compareStrings().

2182 {
2183  int cmp;
2184 
2185  cmp = memcmp(s1, s2, Min(len1, len2));
2186 
2187  if (cmp != 0)
2188  return cmp;
2189 
2190  if (len1 == len2)
2191  return 0;
2192 
2193  return len1 < len2 ? -1 : 1;
2194 }
#define Min(x, y)
Definition: c.h:982
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ castTimeToTimeTz()

static Datum castTimeToTimeTz ( Datum  time,
bool  useTz 
)
static

Definition at line 2598 of file jsonpath_exec.c.

References checkTimezoneIsUsedForCast(), DirectFunctionCall1, and time_timetz().

Referenced by compareDatetime().

2599 {
2600  checkTimezoneIsUsedForCast(useTz, "time", "timetz");
2601 
2602  return DirectFunctionCall1(time_timetz, time);
2603 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2594

◆ checkTimezoneIsUsedForCast()

static void checkTimezoneIsUsedForCast ( bool  useTz,
const char *  type1,
const char *  type2 
)
static

Definition at line 2586 of file jsonpath_exec.c.

References ereport, errcode(), errhint(), errmsg(), and ERROR.

Referenced by castTimeToTimeTz(), cmpDateToTimestampTz(), and cmpTimestampToTimestampTz().

2587 {
2588  if (!useTz)
2589  ereport(ERROR,
2590  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2591  errmsg("cannot convert value from %s to %s without time zone usage",
2592  type1, type2),
2593  errhint("Use *_tz() function for time zone support.")));
2594 }
int errhint(const char *fmt,...)
Definition: elog.c:1149
int errcode(int sqlerrcode)
Definition: elog.c:691
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:902

◆ cmpDateToTimestamp()

static int cmpDateToTimestamp ( DateADT  date1,
Timestamp  ts2,
bool  useTz 
)
static

Definition at line 2610 of file jsonpath_exec.c.

References date_cmp_timestamp_internal().

Referenced by compareDatetime().

2611 {
2612  return date_cmp_timestamp_internal(date1, ts2);
2613 }
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition: date.c:747

◆ cmpDateToTimestampTz()

static int cmpDateToTimestampTz ( DateADT  date1,
TimestampTz  tstz2,
bool  useTz 
)
static

Definition at line 2619 of file jsonpath_exec.c.

References checkTimezoneIsUsedForCast(), and date_cmp_timestamptz_internal().

Referenced by compareDatetime().

2620 {
2621  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
2622 
2623  return date_cmp_timestamptz_internal(date1, tstz2);
2624 }
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition: date.c:827

◆ cmpTimestampToTimestampTz()

static int cmpTimestampToTimestampTz ( Timestamp  ts1,
TimestampTz  tstz2,
bool  useTz 
)
static

Definition at line 2630 of file jsonpath_exec.c.

References checkTimezoneIsUsedForCast(), and timestamp_cmp_timestamptz_internal().

Referenced by compareDatetime().

2631 {
2632  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
2633 
2634  return timestamp_cmp_timestamptz_internal(ts1, tstz2);
2635 }
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2192
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

◆ compareDatetime()

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

Definition at line 2643 of file jsonpath_exec.c.

References castTimeToTimeTz(), cmpDateToTimestamp(), cmpDateToTimestampTz(), cmpTimestampToTimestampTz(), date_cmp(), DatumGetDateADT, DatumGetInt32, DatumGetTimestamp, DatumGetTimestampTz, DirectFunctionCall2, elog, ERROR, time_cmp(), timestamp_cmp(), and timetz_cmp().

Referenced by compareItems().

2645 {
2646  PGFunction cmpfunc;
2647 
2648  *cast_error = false;
2649 
2650  switch (typid1)
2651  {
2652  case DATEOID:
2653  switch (typid2)
2654  {
2655  case DATEOID:
2656  cmpfunc = date_cmp;
2657 
2658  break;
2659 
2660  case TIMESTAMPOID:
2661  return cmpDateToTimestamp(DatumGetDateADT(val1),
2662  DatumGetTimestamp(val2),
2663  useTz);
2664 
2665  case TIMESTAMPTZOID:
2667  DatumGetTimestampTz(val2),
2668  useTz);
2669 
2670  case TIMEOID:
2671  case TIMETZOID:
2672  *cast_error = true; /* uncomparable types */
2673  return 0;
2674 
2675  default:
2676  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2677  typid2);
2678  }
2679  break;
2680 
2681  case TIMEOID:
2682  switch (typid2)
2683  {
2684  case TIMEOID:
2685  cmpfunc = time_cmp;
2686 
2687  break;
2688 
2689  case TIMETZOID:
2690  val1 = castTimeToTimeTz(val1, useTz);
2691  cmpfunc = timetz_cmp;
2692 
2693  break;
2694 
2695  case DATEOID:
2696  case TIMESTAMPOID:
2697  case TIMESTAMPTZOID:
2698  *cast_error = true; /* uncomparable types */
2699  return 0;
2700 
2701  default:
2702  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2703  typid2);
2704  }
2705  break;
2706 
2707  case TIMETZOID:
2708  switch (typid2)
2709  {
2710  case TIMEOID:
2711  val2 = castTimeToTimeTz(val2, useTz);
2712  cmpfunc = timetz_cmp;
2713 
2714  break;
2715 
2716  case TIMETZOID:
2717  cmpfunc = timetz_cmp;
2718 
2719  break;
2720 
2721  case DATEOID:
2722  case TIMESTAMPOID:
2723  case TIMESTAMPTZOID:
2724  *cast_error = true; /* uncomparable types */
2725  return 0;
2726 
2727  default:
2728  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2729  typid2);
2730  }
2731  break;
2732 
2733  case TIMESTAMPOID:
2734  switch (typid2)
2735  {
2736  case DATEOID:
2737  return -cmpDateToTimestamp(DatumGetDateADT(val2),
2738  DatumGetTimestamp(val1),
2739  useTz);
2740 
2741  case TIMESTAMPOID:
2742  cmpfunc = timestamp_cmp;
2743 
2744  break;
2745 
2746  case TIMESTAMPTZOID:
2748  DatumGetTimestampTz(val2),
2749  useTz);
2750 
2751  case TIMEOID:
2752  case TIMETZOID:
2753  *cast_error = true; /* uncomparable types */
2754  return 0;
2755 
2756  default:
2757  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2758  typid2);
2759  }
2760  break;
2761 
2762  case TIMESTAMPTZOID:
2763  switch (typid2)
2764  {
2765  case DATEOID:
2766  return -cmpDateToTimestampTz(DatumGetDateADT(val2),
2767  DatumGetTimestampTz(val1),
2768  useTz);
2769 
2770  case TIMESTAMPOID:
2772  DatumGetTimestampTz(val1),
2773  useTz);
2774 
2775  case TIMESTAMPTZOID:
2776  cmpfunc = timestamp_cmp;
2777 
2778  break;
2779 
2780  case TIMEOID:
2781  case TIMETZOID:
2782  *cast_error = true; /* uncomparable types */
2783  return 0;
2784 
2785  default:
2786  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2787  typid2);
2788  }
2789  break;
2790 
2791  default:
2792  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);
2793  }
2794 
2795  if (*cast_error)
2796  return 0; /* cast error */
2797 
2798  return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2));
2799 }
static Datum castTimeToTimeTz(Datum time, bool useTz)
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2302
Datum(* PGFunction)(FunctionCallInfo fcinfo)
Definition: fmgr.h:40
#define DatumGetDateADT(X)
Definition: date.h:53
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition: timestamp.c:2148
#define ERROR
Definition: elog.h:43
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1558
#define DatumGetTimestampTz(X)
Definition: timestamp.h:28
static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz)
Datum date_cmp(PG_FUNCTION_ARGS)
Definition: date.c:428
#define elog(elevel,...)
Definition: elog.h:228
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz)
static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz)
#define DatumGetTimestamp(X)
Definition: timestamp.h:27

◆ compareItems()

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

Definition at line 2268 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().

2269 {
2270  int cmp;
2271  bool res;
2272 
2273  if (jb1->type != jb2->type)
2274  {
2275  if (jb1->type == jbvNull || jb2->type == jbvNull)
2276 
2277  /*
2278  * Equality and order comparison of nulls to non-nulls returns
2279  * always false, but inequality comparison returns true.
2280  */
2281  return op == jpiNotEqual ? jpbTrue : jpbFalse;
2282 
2283  /* Non-null items of different types are not comparable. */
2284  return jpbUnknown;
2285  }
2286 
2287  switch (jb1->type)
2288  {
2289  case jbvNull:
2290  cmp = 0;
2291  break;
2292  case jbvBool:
2293  cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
2294  jb1->val.boolean ? 1 : -1;
2295  break;
2296  case jbvNumeric:
2297  cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
2298  break;
2299  case jbvString:
2300  if (op == jpiEqual)
2301  return jb1->val.string.len != jb2->val.string.len ||
2302  memcmp(jb1->val.string.val,
2303  jb2->val.string.val,
2304  jb1->val.string.len) ? jpbFalse : jpbTrue;
2305 
2306  cmp = compareStrings(jb1->val.string.val, jb1->val.string.len,
2307  jb2->val.string.val, jb2->val.string.len);
2308  break;
2309  case jbvDatetime:
2310  {
2311  bool cast_error;
2312 
2313  cmp = compareDatetime(jb1->val.datetime.value,
2314  jb1->val.datetime.typid,
2315  jb2->val.datetime.value,
2316  jb2->val.datetime.typid,
2317  useTz,
2318  &cast_error);
2319 
2320  if (cast_error)
2321  return jpbUnknown;
2322  }
2323  break;
2324 
2325  case jbvBinary:
2326  case jbvArray:
2327  case jbvObject:
2328  return jpbUnknown; /* non-scalars are not comparable */
2329 
2330  default:
2331  elog(ERROR, "invalid jsonb value type %d", jb1->type);
2332  }
2333 
2334  switch (op)
2335  {
2336  case jpiEqual:
2337  res = (cmp == 0);
2338  break;
2339  case jpiNotEqual:
2340  res = (cmp != 0);
2341  break;
2342  case jpiLess:
2343  res = (cmp < 0);
2344  break;
2345  case jpiGreater:
2346  res = (cmp > 0);
2347  break;
2348  case jpiLessOrEqual:
2349  res = (cmp <= 0);
2350  break;
2351  case jpiGreaterOrEqual:
2352  res = (cmp >= 0);
2353  break;
2354  default:
2355  elog(ERROR, "unrecognized jsonpath operation: %d", op);
2356  return jpbUnknown;
2357  }
2358 
2359  return res ? jpbTrue : jpbFalse;
2360 }
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:228
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 2364 of file jsonpath_exec.c.

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

Referenced by compareItems().

2365 {
2367  NumericGetDatum(a),
2368  NumericGetDatum(b)));
2369 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2262
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ compareStrings()

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

Definition at line 2201 of file jsonpath_exec.c.

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

Referenced by compareItems().

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

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

2373 {
2374  JsonbValue *dst = palloc(sizeof(*dst));
2375 
2376  *dst = *src;
2377 
2378  return dst;
2379 }
void * palloc(Size size)
Definition: mcxt.c:950

◆ 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 1376 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().

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

◆ executeBinaryArithmExpr()

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

Definition at line 1547 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().

1550 {
1551  JsonPathExecResult jper;
1552  JsonPathItem elem;
1553  JsonValueList lseq = {0};
1554  JsonValueList rseq = {0};
1555  JsonbValue *lval;
1556  JsonbValue *rval;
1557  Numeric res;
1558 
1559  jspGetLeftArg(jsp, &elem);
1560 
1561  /*
1562  * XXX: By standard only operands of multiplicative expressions are
1563  * unwrapped. We extend it to other binary arithmetic expressions too.
1564  */
1565  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &lseq);
1566  if (jperIsError(jper))
1567  return jper;
1568 
1569  jspGetRightArg(jsp, &elem);
1570 
1571  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &rseq);
1572  if (jperIsError(jper))
1573  return jper;
1574 
1575  if (JsonValueListLength(&lseq) != 1 ||
1576  !(lval = getScalar(JsonValueListHead(&lseq), jbvNumeric)))
1578  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
1579  errmsg("left operand of jsonpath operator %s is not a single numeric value",
1580  jspOperationName(jsp->type)))));
1581 
1582  if (JsonValueListLength(&rseq) != 1 ||
1583  !(rval = getScalar(JsonValueListHead(&rseq), jbvNumeric)))
1585  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
1586  errmsg("right operand of jsonpath operator %s is not a single numeric value",
1587  jspOperationName(jsp->type)))));
1588 
1589  if (jspThrowErrors(cxt))
1590  {
1591  res = func(lval->val.numeric, rval->val.numeric, NULL);
1592  }
1593  else
1594  {
1595  bool error = false;
1596 
1597  res = func(lval->val.numeric, rval->val.numeric, &error);
1598 
1599  if (error)
1600  return jperError;
1601  }
1602 
1603  if (!jspGetNext(jsp, &elem) && !found)
1604  return jperOk;
1605 
1606  lval = palloc(sizeof(*lval));
1607  lval->type = jbvNumeric;
1608  lval->val.numeric = res;
1609 
1610  return executeNextItem(cxt, jsp, &elem, lval, found, false);
1611 }
#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:691
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static int JsonValueListLength(const JsonValueList *jvl)
#define ERROR
Definition: elog.h:43
JsonPathExecResult
#define jspThrowErrors(cxt)
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1013
#define ereport(elevel,...)
Definition: elog.h:155
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:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
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 1222 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().

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

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

Referenced by executeBoolItem().

2170 {
2172 
2173  return compareItems(cmp->type, lv, rv, cxt->useTz);
2174 }
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 1775 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, text_to_cstring(), TopMemoryContext, JsonPathItem::type, JsonbValue::type, JsonbValue::val, and value.

Referenced by executeItemOptUnwrapTarget().

1777 {
1778  JsonbValue jbvbuf;
1779  Datum value;
1780  text *datetime;
1781  Oid collid;
1782  Oid typid;
1783  int32 typmod = -1;
1784  int tz = 0;
1785  bool hasNext;
1787  JsonPathItem elem;
1788 
1789  if (!(jb = getScalar(jb, jbvString)))
1791  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
1792  errmsg("jsonpath item method .%s() can only be applied to a string",
1793  jspOperationName(jsp->type)))));
1794 
1795  datetime = cstring_to_text_with_len(jb->val.string.val,
1796  jb->val.string.len);
1797 
1798  /*
1799  * At some point we might wish to have callers supply the collation to
1800  * use, but right now it's unclear that they'd be able to do better than
1801  * DEFAULT_COLLATION_OID anyway.
1802  */
1803  collid = DEFAULT_COLLATION_OID;
1804 
1805  if (jsp->content.arg)
1806  {
1807  text *template;
1808  char *template_str;
1809  int template_len;
1810  bool have_error = false;
1811 
1812  jspGetArg(jsp, &elem);
1813 
1814  if (elem.type != jpiString)
1815  elog(ERROR, "invalid jsonpath item type for .datetime() argument");
1816 
1817  template_str = jspGetString(&elem, &template_len);
1818 
1819  template = cstring_to_text_with_len(template_str,
1820  template_len);
1821 
1822  value = parse_datetime(datetime, template, collid, true,
1823  &typid, &typmod, &tz,
1824  jspThrowErrors(cxt) ? NULL : &have_error);
1825 
1826  if (have_error)
1827  res = jperError;
1828  else
1829  res = jperOk;
1830  }
1831  else
1832  {
1833  /*
1834  * According to SQL/JSON standard enumerate ISO formats for: date,
1835  * timetz, time, timestamptz, timestamp.
1836  *
1837  * We also support ISO 8601 for timestamps, because to_json[b]()
1838  * functions use this format.
1839  */
1840  static const char *fmt_str[] =
1841  {
1842  "yyyy-mm-dd",
1843  "HH24:MI:SSTZH:TZM",
1844  "HH24:MI:SSTZH",
1845  "HH24:MI:SS",
1846  "yyyy-mm-dd HH24:MI:SSTZH:TZM",
1847  "yyyy-mm-dd HH24:MI:SSTZH",
1848  "yyyy-mm-dd HH24:MI:SS",
1849  "yyyy-mm-dd\"T\"HH24:MI:SSTZH:TZM",
1850  "yyyy-mm-dd\"T\"HH24:MI:SSTZH",
1851  "yyyy-mm-dd\"T\"HH24:MI:SS"
1852  };
1853 
1854  /* cache for format texts */
1855  static text *fmt_txt[lengthof(fmt_str)] = {0};
1856  int i;
1857 
1858  /* loop until datetime format fits */
1859  for (i = 0; i < lengthof(fmt_str); i++)
1860  {
1861  bool have_error = false;
1862 
1863  if (!fmt_txt[i])
1864  {
1865  MemoryContext oldcxt =
1867 
1868  fmt_txt[i] = cstring_to_text(fmt_str[i]);
1869  MemoryContextSwitchTo(oldcxt);
1870  }
1871 
1872  value = parse_datetime(datetime, fmt_txt[i], collid, true,
1873  &typid, &typmod, &tz,
1874  &have_error);
1875 
1876  if (!have_error)
1877  {
1878  res = jperOk;
1879  break;
1880  }
1881  }
1882 
1883  if (res == jperNotFound)
1885  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
1886  errmsg("datetime format is not recognized: \"%s\"",
1887  text_to_cstring(datetime)),
1888  errhint("Use a datetime template argument to specify the input data format."))));
1889  }
1890 
1891  pfree(datetime);
1892 
1893  if (jperIsError(res))
1894  return res;
1895 
1896  hasNext = jspGetNext(jsp, &elem);
1897 
1898  if (!hasNext && !found)
1899  return res;
1900 
1901  jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
1902 
1903  jb->type = jbvDatetime;
1904  jb->val.datetime.value = value;
1905  jb->val.datetime.typid = typid;
1906  jb->val.datetime.typmod = typmod;
1907  jb->val.datetime.tz = tz;
1908 
1909  return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
1910 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
int errhint(const char *fmt,...)
Definition: elog.c:1149
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
int errcode(int sqlerrcode)
Definition: elog.c:691
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, bool *have_error)
Definition: formatting.c:4239
#define lengthof(array)
Definition: c.h:730
unsigned int Oid
Definition: postgres_ext.h:31
int32 arg
Definition: jsonpath.h:128
signed int int32
Definition: c.h:417
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:43
JsonPathExecResult
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:200
#define jspThrowErrors(cxt)
MemoryContext TopMemoryContext
Definition: mcxt.c:44
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
uintptr_t Datum
Definition: postgres.h:367
union JsonPathItem::@128 content
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:155
text * cstring_to_text(const char *s)
Definition: varlena.c:188
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
char * text_to_cstring(const text *t)
Definition: varlena.c:221
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
#define elog(elevel,...)
Definition: elog.h:228
int i
Definition: c.h:617
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 599 of file jsonpath_exec.c.

References executeItemOptUnwrapTarget(), and jspAutoUnwrap.

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

601 {
602  return executeItemOptUnwrapTarget(cxt, jsp, jb, found, jspAutoUnwrap(cxt));
603 }
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 1170 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().

1173 {
1174  if (unwrap && jspAutoUnwrap(cxt))
1175  {
1176  JsonValueList seq = {0};
1178  JsonPathExecResult res = executeItem(cxt, jsp, jb, &seq);
1179  JsonbValue *item;
1180 
1181  if (jperIsError(res))
1182  return res;
1183 
1184  JsonValueListInitIterator(&seq, &it);
1185  while ((item = JsonValueListNext(&seq, &it)))
1186  {
1187  Assert(item->type != jbvArray);
1188 
1189  if (JsonbType(item) == jbvArray)
1190  executeItemUnwrapTargetArray(cxt, NULL, item, found, false);
1191  else
1192  JsonValueListAppend(found, item);
1193  }
1194 
1195  return jperOk;
1196  }
1197 
1198  return executeItem(cxt, jsp, jb, found);
1199 }
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:800
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 1205 of file jsonpath_exec.c.

References executeItemOptUnwrapResult(), and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

1209 {
1210  JsonPathExecResult res;
1211  bool throwErrors = cxt->throwErrors;
1212 
1213  cxt->throwErrors = false;
1214  res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found);
1215  cxt->throwErrors = throwErrors;
1216 
1217  return res;
1218 }
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 611 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, int64_to_numeric(), 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().

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

◆ executeItemUnwrapTargetArray()

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

Definition at line 1119 of file jsonpath_exec.c.

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

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

1122 {
1123  if (jb->type != jbvBinary)
1124  {
1125  Assert(jb->type != jbvArray);
1126  elog(ERROR, "invalid jsonb array value type: %d", jb->type);
1127  }
1128 
1129  return executeAnyItem
1130  (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
1131  false, unwrapElements);
1132 }
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:800
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:228

◆ executeJsonPath()

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

Definition at line 539 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().

541 {
543  JsonPathExecResult res;
544  JsonPathItem jsp;
545  JsonbValue jbv;
546 
547  jspInit(&jsp, path);
548 
549  if (!JsonbExtractScalar(&json->root, &jbv))
550  JsonbInitBinary(&jbv, json);
551 
552  if (vars && !JsonContainerIsObject(&vars->root))
553  {
554  ereport(ERROR,
555  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
556  errmsg("\"vars\" argument is not an object"),
557  errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object.")));
558  }
559 
560  cxt.vars = vars;
561  cxt.laxMode = (path->header & JSONPATH_LAX) != 0;
563  cxt.root = &jbv;
564  cxt.current = &jbv;
565  cxt.baseObject.jbc = NULL;
566  cxt.baseObject.id = 0;
567  cxt.lastGeneratedObjectId = vars ? 2 : 1;
568  cxt.innermostArraySize = -1;
569  cxt.throwErrors = throwErrors;
570  cxt.useTz = useTz;
571 
572  if (jspStrictAbsenseOfErrors(&cxt) && !result)
573  {
574  /*
575  * In strict mode we must get a complete list of values to check that
576  * there are no errors at all.
577  */
578  JsonValueList vals = {0};
579 
580  res = executeItem(&cxt, &jsp, &jbv, &vals);
581 
582  if (jperIsError(res))
583  return res;
584 
585  return JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk;
586  }
587 
588  res = executeItem(&cxt, &jsp, &jbv, result);
589 
590  Assert(!throwErrors || !jperIsError(res));
591 
592  return res;
593 }
#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:691
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:97
#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:1035
JsonbValue * root
Definition: jsonpath_exec.c:95
JsonbContainer root
Definition: jsonb.h:223
#define JsonContainerIsObject(jc)
Definition: jsonb.h:216
JsonbContainer * jbc
Definition: jsonpath_exec.c:85
#define ereport(elevel,...)
Definition: elog.h:155
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:800
JsonbValue * current
Definition: jsonpath_exec.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:902
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 1936 of file jsonpath_exec.c.

References Assert, JsonPathExecContext::baseObject, ereport, errcode(), errmsg(), ERROR, executeNextItem(), JsonBaseObjectInfo::id, int64_to_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().

1938 {
1941  JsonbContainer *jbc;
1942  JsonbValue key;
1943  JsonbValue val;
1944  JsonbValue idval;
1945  JsonbValue keystr;
1946  JsonbValue valstr;
1947  JsonbValue idstr;
1948  JsonbIterator *it;
1949  JsonbIteratorToken tok;
1950  int64 id;
1951  bool hasNext;
1952 
1953  if (JsonbType(jb) != jbvObject || jb->type != jbvBinary)
1955  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
1956  errmsg("jsonpath item method .%s() can only be applied to an object",
1957  jspOperationName(jsp->type)))));
1958 
1959  jbc = jb->val.binary.data;
1960 
1961  if (!JsonContainerSize(jbc))
1962  return jperNotFound; /* no key-value pairs */
1963 
1964  hasNext = jspGetNext(jsp, &next);
1965 
1966  keystr.type = jbvString;
1967  keystr.val.string.val = "key";
1968  keystr.val.string.len = 3;
1969 
1970  valstr.type = jbvString;
1971  valstr.val.string.val = "value";
1972  valstr.val.string.len = 5;
1973 
1974  idstr.type = jbvString;
1975  idstr.val.string.val = "id";
1976  idstr.val.string.len = 2;
1977 
1978  /* construct object id from its base object and offset inside that */
1979  id = jb->type != jbvBinary ? 0 :
1980  (int64) ((char *) jbc - (char *) cxt->baseObject.jbc);
1981  id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
1982 
1983  idval.type = jbvNumeric;
1984  idval.val.numeric = int64_to_numeric(id);
1985 
1986  it = JsonbIteratorInit(jbc);
1987 
1988  while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
1989  {
1990  JsonBaseObjectInfo baseObject;
1991  JsonbValue obj;
1992  JsonbParseState *ps;
1993  JsonbValue *keyval;
1994  Jsonb *jsonb;
1995 
1996  if (tok != WJB_KEY)
1997  continue;
1998 
1999  res = jperOk;
2000 
2001  if (!hasNext && !found)
2002  break;
2003 
2004  tok = JsonbIteratorNext(&it, &val, true);
2005  Assert(tok == WJB_VALUE);
2006 
2007  ps = NULL;
2008  pushJsonbValue(&ps, WJB_BEGIN_OBJECT, NULL);
2009 
2010  pushJsonbValue(&ps, WJB_KEY, &keystr);
2011  pushJsonbValue(&ps, WJB_VALUE, &key);
2012 
2013  pushJsonbValue(&ps, WJB_KEY, &valstr);
2014  pushJsonbValue(&ps, WJB_VALUE, &val);
2015 
2016  pushJsonbValue(&ps, WJB_KEY, &idstr);
2017  pushJsonbValue(&ps, WJB_VALUE, &idval);
2018 
2019  keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
2020 
2021  jsonb = JsonbValueToJsonb(keyval);
2022 
2023  JsonbInitBinary(&obj, jsonb);
2024 
2025  baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++);
2026 
2027  res = executeNextItem(cxt, jsp, &next, &obj, found, true);
2028 
2029  cxt->baseObject = baseObject;
2030 
2031  if (jperIsError(res))
2032  return res;
2033 
2034  if (res == jperOk && !found)
2035  break;
2036  }
2037 
2038  return res;
2039 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
static int JsonbType(JsonbValue *jb)
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:85
Definition: jsonb.h:220
static int32 next
Definition: blutils.c:219
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:691
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:97
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:559
#define ERROR
Definition: elog.h:43
JsonPathExecResult
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4079
#define JsonContainerSize(jc)
Definition: jsonb.h:214
Definition: jsonb.h:23
JsonbIteratorToken
Definition: jsonb.h:20
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
JsonbContainer * jbc
Definition: jsonpath_exec.c:85
#define ereport(elevel,...)
Definition: elog.h:155
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:800
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:760
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:902
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
long val
Definition: informix.c:664
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:796

◆ executeLikeRegex()

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

Definition at line 1709 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().

1711 {
1712  JsonLikeRegexContext *cxt = param;
1713 
1714  if (!(str = getScalar(str, jbvString)))
1715  return jpbUnknown;
1716 
1717  /* Cache regex text and converted flags. */
1718  if (!cxt->regex)
1719  {
1720  cxt->regex =
1722  jsp->content.like_regex.patternlen);
1723  cxt->cflags = jspConvertRegexFlags(jsp->content.like_regex.flags);
1724  }
1725 
1726  if (RE_compile_and_execute(cxt->regex, str->val.string.val,
1727  str->val.string.len,
1728  cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
1729  return jpbTrue;
1730 
1731  return jpbFalse;
1732 }
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:200
union JsonPathItem::@128 content
int jspConvertRegexFlags(uint32 xflags)
struct JsonPathItem::@128::@133 like_regex

◆ executeNestedBoolItem()

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

Definition at line 1355 of file jsonpath_exec.c.

References JsonPathExecContext::current, and executeBoolItem().

Referenced by executeItemOptUnwrapTarget().

1357 {
1358  JsonbValue *prev;
1359  JsonPathBool res;
1360 
1361  prev = cxt->current;
1362  cxt->current = jb;
1363  res = executeBoolItem(cxt, jsp, jb, false);
1364  cxt->current = prev;
1365 
1366  return res;
1367 }
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
JsonPathBool
JsonbValue * current
Definition: jsonpath_exec.c:96

◆ executeNextItem()

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

Definition at line 1139 of file jsonpath_exec.c.

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

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

1142 {
1143  JsonPathItem elem;
1144  bool hasNext;
1145 
1146  if (!cur)
1147  hasNext = next != NULL;
1148  else if (next)
1149  hasNext = jspHasNext(cur);
1150  else
1151  {
1152  next = &elem;
1153  hasNext = jspGetNext(cur, next);
1154  }
1155 
1156  if (hasNext)
1157  return executeItem(cxt, next, v, found);
1158 
1159  if (found)
1160  JsonValueListAppend(found, copy ? copyJsonbValue(v) : v);
1161 
1162  return jperOk;
1163 }
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 1739 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().

1742 {
1744  Datum datum;
1745 
1746  if (unwrap && JsonbType(jb) == jbvArray)
1747  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1748 
1749  if (!(jb = getScalar(jb, jbvNumeric)))
1751  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1752  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1753  jspOperationName(jsp->type)))));
1754 
1755  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
1756 
1757  if (!jspGetNext(jsp, &next) && !found)
1758  return jperOk;
1759 
1760  jb = palloc(sizeof(*jb));
1761  jb->type = jbvNumeric;
1762  jb->val.numeric = DatumGetNumeric(datum);
1763 
1764  return executeNextItem(cxt, jsp, &next, jb, found, false);
1765 }
#define RETURN_ERROR(throw_error)
static int JsonbType(JsonbValue *jb)
static int32 next
Definition: blutils.c:219
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:691
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
#define ERROR
Definition: elog.h:43
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:155
#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:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
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 1467 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

1471 {
1472  JsonPathExecResult res;
1473  JsonValueListIterator lseqit;
1474  JsonValueList lseq = {0};
1475  JsonValueList rseq = {0};
1476  JsonbValue *lval;
1477  bool error = false;
1478  bool found = false;
1479 
1480  /* Left argument is always auto-unwrapped. */
1481  res = executeItemOptUnwrapResultNoThrow(cxt, larg, jb, true, &lseq);
1482  if (jperIsError(res))
1483  return jpbUnknown;
1484 
1485  if (rarg)
1486  {
1487  /* Right argument is conditionally auto-unwrapped. */
1488  res = executeItemOptUnwrapResultNoThrow(cxt, rarg, jb,
1489  unwrapRightArg, &rseq);
1490  if (jperIsError(res))
1491  return jpbUnknown;
1492  }
1493 
1494  JsonValueListInitIterator(&lseq, &lseqit);
1495  while ((lval = JsonValueListNext(&lseq, &lseqit)))
1496  {
1497  JsonValueListIterator rseqit;
1498  JsonbValue *rval;
1499  bool first = true;
1500 
1501  JsonValueListInitIterator(&rseq, &rseqit);
1502  if (rarg)
1503  rval = JsonValueListNext(&rseq, &rseqit);
1504  else
1505  rval = NULL;
1506 
1507  /* Loop over right arg sequence or do single pass otherwise */
1508  while (rarg ? (rval != NULL) : first)
1509  {
1510  JsonPathBool res = exec(pred, lval, rval, param);
1511 
1512  if (res == jpbUnknown)
1513  {
1514  if (jspStrictAbsenseOfErrors(cxt))
1515  return jpbUnknown;
1516 
1517  error = true;
1518  }
1519  else if (res == jpbTrue)
1520  {
1521  if (!jspStrictAbsenseOfErrors(cxt))
1522  return jpbTrue;
1523 
1524  found = true;
1525  }
1526 
1527  first = false;
1528  if (rarg)
1529  rval = JsonValueListNext(&rseq, &rseqit);
1530  }
1531  }
1532 
1533  if (found) /* possible only in strict mode */
1534  return jpbTrue;
1535 
1536  if (error) /* possible only in lax mode */
1537  return jpbUnknown;
1538 
1539  return jpbFalse;
1540 }
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 1685 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

1687 {
1688  if (!(whole = getScalar(whole, jbvString)))
1689  return jpbUnknown; /* error */
1690 
1691  if (!(initial = getScalar(initial, jbvString)))
1692  return jpbUnknown; /* error */
1693 
1694  if (whole->val.string.len >= initial->val.string.len &&
1695  !memcmp(whole->val.string.val,
1696  initial->val.string.val,
1697  initial->val.string.len))
1698  return jpbTrue;
1699 
1700  return jpbFalse;
1701 }
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 1618 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().

1620 {
1621  JsonPathExecResult jper;
1622  JsonPathExecResult jper2;
1623  JsonPathItem elem;
1624  JsonValueList seq = {0};
1626  JsonbValue *val;
1627  bool hasNext;
1628 
1629  jspGetArg(jsp, &elem);
1630  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &seq);
1631 
1632  if (jperIsError(jper))
1633  return jper;
1634 
1635  jper = jperNotFound;
1636 
1637  hasNext = jspGetNext(jsp, &elem);
1638 
1639  JsonValueListInitIterator(&seq, &it);
1640  while ((val = JsonValueListNext(&seq, &it)))
1641  {
1642  if ((val = getScalar(val, jbvNumeric)))
1643  {
1644  if (!found && !hasNext)
1645  return jperOk;
1646  }
1647  else
1648  {
1649  if (!found && !hasNext)
1650  continue; /* skip non-numerics processing */
1651 
1653  (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),
1654  errmsg("operand of unary jsonpath operator %s is not a numeric value",
1655  jspOperationName(jsp->type)))));
1656  }
1657 
1658  if (func)
1659  val->val.numeric =
1661  NumericGetDatum(val->val.numeric)));
1662 
1663  jper2 = executeNextItem(cxt, jsp, &elem, val, found, false);
1664 
1665  if (jperIsError(jper2))
1666  return jper2;
1667 
1668  if (jper2 == jperOk)
1669  {
1670  if (!found)
1671  return jperOk;
1672  jper = jperOk;
1673  }
1674  }
1675 
1676  return jper;
1677 }
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:691
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
#define ERROR
Definition: elog.h:43
JsonPathExecResult
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
#define ereport(elevel,...)
Definition: elog.h:155
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonPathItemType type
Definition: jsonpath.h:107
int errmsg(const char *fmt,...)
Definition: elog.c:902
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:664

◆ getArrayIndex()

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

Definition at line 2386 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().

2388 {
2389  JsonbValue *jbv;
2390  JsonValueList found = {0};
2391  JsonPathExecResult res = executeItem(cxt, jsp, jb, &found);
2392  Datum numeric_index;
2393  bool have_error = false;
2394 
2395  if (jperIsError(res))
2396  return res;
2397 
2398  if (JsonValueListLength(&found) != 1 ||
2399  !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric)))
2401  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2402  errmsg("jsonpath array subscript is not a single numeric value"))));
2403 
2404  numeric_index = DirectFunctionCall2(numeric_trunc,
2405  NumericGetDatum(jbv->val.numeric),
2406  Int32GetDatum(0));
2407 
2408  *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index),
2409  &have_error);
2410 
2411  if (have_error)
2413  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2414  errmsg("jsonpath array subscript is out of integer range"))));
2415 
2416  return jperOk;
2417 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
Datum numeric_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:1457
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
int errcode(int sqlerrcode)
Definition: elog.c:691
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)
int32 numeric_int4_opt_error(Numeric num, bool *have_error)
Definition: numeric.c:4104
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:155
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:902
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ getJsonPathItem()

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

Definition at line 2074 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().

2076 {
2077  switch (item->type)
2078  {
2079  case jpiNull:
2080  value->type = jbvNull;
2081  break;
2082  case jpiBool:
2083  value->type = jbvBool;
2084  value->val.boolean = jspGetBool(item);
2085  break;
2086  case jpiNumeric:
2087  value->type = jbvNumeric;
2088  value->val.numeric = jspGetNumeric(item);
2089  break;
2090  case jpiString:
2091  value->type = jbvString;
2092  value->val.string.val = jspGetString(item,
2093  &value->val.string.len);
2094  break;
2095  case jpiVariable:
2096  getJsonPathVariable(cxt, item, cxt->vars, value);
2097  return;
2098  default:
2099  elog(ERROR, "unexpected jsonpath item type");
2100  }
2101 }
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:228
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 2107 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().

2109 {
2110  char *varName;
2111  int varNameLength;
2112  JsonbValue tmp;
2113  JsonbValue *v;
2114 
2115  if (!vars)
2116  {
2117  value->type = jbvNull;
2118  return;
2119  }
2120 
2121  Assert(variable->type == jpiVariable);
2122  varName = jspGetString(variable, &varNameLength);
2123  tmp.type = jbvString;
2124  tmp.val.string.val = varName;
2125  tmp.val.string.len = varNameLength;
2126 
2127  v = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
2128 
2129  if (v)
2130  {
2131  *value = *v;
2132  pfree(v);
2133  }
2134  else
2135  {
2136  ereport(ERROR,
2137  (errcode(ERRCODE_UNDEFINED_OBJECT),
2138  errmsg("could not find jsonpath variable \"%s\"",
2139  pnstrdup(varName, varNameLength))));
2140  }
2141 
2142  JsonbInitBinary(&tmp, vars);
2143  setBaseObject(cxt, &tmp, 1);
2144 }
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1198
char * val
Definition: jsonb.h:272
int errcode(int sqlerrcode)
Definition: elog.c:691
Definition: jsonb.h:236
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:43
JsonbContainer root
Definition: jsonb.h:223
#define ereport(elevel,...)
Definition: elog.h:155
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:800
#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:902
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:337
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1050

◆ getScalar()

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

Definition at line 2558 of file jsonpath_exec.c.

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

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

2559 {
2560  /* Scalars should be always extracted during jsonpath execution. */
2561  Assert(scalar->type != jbvBinary ||
2562  !JsonContainerIsScalar(scalar->val.binary.data));
2563 
2564  return scalar->type == type ? scalar : NULL;
2565 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define Assert(condition)
Definition: c.h:800
enum jbvType type
Definition: jsonb.h:263

◆ jsonb_path_exists()

Datum jsonb_path_exists ( PG_FUNCTION_ARGS  )

Definition at line 298 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

299 {
300  return jsonb_path_exists_internal(fcinfo, false);
301 }
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 272 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().

273 {
274  Jsonb *jb = PG_GETARG_JSONB_P(0);
276  JsonPathExecResult res;
277  Jsonb *vars = NULL;
278  bool silent = true;
279 
280  if (PG_NARGS() == 4)
281  {
282  vars = PG_GETARG_JSONB_P(2);
283  silent = PG_GETARG_BOOL(3);
284  }
285 
286  res = executeJsonPath(jp, vars, jb, !silent, NULL, tz);
287 
288  PG_FREE_IF_COPY(jb, 0);
289  PG_FREE_IF_COPY(jp, 1);
290 
291  if (jperIsError(res))
292  PG_RETURN_NULL();
293 
294  PG_RETURN_BOOL(res == jperOk);
295 }
#define jperIsError(jper)
Definition: jsonb.h:220
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
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:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_NARGS()
Definition: fmgr.h:203
Definition: regcomp.c:224
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#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 315 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

316 {
317  /* just call the other one -- it can handle both cases */
318  return jsonb_path_exists_internal(fcinfo, false);
319 }
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 304 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

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

◆ jsonb_path_match()

Datum jsonb_path_match ( PG_FUNCTION_ARGS  )

Definition at line 366 of file jsonpath_exec.c.

References jsonb_path_match_internal().

367 {
368  return jsonb_path_match_internal(fcinfo, false);
369 }
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 327 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().

328 {
329  Jsonb *jb = PG_GETARG_JSONB_P(0);
331  JsonValueList found = {0};
332  Jsonb *vars = NULL;
333  bool silent = true;
334 
335  if (PG_NARGS() == 4)
336  {
337  vars = PG_GETARG_JSONB_P(2);
338  silent = PG_GETARG_BOOL(3);
339  }
340 
341  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
342 
343  PG_FREE_IF_COPY(jb, 0);
344  PG_FREE_IF_COPY(jp, 1);
345 
346  if (JsonValueListLength(&found) == 1)
347  {
348  JsonbValue *jbv = JsonValueListHead(&found);
349 
350  if (jbv->type == jbvBool)
351  PG_RETURN_BOOL(jbv->val.boolean);
352 
353  if (jbv->type == jbvNull)
354  PG_RETURN_NULL();
355  }
356 
357  if (!silent)
358  ereport(ERROR,
359  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
360  errmsg("single boolean result is expected")));
361 
362  PG_RETURN_NULL();
363 }
Definition: jsonb.h:220
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
int errcode(int sqlerrcode)
Definition: elog.c:691
Definition: jsonb.h:236
static int JsonValueListLength(const JsonValueList *jvl)
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define ERROR
Definition: elog.h:43
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_BOOL(x)
Definition: fmgr.h:359
#define ereport(elevel,...)
Definition: elog.h:155
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_NARGS()
Definition: fmgr.h:203
enum jbvType type
Definition: jsonb.h:263
int errmsg(const char *fmt,...)
Definition: elog.c:902
Definition: regcomp.c:224
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#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 383 of file jsonpath_exec.c.

References jsonb_path_match_internal().

384 {
385  /* just call the other one -- it can handle both cases */
386  return jsonb_path_match_internal(fcinfo, false);
387 }
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 372 of file jsonpath_exec.c.

References jsonb_path_match_internal().

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

◆ jsonb_path_query()

Datum jsonb_path_query ( PG_FUNCTION_ARGS  )

Definition at line 441 of file jsonpath_exec.c.

References jsonb_path_query_internal().

442 {
443  return jsonb_path_query_internal(fcinfo, false);
444 }
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 472 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

473 {
474  return jsonb_path_query_array_internal(fcinfo, false);
475 }
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 458 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().

459 {
460  Jsonb *jb = PG_GETARG_JSONB_P(0);
462  JsonValueList found = {0};
464  bool silent = PG_GETARG_BOOL(3);
465 
466  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
467 
469 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:85
Definition: jsonb.h:220
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
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 478 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

479 {
480  return jsonb_path_query_array_internal(fcinfo, true);
481 }
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 506 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

507 {
508  return jsonb_path_query_first_internal(fcinfo, false);
509 }
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 489 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().

490 {
491  Jsonb *jb = PG_GETARG_JSONB_P(0);
493  JsonValueList found = {0};
495  bool silent = PG_GETARG_BOOL(3);
496 
497  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
498 
499  if (JsonValueListLength(&found) >= 1)
501  else
502  PG_RETURN_NULL();
503 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:85
Definition: jsonb.h:220
static int JsonValueListLength(const JsonValueList *jvl)
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
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:345
#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 512 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

513 {
514  return jsonb_path_query_first_internal(fcinfo, true);
515 }
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 395 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().

396 {
397  FuncCallContext *funcctx;
398  List *found;
399  JsonbValue *v;
400  ListCell *c;
401 
402  if (SRF_IS_FIRSTCALL())
403  {
404  JsonPath *jp;
405  Jsonb *jb;
406  MemoryContext oldcontext;
407  Jsonb *vars;
408  bool silent;
409  JsonValueList found = {0};
410 
411  funcctx = SRF_FIRSTCALL_INIT();
412  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
413 
414  jb = PG_GETARG_JSONB_P_COPY(0);
416  vars = PG_GETARG_JSONB_P_COPY(2);
417  silent = PG_GETARG_BOOL(3);
418 
419  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
420 
421  funcctx->user_fctx = JsonValueListGetList(&found);
422 
423  MemoryContextSwitchTo(oldcontext);
424  }
425 
426  funcctx = SRF_PERCALL_SETUP();
427  found = funcctx->user_fctx;
428 
429  c = list_head(found);
430 
431  if (c == NULL)
432  SRF_RETURN_DONE(funcctx);
433 
434  v = lfirst(c);
435  funcctx->user_fctx = list_delete_first(found);
436 
438 }
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:85
Definition: jsonb.h:220
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:294
#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:274
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:298
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:300
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:169
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
void * user_fctx
Definition: funcapi.h:82
Definition: regcomp.c:224
Definition: pg_list.h:50
List * list_delete_first(List *list)
Definition: list.c:860
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:318
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:296

◆ jsonb_path_query_tz()

Datum jsonb_path_query_tz ( PG_FUNCTION_ARGS  )

Definition at line 447 of file jsonpath_exec.c.

References jsonb_path_query_internal().

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

◆ JsonbArraySize()

static int JsonbArraySize ( JsonbValue jb)
static

Definition at line 2152 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

2153 {
2154  Assert(jb->type != jbvArray);
2155 
2156  if (jb->type == jbvBinary)
2157  {
2158  JsonbContainer *jbc = jb->val.binary.data;
2159 
2160  if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
2161  return JsonContainerSize(jbc);
2162  }
2163 
2164  return -1;
2165 }
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:800
enum jbvType type
Definition: jsonb.h:263

◆ JsonbInitBinary()

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

Definition at line 2521 of file jsonpath_exec.c.

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

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

2522 {
2523  jbv->type = jbvBinary;
2524  jbv->val.binary.data = &jb->root;
2525  jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb);
2526 
2527  return jbv;
2528 }
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 2534 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().

2535 {
2536  int type = jb->type;
2537 
2538  if (jb->type == jbvBinary)
2539  {
2540  JsonbContainer *jbc = (void *) jb->val.binary.data;
2541 
2542  /* Scalars should be always extracted during jsonpath execution. */
2544 
2545  if (JsonContainerIsObject(jbc))
2546  type = jbvObject;
2547  else if (JsonContainerIsArray(jbc))
2548  type = jbvArray;
2549  else
2550  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
2551  }
2552 
2553  return type;
2554 }
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:800
enum jbvType type
Definition: jsonb.h:263
#define elog(elevel,...)
Definition: elog.h:228

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 2433 of file jsonpath_exec.c.

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

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

2434 {
2435  if (jvl->singleton)
2436  {
2437  jvl->list = list_make2(jvl->singleton, jbv);
2438  jvl->singleton = NULL;
2439  }
2440  else if (!jvl->list)
2441  jvl->singleton = jbv;
2442  else
2443  jvl->list = lappend(jvl->list, jbv);
2444 }
#define list_make2(x1, x2)
Definition: pg_list.h:208
List * lappend(List *list, void *datum)
Definition: list.c:321
JsonbValue * singleton

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 2465 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_internal().

2466 {
2467  if (jvl->singleton)
2468  return list_make1(jvl->singleton);
2469 
2470  return jvl->list;
2471 }
#define list_make1(x1)
Definition: pg_list.h:206
JsonbValue * singleton

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

Definition at line 2459 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().

2460 {
2461  return jvl->singleton ? jvl->singleton : linitial(jvl->list);
2462 }
#define linitial(l)
Definition: pg_list.h:174
JsonbValue * singleton

◆ JsonValueListInitIterator()

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

Definition at line 2474 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().

2475 {
2476  if (jvl->singleton)
2477  {
2478  it->value = jvl->singleton;
2479  it->list = NIL;
2480  it->next = NULL;
2481  }
2482  else if (jvl->list != NIL)
2483  {
2484  it->value = (JsonbValue *) linitial(jvl->list);
2485  it->list = jvl->list;
2486  it->next = list_second_cell(jvl->list);
2487  }
2488  else
2489  {
2490  it->value = NULL;
2491  it->list = NIL;
2492  it->next = NULL;
2493  }
2494 }
#define NIL
Definition: pg_list.h:65
#define linitial(l)
Definition: pg_list.h:174
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 2453 of file jsonpath_exec.c.

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

Referenced by executeBoolItem(), and executeJsonPath().

2454 {
2455  return !jvl->singleton && list_length(jvl->list) <= 0;
2456 }
JsonbValue * singleton
static int list_length(const List *l)
Definition: pg_list.h:149

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

Definition at line 2447 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().

2448 {
2449  return jvl->singleton ? 1 : list_length(jvl->list);
2450 }
JsonbValue * singleton
static int list_length(const List *l)
Definition: pg_list.h:149

◆ JsonValueListNext()

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

Definition at line 2500 of file jsonpath_exec.c.

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

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

2501 {
2502  JsonbValue *result = it->value;
2503 
2504  if (it->next)
2505  {
2506  it->value = lfirst(it->next);
2507  it->next = lnext(it->list, it->next);
2508  }
2509  else
2510  {
2511  it->value = NULL;
2512  }
2513 
2514  return result;
2515 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:310
#define lfirst(lc)
Definition: pg_list.h:169

◆ setBaseObject()

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

Definition at line 2421 of file jsonpath_exec.c.

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

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

2422 {
2423  JsonBaseObjectInfo baseObject = cxt->baseObject;
2424 
2425  cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
2426  (JsonbContainer *) jbv->val.binary.data;
2427  cxt->baseObject.id = id;
2428 
2429  return baseObject;
2430 }
char * val
Definition: jsonb.h:272
JsonBaseObjectInfo baseObject
Definition: jsonpath_exec.c:97
JsonbContainer * jbc
Definition: jsonpath_exec.c:85
enum jbvType type
Definition: jsonb.h:263

◆ wrapItemsInArray()

static JsonbValue * wrapItemsInArray ( const JsonValueList items)
static

Definition at line 2569 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().

2570 {
2571  JsonbParseState *ps = NULL;
2573  JsonbValue *jbv;
2574 
2575  pushJsonbValue(&ps, WJB_BEGIN_ARRAY, NULL);
2576 
2577  JsonValueListInitIterator(items, &it);
2578  while ((jbv = JsonValueListNext(items, &it)))
2579  pushJsonbValue(&ps, WJB_ELEM, jbv);
2580 
2581  return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
2582 }
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:559
Definition: jsonb.h:25