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

Go to the source code of this file.

Data Structures

struct  JsonBaseObjectInfo
 
struct  JsonPathExecContext
 
struct  JsonLikeRegexContext
 
struct  JsonValueList
 
struct  JsonValueListIterator
 

Macros

#define jperIsError(jper)   ((jper) == jperError)
 
#define jspStrictAbsenceOfErrors(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 JsonbValue *(* JsonPathGetVarCallback) (void *vars, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)
 
typedef int(* JsonPathCountVarsCallback) (void *vars)
 
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, void *vars, JsonPathGetVarCallback getVar, JsonPathCountVarsCallback countVars, 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, JsonbValue *value)
 
static int countVariablesFromJsonb (void *varsJsonb)
 
static JsonbValuegetJsonPathVariableFromJsonb (void *varsJsonb, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)
 
static int JsonbArraySize (JsonbValue *jb)
 
static JsonPathBool executeComparison (JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)
 
static JsonPathBool compareItems (int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)
 
static int compareNumeric (Numeric a, Numeric b)
 
static JsonbValuecopyJsonbValue (JsonbValue *src)
 
static JsonPathExecResult getArrayIndex (JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)
 
static JsonBaseObjectInfo setBaseObject (JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
 
static void JsonValueListAppend (JsonValueList *jvl, JsonbValue *jbv)
 
static int JsonValueListLength (const JsonValueList *jvl)
 
static bool JsonValueListIsEmpty (JsonValueList *jvl)
 
static JsonbValueJsonValueListHead (JsonValueList *jvl)
 
static ListJsonValueListGetList (JsonValueList *jvl)
 
static void JsonValueListInitIterator (const JsonValueList *jvl, JsonValueListIterator *it)
 
static JsonbValueJsonValueListNext (const JsonValueList *jvl, JsonValueListIterator *it)
 
static int JsonbType (JsonbValue *jb)
 
static JsonbValueJsonbInitBinary (JsonbValue *jbv, Jsonb *jb)
 
static JsonbValuegetScalar (JsonbValue *scalar, enum jbvType type)
 
static JsonbValuewrapItemsInArray (const JsonValueList *items)
 
static int compareDatetime (Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *cast_error)
 
static void checkTimezoneIsUsedForCast (bool useTz, const char *type1, const char *type2)
 
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 Datum castTimeToTimeTz (Datum time, bool useTz)
 
static int cmpDateToTimestamp (DateADT date1, Timestamp ts2, bool useTz)
 
static int cmpDateToTimestampTz (DateADT date1, TimestampTz tstz2, bool useTz)
 
static int cmpTimestampToTimestampTz (Timestamp ts1, TimestampTz tstz2, bool useTz)
 

Macro Definition Documentation

◆ jperIsError

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

Definition at line 144 of file jsonpath_exec.c.

◆ jspAutoUnwrap

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

Definition at line 164 of file jsonpath_exec.c.

◆ jspAutoWrap

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

Definition at line 165 of file jsonpath_exec.c.

◆ jspIgnoreStructuralErrors

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

Definition at line 166 of file jsonpath_exec.c.

◆ jspStrictAbsenceOfErrors

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

Definition at line 163 of file jsonpath_exec.c.

◆ jspThrowErrors

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

Definition at line 167 of file jsonpath_exec.c.

◆ RETURN_ERROR

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

Definition at line 170 of file jsonpath_exec.c.

Typedef Documentation

◆ BinaryArithmFunc

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

Definition at line 182 of file jsonpath_exec.c.

◆ JsonBaseObjectInfo

◆ JsonLikeRegexContext

◆ JsonPathBool

typedef enum JsonPathBool JsonPathBool

◆ JsonPathCountVarsCallback

typedef int(* JsonPathCountVarsCallback) (void *vars)

Definition at line 93 of file jsonpath_exec.c.

◆ JsonPathExecContext

◆ JsonPathExecResult

◆ JsonPathGetVarCallback

typedef JsonbValue*(* JsonPathGetVarCallback) (void *vars, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)

Definition at line 91 of file jsonpath_exec.c.

◆ JsonPathPredicateCallback

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

Definition at line 178 of file jsonpath_exec.c.

◆ JsonValueList

typedef struct JsonValueList JsonValueList

◆ JsonValueListIterator

Enumeration Type Documentation

◆ JsonPathBool

Enumerator
jpbFalse 
jpbTrue 
jpbUnknown 

Definition at line 129 of file jsonpath_exec.c.

130 {
131  jpbFalse = 0,
132  jpbTrue = 1,
133  jpbUnknown = 2
134 } JsonPathBool;
JsonPathBool
@ jpbUnknown
@ jpbFalse
@ jpbTrue

◆ JsonPathExecResult

Enumerator
jperOk 
jperNotFound 
jperError 

Definition at line 137 of file jsonpath_exec.c.

138 {
139  jperOk = 0,
140  jperNotFound = 1,
141  jperError = 2
JsonPathExecResult
@ jperNotFound
@ jperOk

Function Documentation

◆ appendBoolResult()

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

Definition at line 2797 of file jsonpath_exec.c.

2799 {
2801  JsonbValue jbv;
2802 
2803  if (!jspGetNext(jsp, &next) && !found)
2804  return jperOk; /* found singleton boolean value */
2805 
2806  if (res == jpbUnknown)
2807  {
2808  jbv.type = jbvNull;
2809  }
2810  else
2811  {
2812  jbv.type = jbvBool;
2813  jbv.val.boolean = res == jpbTrue;
2814  }
2815 
2816  return executeNextItem(cxt, jsp, &next, &jbv, found, true);
2817 }
static int32 next
Definition: blutils.c:221
@ jbvBool
Definition: jsonb.h:231
@ jbvNull
Definition: jsonb.h:228
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1090
static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, JsonPathItem *cur, JsonPathItem *next, JsonbValue *v, JsonValueList *found, bool copy)
enum jbvType type
Definition: jsonb.h:255
char * val
Definition: jsonb.h:264

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

Referenced by executeItemOptUnwrapTarget().

◆ binaryCompareStrings()

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

Definition at line 2970 of file jsonpath_exec.c.

2972 {
2973  int cmp;
2974 
2975  cmp = memcmp(s1, s2, Min(len1, len2));
2976 
2977  if (cmp != 0)
2978  return cmp;
2979 
2980  if (len1 == len2)
2981  return 0;
2982 
2983  return len1 < len2 ? -1 : 1;
2984 }
#define Min(x, y)
Definition: c.h:993
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

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

Referenced by compareStrings().

◆ castTimeToTimeTz()

static Datum castTimeToTimeTz ( Datum  time,
bool  useTz 
)
static

Definition at line 3388 of file jsonpath_exec.c.

3389 {
3390  checkTimezoneIsUsedForCast(useTz, "time", "timetz");
3391 
3392  return DirectFunctionCall1(time_timetz, time);
3393 }
Datum time_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2828
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
static void checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2)

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

Referenced by compareDatetime().

◆ checkTimezoneIsUsedForCast()

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

Definition at line 3376 of file jsonpath_exec.c.

3377 {
3378  if (!useTz)
3379  ereport(ERROR,
3380  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3381  errmsg("cannot convert value from %s to %s without time zone usage",
3382  type1, type2),
3383  errhint("Use *_tz() function for time zone support.")));
3384 }
int errhint(const char *fmt,...)
Definition: elog.c:1322
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1075
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149

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

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

◆ cmpDateToTimestamp()

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

Definition at line 3400 of file jsonpath_exec.c.

3401 {
3402  return date_cmp_timestamp_internal(date1, ts2);
3403 }
int32 date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2)
Definition: date.c:743

References date_cmp_timestamp_internal().

Referenced by compareDatetime().

◆ cmpDateToTimestampTz()

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

Definition at line 3409 of file jsonpath_exec.c.

3410 {
3411  checkTimezoneIsUsedForCast(useTz, "date", "timestamptz");
3412 
3413  return date_cmp_timestamptz_internal(date1, tstz2);
3414 }
int32 date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2)
Definition: date.c:823

References checkTimezoneIsUsedForCast(), and date_cmp_timestamptz_internal().

Referenced by compareDatetime().

◆ cmpTimestampToTimestampTz()

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

Definition at line 3420 of file jsonpath_exec.c.

3421 {
3422  checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz");
3423 
3424  return timestamp_cmp_timestamptz_internal(ts1, tstz2);
3425 }
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2326

References checkTimezoneIsUsedForCast(), and timestamp_cmp_timestamptz_internal().

Referenced by compareDatetime().

◆ compareDatetime()

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

Definition at line 3433 of file jsonpath_exec.c.

3435 {
3436  PGFunction cmpfunc;
3437 
3438  *cast_error = false;
3439 
3440  switch (typid1)
3441  {
3442  case DATEOID:
3443  switch (typid2)
3444  {
3445  case DATEOID:
3446  cmpfunc = date_cmp;
3447 
3448  break;
3449 
3450  case TIMESTAMPOID:
3451  return cmpDateToTimestamp(DatumGetDateADT(val1),
3452  DatumGetTimestamp(val2),
3453  useTz);
3454 
3455  case TIMESTAMPTZOID:
3457  DatumGetTimestampTz(val2),
3458  useTz);
3459 
3460  case TIMEOID:
3461  case TIMETZOID:
3462  *cast_error = true; /* uncomparable types */
3463  return 0;
3464 
3465  default:
3466  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3467  typid2);
3468  }
3469  break;
3470 
3471  case TIMEOID:
3472  switch (typid2)
3473  {
3474  case TIMEOID:
3475  cmpfunc = time_cmp;
3476 
3477  break;
3478 
3479  case TIMETZOID:
3480  val1 = castTimeToTimeTz(val1, useTz);
3481  cmpfunc = timetz_cmp;
3482 
3483  break;
3484 
3485  case DATEOID:
3486  case TIMESTAMPOID:
3487  case TIMESTAMPTZOID:
3488  *cast_error = true; /* uncomparable types */
3489  return 0;
3490 
3491  default:
3492  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3493  typid2);
3494  }
3495  break;
3496 
3497  case TIMETZOID:
3498  switch (typid2)
3499  {
3500  case TIMEOID:
3501  val2 = castTimeToTimeTz(val2, useTz);
3502  cmpfunc = timetz_cmp;
3503 
3504  break;
3505 
3506  case TIMETZOID:
3507  cmpfunc = timetz_cmp;
3508 
3509  break;
3510 
3511  case DATEOID:
3512  case TIMESTAMPOID:
3513  case TIMESTAMPTZOID:
3514  *cast_error = true; /* uncomparable types */
3515  return 0;
3516 
3517  default:
3518  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3519  typid2);
3520  }
3521  break;
3522 
3523  case TIMESTAMPOID:
3524  switch (typid2)
3525  {
3526  case DATEOID:
3527  return -cmpDateToTimestamp(DatumGetDateADT(val2),
3528  DatumGetTimestamp(val1),
3529  useTz);
3530 
3531  case TIMESTAMPOID:
3532  cmpfunc = timestamp_cmp;
3533 
3534  break;
3535 
3536  case TIMESTAMPTZOID:
3538  DatumGetTimestampTz(val2),
3539  useTz);
3540 
3541  case TIMEOID:
3542  case TIMETZOID:
3543  *cast_error = true; /* uncomparable types */
3544  return 0;
3545 
3546  default:
3547  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3548  typid2);
3549  }
3550  break;
3551 
3552  case TIMESTAMPTZOID:
3553  switch (typid2)
3554  {
3555  case DATEOID:
3556  return -cmpDateToTimestampTz(DatumGetDateADT(val2),
3557  DatumGetTimestampTz(val1),
3558  useTz);
3559 
3560  case TIMESTAMPOID:
3562  DatumGetTimestampTz(val1),
3563  useTz);
3564 
3565  case TIMESTAMPTZOID:
3566  cmpfunc = timestamp_cmp;
3567 
3568  break;
3569 
3570  case TIMEOID:
3571  case TIMETZOID:
3572  *cast_error = true; /* uncomparable types */
3573  return 0;
3574 
3575  default:
3576  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
3577  typid2);
3578  }
3579  break;
3580 
3581  default:
3582  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u", typid1);
3583  }
3584 
3585  if (*cast_error)
3586  return 0; /* cast error */
3587 
3588  return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2));
3589 }
Datum timestamp_cmp(PG_FUNCTION_ARGS)
Definition: timestamp.c:2271
Datum date_cmp(PG_FUNCTION_ARGS)
Definition: date.c:437
Datum time_cmp(PG_FUNCTION_ARGS)
Definition: date.c:1734
Datum timetz_cmp(PG_FUNCTION_ARGS)
Definition: date.c:2524
static DateADT DatumGetDateADT(Datum X)
Definition: date.h:54
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
Datum(* PGFunction)(FunctionCallInfo fcinfo)
Definition: fmgr.h:40
static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz)
static Datum castTimeToTimeTz(Datum time, bool useTz)
static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz)
static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz)
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28
static TimestampTz DatumGetTimestampTz(Datum X)
Definition: timestamp.h:34

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

Referenced by compareItems().

◆ compareItems()

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

Definition at line 3058 of file jsonpath_exec.c.

3059 {
3060  int cmp;
3061  bool res;
3062 
3063  if (jb1->type != jb2->type)
3064  {
3065  if (jb1->type == jbvNull || jb2->type == jbvNull)
3066 
3067  /*
3068  * Equality and order comparison of nulls to non-nulls returns
3069  * always false, but inequality comparison returns true.
3070  */
3071  return op == jpiNotEqual ? jpbTrue : jpbFalse;
3072 
3073  /* Non-null items of different types are not comparable. */
3074  return jpbUnknown;
3075  }
3076 
3077  switch (jb1->type)
3078  {
3079  case jbvNull:
3080  cmp = 0;
3081  break;
3082  case jbvBool:
3083  cmp = jb1->val.boolean == jb2->val.boolean ? 0 :
3084  jb1->val.boolean ? 1 : -1;
3085  break;
3086  case jbvNumeric:
3087  cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric);
3088  break;
3089  case jbvString:
3090  if (op == jpiEqual)
3091  return jb1->val.string.len != jb2->val.string.len ||
3092  memcmp(jb1->val.string.val,
3093  jb2->val.string.val,
3094  jb1->val.string.len) ? jpbFalse : jpbTrue;
3095 
3096  cmp = compareStrings(jb1->val.string.val, jb1->val.string.len,
3097  jb2->val.string.val, jb2->val.string.len);
3098  break;
3099  case jbvDatetime:
3100  {
3101  bool cast_error;
3102 
3103  cmp = compareDatetime(jb1->val.datetime.value,
3104  jb1->val.datetime.typid,
3105  jb2->val.datetime.value,
3106  jb2->val.datetime.typid,
3107  useTz,
3108  &cast_error);
3109 
3110  if (cast_error)
3111  return jpbUnknown;
3112  }
3113  break;
3114 
3115  case jbvBinary:
3116  case jbvArray:
3117  case jbvObject:
3118  return jpbUnknown; /* non-scalars are not comparable */
3119 
3120  default:
3121  elog(ERROR, "invalid jsonb value type %d", jb1->type);
3122  }
3123 
3124  switch (op)
3125  {
3126  case jpiEqual:
3127  res = (cmp == 0);
3128  break;
3129  case jpiNotEqual:
3130  res = (cmp != 0);
3131  break;
3132  case jpiLess:
3133  res = (cmp < 0);
3134  break;
3135  case jpiGreater:
3136  res = (cmp > 0);
3137  break;
3138  case jpiLessOrEqual:
3139  res = (cmp <= 0);
3140  break;
3141  case jpiGreaterOrEqual:
3142  res = (cmp >= 0);
3143  break;
3144  default:
3145  elog(ERROR, "unrecognized jsonpath operation: %d", op);
3146  return jpbUnknown;
3147  }
3148 
3149  return res ? jpbTrue : jpbFalse;
3150 }
@ jbvObject
Definition: jsonb.h:234
@ jbvNumeric
Definition: jsonb.h:230
@ jbvArray
Definition: jsonb.h:233
@ jbvBinary
Definition: jsonb.h:236
@ jbvDatetime
Definition: jsonb.h:244
@ jbvString
Definition: jsonb.h:229
@ jpiNotEqual
Definition: jsonpath.h:71
@ jpiGreaterOrEqual
Definition: jsonpath.h:75
@ jpiGreater
Definition: jsonpath.h:73
@ jpiLess
Definition: jsonpath.h:72
@ jpiEqual
Definition: jsonpath.h:70
@ jpiLessOrEqual
Definition: jsonpath.h:74
static int compareStrings(const char *mbstr1, int mblen1, const char *mbstr2, int mblen2)
static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, bool useTz, bool *cast_error)
static int compareNumeric(Numeric a, Numeric b)

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

