LCOV - code coverage report
Current view: top level - src/include/utils - jsonpath.h (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 4 4 100.0 %
Date: 2024-11-21 11:14:46 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * jsonpath.h
       4             :  *  Definitions for jsonpath datatype
       5             :  *
       6             :  * Copyright (c) 2019-2024, 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      197366 : DatumGetJsonPathP(Datum d)
      36             : {
      37      197366 :     return (JsonPath *) PG_DETOAST_DATUM(d);
      38             : }
      39             : 
      40             : static inline JsonPath *
      41        4068 : DatumGetJsonPathPCopy(Datum d)
      42             : {
      43        4068 :     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 1.14