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-03-03 13:15:30 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        98704 : DatumGetJsonPathP(Datum d)
      36              : {
      37        98704 :     return (JsonPath *) PG_DETOAST_DATUM(d);
      38              : }
      39              : 
      40              : static inline JsonPath *
      41         2034 : DatumGetJsonPathPCopy(Datum d)
      42              : {
      43         2034 :     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.0-1