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 "nodes/miscnodes.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 *cast_error)
 
static Datum jsonb_path_exists_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_exists (PG_FUNCTION_ARGS)
 
Datum jsonb_path_exists_tz (PG_FUNCTION_ARGS)
 
Datum jsonb_path_exists_opr (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_match_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_match (PG_FUNCTION_ARGS)
 
Datum jsonb_path_match_tz (PG_FUNCTION_ARGS)
 
Datum jsonb_path_match_opr (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_tz (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_array_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query_array (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_array_tz (PG_FUNCTION_ARGS)
 
static Datum jsonb_path_query_first_internal (FunctionCallInfo fcinfo, bool tz)
 
Datum jsonb_path_query_first (PG_FUNCTION_ARGS)
 
Datum jsonb_path_query_first_tz (PG_FUNCTION_ARGS)
 
static int binaryCompareStrings (const char *s1, int len1, const char *s2, int len2)
 
static int compareStrings (const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
 
static void checkTimezoneIsUsedForCast (bool useTz, const char *type1, const char *type2)
 
static Datum castTimeToTimeTz (Datum time, bool useTz)
 
static int cmpDateToTimestamp (DateADT date1, Timestamp ts2, bool useTz)
 
static int cmpDateToTimestampTz (DateADT date1, TimestampTz tstz2, bool useTz)
 
static int cmpTimestampToTimestampTz (Timestamp ts1, TimestampTz tstz2, bool useTz)
 

Macro Definition Documentation

◆ jperIsError

#define jperIsError (   jper)    ((jper) == jperError)

Definition at line 137 of file jsonpath_exec.c.

◆ jspAutoUnwrap

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

Definition at line 157 of file jsonpath_exec.c.

◆ jspAutoWrap

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

Definition at line 158 of file jsonpath_exec.c.

◆ jspIgnoreStructuralErrors

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

Definition at line 159 of file jsonpath_exec.c.

◆ jspStrictAbsenseOfErrors

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

Definition at line 156 of file jsonpath_exec.c.

◆ jspThrowErrors

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

Definition at line 160 of file jsonpath_exec.c.

◆ RETURN_ERROR

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

Definition at line 163 of file jsonpath_exec.c.

Typedef Documentation

◆ BinaryArithmFunc

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

Definition at line 175 of file jsonpath_exec.c.

◆ JsonBaseObjectInfo

◆ JsonLikeRegexContext

◆ JsonPathBool

typedef enum JsonPathBool JsonPathBool

◆ JsonPathExecContext

◆ JsonPathExecResult

◆ JsonPathPredicateCallback

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

Definition at line 171 of file jsonpath_exec.c.

◆ JsonValueList

typedef struct JsonValueList JsonValueList

◆ JsonValueListIterator

Enumeration Type Documentation

◆ JsonPathBool

Enumerator
jpbFalse 
jpbTrue 
jpbUnknown 

Definition at line 122 of file jsonpath_exec.c.

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

◆ JsonPathExecResult

Enumerator
jperOk 
jperNotFound 
jperError 

Definition at line 130 of file jsonpath_exec.c.

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

Function Documentation

◆ appendBoolResult()

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

Definition at line 2052 of file jsonpath_exec.c.

2054 {
2056  JsonbValue jbv;
2057 
2058  if (!jspGetNext(jsp, &next) && !found)
2059  return jperOk; /* found singleton boolean value */
2060 
2061  if (res == jpbUnknown)
2062  {
2063  jbv.type = jbvNull;
2064  }
2065  else
2066  {
2067  jbv.type = jbvBool;
2068  jbv.val.boolean = res == jpbTrue;
2069  }
2070 
2071  return executeNextItem(cxt, jsp, &next, &jbv, found, true);
2072 }
static int32 next
Definition: blutils.c:219
@ jbvBool
Definition: jsonb.h:231
@ jbvNull
Definition: jsonb.h:228
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:973
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
enum jbvType type
Definition: jsonb.h:255
char * val
Definition: jsonb.h:264

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

Referenced by executeItemOptUnwrapTarget().

◆ binaryCompareStrings()

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

Definition at line 2186 of file jsonpath_exec.c.

2188 {
2189  int cmp;
2190 
2191  cmp = memcmp(s1, s2, Min(len1, len2));
2192 
2193  if (cmp != 0)
2194  return cmp;
2195 
2196  if (len1 == len2)
2197  return 0;
2198 
2199  return len1 < len2 ? -1 : 1;
2200 }
#define Min(x, y)
Definition: c.h:988
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

References cmp(), Min, s1, and s2.

Referenced by compareStrings().

◆ castTimeToTimeTz()

static Datum castTimeToTimeTz ( Datum  time,
bool  useTz 
)
static

Definition at line 2604 of file jsonpath_exec.c.

2605 {
2606  checkTimezoneIsUsedForCast(useTz, "time", "timetz");
2607 
2608  return DirectFunctionCall1(time_timetz, time);
2609 }
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2807
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

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

Referenced by compareDatetime().

◆ checkTimezoneIsUsedForCast()

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

Definition at line 2592 of file jsonpath_exec.c.

2593 {
2594  if (!useTz)
2595  ereport(ERROR,
2596  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2597  errmsg("cannot convert value from %s to %s without time zone usage",
2598  type1, type2),
2599  errhint("Use *_tz() function for time zone support.")));
2600 }
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

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

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

◆ cmpDateToTimestamp()

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

Definition at line 2616 of file jsonpath_exec.c.

2617 {
2618  return date_cmp_timestamp_internal(date1, ts2);
2619 }
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition: date.c:742

References date_cmp_timestamp_internal().

Referenced by compareDatetime().

◆ cmpDateToTimestampTz()

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

Definition at line 2625 of file jsonpath_exec.c.

2626 {
2627  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
2628 
2629  return date_cmp_timestamptz_internal(date1, tstz2);
2630 }
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition: date.c:822

References checkTimezoneIsUsedForCast(), and date_cmp_timestamptz_internal().

Referenced by compareDatetime().

◆ cmpTimestampToTimestampTz()

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

Definition at line 2636 of file jsonpath_exec.c.

2637 {
2638  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
2639 
2640  return timestamp_cmp_timestamptz_internal(ts1, tstz2);
2641 }
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2240

References checkTimezoneIsUsedForCast(), and timestamp_cmp_timestamptz_internal().

Referenced by compareDatetime().

◆ compareDatetime()

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

Definition at line 2649 of file jsonpath_exec.c.

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

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

Referenced by compareItems().

◆ compareItems()

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

Definition at line 2274 of file jsonpath_exec.c.

2275 {
2276  int cmp;
2277  bool res;
2278 
2279  if (jb1->type != jb2->type)
2280  {
2281  if (jb1->type == jbvNull || jb2->type == jbvNull)
2282 
2283  /*
2284  * Equality and order comparison of nulls to non-nulls returns
2285  * always false, but inequality comparison returns true.
2286  */
2287  return op == jpiNotEqual ? jpbTrue : jpbFalse;
2288 
2289  /* Non-null items of different types are not comparable. */
2290  return jpbUnknown;
2291  }
2292 
2293  switch (jb1->type)
2294  {
2295  case jbvNull:
2296  cmp = 0;
2297  break;
2298  case jbvBool:
2299  cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
2300  jb1->val.boolean ? 1 : -1;
2301  break;
2302  case jbvNumeric:
2303  cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
2304  break;
2305  case jbvString:
2306  if (op == jpiEqual)
2307  return jb1->val.string.len != jb2->val.string.len ||
2308  memcmp(jb1->val.string.val,
2309  jb2->val.string.val,
2310  jb1->val.string.len) ? jpbFalse : jpbTrue;
2311 
2312  cmp = compareStrings(jb1->val.string.val, jb1->val.string.len,
2313  jb2->val.string.val, jb2->val.string.len);
2314  break;
2315  case jbvDatetime:
2316  {
2317  bool cast_error;
2318 
2319  cmp = compareDatetime(jb1->val.datetime.value,
2320  jb1->val.datetime.typid,
2321  jb2->val.datetime.value,
2322  jb2->val.datetime.typid,
2323  useTz,
2324  &cast_error);
2325 
2326  if (cast_error)
2327  return jpbUnknown;
2328  }
2329  break;
2330 
2331  case jbvBinary:
2332  case jbvArray:
2333  case jbvObject:
2334  return jpbUnknown; /* non-scalars are not comparable */
2335 
2336  default:
2337  elog(ERROR, "invalid jsonb value type %d", jb1->type);
2338  }
2339 
2340  switch (op)
2341  {
2342  case jpiEqual:
2343  res = (cmp == 0);
2344  break;
2345  case jpiNotEqual:
2346  res = (cmp != 0);
2347  break;
2348  case jpiLess:
2349  res = (cmp < 0);
2350  break;
2351  case jpiGreater:
2352  res = (cmp > 0);
2353  break;
2354  case jpiLessOrEqual:
2355  res = (cmp <= 0);
2356  break;
2357  case jpiGreaterOrEqual:
2358  res = (cmp >= 0);
2359  break;
2360  default:
2361  elog(ERROR, "unrecognized jsonpath operation: %d", op);
2362  return jpbUnknown;
2363  }
2364 
2365  return res ? jpbTrue : jpbFalse;
2366 }
@ jbvObject
Definition: jsonb.h:234
@ jbvNumeric
Definition: jsonb.h:230
@ jbvArray
Definition: jsonb.h:233
@ jbvBinary
Definition: jsonb.h:236
@ jbvDatetime
Definition: jsonb.h:244
@ jbvString
Definition: jsonb.h:229
@ jpiNotEqual
Definition: jsonpath.h:64
@ jpiGreaterOrEqual
Definition: jsonpath.h:68
@ jpiGreater
Definition: jsonpath.h:66
@ jpiLess
Definition: jsonpath.h:65
@ jpiEqual
Definition: jsonpath.h:63
@ jpiLessOrEqual
Definition: jsonpath.h:67
static int compareStrings(const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *cast_error)
static int compareNumeric(Numeric a, Numeric b)

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

Referenced by executeComparison().

◆ compareNumeric()

static int compareNumeric ( Numeric  a,
Numeric  b 
)
static

Definition at line 2370 of file jsonpath_exec.c.

2371 {
2373  NumericGetDatum(a),
2374  NumericGetDatum(b)));
2375 }
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2398
int b
Definition: isn.c:70
int a
Definition: isn.c:69
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:72

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

Referenced by compareItems().

◆ compareStrings()

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

Definition at line 2207 of file jsonpath_exec.c.

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

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

Referenced by compareItems().

◆ copyJsonbValue()

static JsonbValue * copyJsonbValue ( JsonbValue src)
static

Definition at line 2378 of file jsonpath_exec.c.

2379 {
2380  JsonbValue *dst = palloc(sizeof(*dst));
2381 
2382  *dst = *src;
2383 
2384  return dst;
2385 }
void * palloc(Size size)
Definition: mcxt.c:1226

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

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

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

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

Referenced by executeItemOptUnwrapTarget(), and executeItemUnwrapTargetArray().

◆ executeBinaryArithmExpr()

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

Definition at line 1552 of file jsonpath_exec.c.

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

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

Referenced by executeItemOptUnwrapTarget().

◆ executeBoolItem()

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

Definition at line 1227 of file jsonpath_exec.c.

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

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, res, and JsonPathItem::type.

Referenced by executeItemOptUnwrapTarget(), and executeNestedBoolItem().

◆ executeComparison()

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

Definition at line 2175 of file jsonpath_exec.c.

2176 {
2178 
2179  return compareItems(cmp->type, lv, rv, cxt->useTz);
2180 }
static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)

References cmp(), compareItems(), and JsonPathExecContext::useTz.

Referenced by executeBoolItem().

◆ executeDateTimeMethod()

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

Definition at line 1781 of file jsonpath_exec.c.

1783 {
1784  JsonbValue jbvbuf;
1785  Datum value;
1786  text *datetime;
1787  Oid collid;
1788  Oid typid;
1789  int32 typmod = -1;
1790  int tz = 0;
1791  bool hasNext;
1793  JsonPathItem elem;
1794 
1795  if (!(jb = getScalar(jb, jbvString)))
1797  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
1798  errmsg("jsonpath item method .%s() can only be applied to a string",
1799  jspOperationName(jsp->type)))));
1800 
1801  datetime = cstring_to_text_with_len(jb->val.string.val,
1802  jb->val.string.len);
1803 
1804  /*
1805  * At some point we might wish to have callers supply the collation to
1806  * use, but right now it's unclear that they'd be able to do better than
1807  * DEFAULT_COLLATION_OID anyway.
1808  */
1809  collid = DEFAULT_COLLATION_OID;
1810 
1811  if (jsp->content.arg)
1812  {
1813  text *template;
1814  char *template_str;
1815  int template_len;
1816  ErrorSaveContext escontext = {T_ErrorSaveContext};
1817 
1818  jspGetArg(jsp, &elem);
1819 
1820  if (elem.type != jpiString)
1821  elog(ERROR, "invalid jsonpath item type for .datetime() argument");
1822 
1823  template_str = jspGetString(&elem, &template_len);
1824 
1825  template = cstring_to_text_with_len(template_str,
1826  template_len);
1827 
1828  value = parse_datetime(datetime, template, collid, true,
1829  &typid, &typmod, &tz,
1830  jspThrowErrors(cxt) ? NULL : (Node *) &escontext);
1831 
1832  if (escontext.error_occurred)
1833  res = jperError;
1834  else
1835  res = jperOk;
1836  }
1837  else
1838  {
1839  /*
1840  * According to SQL/JSON standard enumerate ISO formats for: date,
1841  * timetz, time, timestamptz, timestamp.
1842  *
1843  * We also support ISO 8601 for timestamps, because to_json[b]()
1844  * functions use this format.
1845  */
1846  static const char *fmt_str[] =
1847  {
1848  "yyyy-mm-dd",
1849  "HH24:MI:SSTZH:TZM",
1850  "HH24:MI:SSTZH",
1851  "HH24:MI:SS",
1852  "yyyy-mm-dd HH24:MI:SSTZH:TZM",
1853  "yyyy-mm-dd HH24:MI:SSTZH",
1854  "yyyy-mm-dd HH24:MI:SS",
1855  "yyyy-mm-dd\"T\"HH24:MI:SSTZH:TZM",
1856  "yyyy-mm-dd\"T\"HH24:MI:SSTZH",
1857  "yyyy-mm-dd\"T\"HH24:MI:SS"
1858  };
1859 
1860  /* cache for format texts */
1861  static text *fmt_txt[lengthof(fmt_str)] = {0};
1862  int i;
1863 
1864  /* loop until datetime format fits */
1865  for (i = 0; i < lengthof(fmt_str); i++)
1866  {
1867  ErrorSaveContext escontext = {T_ErrorSaveContext};
1868 
1869  if (!fmt_txt[i])
1870  {
1871  MemoryContext oldcxt =
1873 
1874  fmt_txt[i] = cstring_to_text(fmt_str[i]);
1875  MemoryContextSwitchTo(oldcxt);
1876  }
1877 
1878  value = parse_datetime(datetime, fmt_txt[i], collid, true,
1879  &typid, &typmod, &tz,
1880  (Node *) &escontext);
1881 
1882  if (!escontext.error_occurred)
1883  {
1884  res = jperOk;
1885  break;
1886  }
1887  }
1888 
1889  if (res == jperNotFound)
1891  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
1892  errmsg("datetime format is not recognized: \"%s\"",
1893  text_to_cstring(datetime)),
1894  errhint("Use a datetime template argument to specify the input data format."))));
1895  }
1896 
1897  pfree(datetime);
1898 
1899  if (jperIsError(res))
1900  return res;
1901 
1902  hasNext = jspGetNext(jsp, &elem);
1903 
1904  if (!hasNext && !found)
1905  return res;
1906 
1907  jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
1908 
1909  jb->type = jbvDatetime;
1910  jb->val.datetime.value = value;
1911  jb->val.datetime.typid = typid;
1912  jb->val.datetime.typmod = typmod;
1913  jb->val.datetime.tz = tz;
1914 
1915  return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
1916 }
#define lengthof(array)
Definition: c.h:772
Oid collid
Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, Node *escontext)
Definition: formatting.c:4272
static struct @147 value
int i
Definition: isn.c:73
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1086
@ jpiString
Definition: jsonpath.h:56
MemoryContext TopMemoryContext
Definition: mcxt.c:141
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
bool error_occurred
Definition: miscnodes.h:46
int32 arg
Definition: jsonpath.h:138
Definition: nodes.h:129
Definition: c.h:671
char * text_to_cstring(const text *t)
Definition: varlena.c:215
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:194
text * cstring_to_text(const char *s)
Definition: varlena.c:182

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

