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 cmpTimestampWithOverflow (Timestamp ts1, int overflow1, Timestamp ts2)
 
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 2044 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

References cmp(), and Min.

Referenced by compareStrings().

2180 {
2181  int cmp;
2182 
2183  cmp = memcmp(s1, s2, Min(len1, len2));
2184 
2185  if (cmp != 0)
2186  return cmp;
2187 
2188  if (len1 == len2)
2189  return 0;
2190 
2191  return len1 < len2 ? -1 : 1;
2192 }
#define Min(x, y)
Definition: c.h:920
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 2596 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

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

◆ checkTimezoneIsUsedForCast()

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

Definition at line 2584 of file jsonpath_exec.c.

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

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

2585 {
2586  if (!useTz)
2587  ereport(ERROR,
2588  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2589  errmsg("cannot convert value from %s to %s without timezone usage",
2590  type1, type2),
2591  errhint("Use *_tz() function for timezone support.")));
2592 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ cmpDateToTimestamp()

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

Definition at line 2650 of file jsonpath_exec.c.

References cmpTimestampWithOverflow(), and date2timestamp_opt_overflow().

Referenced by compareDatetime().

2651 {
2652  TimestampTz ts1;
2653  int overflow = 0;
2654 
2655  ts1 = date2timestamp_opt_overflow(date1, &overflow);
2656 
2657  return cmpTimestampWithOverflow(ts1, overflow, ts2);
2658 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
Timestamp date2timestamp_opt_overflow(DateADT dateVal, int *overflow)
Definition: date.c:563

◆ cmpDateToTimestampTz()

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

Definition at line 2664 of file jsonpath_exec.c.

References checkTimezoneIsUsedForCast(), cmpTimestampWithOverflow(), and date2timestamptz_opt_overflow().

Referenced by compareDatetime().

2665 {
2666  TimestampTz tstz1;
2667  int overflow = 0;
2668 
2669  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
2670 
2671  tstz1 = date2timestamptz_opt_overflow(date1, &overflow);
2672 
2673  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2674 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
TimestampTz date2timestamptz_opt_overflow(DateADT dateVal, int *overflow)
Definition: date.c:617
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

◆ cmpTimestampToTimestampTz()

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

Definition at line 2680 of file jsonpath_exec.c.

References checkTimezoneIsUsedForCast(), cmpTimestampWithOverflow(), and timestamp2timestamptz_opt_overflow().

Referenced by compareDatetime().

2681 {
2682  TimestampTz tstz1;
2683  int overflow = 0;
2684 
2685  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
2686 
2687  tstz1 = timestamp2timestamptz_opt_overflow(ts1, &overflow);
2688 
2689  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2690 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:5182
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

◆ cmpTimestampWithOverflow()

static int cmpTimestampWithOverflow ( Timestamp  ts1,
int  overflow1,
Timestamp  ts2 
)
static

Definition at line 2613 of file jsonpath_exec.c.

References Assert, IS_VALID_TIMESTAMP, timestamp_cmp_internal(), TIMESTAMP_IS_NOBEGIN, and TIMESTAMP_IS_NOEND.

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

2614 {
2615  /*
2616  * All the timestamps we deal with in jsonpath are produced by
2617  * to_datetime() method. So, they should be valid.
2618  */
2619  Assert(IS_VALID_TIMESTAMP(ts2));
2620 
2621  /*
2622  * Timestamp, which exceed lower (upper) bound, is always lower (higher)
2623  * than any valid timestamp except minus (plus) infinity.
2624  */
2625  if (overflow1)
2626  {
2627  if (overflow1 < 0)
2628  {
2629  if (TIMESTAMP_IS_NOBEGIN(ts2))
2630  return 1;
2631  else
2632  return -1;
2633  }
2634  if (overflow1 > 0)
2635  {
2636  if (TIMESTAMP_IS_NOEND(ts2))
2637  return -1;
2638  else
2639  return 1;
2640  }
2641  }
2642 
2643  return timestamp_cmp_internal(ts1, ts2);
2644 }
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2052
#define Assert(condition)
Definition: c.h:738
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:120
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:115

◆ compareDatetime()

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

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

2700 {
2701  PGFunction cmpfunc;
2702 
2703  *cast_error = false;
2704 
2705  switch (typid1)
2706  {
2707  case DATEOID:
2708  switch (typid2)
2709  {
2710  case DATEOID:
2711  cmpfunc = date_cmp;
2712 
2713  break;
2714 
2715  case TIMESTAMPOID:
2716  return cmpDateToTimestamp(DatumGetDateADT(val1),
2717  DatumGetTimestamp(val2),
2718  useTz);
2719 
2720  case TIMESTAMPTZOID:
2722  DatumGetTimestampTz(val2),
2723  useTz);
2724 
2725  case TIMEOID:
2726  case TIMETZOID:
2727  *cast_error = true; /* uncomparable types */
2728  return 0;
2729 
2730  default:
2731  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2732  typid2);
2733  }
2734  break;
2735 
2736  case TIMEOID:
2737  switch (typid2)
2738  {
2739  case TIMEOID:
2740  cmpfunc = time_cmp;
2741 
2742  break;
2743 
2744  case TIMETZOID:
2745  val1 = castTimeToTimeTz(val1, useTz);
2746  cmpfunc = timetz_cmp;
2747 
2748  break;
2749 
2750  case DATEOID:
2751  case TIMESTAMPOID:
2752  case TIMESTAMPTZOID:
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 TIMETZOID:
2763  switch (typid2)
2764  {
2765  case TIMEOID:
2766  val2 = castTimeToTimeTz(val2, useTz);
2767  cmpfunc = timetz_cmp;
2768 
2769  break;
2770 
2771  case TIMETZOID:
2772  cmpfunc = timetz_cmp;
2773 
2774  break;
2775 
2776  case DATEOID:
2777  case TIMESTAMPOID:
2778  case TIMESTAMPTZOID:
2779  *cast_error = true; /* uncomparable types */
2780  return 0;
2781 
2782  default:
2783  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2784  typid2);
2785  }
2786  break;
2787 
2788  case TIMESTAMPOID:
2789  switch (typid2)
2790  {
2791  case DATEOID:
2792  return -cmpDateToTimestamp(DatumGetDateADT(val2),
2793  DatumGetTimestamp(val1),
2794  useTz);
2795 
2796  case TIMESTAMPOID:
2797  cmpfunc = timestamp_cmp;
2798 
2799  break;
2800 
2801  case TIMESTAMPTZOID:
2803  DatumGetTimestampTz(val2),
2804  useTz);
2805 
2806  case TIMEOID:
2807  case TIMETZOID:
2808  *cast_error = true; /* uncomparable types */
2809  return 0;
2810 
2811  default:
2812  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2813  typid2);
2814  }
2815  break;
2816 
2817  case TIMESTAMPTZOID:
2818  switch (typid2)
2819  {
2820  case DATEOID:
2821  return -cmpDateToTimestampTz(DatumGetDateADT(val2),
2822  DatumGetTimestampTz(val1),
2823  useTz);
2824 
2825  case TIMESTAMPOID:
2827  DatumGetTimestampTz(val1),
2828  useTz);
2829 
2830  case TIMESTAMPTZOID:
2831  cmpfunc = timestamp_cmp;
2832 
2833  break;
2834 
2835  case TIMEOID:
2836  case TIMETZOID:
2837  *cast_error = true; /* uncomparable types */
2838  return 0;
2839 
2840  default:
2841  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2842  typid2);
2843  }
2844  break;
2845 
2846  default:
2847  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);
2848  }
2849 
2850  if (*cast_error)
2851  return 0; /* cast error */
2852 
2853  return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2));
2854 }
static Datum castTimeToTimeTz(Datum time, bool useTz)
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2331
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:2112
#define ERROR
Definition: elog.h:43
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1587
#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:429
#define elog(elevel,...)
Definition: elog.h:214
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:626
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 2266 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().

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

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