Referenced by executeComparison().

◆ compareNumeric()

static int compareNumeric ( Numeric  a,
Numeric  b 
)
static

Definition at line 3154 of file jsonpath_exec.c.

3155 {
3157  NumericGetDatum(a),
3158  NumericGetDatum(b)));
3159 }
Datum numeric_cmp(PG_FUNCTION_ARGS)
Definition: numeric.c:2398
int b
Definition: isn.c:70
int a
Definition: isn.c:69
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:72

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

Referenced by compareItems().

◆ compareStrings()

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

Definition at line 2991 of file jsonpath_exec.c.

2993 {
2994  if (GetDatabaseEncoding() == PG_SQL_ASCII ||
2996  {
2997  /*
2998  * It's known property of UTF-8 strings that their per-byte comparison
2999  * result matches codepoints comparison result. ASCII can be
3000  * considered as special case of UTF-8.
3001  */
3002  return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2);
3003  }
3004  else
3005  {
3006  char *utf8str1,
3007  *utf8str2;
3008  int cmp,
3009  utf8len1,
3010  utf8len2;
3011 
3012  /*
3013  * We have to convert other encodings to UTF-8 first, then compare.
3014  * Input strings may be not null-terminated and pg_server_to_any() may
3015  * return them "as is". So, use strlen() only if there is real
3016  * conversion.
3017  */
3018  utf8str1 = pg_server_to_any(mbstr1, mblen1, PG_UTF8);
3019  utf8str2 = pg_server_to_any(mbstr2, mblen2, PG_UTF8);
3020  utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1);
3021  utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2);
3022 
3023  cmp = binaryCompareStrings(utf8str1, utf8len1, utf8str2, utf8len2);
3024 
3025  /*
3026  * If pg_server_to_any() did no real conversion, then we actually
3027  * compared original strings. So, we already done.
3028  */
3029  if (mbstr1 == utf8str1 && mbstr2 == utf8str2)
3030  return cmp;
3031 
3032  /* Free memory if needed */
3033  if (mbstr1 != utf8str1)
3034  pfree(utf8str1);
3035  if (mbstr2 != utf8str2)
3036  pfree(utf8str2);
3037 
3038  /*
3039  * When all Unicode codepoints are equal, return result of binary
3040  * comparison. In some edge cases, same characters may have different
3041  * representations in encoding. Then our behavior could diverge from
3042  * standard. However, that allow us to do simple binary comparison
3043  * for "==" operator, which is performance critical in typical cases.
3044  * In future to implement strict standard conformance, we can do
3045  * normalization of input JSON strings.
3046  */
3047  if (cmp == 0)
3048  return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2);
3049  else
3050  return cmp;
3051  }
3052 }
static int binaryCompareStrings(const char *s1, int len1, const char *s2, int len2)
int GetDatabaseEncoding(void)
Definition: mbutils.c:1268
char * pg_server_to_any(const char *s, int len, int encoding)
Definition: mbutils.c:750
void pfree(void *pointer)
Definition: mcxt.c:1431
@ PG_SQL_ASCII
Definition: pg_wchar.h:227
@ PG_UTF8
Definition: pg_wchar.h:233

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

Referenced by compareItems().

◆ copyJsonbValue()

static JsonbValue * copyJsonbValue ( JsonbValue src)
static

Definition at line 3162 of file jsonpath_exec.c.

3163 {
3164  JsonbValue *dst = palloc(sizeof(*dst));
3165 
3166  *dst = *src;
3167 
3168  return dst;
3169 }
void * palloc(Size size)
Definition: mcxt.c:1201

References palloc().

Referenced by executeAnyItem(), and executeNextItem().

◆ countVariablesFromJsonb()

static int countVariablesFromJsonb ( void *  varsJsonb)
static

Definition at line 2920 of file jsonpath_exec.c.

2921 {
2922  Jsonb *vars = varsJsonb;
2923 
2924  if (vars && !JsonContainerIsObject(&vars->root))
2925  {
2926  ereport(ERROR,
2927  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2928  errmsg("\"vars\" argument is not an object"),
2929  errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."));
2930  }
2931 
2932  /* count of base objects */
2933  return vars != NULL ? 1 : 0;
2934 }
int errdetail(const char *fmt,...)
Definition: elog.c:1208
#define JsonContainerIsObject(jc)
Definition: jsonb.h:208
Definition: jsonb.h:213
Definition: regcomp.c:281

References ereport, errcode(), errdetail(), errmsg(), ERROR, and JsonContainerIsObject.

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

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

1829 {
1831  JsonbIterator *it;
1832  int32 r;
1833  JsonbValue v;
1834 
1836 
1837  if (level > last)
1838  return res;
1839 
1840  it = JsonbIteratorInit(jbc);
1841 
1842  /*
1843  * Recursively iterate over jsonb objects/arrays
1844  */
1845  while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
1846  {
1847  if (r == WJB_KEY)
1848  {
1849  r = JsonbIteratorNext(&it, &v, true);
1850  Assert(r == WJB_VALUE);
1851  }
1852 
1853  if (r == WJB_VALUE || r == WJB_ELEM)
1854  {
1855 
1856  if (level >= first ||
1857  (first == PG_UINT32_MAX && last == PG_UINT32_MAX &&
1858  v.type != jbvBinary)) /* leaves only requested */
1859  {
1860  /* check expression */
1861  if (jsp)
1862  {
1863  if (ignoreStructuralErrors)
1864  {
1865  bool savedIgnoreStructuralErrors;
1866 
1867  savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors;
1868  cxt->ignoreStructuralErrors = true;
1869  res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext);
1870  cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors;
1871  }
1872  else
1873  res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext);
1874 
1875  if (jperIsError(res))
1876  break;
1877 
1878  if (res == jperOk && !found)
1879  break;
1880  }
1881  else if (found)
1882  JsonValueListAppend(found, copyJsonbValue(&v));
1883  else
1884  return jperOk;
1885  }
1886 
1887  if (level < last && v.type == jbvBinary)
1888  {
1890  (cxt, jsp, v.val.binary.data, found,
1891  level + 1, first, last,
1892  ignoreStructuralErrors, unwrapNext);
1893 
1894  if (jperIsError(res))
1895  break;
1896 
1897  if (res == jperOk && found == NULL)
1898  break;
1899  }
1900  }
1901  }
1902 
1903  return res;
1904 }
#define PG_UINT32_MAX
Definition: c.h:579
signed int int32
Definition: c.h:483
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_DONE
Definition: jsonb.h:22
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_ELEM
Definition: jsonb.h:25
JsonbIterator * JsonbIteratorInit(JsonbContainer *container)
Definition: jsonb_util.c:819
JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
Definition: jsonb_util.c:855
static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrap)
static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, uint32 level, uint32 first, uint32 last, bool ignoreStructuralErrors, bool unwrapNext)
static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv)
#define jperIsError(jper)
static JsonbValue * copyJsonbValue(JsonbValue *src)
Assert(fmt[strlen(fmt) - 1] !='\n')
void check_stack_depth(void)
Definition: postgres.c:3523

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

Referenced by executeItemOptUnwrapTarget(), and executeItemUnwrapTargetArray().

◆ executeBinaryArithmExpr()

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

Definition at line 1997 of file jsonpath_exec.c.

2000 {
2001  JsonPathExecResult jper;
2002  JsonPathItem elem;
2003  JsonValueList lseq = {0};
2004  JsonValueList rseq = {0};
2005  JsonbValue *lval;
2006  JsonbValue *rval;
2007  Numeric res;
2008 
2009  jspGetLeftArg(jsp, &elem);
2010 
2011  /*
2012  * XXX: By standard only operands of multiplicative expressions are
2013  * unwrapped. We extend it to other binary arithmetic expressions too.
2014  */
2015  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &lseq);
2016  if (jperIsError(jper))
2017  return jper;
2018 
2019  jspGetRightArg(jsp, &elem);
2020 
2021  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &rseq);
2022  if (jperIsError(jper))
2023  return jper;
2024 
2025  if (JsonValueListLength(&lseq) != 1 ||
2026  !(lval = getScalar(JsonValueListHead(&lseq), jbvNumeric)))
2028  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
2029  errmsg("left operand of jsonpath operator %s is not a single numeric value",
2030  jspOperationName(jsp->type)))));
2031 
2032  if (JsonValueListLength(&rseq) != 1 ||
2033  !(rval = getScalar(JsonValueListHead(&rseq), jbvNumeric)))
2035  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
2036  errmsg("right operand of jsonpath operator %s is not a single numeric value",
2037  jspOperationName(jsp->type)))));
2038 
2039  if (jspThrowErrors(cxt))
2040  {
2041  res = func(lval->val.numeric, rval->val.numeric, NULL);
2042  }
2043  else
2044  {
2045  bool error = false;
2046 
2047  res = func(lval->val.numeric, rval->val.numeric, &error);
2048 
2049  if (error)
2050  return jperError;
2051  }
2052 
2053  if (!jspGetNext(jsp, &elem) && !found)
2054  return jperOk;
2055 
2056  lval = palloc(sizeof(*lval));
2057  lval->type = jbvNumeric;
2058  lval->val.numeric = res;
2059 
2060  return executeNextItem(cxt, jsp, &elem, lval, found, false);
2061 }
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1157
const char * jspOperationName(JsonPathItemType type)
Definition: jsonpath.c:834
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1179
#define RETURN_ERROR(throw_error)
static JsonbValue * getScalar(JsonbValue *scalar, enum jbvType type)
static int JsonValueListLength(const JsonValueList *jvl)
static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonbValue * JsonValueListHead(JsonValueList *jvl)
static void error(void)
Definition: sql-dyntest.c:147
JsonPathItemType type
Definition: jsonpath.h:135

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

Referenced by executeItemOptUnwrapTarget().

◆ executeBoolItem()

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

Definition at line 1669 of file jsonpath_exec.c.

1671 {
1672  JsonPathItem larg;
1673  JsonPathItem rarg;
1674  JsonPathBool res;
1675  JsonPathBool res2;
1676 
1677  /* since this function recurses, it could be driven to stack overflow */
1679 
1680  if (!canHaveNext && jspHasNext(jsp))
1681  elog(ERROR, "boolean jsonpath item cannot have next item");
1682 
1683  switch (jsp->type)
1684  {
1685  case jpiAnd:
1686  jspGetLeftArg(jsp, &larg);
1687  res = executeBoolItem(cxt, &larg, jb, false);
1688 
1689  if (res == jpbFalse)
1690  return jpbFalse;
1691 
1692  /*
1693  * SQL/JSON says that we should check second arg in case of
1694  * jperError
1695  */
1696 
1697  jspGetRightArg(jsp, &rarg);
1698  res2 = executeBoolItem(cxt, &rarg, jb, false);
1699 
1700  return res2 == jpbTrue ? res : res2;
1701 
1702  case jpiOr:
1703  jspGetLeftArg(jsp, &larg);
1704  res = executeBoolItem(cxt, &larg, jb, false);
1705 
1706  if (res == jpbTrue)
1707  return jpbTrue;
1708 
1709  jspGetRightArg(jsp, &rarg);
1710  res2 = executeBoolItem(cxt, &rarg, jb, false);
1711 
1712  return res2 == jpbFalse ? res : res2;
1713 
1714  case jpiNot:
1715  jspGetArg(jsp, &larg);
1716 
1717  res = executeBoolItem(cxt, &larg, jb, false);
1718 
1719  if (res == jpbUnknown)
1720  return jpbUnknown;
1721 
1722  return res == jpbTrue ? jpbFalse : jpbTrue;
1723 
1724  case jpiIsUnknown:
1725  jspGetArg(jsp, &larg);
1726  res = executeBoolItem(cxt, &larg, jb, false);
1727  return res == jpbUnknown ? jpbTrue : jpbFalse;
1728 
1729  case jpiEqual:
1730  case jpiNotEqual:
1731  case jpiLess:
1732  case jpiGreater:
1733  case jpiLessOrEqual:
1734  case jpiGreaterOrEqual:
1735  jspGetLeftArg(jsp, &larg);
1736  jspGetRightArg(jsp, &rarg);
1737  return executePredicate(cxt, jsp, &larg, &rarg, jb, true,
1738  executeComparison, cxt);
1739 
1740  case jpiStartsWith: /* 'whole STARTS WITH initial' */
1741  jspGetLeftArg(jsp, &larg); /* 'whole' */
1742  jspGetRightArg(jsp, &rarg); /* 'initial' */
1743  return executePredicate(cxt, jsp, &larg, &rarg, jb, false,
1744  executeStartsWith, NULL);
1745 
1746  case jpiLikeRegex: /* 'expr LIKE_REGEX pattern FLAGS flags' */
1747  {
1748  /*
1749  * 'expr' is a sequence-returning expression. 'pattern' is a
1750  * regex string literal. SQL/JSON standard requires XQuery
1751  * regexes, but we use Postgres regexes here. 'flags' is a
1752  * string literal converted to integer flags at compile-time.
1753  */
1754  JsonLikeRegexContext lrcxt = {0};
1755 
1756  jspInitByBuffer(&larg, jsp->base,
1757  jsp->content.like_regex.expr);
1758 
1759  return executePredicate(cxt, jsp, &larg, NULL, jb, false,
1760  executeLikeRegex, &lrcxt);
1761  }
1762 
1763  case jpiExists:
1764  jspGetArg(jsp, &larg);
1765 
1766  if (jspStrictAbsenceOfErrors(cxt))
1767  {
1768  /*
1769  * In strict mode we must get a complete list of values to
1770  * check that there are no errors at all.
1771  */
1772  JsonValueList vals = {0};
1774  executeItemOptUnwrapResultNoThrow(cxt, &larg, jb,
1775  false, &vals);
1776 
1777  if (jperIsError(res))
1778  return jpbUnknown;
1779 
1780  return JsonValueListIsEmpty(&vals) ? jpbFalse : jpbTrue;
1781  }
1782  else
1783  {
1785  executeItemOptUnwrapResultNoThrow(cxt, &larg, jb,
1786  false, NULL);
1787 
1788  if (jperIsError(res))
1789  return jpbUnknown;
1790 
1791  return res == jperOk ? jpbTrue : jpbFalse;
1792  }
1793 
1794  default:
1795  elog(ERROR, "invalid boolean jsonpath item type: %d", jsp->type);
1796  return jpbUnknown;
1797  }
1798 }
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
Definition: jsonpath.c:1072
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
Definition: jsonpath.c:981
#define jspHasNext(jsp)
Definition: jsonpath.h:192
@ jpiExists
Definition: jsonpath.h:92
@ jpiNot
Definition: jsonpath.h:68
@ jpiAnd
Definition: jsonpath.h:66
@ jpiStartsWith
Definition: jsonpath.h:103
@ jpiOr
Definition: jsonpath.h:67
@ jpiLikeRegex
Definition: jsonpath.h:104
@ jpiIsUnknown
Definition: jsonpath.h:69
static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p)
static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext)
static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, JsonValueList *found)
static JsonPathBool executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, void *param)
#define jspStrictAbsenceOfErrors(cxt)
static JsonPathBool executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, void *param)
static bool JsonValueListIsEmpty(JsonValueList *jvl)
static JsonPathBool executePredicate(JsonPathExecContext *cxt, JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, bool unwrapRightArg, JsonPathPredicateCallback exec, void *param)
struct JsonPathItem::@131::@136 like_regex
char * base
Definition: jsonpath.h:144
union JsonPathItem::@131 content