Referenced by executeItemOptUnwrapTarget().

◆ executeItem()

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

Definition at line 600 of file jsonpath_exec.c.

602 {
603  return executeItemOptUnwrapTarget(cxt, jsp, jb, found, jspAutoUnwrap(cxt));
604 }
#define jspAutoUnwrap(cxt)

References executeItemOptUnwrapTarget(), and jspAutoUnwrap.

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

◆ executeItemOptUnwrapResult()

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

Definition at line 1175 of file jsonpath_exec.c.

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

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

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

◆ executeItemOptUnwrapResultNoThrow()

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

Definition at line 1210 of file jsonpath_exec.c.

1214 {
1216  bool throwErrors = cxt->throwErrors;
1217 
1218  cxt->throwErrors = false;
1219  res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found);
1220  cxt->throwErrors = throwErrors;
1221 
1222  return res;
1223 }

References executeItemOptUnwrapResult(), res, and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

◆ executeItemOptUnwrapTarget()

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

Definition at line 612 of file jsonpath_exec.c.

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

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, ErrorSaveContext::error_occurred, executeAnyItem(), executeBinaryArithmExpr(), executeBoolItem(), executeDateTimeMethod(), executeItemUnwrapTargetArray(), executeKeyValueMethod(), executeNestedBoolItem(), executeNextItem(), executeNumericItemMethod(), executeUnaryArithmExpr(), findJsonbValueFromContainer(), float8_numeric(), Float8GetDatum(), float8in_internal(), getArrayIndex(), getIthJsonbValueFromContainer(), getJsonPathItem(), i, JsonPathExecContext::ignoreStructuralErrors, JsonPathExecContext::innermostArraySize, int64_to_numeric(), JB_FOBJECT, jbvArray, jbvBinary, jbvNumeric, jbvObject, jbvString, jpbTrue, jperError, jperIsError, jperNotFound, jperOk, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBool, jpiCeiling, jpiCurrent, jpiDatetime, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiSub, jpiType, jpiVariable, JsonbArraySize(), JsonbType(), JsonbTypeName(), jspAutoUnwrap, jspAutoWrap, jspGetArg(), jspGetArraySubscript(), jspGetNext(), jspGetString(), jspHasNext, jspIgnoreStructuralErrors, jspOperationName(), jspThrowErrors, sort-test::key, numeric_abs(), numeric_add_opt_error(), numeric_ceil(), numeric_div_opt_error(), numeric_floor(), numeric_mod_opt_error(), numeric_mul_opt_error(), numeric_out(), numeric_sub_opt_error(), numeric_uminus(), NumericGetDatum(), palloc(), pfree(), pnstrdup(), pstrdup(), range(), res, RETURN_ERROR, JsonPathExecContext::root, setBaseObject(), JsonbValue::type, JsonPathItem::type, JsonbValue::val, and val.

