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

Go to the source code of this file.

Data Structures

struct  JsonBaseObjectInfo
 
struct  JsonPathExecContext
 
struct  JsonLikeRegexContext
 
struct  JsonValueList
 
struct  JsonValueListIterator
 

Macros

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

Typedefs

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

Enumerations

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

Functions

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

Macro Definition Documentation

◆ jperIsError

◆ jspAutoUnwrap

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

◆ jspAutoWrap

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

Definition at line 157 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspIgnoreStructuralErrors

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

Definition at line 158 of file jsonpath_exec.c.

Referenced by executeItemOptUnwrapTarget().

◆ jspStrictAbsenseOfErrors

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

Definition at line 155 of file jsonpath_exec.c.

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

◆ jspThrowErrors

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

◆ RETURN_ERROR

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

Definition at line 162 of file jsonpath_exec.c.

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

Typedef Documentation

◆ BinaryArithmFunc

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

Definition at line 174 of file jsonpath_exec.c.

◆ JsonBaseObjectInfo

◆ JsonLikeRegexContext

◆ JsonPathBool

typedef enum JsonPathBool JsonPathBool

◆ JsonPathExecContext

◆ JsonPathExecResult

◆ JsonPathPredicateCallback

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

Definition at line 170 of file jsonpath_exec.c.

◆ JsonValueList

typedef struct JsonValueList JsonValueList

◆ JsonValueListIterator

Enumeration Type Documentation

◆ JsonPathBool

Enumerator
jpbFalse 
jpbTrue 
jpbUnknown 

Definition at line 121 of file jsonpath_exec.c.

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

◆ JsonPathExecResult

Enumerator
jperOk 
jperNotFound 
jperError 

Definition at line 129 of file jsonpath_exec.c.

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

Function Documentation

◆ appendBoolResult()

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

Definition at line 2035 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ binaryCompareStrings()

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

Definition at line 2169 of file jsonpath_exec.c.

References cmp(), and Min.

Referenced by compareStrings().

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

◆ castTimeToTimeTz()

static Datum castTimeToTimeTz ( Datum  time,
bool  useTz 
)
static

Definition at line 2587 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

2588 {
2589  checkTimezoneIsUsedForCast(useTz, "time", "timetz");
2590 
2591  return DirectFunctionCall1(time_timetz, time);
2592 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:615
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2567

◆ checkTimezoneIsUsedForCast()

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

Definition at line 2575 of file jsonpath_exec.c.

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

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

2576 {
2577  if (!useTz)
2578  ereport(ERROR,
2579  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2580  errmsg("cannot convert value from %s to %s without timezone usage",
2581  type1, type2),
2582  errhint("Use *_tz() function for timezone support.")));
2583 }
int errhint(const char *fmt,...)
Definition: elog.c:1069
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ cmpDateToTimestamp()

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

Definition at line 2641 of file jsonpath_exec.c.

References cmpTimestampWithOverflow(), and date2timestamp_opt_overflow().

Referenced by compareDatetime().