References JsonPathItem::base, check_stack_depth(), 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(), jspStrictAbsenceOfErrors, JsonPathItem::like_regex, res, and JsonPathItem::type.

Referenced by executeItemOptUnwrapTarget(), and executeNestedBoolItem().

◆ executeComparison()

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

Definition at line 2959 of file jsonpath_exec.c.

2960 {
2962 
2963  return compareItems(cmp->type, lv, rv, cxt->useTz);
2964 }
static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz)

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

Referenced by executeBoolItem().

◆ executeDateTimeMethod()

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

Definition at line 2231 of file jsonpath_exec.c.

2233 {
2234  JsonbValue jbvbuf;
2235  Datum value;
2236  text *datetime;
2237  Oid collid;
2238  Oid typid;
2239  int32 typmod = -1;
2240  int tz = 0;
2241  bool hasNext;
2243  JsonPathItem elem;
2244  int32 time_precision = -1;
2245 
2246  if (!(jb = getScalar(jb, jbvString)))
2248  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2249  errmsg("jsonpath item method .%s() can only be applied to a string",
2250  jspOperationName(jsp->type)))));
2251 
2252  datetime = cstring_to_text_with_len(jb->val.string.val,
2253  jb->val.string.len);
2254 
2255  /*
2256  * At some point we might wish to have callers supply the collation to
2257  * use, but right now it's unclear that they'd be able to do better than
2258  * DEFAULT_COLLATION_OID anyway.
2259  */
2260  collid = DEFAULT_COLLATION_OID;
2261 
2262  /*
2263  * .datetime(template) has an argument, the rest of the methods don't have
2264  * an argument. So we handle that separately.
2265  */
2266  if (jsp->type == jpiDatetime && jsp->content.arg)
2267  {
2268  text *template;
2269  char *template_str;
2270  int template_len;
2271  ErrorSaveContext escontext = {T_ErrorSaveContext};
2272 
2273  jspGetArg(jsp, &elem);
2274 
2275  if (elem.type != jpiString)
2276  elog(ERROR, "invalid jsonpath item type for .datetime() argument");
2277 
2278  template_str = jspGetString(&elem, &template_len);
2279 
2280  template = cstring_to_text_with_len(template_str,
2281  template_len);
2282 
2283  value = parse_datetime(datetime, template, collid, true,
2284  &typid, &typmod, &tz,
2285  jspThrowErrors(cxt) ? NULL : (Node *) &escontext);
2286 
2287  if (escontext.error_occurred)
2288  res = jperError;
2289  else
2290  res = jperOk;
2291  }
2292  else
2293  {
2294  /*
2295  * According to SQL/JSON standard enumerate ISO formats for: date,
2296  * timetz, time, timestamptz, timestamp.
2297  *
2298  * We also support ISO 8601 format (with "T") for timestamps, because
2299  * to_json[b]() functions use this format.
2300  */
2301  static const char *fmt_str[] =
2302  {
2303  "yyyy-mm-dd", /* date */
2304  "HH24:MI:SS.USTZ", /* timetz */
2305  "HH24:MI:SSTZ",
2306  "HH24:MI:SS.US", /* time without tz */
2307  "HH24:MI:SS",
2308  "yyyy-mm-dd HH24:MI:SS.USTZ", /* timestamptz */
2309  "yyyy-mm-dd HH24:MI:SSTZ",
2310  "yyyy-mm-dd\"T\"HH24:MI:SS.USTZ",
2311  "yyyy-mm-dd\"T\"HH24:MI:SSTZ",
2312  "yyyy-mm-dd HH24:MI:SS.US", /* timestamp without tz */
2313  "yyyy-mm-dd HH24:MI:SS",
2314  "yyyy-mm-dd\"T\"HH24:MI:SS.US",
2315  "yyyy-mm-dd\"T\"HH24:MI:SS"
2316  };
2317 
2318  /* cache for format texts */
2319  static text *fmt_txt[lengthof(fmt_str)] = {0};
2320  int i;
2321 
2322  /*
2323  * Check for optional precision for methods other than .datetime() and
2324  * .date()
2325  */
2326  if (jsp->type != jpiDatetime && jsp->type != jpiDate &&
2327  jsp->content.arg)
2328  {
2329  bool have_error;
2330 
2331  jspGetArg(jsp, &elem);
2332 
2333  if (elem.type != jpiNumeric)
2334  elog(ERROR, "invalid jsonpath item type for %s argument",
2335  jspOperationName(jsp->type));
2336 
2337  time_precision = numeric_int4_opt_error(jspGetNumeric(&elem),
2338  &have_error);
2339  if (have_error)
2341  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2342  errmsg("time precision of jsonpath item method .%s() is out of range for type integer",
2343  jspOperationName(jsp->type)))));
2344  }
2345 
2346  /* loop until datetime format fits */
2347  for (i = 0; i < lengthof(fmt_str); i++)
2348  {
2349  ErrorSaveContext escontext = {T_ErrorSaveContext};
2350 
2351  if (!fmt_txt[i])
2352  {
2353  MemoryContext oldcxt =
2355 
2356  fmt_txt[i] = cstring_to_text(fmt_str[i]);
2357  MemoryContextSwitchTo(oldcxt);
2358  }
2359 
2360  value = parse_datetime(datetime, fmt_txt[i], collid, true,
2361  &typid, &typmod, &tz,
2362  (Node *) &escontext);
2363 
2364  if (!escontext.error_occurred)
2365  {
2366  res = jperOk;
2367  break;
2368  }
2369  }
2370 
2371  if (res == jperNotFound)
2372  {
2373  if (jsp->type == jpiDatetime)
2375  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2376  errmsg("datetime format is not recognized: \"%s\"",
2377  text_to_cstring(datetime)),
2378  errhint("Use a datetime template argument to specify the input data format."))));
2379  else
2381  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2382  errmsg("%s format is not recognized: \"%s\"",
2383  jspOperationName(jsp->type), text_to_cstring(datetime)))));
2384 
2385  }
2386  }
2387 
2388  /*
2389  * parse_datetime() processes the entire input string per the template or
2390  * ISO format and returns the Datum in best fitted datetime type. So, if
2391  * this call is for a specific datatype, then we do the conversion here.
2392  * Throw an error for incompatible types.
2393  */
2394  switch (jsp->type)
2395  {
2396  case jpiDatetime: /* Nothing to do for DATETIME */
2397  break;
2398  case jpiDate:
2399  {
2400  /* Convert result type to date */
2401  switch (typid)
2402  {
2403  case DATEOID: /* Nothing to do for DATE */
2404  break;
2405  case TIMEOID:
2406  case TIMETZOID:
2408  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2409  errmsg("date format is not recognized: \"%s\"",
2410  text_to_cstring(datetime)))));
2411  break;
2412  case TIMESTAMPOID:
2414  value);
2415  break;
2416  case TIMESTAMPTZOID:
2418  "timestamptz", "date");
2420  value);
2421  break;
2422  default:
2423  elog(ERROR, "type with oid %u not supported", typid);
2424  }
2425 
2426  typid = DATEOID;
2427  }
2428  break;
2429  case jpiTime:
2430  {
2431  /* Convert result type to time without time zone */
2432  switch (typid)
2433  {
2434  case DATEOID:
2436  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2437  errmsg("time format is not recognized: \"%s\"",
2438  text_to_cstring(datetime)))));
2439  break;
2440  case TIMEOID: /* Nothing to do for TIME */
2441  break;
2442  case TIMETZOID:
2444  "timetz", "time");
2446  value);
2447  break;
2448  case TIMESTAMPOID:
2450  value);
2451  break;
2452  case TIMESTAMPTZOID:
2454  "timestamptz", "time");
2456  value);
2457  break;
2458  default:
2459  elog(ERROR, "type with oid %u not supported", typid);
2460  }
2461 
2462  /* Force the user-given time precision, if any */
2463  if (time_precision != -1)
2464  {
2465  TimeADT result;
2466 
2467  /* Get a warning when precision is reduced */
2468  time_precision = anytime_typmod_check(false,
2469  time_precision);
2470  result = DatumGetTimeADT(value);
2471  AdjustTimeForTypmod(&result, time_precision);
2472  value = TimeADTGetDatum(result);
2473 
2474  /* Update the typmod value with the user-given precision */
2475  typmod = time_precision;
2476  }
2477 
2478  typid = TIMEOID;
2479  }
2480  break;
2481  case jpiTimeTz:
2482  {
2483  /* Convert result type to time with time zone */
2484  switch (typid)
2485  {
2486  case DATEOID:
2487  case TIMESTAMPOID:
2489  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2490  errmsg("time_tz format is not recognized: \"%s\"",
2491  text_to_cstring(datetime)))));
2492  break;
2493  case TIMEOID:
2495  "time", "timetz");
2497  value);
2498  break;
2499  case TIMETZOID: /* Nothing to do for TIMETZ */
2500  break;
2501  case TIMESTAMPTZOID:
2503  value);
2504  break;
2505  default:
2506  elog(ERROR, "type with oid %u not supported", typid);
2507  }
2508 
2509  /* Force the user-given time precision, if any */
2510  if (time_precision != -1)
2511  {
2512  TimeTzADT *result;
2513 
2514  /* Get a warning when precision is reduced */
2515  time_precision = anytime_typmod_check(true,
2516  time_precision);
2517  result = DatumGetTimeTzADTP(value);
2518  AdjustTimeForTypmod(&result->time, time_precision);
2519  value = TimeTzADTPGetDatum(result);
2520 
2521  /* Update the typmod value with the user-given precision */
2522  typmod = time_precision;
2523  }
2524 
2525  typid = TIMETZOID;
2526  }
2527  break;
2528  case jpiTimestamp:
2529  {
2530  /* Convert result type to timestamp without time zone */
2531  switch (typid)
2532  {
2533  case DATEOID:
2535  value);
2536  break;
2537  case TIMEOID:
2538  case TIMETZOID:
2540  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2541  errmsg("timestamp format is not recognized: \"%s\"",
2542  text_to_cstring(datetime)))));
2543  break;
2544  case TIMESTAMPOID: /* Nothing to do for TIMESTAMP */
2545  break;
2546  case TIMESTAMPTZOID:
2548  "timestamptz", "timestamp");
2550  value);
2551  break;
2552  default:
2553  elog(ERROR, "type with oid %u not supported", typid);
2554  }
2555 
2556  /* Force the user-given time precision, if any */
2557  if (time_precision != -1)
2558  {
2559  Timestamp result;
2560  ErrorSaveContext escontext = {T_ErrorSaveContext};
2561 
2562  /* Get a warning when precision is reduced */
2563  time_precision = anytimestamp_typmod_check(false,
2564  time_precision);
2565  result = DatumGetTimestamp(value);
2566  AdjustTimestampForTypmod(&result, time_precision,
2567  (Node *) &escontext);
2568  if (escontext.error_occurred)
2570  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2571  errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
2572  jspOperationName(jsp->type)))));
2573  value = TimestampGetDatum(result);
2574 
2575  /* Update the typmod value with the user-given precision */
2576  typmod = time_precision;
2577  }
2578 
2579  typid = TIMESTAMPOID;
2580  }
2581  break;
2582  case jpiTimestampTz:
2583  {
2584  /* Convert result type to timestamp with time zone */
2585  switch (typid)
2586  {
2587  case DATEOID:
2589  "date", "timestamptz");
2591  value);
2592  break;
2593  case TIMEOID:
2594  case TIMETZOID:
2596  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2597  errmsg("timestamp_tz format is not recognized: \"%s\"",
2598  text_to_cstring(datetime)))));
2599  break;
2600  case TIMESTAMPOID:
2602  "timestamp", "timestamptz");
2604  value);
2605  break;
2606  case TIMESTAMPTZOID: /* Nothing to do for TIMESTAMPTZ */
2607  break;
2608  default:
2609  elog(ERROR, "type with oid %u not supported", typid);
2610  }
2611 
2612  /* Force the user-given time precision, if any */
2613  if (time_precision != -1)
2614  {
2615  Timestamp result;
2616  ErrorSaveContext escontext = {T_ErrorSaveContext};
2617 
2618  /* Get a warning when precision is reduced */
2619  time_precision = anytimestamp_typmod_check(true,
2620  time_precision);
2621  result = DatumGetTimestampTz(value);
2622  AdjustTimestampForTypmod(&result, time_precision,
2623  (Node *) &escontext);
2624  if (escontext.error_occurred)
2626  (errcode(ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION),
2627  errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
2628  jspOperationName(jsp->type)))));
2629  value = TimestampTzGetDatum(result);
2630 
2631  /* Update the typmod value with the user-given precision */
2632  typmod = time_precision;
2633  }
2634 
2635  typid = TIMESTAMPTZOID;
2636  }
2637  break;
2638  default:
2639  elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
2640  }
2641 
2642  pfree(datetime);
2643 
2644  if (jperIsError(res))
2645  return res;
2646 
2647  hasNext = jspGetNext(jsp, &elem);
2648 
2649  if (!hasNext && !found)
2650  return res;
2651 
2652  jb = hasNext ? &jbvbuf : palloc(sizeof(*jb));
2653 
2654  jb->type = jbvDatetime;
2655  jb->val.datetime.value = value;
2656  jb->val.datetime.typid = typid;
2657  jb->val.datetime.typmod = typmod;
2658  jb->val.datetime.tz = tz;
2659 
2660  return executeNextItem(cxt, jsp, &elem, jb, found, hasNext);
2661 }
int32 numeric_int4_opt_error(Numeric num, bool *have_error)
Definition: numeric.c:4346
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition: timestamp.c:367
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition: timestamp.c:6241
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition: timestamp.c:124
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition: timestamp.c:6320
#define lengthof(array)
Definition: c.h:777
Oid collid
int64 Timestamp
Definition: timestamp.h:38
Datum timestamp_time(PG_FUNCTION_ARGS)
Definition: date.c:1905
int32 anytime_typmod_check(bool istz, int32 typmod)
Definition: date.c:71
Datum date_timestamptz(PG_FUNCTION_ARGS)
Definition: date.c:1327
Datum timetz_time(PG_FUNCTION_ARGS)
Definition: date.c:2815
Datum timestamptz_timetz(PG_FUNCTION_ARGS)
Definition: date.c:2854
void AdjustTimeForTypmod(TimeADT *time, int32 typmod)
Definition: date.c:1645
Datum timestamptz_date(PG_FUNCTION_ARGS)
Definition: date.c:1342
Datum timestamp_date(PG_FUNCTION_ARGS)
Definition: date.c:1297
Datum timestamptz_time(PG_FUNCTION_ARGS)
Definition: date.c:1935
Datum date_timestamp(PG_FUNCTION_ARGS)
Definition: date.c:1283
static TimeADT DatumGetTimeADT(Datum X)
Definition: date.h:60
static Datum TimeTzADTPGetDatum(const TimeTzADT *X)
Definition: date.h:84
static TimeTzADT * DatumGetTimeTzADTP(Datum X)
Definition: date.h:66
int64 TimeADT
Definition: date.h:25
static Datum TimeADTGetDatum(TimeADT X)
Definition: date.h:78
Datum parse_datetime(text *date_txt, text *fmt, Oid collid, bool strict, Oid *typid, int32 *typmod, int *tz, Node *escontext)
Definition: formatting.c:4311
static struct @148 value
int i
Definition: isn.c:73
Numeric jspGetNumeric(JsonPathItem *v)
Definition: jsonpath.c:1209
char * jspGetString(JsonPathItem *v, int32 *len)
Definition: jsonpath.c:1217
@ jpiString
Definition: jsonpath.h:63
@ jpiDatetime
Definition: jsonpath.h:99
@ jpiTimeTz
Definition: jsonpath.h:113
@ jpiDate
Definition: jsonpath.h:107
@ jpiTimestamp
Definition: jsonpath.h:114
@ jpiTimestampTz
Definition: jsonpath.h:115
@ jpiTime
Definition: jsonpath.h:112
@ jpiNumeric
Definition: jsonpath.h:64
MemoryContext TopMemoryContext
Definition: mcxt.c:141
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
bool error_occurred
Definition: miscnodes.h:46
int32 arg
Definition: jsonpath.h:156
Definition: nodes.h:129
Definition: date.h:28
TimeADT time
Definition: date.h:29
Definition: c.h:676
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46
char * text_to_cstring(const text *t)
Definition: varlena.c:217
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196
text * cstring_to_text(const char *s)
Definition: varlena.c:184