Referenced by executeAnyItem(), and executeItem().

◆ executeItemUnwrapTargetArray()

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

Definition at line 1124 of file jsonpath_exec.c.

1127 {
1128  if (jb->type != jbvBinary)
1129  {
1130  Assert(jb->type != jbvArray);
1131  elog(ERROR, "invalid jsonb array value type: %d", jb->type);
1132  }
1133 
1134  return executeAnyItem
1135  (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
1136  false, unwrapElements);
1137 }

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

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

◆ executeJsonPath()

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

Definition at line 540 of file jsonpath_exec.c.

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

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, res, 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().

◆ executeKeyValueMethod()

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

Definition at line 1942 of file jsonpath_exec.c.

1944 {
1947  JsonbContainer *jbc;
1948  JsonbValue key;
1949  JsonbValue val;
1950  JsonbValue idval;
1951  JsonbValue keystr;
1952  JsonbValue valstr;
1953  JsonbValue idstr;
1954  JsonbIterator *it;
1955  JsonbIteratorToken tok;
1956  int64 id;
1957  bool hasNext;
1958 
1959  if (JsonbType(jb) != jbvObject || jb->type != jbvBinary)
1961  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
1962  errmsg("jsonpath item method .%s() can only be applied to an object",
1963  jspOperationName(jsp->type)))));
1964 
1965  jbc = jb->val.binary.data;
1966 
1967  if (!JsonContainerSize(jbc))
1968  return jperNotFound; /* no key-value pairs */
1969 
1970  hasNext = jspGetNext(jsp, &next);
1971 
1972  keystr.type = jbvString;
1973  keystr.val.string.val = "key";
1974  keystr.val.string.len = 3;
1975 
1976  valstr.type = jbvString;
1977  valstr.val.string.val = "value";
1978  valstr.val.string.len = 5;
1979 
1980  idstr.type = jbvString;
1981  idstr.val.string.val = "id";
1982  idstr.val.string.len = 2;
1983 
1984  /* construct object id from its base object and offset inside that */
1985  id = jb->type != jbvBinary ? 0 :
1986  (int64) ((char *) jbc - (char *) cxt->baseObject.jbc);
1987  id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
1988 
1989  idval.type = jbvNumeric;
1990  idval.val.numeric = int64_to_numeric(id);
1991 
1992  it = JsonbIteratorInit(jbc);
1993 
1994  while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
1995  {
1996  JsonBaseObjectInfo baseObject;
1997  JsonbValue obj;
1999  JsonbValue *keyval;
2000  Jsonb *jsonb;
2001 
2002  if (tok != WJB_KEY)
2003  continue;
2004 
2005  res = jperOk;
2006 
2007  if (!hasNext && !found)
2008  break;
2009 
2010  tok = JsonbIteratorNext(&it, &val, true);
2011  Assert(tok == WJB_VALUE);
2012 
2013  ps = NULL;
2015 
2016  pushJsonbValue(&ps, WJB_KEY, &keystr);
2018 
2019  pushJsonbValue(&ps, WJB_KEY, &valstr);
2021 
2022  pushJsonbValue(&ps, WJB_KEY, &idstr);
2023  pushJsonbValue(&ps, WJB_VALUE, &idval);
2024 
2025  keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
2026 
2027  jsonb = JsonbValueToJsonb(keyval);
2028 
2029  JsonbInitBinary(&obj, jsonb);
2030 
2031  baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++);
2032 
2033  res = executeNextItem(cxt, jsp, &next, &obj, found, true);
2034 
2035  cxt->baseObject = baseObject;
2036 
2037  if (jperIsError(res))
2038  return res;
2039 
2040  if (res == jperOk && !found)
2041  break;
2042  }
2043 
2044  return res;
2045 }
struct parser_state ps
#define JsonContainerSize(jc)
Definition: jsonb.h:206
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:568
Definition: jsonb.h:213

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

