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

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

Referenced by executeItemOptUnwrapTarget().

2047 {
2049  JsonbValue jbv;
2050 
2051  if (!jspGetNext(jsp, &next) && !found)
2052  return jperOk; /* found singleton boolean value */
2053 
2054  if (res == jpbUnknown)
2055  {
2056  jbv.type = jbvNull;
2057  }
2058  else
2059  {
2060  jbv.type = jbvBool;
2061  jbv.val.boolean = res == jpbTrue;
2062  }
2063 
2064  return executeNextItem(cxt, jsp, &next, &jbv, found, true);
2065 }
static int32 next
Definition: blutils.c:219
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
Definition: jsonb.h:239
Definition: jsonb.h:236
enum jbvType type
Definition: jsonb.h:263
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)

◆ binaryCompareStrings()

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

Definition at line 2179 of file jsonpath_exec.c.

References cmp(), and Min.

Referenced by compareStrings().

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

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

Referenced by compareDatetime().

2598 {
2599  checkTimezoneIsUsedForCast(useTz, "time", "timetz");
2600 
2601  return DirectFunctionCall1(time_timetz, time);
2602 }
#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 2585 of file jsonpath_exec.c.

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

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

2586 {
2587  if (!useTz)
2588  ereport(ERROR,
2589  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2590  errmsg("cannot convert value from %s to %s without timezone usage",
2591  type1, type2),
2592  errhint("Use *_tz() function for timezone support.")));
2593 }
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 2651 of file jsonpath_exec.c.

References cmpTimestampWithOverflow(), and date2timestamp_opt_overflow().

Referenced by compareDatetime().

2652 {
2653  TimestampTz ts1;
2654  int overflow = 0;
2655 
2656  ts1 = date2timestamp_opt_overflow(date1, &overflow);
2657 
2658  return cmpTimestampWithOverflow(ts1, overflow, ts2);
2659 }
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 2665 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

2666 {
2667  TimestampTz tstz1;
2668  int overflow = 0;
2669 
2670  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
2671 
2672  tstz1 = date2timestamptz_opt_overflow(date1, &overflow);
2673 
2674  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2675 }
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 2681 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

2682 {
2683  TimestampTz tstz1;
2684  int overflow = 0;
2685 
2686  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
2687 
2688  tstz1 = timestamp2timestamptz_opt_overflow(ts1, &overflow);
2689 
2690  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2691 }
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 2614 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().

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

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

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

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

Referenced by compareItems().

2364 {
2366  NumericGetDatum(a),
2367  NumericGetDatum(b)));
2368 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define NumericGetDatum(X)
Definition: numeric.h:51
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2260
#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 2200 of file jsonpath_exec.c.

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

Referenced by compareItems().

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

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

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

◆ executeAnyItem()

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

Definition at line 1380 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget(), and executeItemUnwrapTargetArray().

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

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

Referenced by executeItemOptUnwrapTarget().

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

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

Referenced by executeItemOptUnwrapTarget(), and executeNestedBoolItem().

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

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

Referenced by executeBoolItem().

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

◆ executeDateTimeMethod()

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

Definition at line 1779 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

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

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

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

◆ executeItemOptUnwrapResultNoThrow()

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

Definition at line 1209 of file jsonpath_exec.c.

References executeItemOptUnwrapResult(), and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

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

◆ executeItemOptUnwrapTarget()

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