Referenced by compareItems().

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

◆ compareStrings()

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

Definition at line 2199 of file jsonpath_exec.c.

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

Referenced by compareItems().

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

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

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

◆ executeAnyItem()

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

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

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

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

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

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

Referenced by executeBoolItem().

2168 {
2170 
2171  return compareItems(cmp->type, lv, rv, cxt->useTz);
2172 }
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 1778 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().

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

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

References executeItemOptUnwrapResult(), and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

1212 {
1213  JsonPathExecResult res;
1214  bool throwErrors = cxt->throwErrors;
1215 
1216  cxt->throwErrors = false;
1217  res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found);
1218  cxt->throwErrors = throwErrors;
1219 
1220  return res;
1221 }
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, Int32GetDatum, int4_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 =
847  Int32GetDatum(last)));
848 
849  res = executeNextItem(cxt, jsp, &elem,
850  lastjbv, found, hasNext);
851  }
852  break;
853 
854  case jpiAnyKey:
855  if (JsonbType(jb) == jbvObject)
856  {
857  bool hasNext = jspGetNext(jsp, &elem);
858 
859  if (jb->type != jbvBinary)
860  elog(ERROR, "invalid jsonb object type: %d", jb->type);
861 
862  return executeAnyItem
863  (cxt, hasNext ? &elem : NULL,
864  jb->val.binary.data, found, 1, 1, 1,
865  false, jspAutoUnwrap(cxt));
866  }
867  else if (unwrap && JsonbType(jb) == jbvArray)
868  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
869  else if (!jspIgnoreStructuralErrors(cxt))
870  {
871  Assert(found);
873  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
874  errmsg("jsonpath wildcard member accessor can only be applied to an object"))));
875  }
876  break;
877 
878  case jpiAdd:
879  return executeBinaryArithmExpr(cxt, jsp, jb,
880  numeric_add_opt_error, found);
881 
882  case jpiSub:
883  return executeBinaryArithmExpr(cxt, jsp, jb,
884  numeric_sub_opt_error, found);
885 
886  case jpiMul:
887  return executeBinaryArithmExpr(cxt, jsp, jb,
888  numeric_mul_opt_error, found);
889 
890  case jpiDiv:
891  return executeBinaryArithmExpr(cxt, jsp, jb,
892  numeric_div_opt_error, found);
893 
894  case jpiMod:
895  return executeBinaryArithmExpr(cxt, jsp, jb,
896  numeric_mod_opt_error, found);
897 
898  case jpiPlus:
899  return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found);
900 
901  case jpiMinus:
902  return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus,
903  found);
904 
905  case jpiFilter:
906  {
907  JsonPathBool st;
908 
909  if (unwrap && JsonbType(jb) == jbvArray)
910  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
911  false);
912 
913  jspGetArg(jsp, &elem);
914  st = executeNestedBoolItem(cxt, &elem, jb);
915  if (st != jpbTrue)
916  res = jperNotFound;
917  else
918  res = executeNextItem(cxt, jsp, NULL,
919  jb, found, true);
920  break;
921  }
922 
923  case jpiAny:
924  {
925  bool hasNext = jspGetNext(jsp, &elem);
926 
927  /* first try without any intermediate steps */
928  if (jsp->content.anybounds.first == 0)
929  {
930  bool savedIgnoreStructuralErrors;
931 
932  savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors;
933  cxt->ignoreStructuralErrors = true;
934  res = executeNextItem(cxt, jsp, &elem,
935  jb, found, true);
936  cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors;
937 
938  if (res == jperOk && !found)
939  break;
940  }
941 
942  if (jb->type == jbvBinary)
943  res = executeAnyItem
944  (cxt, hasNext ? &elem : NULL,
945  jb->val.binary.data, found,
946  1,
947  jsp->content.anybounds.first,
948  jsp->content.anybounds.last,
949  true, jspAutoUnwrap(cxt));
950  break;
951  }
952 
953  case jpiNull:
954  case jpiBool:
955  case jpiNumeric:
956  case jpiString:
957  case jpiVariable:
958  {
959  JsonbValue vbuf;
960  JsonbValue *v;
961  bool hasNext = jspGetNext(jsp, &elem);
962 
963  if (!hasNext && !found)
964  {
965  res = jperOk; /* skip evaluation */
966  break;
967  }
968 
969  v = hasNext ? &vbuf : palloc(sizeof(*v));
970 
971  baseObject = cxt->baseObject;
972  getJsonPathItem(cxt, jsp, v);
973 
974  res = executeNextItem(cxt, jsp, &elem,
975  v, found, hasNext);
976  cxt->baseObject = baseObject;
977  }
978  break;
979 
980  case jpiType:
981  {
982  JsonbValue *jbv = palloc(sizeof(*jbv));
983 
984  jbv->type = jbvString;
985  jbv->val.string.val = pstrdup(JsonbTypeName(jb));
986  jbv->val.string.len = strlen(jbv->val.string.val);
987 
988  res = executeNextItem(cxt, jsp, NULL, jbv,
989  found, false);
990  }
991  break;
992 
993  case jpiSize:
994  {
995  int size = JsonbArraySize(jb);
996 
997  if (size < 0)
998  {
999  if (!jspAutoWrap(cxt))
1000  {
1001  if (!jspIgnoreStructuralErrors(cxt))
1003  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
1004  errmsg("jsonpath item method .%s() can only be applied to an array",
1005  jspOperationName(jsp->type)))));
1006  break;
1007  }
1008 
1009  size = 1;
1010  }
1011 
1012  jb = palloc(sizeof(*jb));
1013 
1014  jb->type = jbvNumeric;
1015  jb->val.numeric =
1017  Int32GetDatum(size)));
1018 
1019  res = executeNextItem(cxt, jsp, NULL, jb, found, false);
1020  }
1021  break;
1022 
1023  case jpiAbs:
1024  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs,
1025  found);
1026 
1027  case jpiFloor:
1028  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor,
1029  found);
1030 
1031  case jpiCeiling:
1032  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil,
1033  found);
1034 
1035  case jpiDouble:
1036  {
1037  JsonbValue jbv;
1038 
1039  if (unwrap && JsonbType(jb) == jbvArray)
1040  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1041  false);
1042 
1043  if (jb->type == jbvNumeric)
1044  {
1046  NumericGetDatum(jb->val.numeric)));
1047  bool have_error = false;
1048 
1049  (void) float8in_internal_opt_error(tmp,
1050  NULL,
1051  "double precision",
1052  tmp,
1053  &have_error);
1054 
1055  if (have_error)
1057  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1058  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1059  jspOperationName(jsp->type)))));
1060  res = jperOk;
1061  }
1062  else if (jb->type == jbvString)
1063  {
1064  /* cast string as double */
1065  double val;
1066  char *tmp = pnstrdup(jb->val.string.val,
1067  jb->val.string.len);
1068  bool have_error = false;
1069 
1070  val = float8in_internal_opt_error(tmp,
1071  NULL,
1072  "double precision",
1073  tmp,
1074  &have_error);
1075 
1076  if (have_error || isinf(val))
1078  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1079  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1080  jspOperationName(jsp->type)))));
1081 
1082  jb = &jbv;
1083  jb->type = jbvNumeric;
1085  Float8GetDatum(val)));
1086  res = jperOk;
1087  }
1088 
1089  if (res == jperNotFound)
1091  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1092  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1093  jspOperationName(jsp->type)))));
1094 
1095  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1096  }
1097  break;
1098 
1099  case jpiDatetime:
1100  if (unwrap && JsonbType(jb) == jbvArray)
1101  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1102 
1103  return executeDateTimeMethod(cxt, jsp, jb, found);
1104 
1105  case jpiKeyValue:
1106  if (unwrap && JsonbType(jb) == jbvArray)
1107  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1108 
1109  return executeKeyValueMethod(cxt, jsp, jb, found);
1110 
1111  default:
1112  elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
1113  }
1114 
1115  return res;
1116 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
#define jspIgnoreStructuralErrors(cxt)
static int JsonbType(JsonbValue *jb)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
Definition: jsonpath.h:50
static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
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:2422
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2594
char * pstrdup(const char *in)
Definition: mcxt.c:1186
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:649
#define jspHasNext(jsp)
Definition: jsonpath.h:164
int errcode(int sqlerrcode)
Definition: elog.c:610
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
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:2534
JsonPathBool
signed int int32
Definition: c.h:355
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:1056
Datum numeric_uminus(PG_FUNCTION_ARGS)
Definition: numeric.c:1123
Datum numeric_abs(PG_FUNCTION_ARGS)
Definition: numeric.c:1095
#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
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)
unsigned int uint32
Definition: c.h:367
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:1348
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
Datum int4_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3379
union JsonPathItem::@128 content
Datum float8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3569
Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2714
#define ereport(elevel,...)
Definition: elog.h:144
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:738
#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)
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
Datum numeric_ceil(PG_FUNCTION_ARGS)
Definition: numeric.c:1323
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2478
#define elog(elevel,...)
Definition: elog.h:214
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:391
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 1122 of file jsonpath_exec.c.

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

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

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