Referenced by executeItemOptUnwrapTarget().

◆ executeLikeRegex()

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

Definition at line 1714 of file jsonpath_exec.c.

1716 {
1717  JsonLikeRegexContext *cxt = param;
1718 
1719  if (!(str = getScalar(str, jbvString)))
1720  return jpbUnknown;
1721 
1722  /* Cache regex text and converted flags. */
1723  if (!cxt->regex)
1724  {
1725  cxt->regex =
1727  jsp->content.like_regex.patternlen);
1728  (void) jspConvertRegexFlags(jsp->content.like_regex.flags,
1729  &(cxt->cflags), NULL);
1730  }
1731 
1732  if (RE_compile_and_execute(cxt->regex, str->val.string.val,
1733  str->val.string.len,
1734  cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
1735  return jpbTrue;
1736 
1737  return jpbFalse;
1738 }
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
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:359

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 generate_unaccent_rules::str.

Referenced by executeBoolItem().

◆ executeNestedBoolItem()

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

Definition at line 1360 of file jsonpath_exec.c.

1362 {
1363  JsonbValue *prev;
1364  JsonPathBool res;
1365 
1366  prev = cxt->current;
1367  cxt->current = jb;
1368  res = executeBoolItem(cxt, jsp, jb, false);
1369  cxt->current = prev;
1370 
1371  return res;
1372 }

References JsonPathExecContext::current, executeBoolItem(), and res.

Referenced by executeItemOptUnwrapTarget().

◆ executeNextItem()

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

Definition at line 1144 of file jsonpath_exec.c.

1147 {
1148  JsonPathItem elem;
1149  bool hasNext;
1150 
1151  if (!cur)
1152  hasNext = next != NULL;
1153  else if (next)
1154  hasNext = jspHasNext(cur);
1155  else
1156  {
1157  next = &elem;
1158  hasNext = jspGetNext(cur, next);
1159  }
1160 
1161  if (hasNext)
1162  return executeItem(cxt, next, v, found);
1163 
1164  if (found)
1165  JsonValueListAppend(found, copy ? copyJsonbValue(v) : v);
1166 
1167  return jperOk;
1168 }
struct cursor * cur
Definition: ecpg.c:28

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

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

◆ executeNumericItemMethod()

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

Definition at line 1745 of file jsonpath_exec.c.

1748 {
1750  Datum datum;
1751 
1752  if (unwrap && JsonbType(jb) == jbvArray)
1753  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1754 
1755  if (!(jb = getScalar(jb, jbvNumeric)))
1757  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1758  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
1759  jspOperationName(jsp->type)))));
1760 
1761  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
1762 
1763  if (!jspGetNext(jsp, &next) && !found)
1764  return jperOk;
1765 
1766  jb = palloc(sizeof(*jb));
1767  jb->type = jbvNumeric;
1768  jb->val.numeric = DatumGetNumeric(datum);
1769 
1770  return executeNextItem(cxt, jsp, &next, jb, found, false);
1771 }

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