References AdjustTimeForTypmod(), AdjustTimestampForTypmod(), anytime_typmod_check(), anytimestamp_typmod_check(), JsonPathItem::arg, checkTimezoneIsUsedForCast(), collid, JsonPathItem::content, cstring_to_text(), cstring_to_text_with_len(), date_timestamp(), date_timestamptz(), DatumGetTimeADT(), DatumGetTimestamp(), DatumGetTimestampTz(), DatumGetTimeTzADTP(), DirectFunctionCall1, elog(), ereport, errcode(), errhint(), errmsg(), ERROR, ErrorSaveContext::error_occurred, executeNextItem(), getScalar(), i, jbvDatetime, jbvString, jperError, jperIsError, jperNotFound, jperOk, jpiDate, jpiDatetime, jpiNumeric, jpiString, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jspGetArg(), jspGetNext(), jspGetNumeric(), jspGetString(), jspOperationName(), jspThrowErrors, lengthof, MemoryContextSwitchTo(), numeric_int4_opt_error(), palloc(), parse_datetime(), pfree(), res, RETURN_ERROR, text_to_cstring(), TimeTzADT::time, time_timetz(), TimeADTGetDatum(), timestamp_date(), timestamp_time(), timestamp_timestamptz(), TimestampGetDatum(), timestamptz_date(), timestamptz_time(), timestamptz_timestamp(), timestamptz_timetz(), TimestampTzGetDatum(), timetz_time(), TimeTzADTPGetDatum(), TopMemoryContext, JsonbValue::type, JsonPathItem::type, JsonPathExecContext::useTz, JsonbValue::val, and value.

Referenced by executeItemOptUnwrapTarget().

◆ executeItem()

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

Definition at line 625 of file jsonpath_exec.c.

627 {
628  return executeItemOptUnwrapTarget(cxt, jsp, jb, found, jspAutoUnwrap(cxt));
629 }
#define jspAutoUnwrap(cxt)

References executeItemOptUnwrapTarget(), and jspAutoUnwrap.

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

◆ executeItemOptUnwrapResult()

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

Definition at line 1617 of file jsonpath_exec.c.

1620 {
1621  if (unwrap && jspAutoUnwrap(cxt))
1622  {
1623  JsonValueList seq = {0};
1625  JsonPathExecResult res = executeItem(cxt, jsp, jb, &seq);
1626  JsonbValue *item;
1627 
1628  if (jperIsError(res))
1629  return res;
1630 
1631  JsonValueListInitIterator(&seq, &it);
1632  while ((item = JsonValueListNext(&seq, &it)))
1633  {
1634  Assert(item->type != jbvArray);
1635 
1636  if (JsonbType(item) == jbvArray)
1637  executeItemUnwrapTargetArray(cxt, NULL, item, found, false);
1638  else
1639  JsonValueListAppend(found, item);
1640  }
1641 
1642  return jperOk;
1643  }
1644 
1645  return executeItem(cxt, jsp, jb, found);
1646 }
static int JsonbType(JsonbValue *jb)
static JsonPathExecResult executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static void JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it)
static JsonbValue * JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it)
static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found, bool unwrapElements)

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

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

◆ executeItemOptUnwrapResultNoThrow()

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

Definition at line 1652 of file jsonpath_exec.c.

1656 {
1658  bool throwErrors = cxt->throwErrors;
1659 
1660  cxt->throwErrors = false;
1661  res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found);
1662  cxt->throwErrors = throwErrors;
1663 
1664  return res;
1665 }

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

Referenced by executeBoolItem(), and executePredicate().

◆ executeItemOptUnwrapTarget()

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

Definition at line 637 of file jsonpath_exec.c.