Definition at line 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  double val;
1048  bool have_error = false;
1049 
1050  val = float8in_internal_opt_error(tmp,
1051  NULL,
1052  "double precision",
1053  tmp,
1054  &have_error);
1055 
1056  if (have_error || isinf(val) || isnan(val))
1058  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1059  errmsg("numeric argument of jsonpath item method .%s() is out of range for type double precision",
1060  jspOperationName(jsp->type)))));
1061  res = jperOk;
1062  }
1063  else if (jb->type == jbvString)
1064  {
1065  /* cast string as double */
1066  double val;
1067  char *tmp = pnstrdup(jb->val.string.val,
1068  jb->val.string.len);
1069  bool have_error = false;
1070 
1071  val = float8in_internal_opt_error(tmp,
1072  NULL,
1073  "double precision",
1074  tmp,
1075  &have_error);
1076 
1077  if (have_error || isinf(val) || isnan(val))
1079  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1080  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a double precision number",
1081  jspOperationName(jsp->type)))));
1082 
1083  jb = &jbv;
1084  jb->type = jbvNumeric;
1086  Float8GetDatum(val)));
1087  res = jperOk;
1088  }
1089 
1090  if (res == jperNotFound)
1092  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1093  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1094  jspOperationName(jsp->type)))));
1095 
1096  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1097  }
1098  break;
1099 
1100  case jpiDatetime:
1101  if (unwrap && JsonbType(jb) == jbvArray)
1102  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1103 
1104  return executeDateTimeMethod(cxt, jsp, jb, found);
1105 
1106  case jpiKeyValue:
1107  if (unwrap && JsonbType(jb) == jbvArray)
1108  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1109 
1110  return executeKeyValueMethod(cxt, jsp, jb, found);
1111 
1112  default:
1113  elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
1114  }
1115 
1116  return res;
1117 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
#define jspIgnoreStructuralErrors(cxt)
static int JsonbType(JsonbValue *jb)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
Definition: jsonpath.h:50
static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
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:2728
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2998
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:738
#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:2884
JsonPathBool
signed int int32
Definition: c.h:362
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:1284
Datum numeric_abs(PG_FUNCTION_ARGS)
Definition: numeric.c:1257
#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:374
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:1531
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:718
Datum int4_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:4078
union JsonPathItem::@128 content
Datum float8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:4284
Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3222
#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:745
#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:1503
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2806
#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 1123 of file jsonpath_exec.c.

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

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

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

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

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

Referenced by executeBoolItem().

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

References JsonPathExecContext::current, and executeBoolItem().

Referenced by executeItemOptUnwrapTarget().

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

◆ executeNextItem()

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

Definition at line 1143 of file jsonpath_exec.c.

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

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

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

◆ executeNumericItemMethod()

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

Definition at line 1743 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

1746 {
1748  Datum datum;
1749 
1750  if (unwrap && JsonbType(jb) == jbvArray)
1751  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1752 
1753  if (!(jb = getScalar(jb, jbvNumeric)))
1755  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1756  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1757  jspOperationName(jsp->type)))));
1758 
1759  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
1760 
1761  if (!jspGetNext(jsp, &next) && !found)
1762  return jperOk;
1763 
1764  jb = palloc(sizeof(*jb));
1765  jb->type = jbvNumeric;
1766  jb->val.numeric = DatumGetNumeric(datum);
1767 
1768  return executeNextItem(cxt, jsp, &next, jb, found, false);
1769 }
#define RETURN_ERROR(throw_error)
static int JsonbType(JsonbValue *jb)
static int32 next
Definition: blutils.c:219
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:937
char * val
Definition: jsonb.h:272
#define NumericGetDatum(X)
Definition: numeric.h:51
int errcode(int sqlerrcode)
Definition: elog.c: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 1471 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeStartsWith()

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

Definition at line 1689 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeUnaryArithmExpr()

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

Definition at line 1622 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