Referenced by executeItemOptUnwrapTarget().

◆ executePredicate()

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

Definition at line 1472 of file jsonpath_exec.c.

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

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

Referenced by executeBoolItem().

◆ executeStartsWith()

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

Definition at line 1690 of file jsonpath_exec.c.

1692 {
1693  if (!(whole = getScalar(whole, jbvString)))
1694  return jpbUnknown; /* error */
1695 
1696  if (!(initial = getScalar(initial, jbvString)))
1697  return jpbUnknown; /* error */
1698 
1699  if (whole->val.string.len >= initial->val.string.len &&
1700  !memcmp(whole->val.string.val,
1701  initial->val.string.val,
1702  initial->val.string.len))
1703  return jpbTrue;
1704 
1705  return jpbFalse;
1706 }

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

Referenced by executeBoolItem().

◆ executeUnaryArithmExpr()

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

Definition at line 1623 of file jsonpath_exec.c.

1625 {
1626  JsonPathExecResult jper;
1627  JsonPathExecResult jper2;
1628  JsonPathItem elem;
1629  JsonValueList seq = {0};
1631  JsonbValue *val;
1632  bool hasNext;
1633 
1634  jspGetArg(jsp, &elem);
1635  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &seq);
1636 
1637  if (jperIsError(jper))
1638  return jper;
1639 
1640  jper = jperNotFound;
1641 
1642  hasNext = jspGetNext(jsp, &elem);
1643 
1644  JsonValueListInitIterator(&seq, &it);
1645  while ((val = JsonValueListNext(&seq, &it)))
1646  {
1647  if ((val = getScalar(val, jbvNumeric)))
1648  {
1649  if (!found && !hasNext)
1650  return jperOk;
1651  }
1652  else
1653  {
1654  if (!found && !hasNext)
1655  continue; /* skip non-numerics processing */
1656 
1658  (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),
1659  errmsg("operand of unary jsonpath operator %s is not a numeric value",
1660  jspOperationName(jsp->type)))));
1661  }
1662 
1663  if (func)
1664  val->val.numeric =
1666  NumericGetDatum(val->val.numeric)));
1667 
1668  jper2 = executeNextItem(cxt, jsp, &elem, val, found, false);
1669 
1670  if (jperIsError(jper2))
1671  return jper2;
1672 
1673  if (jper2 == jperOk)
1674  {
1675  if (!found)
1676  return jperOk;
1677  jper = jperOk;
1678  }
1679  }
1680 
1681  return jper;
1682 }

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