639 {
640  JsonPathItem elem;
642  JsonBaseObjectInfo baseObject;
643 
646 
647  switch (jsp->type)
648  {
649  case jpiNull:
650  case jpiBool:
651  case jpiNumeric:
652  case jpiString:
653  case jpiVariable:
654  {
655  JsonbValue vbuf;
656  JsonbValue *v;
657  bool hasNext = jspGetNext(jsp, &elem);
658 
659  if (!hasNext && !found && jsp->type != jpiVariable)
660  {
661  /*
662  * Skip evaluation, but not for variables. We must
663  * trigger an error for the missing variable.
664  */
665  res = jperOk;
666  break;
667  }
668 
669  v = hasNext ? &vbuf : palloc(sizeof(*v));
670 
671  baseObject = cxt->baseObject;
672  getJsonPathItem(cxt, jsp, v);
673 
674  res = executeNextItem(cxt, jsp, &elem,
675  v, found, hasNext);
676  cxt->baseObject = baseObject;
677  }
678  break;
679 
680  /* all boolean item types: */
681  case jpiAnd:
682  case jpiOr:
683  case jpiNot:
684  case jpiIsUnknown:
685  case jpiEqual:
686  case jpiNotEqual:
687  case jpiLess:
688  case jpiGreater:
689  case jpiLessOrEqual:
690  case jpiGreaterOrEqual:
691  case jpiExists:
692  case jpiStartsWith:
693  case jpiLikeRegex:
694  {
695  JsonPathBool st = executeBoolItem(cxt, jsp, jb, true);
696 
697  res = appendBoolResult(cxt, jsp, found, st);
698  break;
699  }
700 
701  case jpiAdd:
702  return executeBinaryArithmExpr(cxt, jsp, jb,
703  numeric_add_opt_error, found);
704 
705  case jpiSub:
706  return executeBinaryArithmExpr(cxt, jsp, jb,
707  numeric_sub_opt_error, found);
708 
709  case jpiMul:
710  return executeBinaryArithmExpr(cxt, jsp, jb,
711  numeric_mul_opt_error, found);
712 
713  case jpiDiv:
714  return executeBinaryArithmExpr(cxt, jsp, jb,
715  numeric_div_opt_error, found);
716 
717  case jpiMod:
718  return executeBinaryArithmExpr(cxt, jsp, jb,
719  numeric_mod_opt_error, found);
720 
721  case jpiPlus:
722  return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found);
723 
724  case jpiMinus:
725  return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus,
726  found);
727 
728  case jpiAnyArray:
729  if (JsonbType(jb) == jbvArray)
730  {
731  bool hasNext = jspGetNext(jsp, &elem);
732 
733  res = executeItemUnwrapTargetArray(cxt, hasNext ? &elem : NULL,
734  jb, found, jspAutoUnwrap(cxt));
735  }
736  else if (jspAutoWrap(cxt))
737  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
738  else if (!jspIgnoreStructuralErrors(cxt))
740  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
741  errmsg("jsonpath wildcard array accessor can only be applied to an array"))));
742  break;
743 
744  case jpiAnyKey:
745  if (JsonbType(jb) == jbvObject)
746  {
747  bool hasNext = jspGetNext(jsp, &elem);
748 
749  if (jb->type != jbvBinary)
750  elog(ERROR, "invalid jsonb object type: %d", jb->type);
751 
752  return executeAnyItem
753  (cxt, hasNext ? &elem : NULL,
754  jb->val.binary.data, found, 1, 1, 1,
755  false, jspAutoUnwrap(cxt));
756  }
757  else if (unwrap && JsonbType(jb) == jbvArray)
758  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
759  else if (!jspIgnoreStructuralErrors(cxt))
760  {
761  Assert(found);
763  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
764  errmsg("jsonpath wildcard member accessor can only be applied to an object"))));
765  }
766  break;
767 
768  case jpiIndexArray:
769  if (JsonbType(jb) == jbvArray || jspAutoWrap(cxt))
770  {
771  int innermostArraySize = cxt->innermostArraySize;
772  int i;
773  int size = JsonbArraySize(jb);
774  bool singleton = size < 0;
775  bool hasNext = jspGetNext(jsp, &elem);
776 
777  if (singleton)
778  size = 1;
779 
780  cxt->innermostArraySize = size; /* for LAST evaluation */
781 
782  for (i = 0; i < jsp->content.array.nelems; i++)
783  {
784  JsonPathItem from;
785  JsonPathItem to;
786  int32 index;
787  int32 index_from;
788  int32 index_to;
789  bool range = jspGetArraySubscript(jsp, &from,
790  &to, i);
791 
792  res = getArrayIndex(cxt, &from, jb, &index_from);
793 
794  if (jperIsError(res))
795  break;
796 
797  if (range)
798  {
799  res = getArrayIndex(cxt, &to, jb, &index_to);
800 
801  if (jperIsError(res))
802  break;
803  }
804  else
805  index_to = index_from;
806 
807  if (!jspIgnoreStructuralErrors(cxt) &&
808  (index_from < 0 ||
809  index_from > index_to ||
810  index_to >= size))
812  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
813  errmsg("jsonpath array subscript is out of bounds"))));
814 
815  if (index_from < 0)
816  index_from = 0;
817 
818  if (index_to >= size)
819  index_to = size - 1;
820 
821  res = jperNotFound;
822 
823  for (index = index_from; index <= index_to; index++)
824  {
825  JsonbValue *v;
826  bool copy;
827 
828  if (singleton)
829  {
830  v = jb;
831  copy = true;
832  }
833  else
834  {
835  v = getIthJsonbValueFromContainer(jb->val.binary.data,
836  (uint32) index);
837 
838  if (v == NULL)
839  continue;
840 
841  copy = false;
842  }
843 
844  if (!hasNext && !found)
845  return jperOk;
846 
847  res = executeNextItem(cxt, jsp, &elem, v, found,
848  copy);
849 
850  if (jperIsError(res))
851  break;
852 
853  if (res == jperOk && !found)
854  break;
855  }
856 
857  if (jperIsError(res))
858  break;
859 
860  if (res == jperOk && !found)
861  break;
862  }
863 
864  cxt->innermostArraySize = innermostArraySize;
865  }
866  else if (!jspIgnoreStructuralErrors(cxt))
867  {
869  (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND),
870  errmsg("jsonpath array accessor can only be applied to an array"))));
871  }
872  break;
873 
874  case jpiAny:
875  {
876  bool hasNext = jspGetNext(jsp, &elem);
877 
878  /* first try without any intermediate steps */
879  if (jsp->content.anybounds.first == 0)
880  {
881  bool savedIgnoreStructuralErrors;
882 
883  savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors;
884  cxt->ignoreStructuralErrors = true;
885  res = executeNextItem(cxt, jsp, &elem,
886  jb, found, true);
887  cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors;
888 
889  if (res == jperOk && !found)
890  break;
891  }
892 
893  if (jb->type == jbvBinary)
895  (cxt, hasNext ? &elem : NULL,
896  jb->val.binary.data, found,
897  1,
898  jsp->content.anybounds.first,
899  jsp->content.anybounds.last,
900  true, jspAutoUnwrap(cxt));
901  break;
902  }
903 
904  case jpiKey:
905  if (JsonbType(jb) == jbvObject)
906  {
907  JsonbValue *v;
908  JsonbValue key;
909 
910  key.type = jbvString;
911  key.val.string.val = jspGetString(jsp, &key.val.string.len);
912 
913  v = findJsonbValueFromContainer(jb->val.binary.data,
914  JB_FOBJECT, &key);
915 
916  if (v != NULL)
917  {
918  res = executeNextItem(cxt, jsp, NULL,
919  v, found, false);
920 
921  /* free value if it was not added to found list */
922  if (jspHasNext(jsp) || !found)
923  pfree(v);
924  }
925  else if (!jspIgnoreStructuralErrors(cxt))
926  {
927  Assert(found);
928 
929  if (!jspThrowErrors(cxt))
930  return jperError;
931 
932  ereport(ERROR,
933  (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \
934  errmsg("JSON object does not contain key \"%s\"",
935  pnstrdup(key.val.string.val,
936  key.val.string.len))));
937  }
938  }
939  else if (unwrap && JsonbType(jb) == jbvArray)
940  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
941  else if (!jspIgnoreStructuralErrors(cxt))
942  {
943  Assert(found);
945  (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND),
946  errmsg("jsonpath member accessor can only be applied to an object"))));
947  }
948  break;
949 
950  case jpiCurrent:
951  res = executeNextItem(cxt, jsp, NULL, cxt->current,
952  found, true);
953  break;
954 
955  case jpiRoot:
956  jb = cxt->root;
957  baseObject = setBaseObject(cxt, jb, 0);
958  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
959  cxt->baseObject = baseObject;
960  break;
961 
962  case jpiFilter:
963  {
964  JsonPathBool st;
965 
966  if (unwrap && JsonbType(jb) == jbvArray)
967  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
968  false);
969 
970  jspGetArg(jsp, &elem);
971  st = executeNestedBoolItem(cxt, &elem, jb);
972  if (st != jpbTrue)
973  res = jperNotFound;
974  else
975  res = executeNextItem(cxt, jsp, NULL,
976  jb, found, true);
977  break;
978  }
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 = int64_to_numeric(size);
1016 
1017  res = executeNextItem(cxt, jsp, NULL, jb, found, false);
1018  }
1019  break;
1020 
1021  case jpiAbs:
1022  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs,
1023  found);
1024 
1025  case jpiFloor:
1026  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor,
1027  found);
1028 
1029  case jpiCeiling:
1030  return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil,
1031  found);
1032 
1033  case jpiDouble:
1034  {
1035  JsonbValue jbv;
1036 
1037  if (unwrap && JsonbType(jb) == jbvArray)
1038  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1039  false);
1040 
1041  if (jb->type == jbvNumeric)
1042  {
1044  NumericGetDatum(jb->val.numeric)));
1045  double val;
1046  ErrorSaveContext escontext = {T_ErrorSaveContext};
1047 
1048  val = float8in_internal(tmp,
1049  NULL,
1050  "double precision",
1051  tmp,
1052  (Node *) &escontext);
1053 
1054  if (escontext.error_occurred || isinf(val) || isnan(val))
1056  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1057  errmsg("numeric argument of jsonpath item method .%s() is out of range for type double precision",
1058  jspOperationName(jsp->type)))));
1059  res = jperOk;
1060  }
1061  else if (jb->type == jbvString)
1062  {
1063  /* cast string as double */
1064  double val;
1065  char *tmp = pnstrdup(jb->val.string.val,
1066  jb->val.string.len);
1067  ErrorSaveContext escontext = {T_ErrorSaveContext};
1068 
1069  val = float8in_internal(tmp,
1070  NULL,
1071  "double precision",
1072  tmp,
1073  (Node *) &escontext);
1074 
1075  if (escontext.error_occurred || isinf(val) || isnan(val))
1077  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1078  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a double precision number",
1079  jspOperationName(jsp->type)))));
1080 
1081  jb = &jbv;
1082  jb->type = jbvNumeric;
1084  Float8GetDatum(val)));
1085  res = jperOk;
1086  }
1087 
1088  if (res == jperNotFound)
1090  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1091  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1092  jspOperationName(jsp->type)))));
1093 
1094  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1095  }
1096  break;
1097 
1098  case jpiDatetime:
1099  case jpiDate:
1100  case jpiTime:
1101  case jpiTimeTz:
1102  case jpiTimestamp:
1103  case jpiTimestampTz:
1104  if (unwrap && JsonbType(jb) == jbvArray)
1105  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1106 
1107  return executeDateTimeMethod(cxt, jsp, jb, found);
1108 
1109  case jpiKeyValue:
1110  if (unwrap && JsonbType(jb) == jbvArray)
1111  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
1112 
1113  return executeKeyValueMethod(cxt, jsp, jb, found);
1114 
1115  case jpiLast:
1116  {
1117  JsonbValue tmpjbv;
1118  JsonbValue *lastjbv;
1119  int last;
1120  bool hasNext = jspGetNext(jsp, &elem);
1121 
1122  if (cxt->innermostArraySize < 0)
1123  elog(ERROR, "evaluating jsonpath LAST outside of array subscript");
1124 
1125  if (!hasNext && !found)
1126  {
1127  res = jperOk;
1128  break;
1129  }
1130 
1131  last = cxt->innermostArraySize - 1;
1132 
1133  lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv));
1134 
1135  lastjbv->type = jbvNumeric;
1136  lastjbv->val.numeric = int64_to_numeric(last);
1137 
1138  res = executeNextItem(cxt, jsp, &elem,
1139  lastjbv, found, hasNext);
1140  }
1141  break;
1142 
1143  case jpiBigint:
1144  {
1145  JsonbValue jbv;
1146  Datum datum;
1147 
1148  if (unwrap && JsonbType(jb) == jbvArray)
1149  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1150  false);
1151 
1152  if (jb->type == jbvNumeric)
1153  {
1154  bool have_error;
1155  int64 val;
1156 
1157  val = numeric_int8_opt_error(jb->val.numeric, &have_error);
1158  if (have_error)
1160  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1161  errmsg("numeric argument of jsonpath item method .%s() is out of range for type bigint",
1162  jspOperationName(jsp->type)))));
1163 
1164  datum = Int64GetDatum(val);
1165  res = jperOk;
1166  }
1167  else if (jb->type == jbvString)
1168  {
1169  /* cast string as bigint */
1170  char *tmp = pnstrdup(jb->val.string.val,
1171  jb->val.string.len);
1172  ErrorSaveContext escontext = {T_ErrorSaveContext};
1173  bool noerr;
1174 
1175  noerr = DirectInputFunctionCallSafe(int8in, tmp,
1176  InvalidOid, -1,
1177  (Node *) &escontext,
1178  &datum);
1179 
1180  if (!noerr || escontext.error_occurred)
1182  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1183  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a big integer",
1184  jspOperationName(jsp->type)))));
1185  res = jperOk;
1186  }
1187 
1188  if (res == jperNotFound)
1190  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1191  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1192  jspOperationName(jsp->type)))));
1193 
1194  jb = &jbv;
1195  jb->type = jbvNumeric;
1197  datum));
1198 
1199  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1200  }
1201  break;
1202 
1203  case jpiBoolean:
1204  {
1205  JsonbValue jbv;
1206  bool bval;
1207 
1208  if (unwrap && JsonbType(jb) == jbvArray)
1209  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1210  false);
1211 
1212  if (jb->type == jbvBool)
1213  {
1214  bval = jb->val.boolean;
1215 
1216  res = jperOk;
1217  }
1218  else if (jb->type == jbvNumeric)
1219  {
1220  int ival;
1221  Datum datum;
1222  bool noerr;
1224  NumericGetDatum(jb->val.numeric)));
1225  ErrorSaveContext escontext = {T_ErrorSaveContext};
1226 
1227  noerr = DirectInputFunctionCallSafe(int4in, tmp,
1228  InvalidOid, -1,
1229  (Node *) &escontext,
1230  &datum);
1231 
1232  if (!noerr || escontext.error_occurred)
1234  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1235  errmsg("numeric argument of jsonpath item method .%s() is out of range for type boolean",
1236  jspOperationName(jsp->type)))));
1237 
1238  ival = DatumGetInt32(datum);
1239  if (ival == 0)
1240  bval = false;
1241  else
1242  bval = true;
1243 
1244  res = jperOk;
1245  }
1246  else if (jb->type == jbvString)
1247  {
1248  /* cast string as boolean */
1249  char *tmp = pnstrdup(jb->val.string.val,
1250  jb->val.string.len);
1251 
1252  if (!parse_bool(tmp, &bval))
1254  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1255  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a boolean",
1256  jspOperationName(jsp->type)))));
1257 
1258  res = jperOk;
1259  }
1260 
1261  if (res == jperNotFound)
1263  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1264  errmsg("jsonpath item method .%s() can only be applied to a bool, string, or numeric value",
1265  jspOperationName(jsp->type)))));
1266 
1267  jb = &jbv;
1268  jb->type = jbvBool;
1269  jb->val.boolean = bval;
1270 
1271  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1272  }
1273  break;
1274 
1275  case jpiDecimal:
1276  case jpiNumber:
1277  {
1278  JsonbValue jbv;
1279  Numeric num;
1280  char *numstr = NULL;
1281 
1282  if (unwrap && JsonbType(jb) == jbvArray)
1283  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1284  false);
1285 
1286  if (jb->type == jbvNumeric)
1287  {
1288  num = jb->val.numeric;
1289  if (numeric_is_nan(num) || numeric_is_inf(num))
1291  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1292  errmsg("numeric argument of jsonpath item method .%s() is out of range for type decimal or number",
1293  jspOperationName(jsp->type)))));
1294 
1295  if (jsp->type == jpiDecimal)
1297  NumericGetDatum(num)));
1298  res = jperOk;
1299  }
1300  else if (jb->type == jbvString)
1301  {
1302  /* cast string as number */
1303  Datum datum;
1304  bool noerr;
1305  ErrorSaveContext escontext = {T_ErrorSaveContext};
1306 
1307  numstr = pnstrdup(jb->val.string.val, jb->val.string.len);
1308 
1309  noerr = DirectInputFunctionCallSafe(numeric_in, numstr,
1310  InvalidOid, -1,
1311  (Node *) &escontext,
1312  &datum);
1313 
1314  if (!noerr || escontext.error_occurred)
1316  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1317  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1318  jspOperationName(jsp->type)))));
1319 
1320  num = DatumGetNumeric(datum);
1321  if (numeric_is_nan(num) || numeric_is_inf(num))
1323  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1324  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1325  jspOperationName(jsp->type)))));
1326 
1327  res = jperOk;
1328  }
1329 
1330  if (res == jperNotFound)
1332  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1333  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1334  jspOperationName(jsp->type)))));
1335 
1336  /*
1337  * If we have arguments, then they must be the precision and
1338  * optional scale used in .decimal(). Convert them to the
1339  * typmod equivalent and then truncate the numeric value per
1340  * this typmod details.
1341  */
1342  if (jsp->type == jpiDecimal && jsp->content.args.left)
1343  {
1344  Datum numdatum;
1345  Datum dtypmod;
1346  int32 precision;
1347  int32 scale = 0;
1348  bool have_error;
1349  bool noerr;
1350  ArrayType *arrtypmod;
1351  Datum datums[2];
1352  char pstr[12]; /* sign, 10 digits and '\0' */
1353  char sstr[12]; /* sign, 10 digits and '\0' */
1354  ErrorSaveContext escontext = {T_ErrorSaveContext};
1355 
1356  jspGetLeftArg(jsp, &elem);
1357  if (elem.type != jpiNumeric)
1358  elog(ERROR, "invalid jsonpath item type for .decimal() precision");
1359 
1360  precision = numeric_int4_opt_error(jspGetNumeric(&elem),
1361  &have_error);
1362  if (have_error)
1364  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1365  errmsg("precision of jsonpath item method .%s() is out of range for type integer",
1366  jspOperationName(jsp->type)))));
1367 
1368  if (jsp->content.args.right)
1369  {
1370  jspGetRightArg(jsp, &elem);
1371  if (elem.type != jpiNumeric)
1372  elog(ERROR, "invalid jsonpath item type for .decimal() scale");
1373 
1375  &have_error);
1376  if (have_error)
1378  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1379  errmsg("scale of jsonpath item method .%s() is out of range for type integer",
1380  jspOperationName(jsp->type)))));
1381  }
1382 
1383  /*
1384  * numerictypmodin() takes the precision and scale in the
1385  * form of CString arrays.
1386  */
1387  pg_ltoa(precision, pstr);
1388  datums[0] = CStringGetDatum(pstr);
1389  pg_ltoa(scale, sstr);
1390  datums[1] = CStringGetDatum(sstr);
1391  arrtypmod = construct_array_builtin(datums, 2, CSTRINGOID);
1392 
1394  PointerGetDatum(arrtypmod));
1395 
1396  /* Convert numstr to Numeric with typmod */
1397  Assert(numstr != NULL);
1398  noerr = DirectInputFunctionCallSafe(numeric_in, numstr,
1399  InvalidOid, dtypmod,
1400  (Node *) &escontext,
1401  &numdatum);
1402 
1403  if (!noerr || escontext.error_occurred)
1405  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1406  errmsg("string argument of jsonpath item method .%s() is not a valid representation of a decimal or number",
1407  jspOperationName(jsp->type)))));
1408 
1409  num = DatumGetNumeric(numdatum);
1410  pfree(arrtypmod);
1411  }
1412 
1413  jb = &jbv;
1414  jb->type = jbvNumeric;
1415  jb->val.numeric = num;
1416 
1417  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1418  }
1419  break;
1420 
1421  case jpiInteger:
1422  {
1423  JsonbValue jbv;
1424  Datum datum;
1425 
1426  if (unwrap && JsonbType(jb) == jbvArray)
1427  return executeItemUnwrapTargetArray(cxt, jsp, jb, found,
1428  false);
1429 
1430  if (jb->type == jbvNumeric)
1431  {
1432  bool have_error;
1433  int32 val;
1434 
1435  val = numeric_int4_opt_error(jb->val.numeric, &have_error);
1436  if (have_error)
1438  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1439  errmsg("numeric argument of jsonpath item method .%s() is out of range for type integer",
1440  jspOperationName(jsp->type)))));
1441 
1442  datum = Int32GetDatum(val);
1443  res = jperOk;
1444  }
1445  else if (jb->type == jbvString)
1446  {
1447  /* cast string as integer */
1448  char *tmp = pnstrdup(jb->val.string.val,
1449  jb->val.string.len);
1450  ErrorSaveContext escontext = {T_ErrorSaveContext};
1451  bool noerr;
1452 
1453  noerr = DirectInputFunctionCallSafe(int4in, tmp,
1454  InvalidOid, -1,
1455  (Node *) &escontext,
1456  &datum);
1457 
1458  if (!noerr || escontext.error_occurred)
1460  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1461  errmsg("string argument of jsonpath item method .%s() is not a valid representation of an integer",
1462  jspOperationName(jsp->type)))));
1463  res = jperOk;
1464  }
1465 
1466  if (res == jperNotFound)
1468  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1469  errmsg("jsonpath item method .%s() can only be applied to a string or numeric value",
1470  jspOperationName(jsp->type)))));
1471 
1472  jb = &jbv;
1473  jb->type = jbvNumeric;
1475  datum));
1476 
1477  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1478  }
1479  break;
1480 
1481  case jpiStringFunc:
1482  {
1483  JsonbValue jbv;
1484  char *tmp = NULL;
1485 
1486  switch (JsonbType(jb))
1487  {
1488  case jbvString:
1489 
1490  /*
1491  * Value is not necessarily null-terminated, so we do
1492  * pnstrdup() here.
1493  */
1494  tmp = pnstrdup(jb->val.string.val,
1495  jb->val.string.len);
1496  break;
1497  case jbvNumeric:
1499  NumericGetDatum(jb->val.numeric)));
1500  break;
1501  case jbvBool:
1502  tmp = (jb->val.boolean) ? "true" : "false";
1503  break;
1504  case jbvDatetime:
1505  {
1506  switch (jb->val.datetime.typid)
1507  {
1508  case DATEOID:
1510  jb->val.datetime.value));
1511  break;
1512  case TIMEOID:
1514  jb->val.datetime.value));
1515  break;
1516  case TIMETZOID:
1518  jb->val.datetime.value));
1519  break;
1520  case TIMESTAMPOID:
1522  jb->val.datetime.value));
1523  break;
1524  case TIMESTAMPTZOID:
1526  jb->val.datetime.value));
1527  break;
1528  default:
1529  elog(ERROR, "unrecognized SQL/JSON datetime type oid: %u",
1530  jb->val.datetime.typid);
1531  }
1532  }
1533  break;
1534  case jbvNull:
1535  case jbvArray:
1536  case jbvObject:
1537  case jbvBinary:
1539  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
1540  errmsg("jsonpath item method .%s() can only be applied to a bool, string, numeric, or datetime value",
1541  jspOperationName(jsp->type)))));
1542  break;
1543  }
1544 
1545  jb = &jbv;
1546  Assert(tmp != NULL); /* We must have set tmp above */
1547  jb->val.string.val = tmp;
1548  jb->val.string.len = strlen(jb->val.string.val);
1549  jb->type = jbvString;
1550 
1551  res = executeNextItem(cxt, jsp, NULL, jb, found, true);
1552  }
1553  break;
1554 
1555  default:
1556  elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type);
1557  }
1558 
1559  return res;
1560 }
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3375
Datum float8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:4542
Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3367
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3143
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4232
Datum int4_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:4338
Datum numeric_uminus(PG_FUNCTION_ARGS)
Definition: numeric.c:1410
Datum numeric_ceil(PG_FUNCTION_ARGS)
Definition: numeric.c:1629
Datum numerictypmodin(PG_FUNCTION_ARGS)
Definition: numeric.c:1314
Datum numeric_out(PG_FUNCTION_ARGS)
Definition: numeric.c:806
int64 numeric_int8_opt_error(Numeric num, bool *have_error)
Definition: numeric.c:4434
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:627
bool numeric_is_nan(Numeric num)
Definition: numeric.c:841
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2944
Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3022
Datum numeric_abs(PG_FUNCTION_ARGS)
Definition: numeric.c:1383
Datum int8_numeric(PG_FUNCTION_ARGS)
Definition: numeric.c:4426
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2866
bool numeric_is_inf(Numeric num)
Definition: numeric.c:852
Datum numeric_floor(PG_FUNCTION_ARGS)
Definition: numeric.c:1657
Datum timestamptz_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:786
Datum timestamp_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:233
bool parse_bool(const char *value, bool *result)
Definition: bool.c:30
unsigned int uint32
Definition: c.h:495
Datum date_out(PG_FUNCTION_ARGS)
Definition: date.c:184
Datum time_out(PG_FUNCTION_ARGS)
Definition: date.c:1501
Datum timetz_out(PG_FUNCTION_ARGS)
Definition: date.c:2314
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
Definition: float.c:394
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1807
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1816
bool DirectInputFunctionCallSafe(PGFunction func, char *str, Oid typioparam, int32 typmod, fmNodePtr escontext, Datum *result)
Definition: fmgr.c:1640
long val
Definition: informix.c:664
Datum int8in(PG_FUNCTION_ARGS)
Definition: int8.c:51
Datum int4in(PG_FUNCTION_ARGS)
Definition: int.c:287
const char * JsonbTypeName(JsonbValue *val)
Definition: jsonb.c:185
#define JB_FOBJECT
Definition: jsonb.h:202
JsonbValue * getIthJsonbValueFromContainer(JsonbContainer *container, uint32 i)
Definition: jsonb_util.c:470
JsonbValue * findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JsonbValue *key)
Definition: jsonb_util.c:346
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
Definition: jsonpath.c:1229
@ jpiAdd
Definition: jsonpath.h:76
@ jpiAbs
Definition: jsonpath.h:95
@ jpiIndexArray
Definition: jsonpath.h:85
@ jpiAny
Definition: jsonpath.h:86
@ jpiBigint
Definition: jsonpath.h:105
@ jpiBool
Definition: jsonpath.h:65
@ jpiType
Definition: jsonpath.h:93
@ jpiFloor
Definition: jsonpath.h:96
@ jpiAnyArray
Definition: jsonpath.h:83
@ jpiSize
Definition: jsonpath.h:94
@ jpiSub
Definition: jsonpath.h:77
@ jpiMul
Definition: jsonpath.h:78
@ jpiVariable
Definition: jsonpath.h:90
@ jpiPlus
Definition: jsonpath.h:81
@ jpiDouble
Definition: jsonpath.h:98
@ jpiNumber
Definition: jsonpath.h:110
@ jpiMod
Definition: jsonpath.h:80
@ jpiInteger
Definition: jsonpath.h:109
@ jpiRoot
Definition: jsonpath.h:89
@ jpiFilter
Definition: jsonpath.h:91
@ jpiNull
Definition: jsonpath.h:62
@ jpiCurrent
Definition: jsonpath.h:88
@ jpiKey
Definition: jsonpath.h:87
@ jpiDiv
Definition: jsonpath.h:79
@ jpiLast
Definition: jsonpath.h:102
@ jpiMinus
Definition: jsonpath.h:82
@ jpiCeiling
Definition: jsonpath.h:97
@ jpiKeyValue
Definition: jsonpath.h:100
@ jpiBoolean
Definition: jsonpath.h:106
@ jpiStringFunc
Definition: jsonpath.h:111
@ jpiDecimal
Definition: jsonpath.h:108
@ jpiAnyKey
Definition: jsonpath.h:84
static int JsonbArraySize(JsonbValue *jb)
static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonValueList *found, JsonPathBool res)
static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, BinaryArithmFunc func, JsonValueList *found)
#define jspAutoWrap(cxt)
static JsonPathExecResult executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id)
static JsonPathExecResult executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, PGFunction func, JsonValueList *found)
static JsonPathExecResult executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found)
static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb)
#define jspIgnoreStructuralErrors(cxt)
static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, int32 *index)
static JsonPathExecResult executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, JsonValueList *found)
static void getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, JsonbValue *value)
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1630
char * pstrdup(const char *in)
Definition: mcxt.c:1619
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:60
int pg_ltoa(int32 value, char *a)
Definition: numutils.c:1123
int scale
Definition: pgbench.c:181
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
JsonbValue * current
JsonBaseObjectInfo baseObject
struct JsonPathItem::@131::@134 anybounds
struct JsonPathItem::@131::@133 array
struct JsonPathItem::@131::@132 args
Definition: type.h:95

