LCOV - code coverage report
Current view: top level - src/include/utils - jsonpath.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 4 4
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * jsonpath.h
       4              :  *      Definitions for jsonpath datatype
       5              :  *
       6              :  * Copyright (c) 2019-2026, PostgreSQL Global Development Group
       7              :  *
       8              :  * IDENTIFICATION
       9              :  *      src/include/utils/jsonpath.h
      10              :  *
      11              :  *-------------------------------------------------------------------------
      12              :  */
      13              : 
      14              : #ifndef JSONPATH_H
      15              : #define JSONPATH_H
      16              : 
      17              : #include "executor/tablefunc.h"
      18              : #include "fmgr.h"
      19              : #include "nodes/pg_list.h"
      20              : #include "nodes/primnodes.h"
      21              : #include "utils/jsonb.h"
      22              : 
      23              : typedef struct
      24              : {
      25              :         int32           vl_len_;                /* varlena header (do not touch directly!) */
      26              :         uint32          header;                 /* version and flags (see below) */
      27              :         char            data[FLEXIBLE_ARRAY_MEMBER];
      28              : } JsonPath;
      29              : 
      30              : #define JSONPATH_VERSION        (0x01)
      31              : #define JSONPATH_LAX            (0x80000000)
      32              : #define JSONPATH_HDRSZ          (offsetof(JsonPath, data))
      33              : 
      34              : static inline JsonPath *
      35        32750 : DatumGetJsonPathP(Datum d)
      36              : {
      37        32750 :         return (JsonPath *) PG_DETOAST_DATUM(d);
      38              : }
      39              : 
      40              : static inline JsonPath *
      41          678 : DatumGetJsonPathPCopy(Datum d)
      42              : {
      43          678 :         return (JsonPath *) PG_DETOAST_DATUM_COPY(d);
      44              : }
      45              : 
      46              : #define PG_GETARG_JSONPATH_P(x)                 DatumGetJsonPathP(PG_GETARG_DATUM(x))
      47              : #define PG_GETARG_JSONPATH_P_COPY(x)    DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
      48              : #define PG_RETURN_JSONPATH_P(p)                 PG_RETURN_POINTER(p)
      49              : 
      50              : #define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)
      51              : 
      52              : /*
      53              :  * All node's type of jsonpath expression
      54              :  *
      55              :  * These become part of the on-disk representation of the jsonpath type.
      56              :  * Therefore, to preserve pg_upgradability, the order must not be changed, and
      57              :  * new values must be added at the end.
      58              :  *
      59              :  * It is recommended that switch cases etc. in other parts of the code also
      60              :  * use this order, to maintain some consistency.
      61              :  */
      62              : typedef enum JsonPathItemType
      63              : {
      64              :         jpiNull = jbvNull,                      /* NULL literal */
      65              :         jpiString = jbvString,          /* string literal */
      66              :         jpiNumeric = jbvNumeric,        /* numeric literal */
      67              :         jpiBool = jbvBool,                      /* boolean literal: TRUE or FALSE */
      68              :         jpiAnd,                                         /* predicate && predicate */
      69              :         jpiOr,                                          /* predicate || predicate */
      70              :         jpiNot,                                         /* ! predicate */
      71              :         jpiIsUnknown,                           /* (predicate) IS UNKNOWN */
      72              :         jpiEqual,                                       /* expr == expr */
      73              :         jpiNotEqual,                            /* expr != expr */
      74              :         jpiLess,                                        /* expr < expr */
      75              :         jpiGreater,                                     /* expr > expr */
      76              :         jpiLessOrEqual,                         /* expr <= expr */
      77              :         jpiGreaterOrEqual,                      /* expr >= expr */
      78              :         jpiAdd,                                         /* expr + expr */
      79              :         jpiSub,                                         /* expr - expr */
      80              :         jpiMul,                                         /* expr * expr */
      81              :         jpiDiv,                                         /* expr / expr */
      82              :         jpiMod,                                         /* expr % expr */
      83              :         jpiPlus,                                        /* + expr */
      84              :         jpiMinus,                                       /* - expr */
      85              :         jpiAnyArray,                            /* [*] */
      86              :         jpiAnyKey,                                      /* .* */
      87              :         jpiIndexArray,                          /* [subscript, ...] */
      88              :         jpiAny,                                         /* .** */
      89              :         jpiKey,                                         /* .key */
      90              :         jpiCurrent,                                     /* @ */
      91              :         jpiRoot,                                        /* $ */
      92              :         jpiVariable,                            /* $variable */
      93              :         jpiFilter,                                      /* ? (predicate) */
      94              :         jpiExists,                                      /* EXISTS (expr) predicate */
      95              :         jpiType,                                        /* .type() item method */
      96              :         jpiSize,                                        /* .size() item method */
      97              :         jpiAbs,                                         /* .abs() item method */
      98              :         jpiFloor,                                       /* .floor() item method */
      99              :         jpiCeiling,                                     /* .ceiling() item method */
     100              :         jpiDouble,                                      /* .double() item method */
     101              :         jpiDatetime,                            /* .datetime() item method */
     102              :         jpiKeyValue,                            /* .keyvalue() item method */
     103              :         jpiSubscript,                           /* array subscript: 'expr' or 'expr TO expr' */
     104              :         jpiLast,                                        /* LAST array subscript */
     105              :         jpiStartsWith,                          /* STARTS WITH predicate */
     106              :         jpiLikeRegex,                           /* LIKE_REGEX predicate */
     107              :         jpiBigint,                                      /* .bigint() item method */
     108              :         jpiBoolean,                                     /* .boolean() item method */
     109              :         jpiDate,                                        /* .date() item method */
     110              :         jpiDecimal,                                     /* .decimal() item method */
     111              :         jpiInteger,                                     /* .integer() item method */
     112              :         jpiNumber,                                      /* .number() item method */
     113              :         jpiStringFunc,                          /* .string() item method */
     114              :         jpiTime,                                        /* .time() item method */
     115              :         jpiTimeTz,                                      /* .time_tz() item method */
     116              :         jpiTimestamp,                           /* .timestamp() item method */
     117              :         jpiTimestampTz,                         /* .timestamp_tz() item method */
     118              : } JsonPathItemType;
     119              : 
     120              : /* XQuery regex mode flags for LIKE_REGEX predicate */
     121              : #define JSP_REGEX_ICASE         0x01    /* i flag, case insensitive */
     122              : #define JSP_REGEX_DOTALL        0x02    /* s flag, dot matches newline */
     123              : #define JSP_REGEX_MLINE         0x04    /* m flag, ^/$ match at newlines */
     124              : #define JSP_REGEX_WSPACE        0x08    /* x flag, ignore whitespace in pattern */
     125              : #define JSP_REGEX_QUOTE         0x10    /* q flag, no special characters */
     126              : 
     127              : /*
     128              :  * Support functions to parse/construct binary value.
     129              :  * Unlike many other representation of expression the first/main
     130              :  * node is not an operation but left operand of expression. That
     131              :  * allows to implement cheap follow-path descending in jsonb
     132              :  * structure and then execute operator with right operand
     133              :  */
     134              : 
     135              : typedef struct JsonPathItem
     136              : {
     137              :         JsonPathItemType type;
     138              : 
     139              :         /* position form base to next node */
     140              :         int32           nextPos;
     141              : 
     142              :         /*
     143              :          * pointer into JsonPath value to current node, all positions of current
     144              :          * are relative to this base
     145              :          */
     146              :         char       *base;
     147              : 
     148              :         union
     149              :         {
     150              :                 /* classic operator with two operands: and, or etc */
     151              :                 struct
     152              :                 {
     153              :                         int32           left;
     154              :                         int32           right;
     155              :                 }                       args;
     156              : 
     157              :                 /* any unary operation */
     158              :                 int32           arg;
     159              : 
     160              :                 /* storage for jpiIndexArray: indexes of array */
     161              :                 struct
     162              :                 {
     163              :                         int32           nelems;
     164              :                         struct
     165              :                         {
     166              :                                 int32           from;
     167              :                                 int32           to;
     168              :                         }                  *elems;
     169              :                 }                       array;
     170              : 
     171              :                 /* jpiAny: levels */
     172              :                 struct
     173              :                 {
     174              :                         uint32          first;
     175              :                         uint32          last;
     176              :                 }                       anybounds;
     177              : 
     178              :                 struct
     179              :                 {
     180              :                         char       *data;       /* for bool, numeric and string/key */
     181              :                         int32           datalen;        /* filled only for string/key */
     182              :                 }                       value;
     183              : 
     184              :                 struct
     185              :                 {
     186              :                         int32           expr;
     187              :                         char       *pattern;
     188              :                         int32           patternlen;
     189              :                         uint32          flags;
     190              :                 }                       like_regex;
     191              :         }                       content;
     192              : } JsonPathItem;
     193              : 
     194              : #define jspHasNext(jsp) ((jsp)->nextPos > 0)
     195              : 
     196              : extern void jspInit(JsonPathItem *v, JsonPath *js);
     197              : extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
     198              : extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
     199              : extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
     200              : extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
     201              : extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
     202              : extern Numeric jspGetNumeric(JsonPathItem *v);
     203              : extern bool jspGetBool(JsonPathItem *v);
     204              : extern char *jspGetString(JsonPathItem *v, int32 *len);
     205              : extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
     206              :                                                                  JsonPathItem *to, int i);
     207              : extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
     208              : 
     209              : extern const char *jspOperationName(JsonPathItemType type);
     210              : 
     211              : /*
     212              :  * Parsing support data structures.
     213              :  */
     214              : 
     215              : typedef struct JsonPathParseItem JsonPathParseItem;
     216              : 
     217              : struct JsonPathParseItem
     218              : {
     219              :         JsonPathItemType type;
     220              :         JsonPathParseItem *next;        /* next in path */
     221              : 
     222              :         union
     223              :         {
     224              : 
     225              :                 /* classic operator with two operands: and, or etc */
     226              :                 struct
     227              :                 {
     228              :                         JsonPathParseItem *left;
     229              :                         JsonPathParseItem *right;
     230              :                 }                       args;
     231              : 
     232              :                 /* any unary operation */
     233              :                 JsonPathParseItem *arg;
     234              : 
     235              :                 /* storage for jpiIndexArray: indexes of array */
     236              :                 struct
     237              :                 {
     238              :                         int                     nelems;
     239              :                         struct
     240              :                         {
     241              :                                 JsonPathParseItem *from;
     242              :                                 JsonPathParseItem *to;
     243              :                         }                  *elems;
     244              :                 }                       array;
     245              : 
     246              :                 /* jpiAny: levels */
     247              :                 struct
     248              :                 {
     249              :                         uint32          first;
     250              :                         uint32          last;
     251              :                 }                       anybounds;
     252              : 
     253              :                 struct
     254              :                 {
     255              :                         JsonPathParseItem *expr;
     256              :                         char       *pattern;    /* could not be not null-terminated */
     257              :                         uint32          patternlen;
     258              :                         uint32          flags;
     259              :                 }                       like_regex;
     260              : 
     261              :                 /* scalars */
     262              :                 Numeric numeric;
     263              :                 bool            boolean;
     264              :                 struct
     265              :                 {
     266              :                         uint32          len;
     267              :                         char       *val;        /* could not be not null-terminated */
     268              :                 }                       string;
     269              :         }                       value;
     270              : };
     271              : 
     272              : typedef struct JsonPathParseResult
     273              : {
     274              :         JsonPathParseItem *expr;
     275              :         bool            lax;
     276              : } JsonPathParseResult;
     277              : 
     278              : extern JsonPathParseResult *parsejsonpath(const char *str, int len,
     279              :                                                                                   struct Node *escontext);
     280              : 
     281              : extern bool jspConvertRegexFlags(uint32 xflags, int *result,
     282              :                                                                  struct Node *escontext);
     283              : 
     284              : /*
     285              :  * Struct for details about external variables passed into jsonpath executor
     286              :  */
     287              : typedef struct JsonPathVariable
     288              : {
     289              :         char       *name;
     290              :         int                     namelen;                /* strlen(name) as cache for GetJsonPathVar() */
     291              :         Oid                     typid;
     292              :         int32           typmod;
     293              :         Datum           value;
     294              :         bool            isnull;
     295              : } JsonPathVariable;
     296              : 
     297              : 
     298              : /* SQL/JSON query functions */
     299              : extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars);
     300              : extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
     301              :                                                    bool *empty, bool *error, List *vars,
     302              :                                                    const char *column_name);
     303              : extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
     304              :                                                                  bool *error, List *vars,
     305              :                                                                  const char *column_name);
     306              : 
     307              : /* For JSON_TABLE() */
     308              : extern PGDLLIMPORT const TableFuncRoutine JsonbTableRoutine;
     309              : 
     310              : #endif
        

Generated by: LCOV version 2.3.2-1