Referenced by executeItemOptUnwrapTarget().

◆ getArrayIndex()

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

Definition at line 2392 of file jsonpath_exec.c.

2394 {
2395  JsonbValue *jbv;
2396  JsonValueList found = {0};
2397  JsonPathExecResult res = executeItem(cxt, jsp, jb, &found);
2398  Datum numeric_index;
2399  bool have_error = false;
2400 
2401  if (jperIsError(res))
2402  return res;
2403 
2404  if (JsonValueListLength(&found) != 1 ||
2405  !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric)))
2407  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2408  errmsg("jsonpath array subscript is not a single numeric value"))));
2409 
2410  numeric_index = DirectFunctionCall2(numeric_trunc,
2411  NumericGetDatum(jbv->val.numeric),
2412  Int32GetDatum(0));
2413 
2414  *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index),
2415  &have_error);
2416 
2417  if (have_error)
2419  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
2420  errmsg("jsonpath array subscript is out of integer range"))));
2421 
2422  return jperOk;
2423 }
int32 numeric_int4_opt_error(Numeric num, bool *have_error)
Definition: numeric.c:4346
Datum numeric_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:1582
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212

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

Referenced by executeItemOptUnwrapTarget().

◆ getJsonPathItem()

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

Definition at line 2080 of file jsonpath_exec.c.

2082 {
2083  switch (item->type)
2084  {
2085  case jpiNull:
2086  value->type = jbvNull;
2087  break;
2088  case jpiBool:
2089  value->type = jbvBool;
2090  value->val.boolean = jspGetBool(item);
2091  break;
2092  case jpiNumeric:
2093  value->type = jbvNumeric;
2094  value->val.numeric = jspGetNumeric(item);
2095  break;
2096  case jpiString:
2097  value->type = jbvString;
2098  value->val.string.val = jspGetString(item,
2099  &value->val.string.len);
2100  break;
2101  case jpiVariable:
2102  getJsonPathVariable(cxt, item, cxt->vars, value);
2103  return;
2104  default:
2105  elog(ERROR, "unexpected jsonpath item type");
2106  }
2107 }
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1070
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1078
static void getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, Jsonb *vars, JsonbValue *value)

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

Referenced by executeItemOptUnwrapTarget().

◆ getJsonPathVariable()

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

Definition at line 2113 of file jsonpath_exec.c.

2115 {
2116  char *varName;
2117  int varNameLength;
2118  JsonbValue tmp;
2119  JsonbValue *v;
2120 
2121  if (!vars)
2122  {
2123  value->type = jbvNull;
2124  return;
2125  }
2126 
2128  varName = jspGetString(variable, &varNameLength);
2129  tmp.type = jbvString;
2130  tmp.val.string.val = varName;
2131  tmp.val.string.len = varNameLength;
2132 
2133  v = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
2134 
2135  if (v)
2136  {
2137  *value = *v;
2138  pfree(v);
2139  }
2140  else
2141  {
2142  ereport(ERROR,
2143  (errcode(ERRCODE_UNDEFINED_OBJECT),
2144  errmsg("could not find jsonpath variable \"%s\"",
2145  pnstrdup(varName, varNameLength))));
2146  }
2147 
2148  JsonbInitBinary(&tmp, vars);
2149  setBaseObject(cxt, &tmp, 1);
2150 }
enum ECPGttype type

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

Referenced by getJsonPathItem().

◆ getScalar()

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

Definition at line 2564 of file jsonpath_exec.c.

2565 {
2566  /* Scalars should be always extracted during jsonpath execution. */
2567  Assert(scalar->type != jbvBinary ||
2568  !JsonContainerIsScalar(scalar->val.binary.data));
2569 
2570  return scalar->type == type ? scalar : NULL;
2571 }
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:207

References Assert(), jbvBinary, JsonContainerIsScalar, generate_unaccent_rules::type, JsonbValue::type, and JsonbValue::val.

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

◆ jsonb_path_exists()

Datum jsonb_path_exists ( PG_FUNCTION_ARGS  )

Definition at line 299 of file jsonpath_exec.c.

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

References jsonb_path_exists_internal().

◆ jsonb_path_exists_internal()

static Datum jsonb_path_exists_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 273 of file jsonpath_exec.c.

274 {
275  Jsonb *jb = PG_GETARG_JSONB_P(0);
278  Jsonb *vars = NULL;
279  bool silent = true;
280 
281  if (PG_NARGS() == 4)
282  {
283  vars = PG_GETARG_JSONB_P(2);
284  silent = PG_GETARG_BOOL(3);
285  }
286 
287  res = executeJsonPath(jp, vars, jb, !silent, NULL, tz);
288 
289  PG_FREE_IF_COPY(jb, 0);
290  PG_FREE_IF_COPY(jp, 1);
291 
292  if (jperIsError(res))
293  PG_RETURN_NULL();
294 
296 }
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_NARGS()
Definition: fmgr.h:203
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:391
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:44
static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)

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

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

◆ jsonb_path_exists_opr()

Datum jsonb_path_exists_opr ( PG_FUNCTION_ARGS  )

Definition at line 316 of file jsonpath_exec.c.

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

References jsonb_path_exists_internal().

◆ jsonb_path_exists_tz()

Datum jsonb_path_exists_tz ( PG_FUNCTION_ARGS  )

Definition at line 305 of file jsonpath_exec.c.

306 {
307  return jsonb_path_exists_internal(fcinfo, true);
308 }

References jsonb_path_exists_internal().

◆ jsonb_path_match()