◆ 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:610
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:957
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:144
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define Assert(condition)
Definition: c.h:738
JsonbValue * current
Definition: jsonpath_exec.c:96
int errmsg(const char *fmt,...)
Definition: elog.c:824
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 1933 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

1935 {
1938  JsonbContainer *jbc;
1939  JsonbValue key;
1940  JsonbValue val;
1941  JsonbValue idval;
1942  JsonbValue keystr;
1943  JsonbValue valstr;
1944  JsonbValue idstr;
1945  JsonbIterator *it;
1946  JsonbIteratorToken tok;
1947  int64 id;
1948  bool hasNext;
1949 
1950  if (JsonbType(jb) != jbvObject || jb->type != jbvBinary)
1952  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
1953  errmsg("jsonpath item method .%s() can only be applied to an object",
1954  jspOperationName(jsp->type)))));
1955 
1956  jbc = jb->val.binary.data;
1957 
1958  if (!JsonContainerSize(jbc))
1959  return jperNotFound; /* no key-value pairs */
1960 
1961  hasNext = jspGetNext(jsp, &next);
1962 
1963  keystr.type = jbvString;
1964  keystr.val.string.val = "key";
1965  keystr.val.string.len = 3;
1966 
1967  valstr.type = jbvString;
1968  valstr.val.string.val = "value";
1969  valstr.val.string.len = 5;
1970 
1971  idstr.type = jbvString;
1972  idstr.val.string.val = "id";
1973  idstr.val.string.len = 2;
1974 
1975  /* construct object id from its base object and offset inside that */
1976  id = jb->type != jbvBinary ? 0 :
1977  (int64) ((char *) jbc - (char *) cxt->baseObject.jbc);
1978  id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
1979 
1980  idval.type = jbvNumeric;
1982  Int64GetDatum(id)));
1983 
1984  it = JsonbIteratorInit(jbc);
1985 
1986  while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
1987  {
1988  JsonBaseObjectInfo baseObject;
1989  JsonbValue obj;
1990  JsonbParseState *ps;
1991  JsonbValue *keyval;
1992  Jsonb *jsonb;
1993 
1994  if (tok != WJB_KEY)
1995  continue;
1996 
1997  res = jperOk;
1998 
1999  if (!hasNext && !found)
2000  break;
2001 
2002  tok = JsonbIteratorNext(&it, &val, true);
2003  Assert(tok == WJB_VALUE);
2004 
2005  ps = NULL;
2006  pushJsonbValue(&ps, WJB_BEGIN_OBJECT, NULL);
2007 
2008  pushJsonbValue(&ps, WJB_KEY, &keystr);
2009  pushJsonbValue(&ps, WJB_VALUE, &key);
2010 
2011  pushJsonbValue(&ps, WJB_KEY, &valstr);
2012  pushJsonbValue(&ps, WJB_VALUE, &val);
2013 
2014  pushJsonbValue(&ps, WJB_KEY, &idstr);
2015  pushJsonbValue(&ps, WJB_VALUE, &idval);
2016 
2017  keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
2018 
2019  jsonb = JsonbValueToJsonb(keyval);
2020 
2021  JsonbInitBinary(&obj, jsonb);
2022 
2023  baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++);
2024 
2025  res = executeNextItem(cxt, jsp, &next, &obj, found, true);
2026 
2027  cxt->baseObject = baseObject;
2028 
2029  if (jperIsError(res))
2030  return res;
2031 
2032  if (res == jperOk && !found)
2033  break;
2034  }
2035 
2036  return res;
2037 }
#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:218
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:610
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:3471
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
#define JsonContainerSize(jc)
Definition: jsonb.h:214
Definition: jsonb.h:23
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1701
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:144
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
#define DatumGetNumeric(X)
Definition: numeric.h:49
#define Assert(condition)
Definition: c.h:738
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:824
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 1712 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().