2642 {
2643  TimestampTz ts1;
2644  int overflow = 0;
2645 
2646  ts1 = date2timestamp_opt_overflow(date1, &overflow);
2647 
2648  return cmpTimestampWithOverflow(ts1, overflow, ts2);
2649 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
Timestamp date2timestamp_opt_overflow(DateADT dateVal, int *overflow)
Definition: date.c:562

◆ cmpDateToTimestampTz()

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

Definition at line 2655 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

2656 {
2657  TimestampTz tstz1;
2658  int overflow = 0;
2659 
2660  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
2661 
2662  tstz1 = date2timestamptz_opt_overflow(date1, &overflow);
2663 
2664  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2665 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
TimestampTz date2timestamptz_opt_overflow(DateADT dateVal, int *overflow)
Definition: date.c:616
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

◆ cmpTimestampToTimestampTz()

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

Definition at line 2671 of file jsonpath_exec.c.

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

Referenced by compareDatetime().

2672 {
2673  TimestampTz tstz1;
2674  int overflow = 0;
2675 
2676  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
2677 
2678  tstz1 = timestamp2timestamptz_opt_overflow(ts1, &overflow);
2679 
2680  return cmpTimestampWithOverflow(tstz1, overflow, tstz2);
2681 }
int64 TimestampTz
Definition: timestamp.h:39
static int cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2)
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:5189
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

◆ cmpTimestampWithOverflow()

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

Definition at line 2604 of file jsonpath_exec.c.

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

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

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

◆ compareDatetime()

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

Definition at line 2689 of file jsonpath_exec.c.

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

Referenced by compareItems().

2691 {
2692  PGFunction cmpfunc;
2693 
2694  *cast_error = false;
2695 
2696  switch (typid1)
2697  {
2698  case DATEOID:
2699  switch (typid2)
2700  {
2701  case DATEOID:
2702  cmpfunc = date_cmp;
2703 
2704  break;
2705 
2706  case TIMESTAMPOID:
2707  return cmpDateToTimestamp(DatumGetDateADT(val1),
2708  DatumGetTimestamp(val2),
2709  useTz);
2710 
2711  case TIMESTAMPTZOID:
2713  DatumGetTimestampTz(val2),
2714  useTz);
2715 
2716  case TIMEOID:
2717  case TIMETZOID:
2718  *cast_error = true; /* uncomparable types */
2719  return 0;
2720 
2721  default:
2722  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2723  typid2);
2724  }
2725  break;
2726 
2727  case TIMEOID:
2728  switch (typid2)
2729  {
2730  case TIMEOID:
2731  cmpfunc = time_cmp;
2732 
2733  break;
2734 
2735  case TIMETZOID:
2736  val1 = castTimeToTimeTz(val1, useTz);
2737  cmpfunc = timetz_cmp;
2738 
2739  break;
2740 
2741  case DATEOID:
2742  case TIMESTAMPOID:
2743  case TIMESTAMPTZOID:
2744  *cast_error = true; /* uncomparable types */
2745  return 0;
2746 
2747  default:
2748  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2749  typid2);
2750  }
2751  break;
2752 
2753  case TIMETZOID:
2754  switch (typid2)
2755  {
2756  case TIMEOID:
2757  val2 = castTimeToTimeTz(val2, useTz);
2758  cmpfunc = timetz_cmp;
2759 
2760  break;
2761 
2762  case TIMETZOID:
2763  cmpfunc = timetz_cmp;
2764 
2765  break;
2766 
2767  case DATEOID:
2768  case TIMESTAMPOID:
2769  case TIMESTAMPTZOID:
2770  *cast_error = true; /* uncomparable types */
2771  return 0;
2772 
2773  default:
2774  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2775  typid2);
2776  }
2777  break;
2778 
2779  case TIMESTAMPOID:
2780  switch (typid2)
2781  {
2782  case DATEOID:
2783  return -cmpDateToTimestamp(DatumGetDateADT(val2),
2784  DatumGetTimestamp(val1),
2785  useTz);
2786 
2787  case TIMESTAMPOID:
2788  cmpfunc = timestamp_cmp;
2789 
2790  break;
2791 
2792  case TIMESTAMPTZOID:
2794  DatumGetTimestampTz(val2),
2795  useTz);
2796 
2797  case TIMEOID:
2798  case TIMETZOID:
2799  *cast_error = true; /* uncomparable types */
2800  return 0;
2801 
2802  default:
2803  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2804  typid2);
2805  }
2806  break;
2807 
2808  case TIMESTAMPTZOID:
2809  switch (typid2)
2810  {
2811  case DATEOID:
2812  return -cmpDateToTimestampTz(DatumGetDateADT(val2),
2813  DatumGetTimestampTz(val1),
2814  useTz);
2815 
2816  case TIMESTAMPOID:
2818  DatumGetTimestampTz(val1),
2819  useTz);
2820 
2821  case TIMESTAMPTZOID:
2822  cmpfunc = timestamp_cmp;
2823 
2824  break;
2825 
2826  case TIMEOID:
2827  case TIMETZOID:
2828  *cast_error = true; /* uncomparable types */
2829  return 0;
2830 
2831  default:
2832  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
2833  typid2);
2834  }
2835  break;
2836 
2837  default:
2838  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);
2839  }
2840 
2841  if (*cast_error)
2842  return 0; /* cast error */
2843 
2844  return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2));
2845 }
static Datum castTimeToTimeTz(Datum time, bool useTz)
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2275
Datum(* PGFunction)(FunctionCallInfo fcinfo)
Definition: fmgr.h:40
#define DatumGetDateADT(X)
Definition: date.h:53
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition: timestamp.c:2119
#define ERROR
Definition: elog.h:43
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1531
#define DatumGetTimestampTz(X)
Definition: timestamp.h:28
static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz)
Datum date_cmp(PG_FUNCTION_ARGS)
Definition: date.c:428
#define elog(elevel,...)
Definition: elog.h:228
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617
static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz)
static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz)
#define DatumGetTimestamp(X)
Definition: timestamp.h:27