Datum jsonb_path_match ( PG_FUNCTION_ARGS  )

Definition at line 367 of file jsonpath_exec.c.

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

References jsonb_path_match_internal().

◆ jsonb_path_match_internal()

static Datum jsonb_path_match_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 328 of file jsonpath_exec.c.

329 {
330  Jsonb *jb = PG_GETARG_JSONB_P(0);
332  JsonValueList found = {0};
333  Jsonb *vars = NULL;
334  bool silent = true;
335 
336  if (PG_NARGS() == 4)
337  {
338  vars = PG_GETARG_JSONB_P(2);
339  silent = PG_GETARG_BOOL(3);
340  }
341 
342  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
343 
344  PG_FREE_IF_COPY(jb, 0);
345  PG_FREE_IF_COPY(jp, 1);
346 
347  if (JsonValueListLength(&found) == 1)
348  {
349  JsonbValue *jbv = JsonValueListHead(&found);
350 
351  if (jbv->type == jbvBool)
352  PG_RETURN_BOOL(jbv->val.boolean);
353 
354  if (jbv->type == jbvNull)
355  PG_RETURN_NULL();
356  }
357 
358  if (!silent)
359  ereport(ERROR,
360  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
361  errmsg("single boolean result is expected")));
362 
363  PG_RETURN_NULL();
364 }

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

◆ jsonb_path_match_opr()

Datum jsonb_path_match_opr ( PG_FUNCTION_ARGS  )

Definition at line 384 of file jsonpath_exec.c.

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

References jsonb_path_match_internal().

◆ jsonb_path_match_tz()

Datum jsonb_path_match_tz ( PG_FUNCTION_ARGS  )

Definition at line 373 of file jsonpath_exec.c.

374 {
375  return jsonb_path_match_internal(fcinfo, true);
376 }

References jsonb_path_match_internal().

◆ jsonb_path_query()

Datum jsonb_path_query ( PG_FUNCTION_ARGS  )

Definition at line 442 of file jsonpath_exec.c.

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

References jsonb_path_query_internal().

◆ jsonb_path_query_array()

Datum jsonb_path_query_array ( PG_FUNCTION_ARGS  )

Definition at line 473 of file jsonpath_exec.c.

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

References jsonb_path_query_array_internal().

◆ jsonb_path_query_array_internal()

static Datum jsonb_path_query_array_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 459 of file jsonpath_exec.c.

460 {
461  Jsonb *jb = PG_GETARG_JSONB_P(0);
463  JsonValueList found = {0};
465  bool silent = PG_GETARG_BOOL(3);
466 
467  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
468 
470 }
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:393
static JsonbValue * wrapItemsInArray(const JsonValueList *items)

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

◆ jsonb_path_query_array_tz()

Datum jsonb_path_query_array_tz ( PG_FUNCTION_ARGS  )

Definition at line 479 of file jsonpath_exec.c.

480 {
481  return jsonb_path_query_array_internal(fcinfo, true);
482 }

References jsonb_path_query_array_internal().

◆ jsonb_path_query_first()

Datum jsonb_path_query_first ( PG_FUNCTION_ARGS  )

Definition at line 507 of file jsonpath_exec.c.

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

References jsonb_path_query_first_internal().

◆ jsonb_path_query_first_internal()

static Datum jsonb_path_query_first_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 490 of file jsonpath_exec.c.

491 {
492  Jsonb *jb = PG_GETARG_JSONB_P(0);
494  JsonValueList found = {0};
496  bool silent = PG_GETARG_BOOL(3);
497 
498  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
499 
500  if (JsonValueListLength(&found) >= 1)
502  else
503  PG_RETURN_NULL();
504 }

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

◆ jsonb_path_query_first_tz()

Datum jsonb_path_query_first_tz ( PG_FUNCTION_ARGS  )

Definition at line 513 of file jsonpath_exec.c.

514 {
515  return jsonb_path_query_first_internal(fcinfo, true);
516 }

References jsonb_path_query_first_internal().

◆ jsonb_path_query_internal()

static Datum jsonb_path_query_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 396 of file jsonpath_exec.c.

397 {
398  FuncCallContext *funcctx;
399  List *found;
400  JsonbValue *v;
401  ListCell *c;
402 
403  if (SRF_IS_FIRSTCALL())
404  {
405  JsonPath *jp;
406  Jsonb *jb;
407  MemoryContext oldcontext;
408  Jsonb *vars;
409  bool silent;
410  JsonValueList found = {0};
411 
412  funcctx = SRF_FIRSTCALL_INIT();
413  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
414 
415  jb = PG_GETARG_JSONB_P_COPY(0);
418  silent = PG_GETARG_BOOL(3);
419 
420  (void) executeJsonPath(jp, vars, jb, !silent, &found, tz);
421 
422  funcctx->user_fctx = JsonValueListGetList(&found);
423 
424  MemoryContextSwitchTo(oldcontext);
425  }
426 
427  funcctx = SRF_PERCALL_SETUP();
428  found = funcctx->user_fctx;
429 
430  c = list_head(found);
431 
432  if (c == NULL)
433  SRF_RETURN_DONE(funcctx);
434 
435  v = lfirst(c);
436  funcctx->user_fctx = list_delete_first(found);
437 
439 }
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
#define PG_GETARG_JSONB_P_COPY(x)
Definition: jsonb.h:392
static Datum JsonbPGetDatum(const Jsonb *p)
Definition: jsonb.h:386
#define PG_GETARG_JSONPATH_P_COPY(x)
Definition: jsonpath.h:45
static List * JsonValueListGetList(JsonValueList *jvl)
List * list_delete_first(List *list)
Definition: list.c:942
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char * c
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
Definition: pg_list.h:54

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

◆ jsonb_path_query_tz()

