codekingpro/portable-devtools
115k
1/*-------------------------------------------------------------------------2 *3 * jsonpath.h4 * Definitions for jsonpath datatype5 *6 * Copyright (c) 2019-2023, PostgreSQL Global Development Group7 *8 * IDENTIFICATION9 * src/include/utils/jsonpath.h10 *11 *-------------------------------------------------------------------------12 */13 14#ifndef JSONPATH_H15#define JSONPATH_H16 17#include "fmgr.h"18#include "nodes/pg_list.h"19#include "utils/jsonb.h"20 21typedef struct22{23 int32 vl_len_; /* varlena header (do not touch directly!) */24 uint32 header; /* version and flags (see below) */25 char data[FLEXIBLE_ARRAY_MEMBER];26} JsonPath;27 28#define JSONPATH_VERSION (0x01)29#define JSONPATH_LAX (0x80000000)30#define JSONPATH_HDRSZ (offsetof(JsonPath, data))31 32static inline JsonPath *33DatumGetJsonPathP(Datum d)34{35 return (JsonPath *) PG_DETOAST_DATUM(d);36}37 38static inline JsonPath *39DatumGetJsonPathPCopy(Datum d)40{41 return (JsonPath *) PG_DETOAST_DATUM_COPY(d);42}43 44#define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x))45#define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))46#define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p)47 48#define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)49 50/*51 * All node's type of jsonpath expression52 */53typedef enum JsonPathItemType54{55 jpiNull = jbvNull, /* NULL literal */56 jpiString = jbvString, /* string literal */57 jpiNumeric = jbvNumeric, /* numeric literal */58 jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */59 jpiAnd, /* predicate && predicate */60 jpiOr, /* predicate || predicate */61 jpiNot, /* ! predicate */62 jpiIsUnknown, /* (predicate) IS UNKNOWN */63 jpiEqual, /* expr == expr */64 jpiNotEqual, /* expr != expr */65 jpiLess, /* expr < expr */66 jpiGreater, /* expr > expr */67 jpiLessOrEqual, /* expr <= expr */68 jpiGreaterOrEqual, /* expr >= expr */69 jpiAdd, /* expr + expr */70 jpiSub, /* expr - expr */71 jpiMul, /* expr * expr */72 jpiDiv, /* expr / expr */73 jpiMod, /* expr % expr */74 jpiPlus, /* + expr */75 jpiMinus, /* - expr */76 jpiAnyArray, /* [*] */77 jpiAnyKey, /* .* */78 jpiIndexArray, /* [subscript, ...] */79 jpiAny, /* .** */80 jpiKey, /* .key */81 jpiCurrent, /* @ */82 jpiRoot, /* $ */83 jpiVariable, /* $variable */84 jpiFilter, /* ? (predicate) */85 jpiExists, /* EXISTS (expr) predicate */86 jpiType, /* .type() item method */87 jpiSize, /* .size() item method */88 jpiAbs, /* .abs() item method */89 jpiFloor, /* .floor() item method */90 jpiCeiling, /* .ceiling() item method */91 jpiDouble, /* .double() item method */92 jpiDatetime, /* .datetime() item method */93 jpiKeyValue, /* .keyvalue() item method */94 jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */95 jpiLast, /* LAST array subscript */96 jpiStartsWith, /* STARTS WITH predicate */97 jpiLikeRegex, /* LIKE_REGEX predicate */98} JsonPathItemType;99 100/* XQuery regex mode flags for LIKE_REGEX predicate */101#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */102#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */103#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */104#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */105#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */106 107/*108 * Support functions to parse/construct binary value.109 * Unlike many other representation of expression the first/main110 * node is not an operation but left operand of expression. That111 * allows to implement cheap follow-path descending in jsonb112 * structure and then execute operator with right operand113 */114 115typedef struct JsonPathItem116{117 JsonPathItemType type;118 119 /* position form base to next node */120 int32 nextPos;121 122 /*123 * pointer into JsonPath value to current node, all positions of current124 * are relative to this base125 */126 char *base;127 128 union129 {130 /* classic operator with two operands: and, or etc */131 struct132 {133 int32 left;134 int32 right;135 } args;136 137 /* any unary operation */138 int32 arg;139 140 /* storage for jpiIndexArray: indexes of array */141 struct142 {143 int32 nelems;144 struct145 {146 int32 from;147 int32 to;148 } *elems;149 } array;150 151 /* jpiAny: levels */152 struct153 {154 uint32 first;155 uint32 last;156 } anybounds;157 158 struct159 {160 char *data; /* for bool, numeric and string/key */161 int32 datalen; /* filled only for string/key */162 } value;163 164 struct165 {166 int32 expr;167 char *pattern;168 int32 patternlen;169 uint32 flags;170 } like_regex;171 } content;172} JsonPathItem;173 174#define jspHasNext(jsp) ((jsp)->nextPos > 0)175 176extern void jspInit(JsonPathItem *v, JsonPath *js);177extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);178extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);179extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);180extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);181extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);182extern Numeric jspGetNumeric(JsonPathItem *v);183extern bool jspGetBool(JsonPathItem *v);184extern char *jspGetString(JsonPathItem *v, int32 *len);185extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,186 JsonPathItem *to, int i);187 188extern const char *jspOperationName(JsonPathItemType type);189 190/*191 * Parsing support data structures.192 */193 194typedef struct JsonPathParseItem JsonPathParseItem;195 196struct JsonPathParseItem197{198 JsonPathItemType type;199 JsonPathParseItem *next; /* next in path */200 201 union202 {203 204 /* classic operator with two operands: and, or etc */205 struct206 {207 JsonPathParseItem *left;208 JsonPathParseItem *right;209 } args;210 211 /* any unary operation */212 JsonPathParseItem *arg;213 214 /* storage for jpiIndexArray: indexes of array */215 struct216 {217 int nelems;218 struct219 {220 JsonPathParseItem *from;221 JsonPathParseItem *to;222 } *elems;223 } array;224 225 /* jpiAny: levels */226 struct227 {228 uint32 first;229 uint32 last;230 } anybounds;231 232 struct233 {234 JsonPathParseItem *expr;235 char *pattern; /* could not be not null-terminated */236 uint32 patternlen;237 uint32 flags;238 } like_regex;239 240 /* scalars */241 Numeric numeric;242 bool boolean;243 struct244 {245 uint32 len;246 char *val; /* could not be not null-terminated */247 } string;248 } value;249};250 251typedef struct JsonPathParseResult252{253 JsonPathParseItem *expr;254 bool lax;255} JsonPathParseResult;256 257extern JsonPathParseResult *parsejsonpath(const char *str, int len,258 struct Node *escontext);259 260extern bool jspConvertRegexFlags(uint32 xflags, int *result,261 struct Node *escontext);262 263 264#endif265 