◆ compareItems()

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

Definition at line 2257 of file jsonpath_exec.c.

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

Referenced by executeComparison().

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

◆ compareNumeric()

static int compareNumeric ( Numeric  a,
Numeric  b 
)
static

Definition at line 2353 of file jsonpath_exec.c.

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

Referenced by compareItems().

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

◆ compareStrings()

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

Definition at line 2190 of file jsonpath_exec.c.

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

Referenced by compareItems().

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

◆ copyJsonbValue()

static JsonbValue * copyJsonbValue ( JsonbValue src)
static

Definition at line 2361 of file jsonpath_exec.c.

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

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

◆ executeAnyItem()

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

Definition at line 1379 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget(), and executeItemUnwrapTargetArray().

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

◆ executeBinaryArithmExpr()

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

Definition at line 1550 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ executeBoolItem()

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

Definition at line 1225 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget(), and executeNestedBoolItem().

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

◆ executeComparison()

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

Definition at line 2158 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeDateTimeMethod()

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

Definition at line 1778 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ executeItem()

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

Definition at line 599 of file jsonpath_exec.c.

References executeItemOptUnwrapTarget(), and jspAutoUnwrap.

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

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

◆ executeItemOptUnwrapResult()

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

Definition at line 1173 of file jsonpath_exec.c.

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

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

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

◆ executeItemOptUnwrapResultNoThrow()

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

Definition at line 1208 of file jsonpath_exec.c.

References executeItemOptUnwrapResult(), and JsonPathExecContext::throwErrors.

Referenced by executeBoolItem(), and executePredicate().

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

◆ executeItemOptUnwrapTarget()

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

Definition at line 611 of file jsonpath_exec.c.

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

Referenced by executeAnyItem(), and executeItem().

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

◆ executeItemUnwrapTargetArray()

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

Definition at line 1122 of file jsonpath_exec.c.

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

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

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

◆ executeJsonPath()

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

Definition at line 539 of file jsonpath_exec.c.

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

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

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

◆ executeKeyValueMethod()

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

Definition at line 1924 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ executeLikeRegex()

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

Definition at line 1712 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeNestedBoolItem()

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

Definition at line 1358 of file jsonpath_exec.c.

References JsonPathExecContext::current, and executeBoolItem().

Referenced by executeItemOptUnwrapTarget().

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

◆ executeNextItem()

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

Definition at line 1142 of file jsonpath_exec.c.

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

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

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

◆ executeNumericItemMethod()

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

Definition at line 1742 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ executePredicate()

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

Definition at line 1470 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeStartsWith()

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

Definition at line 1688 of file jsonpath_exec.c.

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

Referenced by executeBoolItem().

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

◆ executeUnaryArithmExpr()

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

Definition at line 1621 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ getArrayIndex()

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

Definition at line 2375 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ getJsonPathItem()

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

Definition at line 2063 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ getJsonPathVariable()

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

Definition at line 2096 of file jsonpath_exec.c.

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

Referenced by getJsonPathItem().

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

◆ getScalar()

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

Definition at line 2547 of file jsonpath_exec.c.

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

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

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

◆ jsonb_path_exists()

Datum jsonb_path_exists ( PG_FUNCTION_ARGS  )

Definition at line 298 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

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

◆ jsonb_path_exists_internal()