2387 {
2388  JsonbValue *jbv;
2389  JsonValueList found = {0};
2390  JsonPathExecResult res = executeItem(cxt, jsp, jb, &found);
2391  Datum numeric_index;
2392  bool have_error = false;
2393 
2394  if (jperIsError(res))
2395  return res;
2396 
2397  if (JsonValueListLength(&found) != 1 ||
2398  !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric)))
2400  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2401  errmsg("jsonpath array subscript is not a single numeric value"))));
2402 
2403  numeric_index = DirectFunctionCall2(numeric_trunc,
2404  NumericGetDatum(jbv->val.numeric),
2405  Int32GetDatum(0));
2406 
2407  *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index),
2408  &have_error);
2409 
2410  if (have_error)
2412  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2413  errmsg("jsonpath array subscript is out of integer range"))));
2414 
2415  return jperOk;
2416 }
#define RETURN_ERROR(throw_error)
#define jperIsError(jper)
Datum numeric_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:1456
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:4096
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 2073 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().

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

2108 {
2109  char *varName;
2110  int varNameLength;
2111  JsonbValue tmp;
2112  JsonbValue *v;
2113 
2114  if (!vars)
2115  {
2116  value->type = jbvNull;
2117  return;
2118  }
2119 
2120  Assert(variable->type == jpiVariable);
2121  varName = jspGetString(variable, &varNameLength);
2122  tmp.type = jbvString;
2123  tmp.val.string.val = varName;
2124  tmp.val.string.len = varNameLength;
2125 
2126  v = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
2127 
2128  if (v)
2129  {
2130  *value = *v;
2131  pfree(v);
2132  }
2133  else
2134  {
2135  ereport(ERROR,
2136  (errcode(ERRCODE_UNDEFINED_OBJECT),
2137  errmsg("could not find jsonpath variable \"%s\"",
2138  pnstrdup(varName, varNameLength))));
2139  }
2140 
2141  JsonbInitBinary(&tmp, vars);
2142  setBaseObject(cxt, &tmp, 1);
2143 }
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:745
#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 2557 of file jsonpath_exec.c.

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

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

2558 {
2559  /* Scalars should be always extracted during jsonpath execution. */
2560  Assert(scalar->type != jbvBinary ||
2561  !JsonContainerIsScalar(scalar->val.binary.data));
2562 
2563  return scalar->type == type ? scalar : NULL;
2564 }
char * val
Definition: jsonb.h:272
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:215
#define Assert(condition)
Definition: c.h:745
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 2151 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ JsonbInitBinary()

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

Definition at line 2520 of file jsonpath_exec.c.

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

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

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

2534 {
2535  int type = jb->type;
2536 
2537  if (jb->type == jbvBinary)
2538  {
2539  JsonbContainer *jbc = (void *) jb->val.binary.data;
2540 
2541  /* Scalars should be always extracted during jsonpath execution. */
2543 
2544  if (JsonContainerIsObject(jbc))
2545  type = jbvObject;
2546  else if (JsonContainerIsArray(jbc))
2547  type = jbvArray;
2548  else
2549  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
2550  }
2551 
2552  return type;
2553 }
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:745
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 2432 of file jsonpath_exec.c.

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

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

2433 {
2434  if (jvl->singleton)
2435  {
2436  jvl->list = list_make2(jvl->singleton, jbv);
2437  jvl->singleton = NULL;
2438  }
2439  else if (!jvl->list)
2440  jvl->singleton = jbv;
2441  else
2442  jvl->list = lappend(jvl->list, jbv);
2443 }
#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 2464 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_internal().

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

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

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

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

◆ JsonValueListInitIterator()

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

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

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

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

Referenced by executeBoolItem(), and executeJsonPath().

2453 {
2454  return !jvl->singleton && list_length(jvl->list) <= 0;
2455 }
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 2446 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().

2447 {
2448  return jvl->singleton ? 1 : list_length(jvl->list);
2449 }
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 2499 of file jsonpath_exec.c.

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

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

2500 {
2501  JsonbValue *result = it->value;
2502 
2503  if (it->next)
2504  {
2505  it->value = lfirst(it->next);
2506  it->next = lnext(it->list, it->next);
2507  }
2508  else
2509  {
2510  it->value = NULL;
2511  }
2512 
2513  return result;
2514 }
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 2420 of file jsonpath_exec.c.

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

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

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

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