References JsonPathItem::anybounds, appendBoolResult(), JsonPathItem::args, JsonPathItem::array, Assert(), JsonPathExecContext::baseObject, CHECK_FOR_INTERRUPTS, check_stack_depth(), construct_array_builtin(), JsonPathItem::content, CStringGetDatum(), JsonPathExecContext::current, date_out(), DatumGetCString(), DatumGetInt32(), DatumGetNumeric(), DirectFunctionCall1, DirectInputFunctionCallSafe(), elog(), ereport, errcode(), errmsg(), ERROR, ErrorSaveContext::error_occurred, executeAnyItem(), executeBinaryArithmExpr(), executeBoolItem(), executeDateTimeMethod(), executeItemUnwrapTargetArray(), executeKeyValueMethod(), executeNestedBoolItem(), executeNextItem(), executeNumericItemMethod(), executeUnaryArithmExpr(), findJsonbValueFromContainer(), float8_numeric(), Float8GetDatum(), float8in_internal(), getArrayIndex(), getIthJsonbValueFromContainer(), getJsonPathItem(), i, JsonPathExecContext::ignoreStructuralErrors, JsonPathExecContext::innermostArraySize, Int32GetDatum(), int4_numeric(), int4in(), int64_to_numeric(), Int64GetDatum(), int8_numeric(), int8in(), InvalidOid, JB_FOBJECT, jbvArray, jbvBinary, jbvBool, jbvDatetime, jbvNull, jbvNumeric, jbvObject, jbvString, jpbTrue, jperError, jperIsError, jperNotFound, jperOk, jpiAbs, jpiAdd, jpiAnd, jpiAny, jpiAnyArray, jpiAnyKey, jpiBigint, jpiBool, jpiBoolean, jpiCeiling, jpiCurrent, jpiDate, jpiDatetime, jpiDecimal, jpiDiv, jpiDouble, jpiEqual, jpiExists, jpiFilter, jpiFloor, jpiGreater, jpiGreaterOrEqual, jpiIndexArray, jpiInteger, jpiIsUnknown, jpiKey, jpiKeyValue, jpiLast, jpiLess, jpiLessOrEqual, jpiLikeRegex, jpiMinus, jpiMod, jpiMul, jpiNot, jpiNotEqual, jpiNull, jpiNumber, jpiNumeric, jpiOr, jpiPlus, jpiRoot, jpiSize, jpiStartsWith, jpiString, jpiStringFunc, jpiSub, jpiTime, jpiTimestamp, jpiTimestampTz, jpiTimeTz, jpiType, jpiVariable, JsonbArraySize(), JsonbType(), JsonbTypeName(), jspAutoUnwrap, jspAutoWrap, jspGetArg(), jspGetArraySubscript(), jspGetLeftArg(), jspGetNext(), jspGetNumeric(), jspGetRightArg(), jspGetString(), jspHasNext, jspIgnoreStructuralErrors, jspOperationName(), jspThrowErrors, sort-test::key, numeric_abs(), numeric_add_opt_error(), numeric_ceil(), numeric_div_opt_error(), numeric_floor(), numeric_in(), numeric_int4_opt_error(), numeric_int8_opt_error(), numeric_is_inf(), numeric_is_nan(), numeric_mod_opt_error(), numeric_mul_opt_error(), numeric_out(), numeric_sub_opt_error(), numeric_uminus(), NumericGetDatum(), numerictypmodin(), palloc(), parse_bool(), pfree(), pg_ltoa(), pnstrdup(), PointerGetDatum(), pstrdup(), range(), res, RETURN_ERROR, JsonPathExecContext::root, scale, setBaseObject(), time_out(), timestamp_out(), timestamptz_out(), timetz_out(), JsonbValue::type, JsonPathItem::type, JsonbValue::val, and val.

Referenced by executeAnyItem(), and executeItem().

◆ executeItemUnwrapTargetArray()

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

Definition at line 1566 of file jsonpath_exec.c.

1569 {
1570  if (jb->type != jbvBinary)
1571  {
1572  Assert(jb->type != jbvArray);
1573  elog(ERROR, "invalid jsonb array value type: %d", jb->type);
1574  }
1575 
1576  return executeAnyItem
1577  (cxt, jsp, jb->val.binary.data, found, 1, 1, 1,
1578  false, unwrapElements);
1579 }

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

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

◆ executeJsonPath()

static JsonPathExecResult executeJsonPath ( JsonPath path,
void *  vars,
JsonPathGetVarCallback  getVar,
JsonPathCountVarsCallback  countVars,
Jsonb json,
bool  throwErrors,
JsonValueList result,
bool  useTz 
)
static

Definition at line 569 of file jsonpath_exec.c.

573 {
576  JsonPathItem jsp;
577  JsonbValue jbv;
578 
579  jspInit(&jsp, path);
580 
581  if (!JsonbExtractScalar(&json->root, &jbv))
582  JsonbInitBinary(&jbv, json);
583 
584  cxt.vars = vars;
585  cxt.getVar = getVar;
586  cxt.laxMode = (path->header & JSONPATH_LAX) != 0;
588  cxt.root = &jbv;
589  cxt.current = &jbv;
590  cxt.baseObject.jbc = NULL;
591  cxt.baseObject.id = 0;
592  /* 1 + number of base objects in vars */
593  cxt.lastGeneratedObjectId = 1 + countVars(vars);
594  cxt.innermostArraySize = -1;
595  cxt.throwErrors = throwErrors;
596  cxt.useTz = useTz;
597 
598  if (jspStrictAbsenceOfErrors(&cxt) && !result)
599  {
600  /*
601  * In strict mode we must get a complete list of values to check that
602  * there are no errors at all.
603  */
604  JsonValueList vals = {0};
605 
606  res = executeItem(&cxt, &jsp, &jbv, &vals);
607 
608  if (jperIsError(res))
609  return res;
610 
611  return JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk;
612  }
613 
614  res = executeItem(&cxt, &jsp, &jbv, result);
615 
616  Assert(!throwErrors || !jperIsError(res));
617 
618  return res;
619 }
bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
Definition: jsonb.c:1973
void jspInit(JsonPathItem *v, JsonPath *js)
Definition: jsonpath.c:971
#define JSONPATH_LAX
Definition: jsonpath.h:29
static JsonbValue * JsonbInitBinary(JsonbValue *jbv, Jsonb *jb)
JsonbContainer * jbc
Definition: jsonpath_exec.c:86
JsonPathGetVarCallback getVar
uint32 header
Definition: jsonpath.h:24
JsonbContainer root
Definition: jsonb.h:215

References Assert(), JsonPathExecContext::baseObject, JsonPathExecContext::current, executeItem(), JsonPathExecContext::getVar, JsonPath::header, JsonBaseObjectInfo::id, JsonPathExecContext::ignoreStructuralErrors, JsonPathExecContext::innermostArraySize, JsonBaseObjectInfo::jbc, jperIsError, jperNotFound, jperOk, JsonbExtractScalar(), JsonbInitBinary(), JSONPATH_LAX, JsonValueListIsEmpty(), jspInit(), jspStrictAbsenceOfErrors, JsonPathExecContext::lastGeneratedObjectId, JsonPathExecContext::laxMode, res, JsonPathExecContext::root, Jsonb::root, JsonPathExecContext::throwErrors, JsonPathExecContext::useTz, and JsonPathExecContext::vars.

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

◆ executeKeyValueMethod()

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

Definition at line 2687 of file jsonpath_exec.c.

