LCOV - code coverage report
Current view: top level - src/include/utils - jsonpath.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 4 4
Test Date: 2026-04-30 22:16:37 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       131929 : DatumGetJsonPathP(Datum d)
      36              : {
      37       131929 :     return (JsonPath *) PG_DETOAST_DATUM(d);
      38              : }
      39              : 
      40              : static inline JsonPath *
      41         3040 : DatumGetJsonPathPCopy(Datum d)
      42              : {
      43         3040 :     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              :     jpiStrReplace,              /* .replace() item method */
     119              :     jpiStrLower,                /* .lower() item method */
     120              :     jpiStrUpper,                /* .upper() item method */
     121              :     jpiStrLtrim,                /* .ltrim() item method */
     122              :     jpiStrRtrim,                /* .rtrim() item method */
     123              :     jpiStrBtrim,                /* .btrim() item method */
     124              :     jpiStrInitcap,              /* .initcap() item method */
     125              :     jpiStrSplitPart,            /* .split_part() item method */
     126              : } JsonPathItemType;
     127              : 
     128              : /* XQuery regex mode flags for LIKE_REGEX predicate */
     129              : #define JSP_REGEX_ICASE     0x01    /* i flag, case insensitive */
     130              : #define JSP_REGEX_DOTALL    0x02    /* s flag, dot matches newline */
     131              : #define JSP_REGEX_MLINE     0x04    /* m flag, ^/$ match at newlines */
     132              : #define JSP_REGEX_WSPACE    0x08    /* x flag, ignore whitespace in pattern */
     133              : #define JSP_REGEX_QUOTE     0x10    /* q flag, no special characters */
     134              : 
     135              : /*
     136              :  * Support functions to parse/construct binary value.
     137              :  * Unlike many other representation of expression the first/main
     138              :  * node is not an operation but left operand of expression. That
     139              :  * allows to implement cheap follow-path descending in jsonb
     140              :  * structure and then execute operator with right operand
     141              :  */
     142              : 
     143              : typedef struct JsonPathItem
     144              : {
     145              :     JsonPathItemType type;
     146              : 
     147              :     /* position form base to next node */
     148              :     int32       nextPos;
     149              : 
     150              :     /*
     151              :      * pointer into JsonPath value to current node, all positions of current
     152              :      * are relative to this base
     153              :      */
     154              :     char       *base;
     155              : 
     156              :     union
     157              :     {
     158              :         /* classic operator with two operands: and, or etc */
     159              :         struct
     160              :         {
     161              :             int32       left;
     162              :             int32       right;
     163              :         }           args;
     164              : 
     165              :         /* any unary operation */
     166              :         int32       arg;
     167              : 
     168              :         /* storage for jpiIndexArray: indexes of array */
     169              :         struct
     170              :         {
     171              :             int32       nelems;
     172              :             struct
     173              :             {
     174              :                 int32       from;
     175              :                 int32       to;
     176              :             }          *elems;
     177              :         }           array;
     178              : 
     179              :         /* jpiAny: levels */
     180              :         struct
     181              :         {
     182              :             uint32      first;
     183              :             uint32      last;
     184              :         }           anybounds;
     185              : 
     186              :         struct
     187              :         {
     188              :             char       *data;   /* for bool, numeric and string/key */
     189              :             int32       datalen;    /* filled only for string/key */
     190              :         }           value;
     191              : 
     192              :         struct
     193              :         {
     194              :             int32       expr;
     195              :             char       *pattern;
     196              :             int32       patternlen;
     197              :             uint32      flags;
     198              :         }           like_regex;
     199              :     }           content;
     200              : } JsonPathItem;
     201              : 
     202              : #define jspHasNext(jsp) ((jsp)->nextPos > 0)
     203              : 
     204              : extern void jspInit(JsonPathItem *v, JsonPath *js);
     205              : extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
     206              : extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
     207              : extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
     208              : extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
     209              : extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
     210              : extern Numeric jspGetNumeric(JsonPathItem *v);
     211              : extern bool jspGetBool(JsonPathItem *v);
     212              : extern char *jspGetString(JsonPathItem *v, int32 *len);
     213              : extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
     214              :                                  JsonPathItem *to, int i);
     215              : extern bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs);
     216              : 
     217              : extern const char *jspOperationName(JsonPathItemType type);
     218              : 
     219              : /*
     220              :  * Parsing support data structures.
     221              :  */
     222              : 
     223              : typedef struct JsonPathParseItem JsonPathParseItem;
     224              : 
     225              : struct JsonPathParseItem
     226              : {
     227              :     JsonPathItemType type;
     228              :     JsonPathParseItem *next;    /* next in path */
     229              : 
     230              :     union
     231              :     {
     232              : 
     233              :         /* classic operator with two operands: and, or etc */
     234              :         struct
     235              :         {
     236              :             JsonPathParseItem *left;
     237              :             JsonPathParseItem *right;
     238              :         }           args;
     239              : 
     240              :         /* any unary operation */
     241              :         JsonPathParseItem *arg;
     242              : 
     243              :         /* storage for jpiIndexArray: indexes of array */
     244              :         struct
     245              :         {
     246              :             int         nelems;
     247              :             struct
     248              :             {
     249              :                 JsonPathParseItem *from;
     250              :                 JsonPathParseItem *to;
     251              :             }          *elems;
     252              :         }           array;
     253              : 
     254              :         /* jpiAny: levels */
     255              :         struct
     256              :         {
     257              :             uint32      first;
     258              :             uint32      last;
     259              :         }           anybounds;
     260              : 
     261              :         struct
     262              :         {
     263              :             JsonPathParseItem *expr;
     264              :             char       *pattern;    /* could not be not null-terminated */
     265              :             uint32      patternlen;
     266              :             uint32      flags;
     267              :         }           like_regex;
     268              : 
     269              :         /* scalars */
     270              :         Numeric numeric;
     271              :         bool        boolean;
     272              :         struct
     273              :         {
     274              :             uint32      len;
     275              :             char       *val;    /* could not be not null-terminated */
     276              :         }           string;
     277              :     }           value;
     278              : };
     279              : 
     280              : typedef struct JsonPathParseResult
     281              : {
     282              :     JsonPathParseItem *expr;
     283              :     bool        lax;
     284              : } JsonPathParseResult;
     285              : 
     286              : extern JsonPathParseResult *parsejsonpath(const char *str, int len,
     287              :                                           struct Node *escontext);
     288              : 
     289              : extern bool jspConvertRegexFlags(uint32 xflags, int *result,
     290              :                                  struct Node *escontext);
     291              : 
     292              : /*
     293              :  * Struct for details about external variables passed into jsonpath executor
     294              :  */
     295              : typedef struct JsonPathVariable
     296              : {
     297              :     char       *name;
     298              :     int         namelen;        /* strlen(name) as cache for GetJsonPathVar() */
     299              :     Oid         typid;
     300              :     int32       typmod;
     301              :     Datum       value;
     302              :     bool        isnull;
     303              : } JsonPathVariable;
     304              : 
     305              : 
     306              : /* SQL/JSON query functions */
     307              : extern bool JsonPathExists(Datum jb, JsonPath *jp, bool *error, List *vars);
     308              : extern Datum JsonPathQuery(Datum jb, JsonPath *jp, JsonWrapper wrapper,
     309              :                            bool *empty, bool *error, List *vars,
     310              :                            const char *column_name);
     311              : extern JsonbValue *JsonPathValue(Datum jb, JsonPath *jp, bool *empty,
     312              :                                  bool *error, List *vars,
     313              :                                  const char *column_name);
     314              : 
     315              : /* For JSON_TABLE() */
     316              : extern PGDLLIMPORT const TableFuncRoutine JsonbTableRoutine;
     317              : 
     318              : #endif
        

Generated by: LCOV version 2.0-1