Datum jsonb_path_query_tz ( PG_FUNCTION_ARGS  )

Definition at line 448 of file jsonpath_exec.c.

449 {
450  return jsonb_path_query_internal(fcinfo, true);
451 }

References jsonb_path_query_internal().

◆ JsonbArraySize()

static int JsonbArraySize ( JsonbValue jb)
static

Definition at line 2158 of file jsonpath_exec.c.

2159 {
2160  Assert(jb->type != jbvArray);
2161 
2162  if (jb->type == jbvBinary)
2163  {
2164  JsonbContainer *jbc = jb->val.binary.data;
2165 
2166  if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
2167  return JsonContainerSize(jbc);
2168  }
2169 
2170  return -1;
2171 }
#define JsonContainerIsArray(jc)
Definition: jsonb.h:209

References Assert(), jbvArray, jbvBinary, JsonContainerIsArray, JsonContainerIsScalar, JsonContainerSize, JsonbValue::type, and JsonbValue::val.

Referenced by executeItemOptUnwrapTarget().

◆ JsonbInitBinary()

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

Definition at line 2527 of file jsonpath_exec.c.

2528 {
2529  jbv->type = jbvBinary;
2530  jbv->val.binary.data = &jb->root;
2531  jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb);
2532 
2533  return jbv;
2534 }
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

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

◆ JsonbType()

static int JsonbType ( JsonbValue jb)
static

Definition at line 2540 of file jsonpath_exec.c.

2541 {
2542  int type = jb->type;
2543 
2544  if (jb->type == jbvBinary)
2545  {
2546  JsonbContainer *jbc = (void *) jb->val.binary.data;
2547 
2548  /* Scalars should be always extracted during jsonpath execution. */
2550 
2551  if (JsonContainerIsObject(jbc))
2552  type = jbvObject;
2553  else if (JsonContainerIsArray(jbc))
2554  type = jbvArray;
2555  else
2556  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
2557  }
2558 
2559  return type;
2560 }
uint32 header
Definition: jsonb.h:192

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

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

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 2439 of file jsonpath_exec.c.

2440 {
2441  if (jvl->singleton)
2442  {
2443  jvl->list = list_make2(jvl->singleton, jbv);
2444  jvl->singleton = NULL;
2445  }
2446  else if (!jvl->list)
2447  jvl->singleton = jbv;
2448  else
2449  jvl->list = lappend(jvl->list, jbv);
2450 }
List * lappend(List *list, void *datum)
Definition: list.c:338
#define list_make2(x1, x2)
Definition: pg_list.h:214
JsonbValue * singleton

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

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

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 2471 of file jsonpath_exec.c.

2472 {
2473  if (jvl->singleton)
2474  return list_make1(jvl->singleton);
2475 
2476  return jvl->list;
2477 }
#define list_make1(x1)
Definition: pg_list.h:212

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

Referenced by jsonb_path_query_internal().

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

Definition at line 2465 of file jsonpath_exec.c.

2466 {
2467  return jvl->singleton ? jvl->singleton : linitial(jvl->list);
2468 }
#define linitial(l)
Definition: pg_list.h:178

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

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

◆ JsonValueListInitIterator()

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

Definition at line 2480 of file jsonpath_exec.c.

2481 {
2482  if (jvl->singleton)
2483  {
2484  it->value = jvl->singleton;
2485  it->list = NIL;
2486  it->next = NULL;
2487  }
2488  else if (jvl->list != NIL)
2489  {
2490  it->value = (JsonbValue *) linitial(jvl->list);
2491  it->list = jvl->list;
2492  it->next = list_second_cell(jvl->list);
2493  }
2494  else
2495  {
2496  it->value = NULL;
2497  it->list = NIL;
2498  it->next = NULL;
2499  }
2500 }
#define NIL
Definition: pg_list.h:68
static ListCell * list_second_cell(const List *l)
Definition: pg_list.h:142

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

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

◆ JsonValueListIsEmpty()

static bool JsonValueListIsEmpty ( JsonValueList jvl)
static

Definition at line 2459 of file jsonpath_exec.c.

2460 {
2461  return !jvl->singleton && (jvl->list == NIL);
2462 }

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

Referenced by executeBoolItem(), and executeJsonPath().

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

Definition at line 2453 of file jsonpath_exec.c.

2454 {
2455  return jvl->singleton ? 1 : list_length(jvl->list);
2456 }
static int list_length(const List *l)
Definition: pg_list.h:152

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

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

◆ JsonValueListNext()

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

Definition at line 2506 of file jsonpath_exec.c.

2507 {
2508  JsonbValue *result = it->value;
2509 
2510  if (it->next)
2511  {
2512  it->value = lfirst(it->next);
2513  it->next = lnext(it->list, it->next);
2514  }
2515  else
2516  {
2517  it->value = NULL;
2518  }
2519 
2520  return result;
2521 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343

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

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

◆ setBaseObject()

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

Definition at line 2427 of file jsonpath_exec.c.

2428 {
2429  JsonBaseObjectInfo baseObject = cxt->baseObject;
2430 
2431  cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
2432  (JsonbContainer *) jbv->val.binary.data;
2433  cxt->baseObject.id = id;
2434 
2435  return baseObject;
2436 }

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

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

◆ wrapItemsInArray()

static JsonbValue * wrapItemsInArray ( const JsonValueList items)
static

Definition at line 2575 of file jsonpath_exec.c.

2576 {
2577  JsonbParseState *ps = NULL;
2579  JsonbValue *jbv;
2580 
2582 
2583  JsonValueListInitIterator(items, &it);
2584  while ((jbv = JsonValueListNext(items, &it)))
2585  pushJsonbValue(&ps, WJB_ELEM, jbv);
2586 
2587  return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
2588 }
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26

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

Referenced by jsonb_path_query_array_internal().