2689 {
2692  JsonbContainer *jbc;
2693  JsonbValue key;
2694  JsonbValue val;
2695  JsonbValue idval;
2696  JsonbValue keystr;
2697  JsonbValue valstr;
2698  JsonbValue idstr;
2699  JsonbIterator *it;
2700  JsonbIteratorToken tok;
2701  int64 id;
2702  bool hasNext;
2703 
2704  if (JsonbType(jb) != jbvObject || jb->type != jbvBinary)
2706  (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND),
2707  errmsg("jsonpath item method .%s() can only be applied to an object",
2708  jspOperationName(jsp->type)))));
2709 
2710  jbc = jb->val.binary.data;
2711 
2712  if (!JsonContainerSize(jbc))
2713  return jperNotFound; /* no key-value pairs */
2714 
2715  hasNext = jspGetNext(jsp, &next);
2716 
2717  keystr.type = jbvString;
2718  keystr.val.string.val = "key";
2719  keystr.val.string.len = 3;
2720 
2721  valstr.type = jbvString;
2722  valstr.val.string.val = "value";
2723  valstr.val.string.len = 5;
2724 
2725  idstr.type = jbvString;
2726  idstr.val.string.val = "id";
2727  idstr.val.string.len = 2;
2728 
2729  /* construct object id from its base object and offset inside that */
2730  id = jb->type != jbvBinary ? 0 :
2731  (int64) ((char *) jbc - (char *) cxt->baseObject.jbc);
2732  id += (int64) cxt->baseObject.id * INT64CONST(10000000000);
2733 
2734  idval.type = jbvNumeric;
2735  idval.val.numeric = int64_to_numeric(id);
2736 
2737  it = JsonbIteratorInit(jbc);
2738 
2739  while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE)
2740  {
2741  JsonBaseObjectInfo baseObject;
2742  JsonbValue obj;
2744  JsonbValue *keyval;
2745  Jsonb *jsonb;
2746 
2747  if (tok != WJB_KEY)
2748  continue;
2749 
2750  res = jperOk;
2751 
2752  if (!hasNext && !found)
2753  break;
2754 
2755  tok = JsonbIteratorNext(&it, &val, true);
2756  Assert(tok == WJB_VALUE);
2757 
2758  ps = NULL;
2760 
2761  pushJsonbValue(&ps, WJB_KEY, &keystr);
2763 
2764  pushJsonbValue(&ps, WJB_KEY, &valstr);
2766 
2767  pushJsonbValue(&ps, WJB_KEY, &idstr);
2768  pushJsonbValue(&ps, WJB_VALUE, &idval);
2769 
2770  keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL);
2771 
2772  jsonb = JsonbValueToJsonb(keyval);
2773 
2774  JsonbInitBinary(&obj, jsonb);
2775 
2776  baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++);
2777 
2778  res = executeNextItem(cxt, jsp, &next, &obj, found, true);
2779 
2780  cxt->baseObject = baseObject;
2781 
2782  if (jperIsError(res))
2783  return res;
2784 
2785  if (res == jperOk && !found)
2786  break;
2787  }
2788 
2789  return res;
2790 }
struct parser_state ps
#define JsonContainerSize(jc)
Definition: jsonb.h:206
JsonbIteratorToken
Definition: jsonb.h:21
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:568

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

Referenced by executeItemOptUnwrapTarget().

◆ executeLikeRegex()

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

Definition at line 2159 of file jsonpath_exec.c.

2161 {
2162  JsonLikeRegexContext *cxt = param;
2163 
2164  if (!(str = getScalar(str, jbvString)))
2165  return jpbUnknown;
2166 
2167  /* Cache regex text and converted flags. */
2168  if (!cxt->regex)
2169  {
2170  cxt->regex =
2172  jsp->content.like_regex.patternlen);
2173  (void) jspConvertRegexFlags(jsp->content.like_regex.flags,
2174  &(cxt->cflags), NULL);
2175  }
2176 
2177  if (RE_compile_and_execute(cxt->regex, str->val.string.val,
2178  str->val.string.len,
2179  cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL))
2180  return jpbTrue;
2181 
2182  return jpbFalse;
2183 }
bool jspConvertRegexFlags(uint32 xflags, int *result, struct Node *escontext)
bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
Definition: regexp.c:359

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

Referenced by executeBoolItem().

◆ executeNestedBoolItem()

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

Definition at line 1805 of file jsonpath_exec.c.

1807 {
1808  JsonbValue *prev;
1809  JsonPathBool res;
1810 
1811  prev = cxt->current;
1812  cxt->current = jb;
1813  res = executeBoolItem(cxt, jsp, jb, false);
1814  cxt->current = prev;
1815 
1816  return res;
1817 }

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

Referenced by executeItemOptUnwrapTarget().

◆ executeNextItem()

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

Definition at line 1586 of file jsonpath_exec.c.

1589 {
1590  JsonPathItem elem;
1591  bool hasNext;
1592 
1593  if (!cur)
1594  hasNext = next != NULL;
1595  else if (next)
1596  hasNext = jspHasNext(cur);
1597  else
1598  {
1599  next = &elem;
1600  hasNext = jspGetNext(cur, next);
1601  }
1602 
1603  if (hasNext)
1604  return executeItem(cxt, next, v, found);
1605 
1606  if (found)
1607  JsonValueListAppend(found, copy ? copyJsonbValue(v) : v);
1608 
1609  return jperOk;
1610 }
struct cursor * cur
Definition: ecpg.c:28

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

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

◆ executeNumericItemMethod()

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

Definition at line 2190 of file jsonpath_exec.c.

2193 {
2195  Datum datum;
2196 
2197  if (unwrap && JsonbType(jb) == jbvArray)
2198  return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false);
2199 
2200  if (!(jb = getScalar(jb, jbvNumeric)))
2202  (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM),
2203  errmsg("jsonpath item method .%s() can only be applied to a numeric value",
2204  jspOperationName(jsp->type)))));
2205 
2206  datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric));
2207 
2208  if (!jspGetNext(jsp, &next) && !found)
2209  return jperOk;
2210 
2211  jb = palloc(sizeof(*jb));
2212  jb->type = jbvNumeric;
2213  jb->val.numeric = DatumGetNumeric(datum);
2214 
2215  return executeNextItem(cxt, jsp, &next, jb, found, false);
2216 }

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

Referenced by executeItemOptUnwrapTarget().

◆ executePredicate()

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

Definition at line 1917 of file jsonpath_exec.c.

1921 {
1923  JsonValueListIterator lseqit;
1924  JsonValueList lseq = {0};
1925  JsonValueList rseq = {0};
1926  JsonbValue *lval;
1927  bool error = false;
1928  bool found = false;
1929 
1930  /* Left argument is always auto-unwrapped. */
1931  res = executeItemOptUnwrapResultNoThrow(cxt, larg, jb, true, &lseq);
1932  if (jperIsError(res))
1933  return jpbUnknown;
1934 
1935  if (rarg)
1936  {
1937  /* Right argument is conditionally auto-unwrapped. */
1938  res = executeItemOptUnwrapResultNoThrow(cxt, rarg, jb,
1939  unwrapRightArg, &rseq);
1940  if (jperIsError(res))
1941  return jpbUnknown;
1942  }
1943 
1944  JsonValueListInitIterator(&lseq, &lseqit);
1945  while ((lval = JsonValueListNext(&lseq, &lseqit)))
1946  {
1947  JsonValueListIterator rseqit;
1948  JsonbValue *rval;
1949  bool first = true;
1950 
1951  JsonValueListInitIterator(&rseq, &rseqit);
1952  if (rarg)
1953  rval = JsonValueListNext(&rseq, &rseqit);
1954  else
1955  rval = NULL;
1956 
1957  /* Loop over right arg sequence or do single pass otherwise */
1958  while (rarg ? (rval != NULL) : first)
1959  {
1960  JsonPathBool res = exec(pred, lval, rval, param);
1961 
1962  if (res == jpbUnknown)
1963  {
1964  if (jspStrictAbsenceOfErrors(cxt))
1965  return jpbUnknown;
1966 
1967  error = true;
1968  }
1969  else if (res == jpbTrue)
1970  {
1971  if (!jspStrictAbsenceOfErrors(cxt))
1972  return jpbTrue;
1973 
1974  found = true;
1975  }
1976 
1977  first = false;
1978  if (rarg)
1979  rval = JsonValueListNext(&rseq, &rseqit);
1980  }
1981  }
1982 
1983  if (found) /* possible only in strict mode */
1984  return jpbTrue;
1985 
1986  if (error) /* possible only in lax mode */
1987  return jpbUnknown;
1988 
1989  return jpbFalse;
1990 }
Definition: type.h:115

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

Referenced by executeBoolItem().

◆ executeStartsWith()

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

Definition at line 2135 of file jsonpath_exec.c.

2137 {
2138  if (!(whole = getScalar(whole, jbvString)))
2139  return jpbUnknown; /* error */
2140 
2141  if (!(initial = getScalar(initial, jbvString)))
2142  return jpbUnknown; /* error */
2143 
2144  if (whole->val.string.len >= initial->val.string.len &&
2145  !memcmp(whole->val.string.val,
2146  initial->val.string.val,
2147  initial->val.string.len))
2148  return jpbTrue;
2149 
2150  return jpbFalse;
2151 }

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

Referenced by executeBoolItem().

◆ executeUnaryArithmExpr()

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

Definition at line 2068 of file jsonpath_exec.c.

2070 {
2071  JsonPathExecResult jper;
2072  JsonPathExecResult jper2;
2073  JsonPathItem elem;
2074  JsonValueList seq = {0};
2076  JsonbValue *val;
2077  bool hasNext;
2078 
2079  jspGetArg(jsp, &elem);
2080  jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &seq);
2081 
2082  if (jperIsError(jper))
2083  return jper;
2084 
2085  jper = jperNotFound;
2086 
2087  hasNext = jspGetNext(jsp, &elem);
2088 
2089  JsonValueListInitIterator(&seq, &it);
2090  while ((val = JsonValueListNext(&seq, &it)))
2091  {
2092  if ((val = getScalar(val, jbvNumeric)))
2093  {
2094  if (!found && !hasNext)
2095  return jperOk;
2096  }
2097  else
2098  {
2099  if (!found && !hasNext)
2100  continue; /* skip non-numerics processing */
2101 
2103  (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND),
2104  errmsg("operand of unary jsonpath operator %s is not a numeric value",
2105  jspOperationName(jsp->type)))));
2106  }
2107 
2108  if (func)
2109  val->val.numeric =
2111  NumericGetDatum(val->val.numeric)));
2112 
2113  jper2 = executeNextItem(cxt, jsp, &elem, val, found, false);
2114 
2115  if (jperIsError(jper2))
2116  return jper2;
2117 
2118  if (jper2 == jperOk)
2119  {
2120  if (!found)
2121  return jperOk;
2122  jper = jperOk;
2123  }
2124  }
2125 
2126  return jper;
2127 }

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

Referenced by executeItemOptUnwrapTarget().

◆ getArrayIndex()

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

Definition at line 3176 of file jsonpath_exec.c.

3178 {
3179  JsonbValue *jbv;
3180  JsonValueList found = {0};
3181  JsonPathExecResult res = executeItem(cxt, jsp, jb, &found);
3182  Datum numeric_index;
3183  bool have_error = false;
3184 
3185  if (jperIsError(res))
3186  return res;
3187 
3188  if (JsonValueListLength(&found) != 1 ||
3189  !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric)))
3191  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
3192  errmsg("jsonpath array subscript is not a single numeric value"))));
3193 
3194  numeric_index = DirectFunctionCall2(numeric_trunc,
3195  NumericGetDatum(jbv->val.numeric),
3196  Int32GetDatum(0));
3197 
3198  *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index),
3199  &have_error);
3200 
3201  if (have_error)
3203  (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT),
3204  errmsg("jsonpath array subscript is out of integer range"))));
3205 
3206  return jperOk;
3207 }
Datum numeric_trunc(PG_FUNCTION_ARGS)
Definition: numeric.c:1582

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

Referenced by executeItemOptUnwrapTarget().

◆ getJsonPathItem()

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

Definition at line 2825 of file jsonpath_exec.c.

2827 {
2828  switch (item->type)
2829  {
2830  case jpiNull:
2831  value->type = jbvNull;
2832  break;
2833  case jpiBool:
2834  value->type = jbvBool;
2835  value->val.boolean = jspGetBool(item);
2836  break;
2837  case jpiNumeric:
2838  value->type = jbvNumeric;
2839  value->val.numeric = jspGetNumeric(item);
2840  break;
2841  case jpiString:
2842  value->type = jbvString;
2843  value->val.string.val = jspGetString(item,
2844  &value->val.string.len);
2845  break;
2846  case jpiVariable:
2847  getJsonPathVariable(cxt, item, value);
2848  return;
2849  default:
2850  elog(ERROR, "unexpected jsonpath item type");
2851  }
2852 }
bool jspGetBool(JsonPathItem *v)
Definition: jsonpath.c:1201
static void getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, JsonbValue *value)

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

Referenced by executeItemOptUnwrapTarget().

◆ getJsonPathVariable()

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

Definition at line 2858 of file jsonpath_exec.c.

2860 {
2861  char *varName;
2862  int varNameLength;
2863  JsonbValue baseObject;
2864  int baseObjectId;
2865  JsonbValue *v;
2866 
2868  varName = jspGetString(variable, &varNameLength);
2869 
2870  if (cxt->vars == NULL ||
2871  (v = cxt->getVar(cxt->vars, varName, varNameLength,
2872  &baseObject, &baseObjectId)) == NULL)
2873  ereport(ERROR,
2874  (errcode(ERRCODE_UNDEFINED_OBJECT),
2875  errmsg("could not find jsonpath variable \"%s\"",
2876  pnstrdup(varName, varNameLength))));
2877 
2878  if (baseObjectId > 0)
2879  {
2880  *value = *v;
2881  setBaseObject(cxt, &baseObject, baseObjectId);
2882  }
2883 }
enum ECPGttype type

References Assert(), ereport, errcode(), errmsg(), ERROR, JsonPathExecContext::getVar, jpiVariable, jspGetString(), pnstrdup(), setBaseObject(), variable::type, value, and JsonPathExecContext::vars.

Referenced by getJsonPathItem().

◆ getJsonPathVariableFromJsonb()

static JsonbValue * getJsonPathVariableFromJsonb ( void *  varsJsonb,
char *  varName,
int  varNameLen,
JsonbValue baseObject,
int *  baseObjectId 
)
static

Definition at line 2890 of file jsonpath_exec.c.

2892 {
2893  Jsonb *vars = varsJsonb;
2894  JsonbValue tmp;
2895  JsonbValue *result;
2896 
2897  tmp.type = jbvString;
2898  tmp.val.string.val = varName;
2899  tmp.val.string.len = varNameLength;
2900 
2901  result = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp);
2902 
2903  if (result == NULL)
2904  {
2905  *baseObjectId = -1;
2906  return NULL;
2907  }
2908 
2909  *baseObjectId = 1;
2910  JsonbInitBinary(baseObject, vars);
2911 
2912  return result;
2913 }

References findJsonbValueFromContainer(), JB_FOBJECT, jbvString, JsonbInitBinary(), JsonbValue::type, and JsonbValue::val.

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

◆ getScalar()

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

Definition at line 3348 of file jsonpath_exec.c.