1714 {
1715  JsonLikeRegexContext *cxt = param;
1716 
1717  if (!(str = getScalar(str, jbvString)))
1718  return jpbUnknown;
1719 
1720  /* Cache regex text and converted flags. */
1721  if (!cxt->regex)
1722  {
1723  cxt->regex =
1725  jsp->content.like_regex.patternlen);
1726  cxt->cflags = jspConvertRegexFlags(jsp->content.like_regex.flags);
1727  }
1728 
1729  if (RE_compile_and_execute(cxt->regex, str->val.string.val,
1730  str->val.string.len,
1731  cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
1732  return jpbTrue;
1733 
1734  return jpbFalse;
1735 }
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:184
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 1358 of file jsonpath_exec.c.

References JsonPathExecContext::current, and executeBoolItem().

Referenced by executeItemOptUnwrapTarget().

1360 {
1361  JsonbValue *prev;
1362  JsonPathBool res;
1363 
1364  prev = cxt->current;
1365  cxt->current = jb;
1366  res = executeBoolItem(cxt, jsp, jb, false);
1367  cxt->current = prev;
1368 
1369  return res;
1370 }
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 1142 of file jsonpath_exec.c.

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

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

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

1745 {
1747  Datum datum;
1748 
1749  if (unwrap && JsonbType(jb) == jbvArray)
1750  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1751 
1752  if (!(jb = getScalar(jb, jbvNumeric)))
1754  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1755  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1756  jspOperationName(jsp->type)))));
1757 
1758  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
1759 
1760  if (!jspGetNext(jsp, &next) && !found)
1761  return jperOk;
1762 
1763  jb = palloc(sizeof(*jb));
1764  jb->type = jbvNumeric;
1765  jb->val.numeric = DatumGetNumeric(datum);
1766 
1767  return executeNextItem(cxt, jsp, &next, jb, found, false);
1768 }
#define RETURN_ERROR(throw_error)
static int JsonbType(JsonbValue *jb)
static int32 next
Definition: blutils.c:218
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:610
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:624
#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:144
#define DatumGetNumeric(X)
Definition: numeric.h:49
JsonPathItemType type
Definition: jsonpath.h:107
enum jbvType type
Definition: jsonb.h:263
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
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 1470 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

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