static Datum jsonb_path_exists_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 272 of file jsonpath_exec.c.

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

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

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

◆ jsonb_path_exists_opr()

Datum jsonb_path_exists_opr ( PG_FUNCTION_ARGS  )

Definition at line 315 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

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

◆ jsonb_path_exists_tz()

Datum jsonb_path_exists_tz ( PG_FUNCTION_ARGS  )

Definition at line 304 of file jsonpath_exec.c.

References jsonb_path_exists_internal().

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

◆ jsonb_path_match()

Datum jsonb_path_match ( PG_FUNCTION_ARGS  )

Definition at line 366 of file jsonpath_exec.c.

References jsonb_path_match_internal().

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

◆ jsonb_path_match_internal()

static Datum jsonb_path_match_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 327 of file jsonpath_exec.c.

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

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

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

◆ jsonb_path_match_opr()

Datum jsonb_path_match_opr ( PG_FUNCTION_ARGS  )

Definition at line 383 of file jsonpath_exec.c.

References jsonb_path_match_internal().

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

◆ jsonb_path_match_tz()

Datum jsonb_path_match_tz ( PG_FUNCTION_ARGS  )

Definition at line 372 of file jsonpath_exec.c.

References jsonb_path_match_internal().

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

◆ jsonb_path_query()

Datum jsonb_path_query ( PG_FUNCTION_ARGS  )

Definition at line 441 of file jsonpath_exec.c.

References jsonb_path_query_internal().

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

◆ jsonb_path_query_array()

Datum jsonb_path_query_array ( PG_FUNCTION_ARGS  )

Definition at line 472 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

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

◆ jsonb_path_query_array_internal()

static Datum jsonb_path_query_array_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 458 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_array(), and jsonb_path_query_array_tz().

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

◆ jsonb_path_query_array_tz()

Datum jsonb_path_query_array_tz ( PG_FUNCTION_ARGS  )

Definition at line 478 of file jsonpath_exec.c.

References jsonb_path_query_array_internal().

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

◆ jsonb_path_query_first()

Datum jsonb_path_query_first ( PG_FUNCTION_ARGS  )

Definition at line 506 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

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

◆ jsonb_path_query_first_internal()

static Datum jsonb_path_query_first_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 489 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_first(), and jsonb_path_query_first_tz().

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

◆ jsonb_path_query_first_tz()

Datum jsonb_path_query_first_tz ( PG_FUNCTION_ARGS  )

Definition at line 512 of file jsonpath_exec.c.

References jsonb_path_query_first_internal().

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

◆ jsonb_path_query_internal()

static Datum jsonb_path_query_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 395 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query(), and jsonb_path_query_tz().

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

◆ jsonb_path_query_tz()

Datum jsonb_path_query_tz ( PG_FUNCTION_ARGS  )

Definition at line 447 of file jsonpath_exec.c.

References jsonb_path_query_internal().

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

◆ JsonbArraySize()

static int JsonbArraySize ( JsonbValue jb)
static

Definition at line 2141 of file jsonpath_exec.c.

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

Referenced by executeItemOptUnwrapTarget().

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

◆ JsonbInitBinary()

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

Definition at line 2510 of file jsonpath_exec.c.

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

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

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

◆ JsonbType()

static int JsonbType ( JsonbValue jb)
static

Definition at line 2523 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 2422 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 2454 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_internal().

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

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

Definition at line 2448 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListInitIterator()

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

Definition at line 2463 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListIsEmpty()

static bool JsonValueListIsEmpty ( JsonValueList jvl)
static

Definition at line 2442 of file jsonpath_exec.c.

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

Referenced by executeBoolItem(), and executeJsonPath().

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

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

Definition at line 2436 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListNext()

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

Definition at line 2489 of file jsonpath_exec.c.

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

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

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

◆ setBaseObject()

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

Definition at line 2410 of file jsonpath_exec.c.

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

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

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

◆ wrapItemsInArray()

static JsonbValue * wrapItemsInArray ( const JsonValueList items)
static

Definition at line 2558 of file jsonpath_exec.c.

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

Referenced by jsonb_path_query_array_internal().

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