3349 {
3350  /* Scalars should be always extracted during jsonpath execution. */
3351  Assert(scalar->type != jbvBinary ||
3352  !JsonContainerIsScalar(scalar->val.binary.data));
3353 
3354  return scalar->type == type ? scalar : NULL;
3355 }
#define JsonContainerIsScalar(jc)
Definition: jsonb.h:207
const char * type

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

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

◆ jsonb_path_exists()

Datum jsonb_path_exists ( PG_FUNCTION_ARGS  )

Definition at line 317 of file jsonpath_exec.c.

318 {
319  return jsonb_path_exists_internal(fcinfo, false);
320 }
static Datum jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz)

References jsonb_path_exists_internal().

◆ jsonb_path_exists_internal()

static Datum jsonb_path_exists_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 289 of file jsonpath_exec.c.

290 {
291  Jsonb *jb = PG_GETARG_JSONB_P(0);
294  Jsonb *vars = NULL;
295  bool silent = true;
296 
297  if (PG_NARGS() == 4)
298  {
299  vars = PG_GETARG_JSONB_P(2);
300  silent = PG_GETARG_BOOL(3);
301  }
302 
305  jb, !silent, NULL, tz);
306 
307  PG_FREE_IF_COPY(jb, 0);
308  PG_FREE_IF_COPY(jp, 1);
309 
310  if (jperIsError(res))
311  PG_RETURN_NULL();
312 
314 }
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_NARGS()
Definition: fmgr.h:203
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_JSONB_P(x)
Definition: jsonb.h:391
#define PG_GETARG_JSONPATH_P(x)
Definition: jsonpath.h:44
static JsonbValue * getJsonPathVariableFromJsonb(void *varsJsonb, char *varName, int varNameLen, JsonbValue *baseObject, int *baseObjectId)
static int countVariablesFromJsonb(void *varsJsonb)
static JsonPathExecResult executeJsonPath(JsonPath *path, void *vars, JsonPathGetVarCallback getVar, JsonPathCountVarsCallback countVars, Jsonb *json, bool throwErrors, JsonValueList *result, bool useTz)

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

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

◆ jsonb_path_exists_opr()

Datum jsonb_path_exists_opr ( PG_FUNCTION_ARGS  )

Definition at line 334 of file jsonpath_exec.c.

335 {
336  /* just call the other one -- it can handle both cases */
337  return jsonb_path_exists_internal(fcinfo, false);
338 }

References jsonb_path_exists_internal().

◆ jsonb_path_exists_tz()

Datum jsonb_path_exists_tz ( PG_FUNCTION_ARGS  )

Definition at line 323 of file jsonpath_exec.c.

324 {
325  return jsonb_path_exists_internal(fcinfo, true);
326 }

References jsonb_path_exists_internal().

◆ jsonb_path_match()

Datum jsonb_path_match ( PG_FUNCTION_ARGS  )

Definition at line 387 of file jsonpath_exec.c.

388 {
389  return jsonb_path_match_internal(fcinfo, false);
390 }
static Datum jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz)

References jsonb_path_match_internal().

◆ jsonb_path_match_internal()

static Datum jsonb_path_match_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 346 of file jsonpath_exec.c.

347 {
348  Jsonb *jb = PG_GETARG_JSONB_P(0);
350  JsonValueList found = {0};
351  Jsonb *vars = NULL;
352  bool silent = true;
353 
354  if (PG_NARGS() == 4)
355  {
356  vars = PG_GETARG_JSONB_P(2);
357  silent = PG_GETARG_BOOL(3);
358  }
359 
362  jb, !silent, &found, tz);
363 
364  PG_FREE_IF_COPY(jb, 0);
365  PG_FREE_IF_COPY(jp, 1);
366 
367  if (JsonValueListLength(&found) == 1)
368  {
369  JsonbValue *jbv = JsonValueListHead(&found);
370 
371  if (jbv->type == jbvBool)
372  PG_RETURN_BOOL(jbv->val.boolean);
373 
374  if (jbv->type == jbvNull)
375  PG_RETURN_NULL();
376  }
377 
378  if (!silent)
379  ereport(ERROR,
380  (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED),
381  errmsg("single boolean result is expected")));
382 
383  PG_RETURN_NULL();
384 }

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

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

◆ jsonb_path_match_opr()

Datum jsonb_path_match_opr ( PG_FUNCTION_ARGS  )

Definition at line 404 of file jsonpath_exec.c.

405 {
406  /* just call the other one -- it can handle both cases */
407  return jsonb_path_match_internal(fcinfo, false);
408 }

References jsonb_path_match_internal().

◆ jsonb_path_match_tz()

Datum jsonb_path_match_tz ( PG_FUNCTION_ARGS  )

Definition at line 393 of file jsonpath_exec.c.

394 {
395  return jsonb_path_match_internal(fcinfo, true);
396 }

References jsonb_path_match_internal().

◆ jsonb_path_query()

Datum jsonb_path_query ( PG_FUNCTION_ARGS  )

Definition at line 464 of file jsonpath_exec.c.

465 {
466  return jsonb_path_query_internal(fcinfo, false);
467 }
static Datum jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz)

References jsonb_path_query_internal().

◆ jsonb_path_query_array()

Datum jsonb_path_query_array ( PG_FUNCTION_ARGS  )

Definition at line 497 of file jsonpath_exec.c.

498 {
499  return jsonb_path_query_array_internal(fcinfo, false);
500 }
static Datum jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz)

References jsonb_path_query_array_internal().

◆ jsonb_path_query_array_internal()

static Datum jsonb_path_query_array_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 481 of file jsonpath_exec.c.

482 {
483  Jsonb *jb = PG_GETARG_JSONB_P(0);
485  JsonValueList found = {0};
487  bool silent = PG_GETARG_BOOL(3);
488 
491  jb, !silent, &found, tz);
492 
494 }
#define PG_RETURN_JSONB_P(x)
Definition: jsonb.h:393
static JsonbValue * wrapItemsInArray(const JsonValueList *items)

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

Referenced by jsonb_path_query_array(), and jsonb_path_query_array_tz().

◆ jsonb_path_query_array_tz()

Datum jsonb_path_query_array_tz ( PG_FUNCTION_ARGS  )

Definition at line 503 of file jsonpath_exec.c.

504 {
505  return jsonb_path_query_array_internal(fcinfo, true);
506 }

References jsonb_path_query_array_internal().

◆ jsonb_path_query_first()

Datum jsonb_path_query_first ( PG_FUNCTION_ARGS  )

Definition at line 533 of file jsonpath_exec.c.

534 {
535  return jsonb_path_query_first_internal(fcinfo, false);
536 }
static Datum jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz)

References jsonb_path_query_first_internal().

◆ jsonb_path_query_first_internal()

static Datum jsonb_path_query_first_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

◆ jsonb_path_query_first_tz()

Datum jsonb_path_query_first_tz ( PG_FUNCTION_ARGS  )

Definition at line 539 of file jsonpath_exec.c.

540 {
541  return jsonb_path_query_first_internal(fcinfo, true);
542 }

References jsonb_path_query_first_internal().

◆ jsonb_path_query_internal()

static Datum jsonb_path_query_internal ( FunctionCallInfo  fcinfo,
bool  tz 
)
static

Definition at line 416 of file jsonpath_exec.c.

417 {
418  FuncCallContext *funcctx;
419  List *found;
420  JsonbValue *v;
421  ListCell *c;
422 
423  if (SRF_IS_FIRSTCALL())
424  {
425  JsonPath *jp;
426  Jsonb *jb;
427  MemoryContext oldcontext;
428  Jsonb *vars;
429  bool silent;
430  JsonValueList found = {0};
431 
432  funcctx = SRF_FIRSTCALL_INIT();
433  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
434 
435  jb = PG_GETARG_JSONB_P_COPY(0);
438  silent = PG_GETARG_BOOL(3);
439 
442  jb, !silent, &found, tz);
443 
444  funcctx->user_fctx = JsonValueListGetList(&found);
445 
446  MemoryContextSwitchTo(oldcontext);
447  }
448 
449  funcctx = SRF_PERCALL_SETUP();
450  found = funcctx->user_fctx;
451 
452  c = list_head(found);
453 
454  if (c == NULL)
455  SRF_RETURN_DONE(funcctx);
456 
457  v = lfirst(c);
458  funcctx->user_fctx = list_delete_first(found);
459 
461 }
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
#define PG_GETARG_JSONB_P_COPY(x)
Definition: jsonb.h:392
static Datum JsonbPGetDatum(const Jsonb *p)
Definition: jsonb.h:386
#define PG_GETARG_JSONPATH_P_COPY(x)
Definition: jsonpath.h:45
static List * JsonValueListGetList(JsonValueList *jvl)
List * list_delete_first(List *list)
Definition: list.c:943
#define lfirst(lc)
Definition: pg_list.h:172
static ListCell * list_head(const List *l)
Definition: pg_list.h:128
char * c
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
Definition: pg_list.h:54

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

Referenced by jsonb_path_query(), and jsonb_path_query_tz().

◆ jsonb_path_query_tz()

Datum jsonb_path_query_tz ( PG_FUNCTION_ARGS  )

Definition at line 470 of file jsonpath_exec.c.

471 {
472  return jsonb_path_query_internal(fcinfo, true);
473 }

References jsonb_path_query_internal().

◆ JsonbArraySize()

static int JsonbArraySize ( JsonbValue jb)
static

Definition at line 2942 of file jsonpath_exec.c.

2943 {
2944  Assert(jb->type != jbvArray);
2945 
2946  if (jb->type == jbvBinary)
2947  {
2948  JsonbContainer *jbc = jb->val.binary.data;
2949 
2950  if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
2951  return JsonContainerSize(jbc);
2952  }
2953 
2954  return -1;
2955 }
#define JsonContainerIsArray(jc)
Definition: jsonb.h:209

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

Referenced by executeItemOptUnwrapTarget().

◆ JsonbInitBinary()

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

Definition at line 3311 of file jsonpath_exec.c.

3312 {
3313  jbv->type = jbvBinary;
3314  jbv->val.binary.data = &jb->root;
3315  jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb);
3316 
3317  return jbv;
3318 }
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

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

◆ JsonbType()

static int JsonbType ( JsonbValue jb)
static

Definition at line 3324 of file jsonpath_exec.c.

3325 {
3326  int type = jb->type;
3327 
3328  if (jb->type == jbvBinary)
3329  {
3330  JsonbContainer *jbc = (void *) jb->val.binary.data;
3331 
3332  /* Scalars should be always extracted during jsonpath execution. */
3334 
3335  if (JsonContainerIsObject(jbc))
3336  type = jbvObject;
3337  else if (JsonContainerIsArray(jbc))
3338  type = jbvArray;
3339  else
3340  elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header);
3341  }
3342 
3343  return type;
3344 }
uint32 header
Definition: jsonb.h:192

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

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

◆ JsonValueListAppend()

static void JsonValueListAppend ( JsonValueList jvl,
JsonbValue jbv 
)
static

Definition at line 3223 of file jsonpath_exec.c.

3224 {
3225  if (jvl->singleton)
3226  {
3227  jvl->list = list_make2(jvl->singleton, jbv);
3228  jvl->singleton = NULL;
3229  }
3230  else if (!jvl->list)
3231  jvl->singleton = jbv;
3232  else
3233  jvl->list = lappend(jvl->list, jbv);
3234 }
List * lappend(List *list, void *datum)
Definition: list.c:339
#define list_make2(x1, x2)
Definition: pg_list.h:214
JsonbValue * singleton

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

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

◆ JsonValueListGetList()

static List * JsonValueListGetList ( JsonValueList jvl)
static

Definition at line 3255 of file jsonpath_exec.c.

3256 {
3257  if (jvl->singleton)
3258  return list_make1(jvl->singleton);
3259 
3260  return jvl->list;
3261 }
#define list_make1(x1)
Definition: pg_list.h:212

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

Referenced by jsonb_path_query_internal().

◆ JsonValueListHead()

static JsonbValue * JsonValueListHead ( JsonValueList jvl)
static

Definition at line 3249 of file jsonpath_exec.c.

3250 {
3251  return jvl->singleton ? jvl->singleton : linitial(jvl->list);
3252 }
#define linitial(l)
Definition: pg_list.h:178

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

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

◆ JsonValueListInitIterator()

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

Definition at line 3264 of file jsonpath_exec.c.

3265 {
3266  if (jvl->singleton)
3267  {
3268  it->value = jvl->singleton;
3269  it->list = NIL;
3270  it->next = NULL;
3271  }
3272  else if (jvl->list != NIL)
3273  {
3274  it->value = (JsonbValue *) linitial(jvl->list);
3275  it->list = jvl->list;
3276  it->next = list_second_cell(jvl->list);
3277  }
3278  else
3279  {
3280  it->value = NULL;
3281  it->list = NIL;
3282  it->next = NULL;
3283  }
3284 }
#define NIL
Definition: pg_list.h:68
static ListCell * list_second_cell(const List *l)
Definition: pg_list.h:142

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

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

◆ JsonValueListIsEmpty()

static bool JsonValueListIsEmpty ( JsonValueList jvl)
static

Definition at line 3243 of file jsonpath_exec.c.

3244 {
3245  return !jvl->singleton && (jvl->list == NIL);
3246 }

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

Referenced by executeBoolItem(), and executeJsonPath().

◆ JsonValueListLength()

static int JsonValueListLength ( const JsonValueList jvl)
static

Definition at line 3237 of file jsonpath_exec.c.

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

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

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

◆ JsonValueListNext()

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

Definition at line 3290 of file jsonpath_exec.c.

3291 {
3292  JsonbValue *result = it->value;
3293 
3294  if (it->next)
3295  {
3296  it->value = lfirst(it->next);
3297  it->next = lnext(it->list, it->next);
3298  }
3299  else
3300  {
3301  it->value = NULL;
3302  }
3303 
3304  return result;
3305 }
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343

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

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

◆ setBaseObject()

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

Definition at line 3211 of file jsonpath_exec.c.

3212 {
3213  JsonBaseObjectInfo baseObject = cxt->baseObject;
3214 
3215  cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL :
3216  (JsonbContainer *) jbv->val.binary.data;
3217  cxt->baseObject.id = id;
3218 
3219  return baseObject;
3220 }

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

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

◆ wrapItemsInArray()

static JsonbValue * wrapItemsInArray ( const JsonValueList items)
static

Definition at line 3359 of file jsonpath_exec.c.

3360 {
3361  JsonbParseState *ps = NULL;
3363  JsonbValue *jbv;
3364 
3366 
3367  JsonValueListInitIterator(items, &it);
3368  while ((jbv = JsonValueListNext(items, &it)))
3369  pushJsonbValue(&ps, WJB_ELEM, jbv);
3370 
3371  return pushJsonbValue(&ps, WJB_END_ARRAY, NULL);
3372 }
@ WJB_END_ARRAY
Definition: jsonb.h:27
@ WJB_BEGIN_ARRAY
Definition: jsonb.h:26

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

Referenced by jsonb_path_query_array_internal().