Referenced by executeBoolItem().

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

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

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

◆ getJsonPathItem()

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

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

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

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

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

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

2557 {
2558  /* Scalars should be always extracted during jsonpath execution. */
2559  Assert(scalar->type != jbvBinary ||
2560  !JsonContainerIsScalar(scalar->val.binary.data));
2561 
2562  return scalar->type == type ? scalar : NULL;
2563 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define Assert(condition)
Definition: c.h:738
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:358
#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:344
#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:610
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:358
#define ereport(elevel,...)
Definition: elog.h:144
#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:824
Definition: regcomp.c:224
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
#define PG_RETURN_NULL()
Definition: fmgr.h:344
#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:344
#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:293
#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:297
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)
static List * JsonValueListGetList(JsonValueList *jvl)
#define PG_GETARG_JSONPATH_P_COPY(x)
Definition: jsonpath.h:35
char * c
static ListCell * list_head(const List *l)
Definition: pg_list.h:125
#define lfirst(lc)
Definition: pg_list.h:190
MemoryContext multi_call_memory_ctx
Definition: funcapi.h: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:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ 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 2150 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ JsonbInitBinary()

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

Definition at line 2519 of file jsonpath_exec.c.

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

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

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

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

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 2431 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 2463 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_internal().

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

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

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

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

◆ JsonValueListInitIterator()

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

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

2473 {
2474  if (jvl->singleton)
2475  {
2476  it->value = jvl->singleton;
2477  it->list = NIL;
2478  it->next = NULL;
2479  }
2480  else if (jvl->list != NIL)
2481  {
2482  it->value = (JsonbValue *) linitial(jvl->list);
2483  it->list = jvl->list;
2484  it->next = list_second_cell(jvl->list);
2485  }
2486  else
2487  {
2488  it->value = NULL;
2489  it->list = NIL;
2490  it->next = NULL;
2491  }
2492 }
#define NIL
Definition: pg_list.h:65
#define linitial(l)
Definition: pg_list.h:195
static ListCell * list_second_cell(const List *l)
Definition: pg_list.h:139
JsonbValue * singleton

◆ JsonValueListIsEmpty()

static bool JsonValueListIsEmpty ( JsonValueList jvl)
static

Definition at line 2451 of file jsonpath_exec.c.

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

Referenced by executeBoolItem(), and executeJsonPath().

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

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

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

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

◆ JsonValueListNext()

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

Definition at line 2498 of file jsonpath_exec.c.

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

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

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

◆ setBaseObject()

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

Definition at line 2419 of file jsonpath_exec.c.

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

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

2420 {
2421  JsonBaseObjectInfo baseObject = cxt->baseObject;
2422 
2423  cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
2424  (JsonbContainer *) jbv->val.binary.data;
2425  cxt->baseObject.id = id;
2426 
2427  return baseObject;
2428 }
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 2567 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().

2568 {
2569  JsonbParseState *ps = NULL;
2571  JsonbValue *jbv;
2572 
2573  pushJsonbValue(&ps, WJB_BEGIN_ARRAY, NULL);
2574 
2575  JsonValueListInitIterator(items, &it);
2576  while ((jbv = JsonValueListNext(items, &it)))
2577  pushJsonbValue(&ps, WJB_ELEM, jbv);
2578 
2579  return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
2580 }
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