init
This commit is contained in:
251
db_include/utils/jsonpath.h
Executable file
251
db_include/utils/jsonpath.h
Executable file
@@ -0,0 +1,251 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* jsonpath.h
|
||||
* Definitions for jsonpath datatype
|
||||
*
|
||||
* Copyright (c) 2019-2021, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/include/utils/jsonpath.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef JSONPATH_H
|
||||
#define JSONPATH_H
|
||||
|
||||
#include "fmgr.h"
|
||||
#include "nodes/pg_list.h"
|
||||
#include "utils/jsonb.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32 vl_len_; /* varlena header (do not touch directly!) */
|
||||
uint32 header; /* version and flags (see below) */
|
||||
char data[FLEXIBLE_ARRAY_MEMBER];
|
||||
} JsonPath;
|
||||
|
||||
#define JSONPATH_VERSION (0x01)
|
||||
#define JSONPATH_LAX (0x80000000)
|
||||
#define JSONPATH_HDRSZ (offsetof(JsonPath, data))
|
||||
|
||||
#define DatumGetJsonPathP(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM(d)))
|
||||
#define DatumGetJsonPathPCopy(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM_COPY(d)))
|
||||
#define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x))
|
||||
#define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
|
||||
#define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p)
|
||||
|
||||
#define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)
|
||||
|
||||
/*
|
||||
* All node's type of jsonpath expression
|
||||
*/
|
||||
typedef enum JsonPathItemType
|
||||
{
|
||||
jpiNull = jbvNull, /* NULL literal */
|
||||
jpiString = jbvString, /* string literal */
|
||||
jpiNumeric = jbvNumeric, /* numeric literal */
|
||||
jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */
|
||||
jpiAnd, /* predicate && predicate */
|
||||
jpiOr, /* predicate || predicate */
|
||||
jpiNot, /* ! predicate */
|
||||
jpiIsUnknown, /* (predicate) IS UNKNOWN */
|
||||
jpiEqual, /* expr == expr */
|
||||
jpiNotEqual, /* expr != expr */
|
||||
jpiLess, /* expr < expr */
|
||||
jpiGreater, /* expr > expr */
|
||||
jpiLessOrEqual, /* expr <= expr */
|
||||
jpiGreaterOrEqual, /* expr >= expr */
|
||||
jpiAdd, /* expr + expr */
|
||||
jpiSub, /* expr - expr */
|
||||
jpiMul, /* expr * expr */
|
||||
jpiDiv, /* expr / expr */
|
||||
jpiMod, /* expr % expr */
|
||||
jpiPlus, /* + expr */
|
||||
jpiMinus, /* - expr */
|
||||
jpiAnyArray, /* [*] */
|
||||
jpiAnyKey, /* .* */
|
||||
jpiIndexArray, /* [subscript, ...] */
|
||||
jpiAny, /* .** */
|
||||
jpiKey, /* .key */
|
||||
jpiCurrent, /* @ */
|
||||
jpiRoot, /* $ */
|
||||
jpiVariable, /* $variable */
|
||||
jpiFilter, /* ? (predicate) */
|
||||
jpiExists, /* EXISTS (expr) predicate */
|
||||
jpiType, /* .type() item method */
|
||||
jpiSize, /* .size() item method */
|
||||
jpiAbs, /* .abs() item method */
|
||||
jpiFloor, /* .floor() item method */
|
||||
jpiCeiling, /* .ceiling() item method */
|
||||
jpiDouble, /* .double() item method */
|
||||
jpiDatetime, /* .datetime() item method */
|
||||
jpiKeyValue, /* .keyvalue() item method */
|
||||
jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */
|
||||
jpiLast, /* LAST array subscript */
|
||||
jpiStartsWith, /* STARTS WITH predicate */
|
||||
jpiLikeRegex, /* LIKE_REGEX predicate */
|
||||
} JsonPathItemType;
|
||||
|
||||
/* XQuery regex mode flags for LIKE_REGEX predicate */
|
||||
#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */
|
||||
#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */
|
||||
#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */
|
||||
#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */
|
||||
#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
|
||||
|
||||
/*
|
||||
* Support functions to parse/construct binary value.
|
||||
* Unlike many other representation of expression the first/main
|
||||
* node is not an operation but left operand of expression. That
|
||||
* allows to implement cheap follow-path descending in jsonb
|
||||
* structure and then execute operator with right operand
|
||||
*/
|
||||
|
||||
typedef struct JsonPathItem
|
||||
{
|
||||
JsonPathItemType type;
|
||||
|
||||
/* position form base to next node */
|
||||
int32 nextPos;
|
||||
|
||||
/*
|
||||
* pointer into JsonPath value to current node, all positions of current
|
||||
* are relative to this base
|
||||
*/
|
||||
char *base;
|
||||
|
||||
union
|
||||
{
|
||||
/* classic operator with two operands: and, or etc */
|
||||
struct
|
||||
{
|
||||
int32 left;
|
||||
int32 right;
|
||||
} args;
|
||||
|
||||
/* any unary operation */
|
||||
int32 arg;
|
||||
|
||||
/* storage for jpiIndexArray: indexes of array */
|
||||
struct
|
||||
{
|
||||
int32 nelems;
|
||||
struct
|
||||
{
|
||||
int32 from;
|
||||
int32 to;
|
||||
} *elems;
|
||||
} array;
|
||||
|
||||
/* jpiAny: levels */
|
||||
struct
|
||||
{
|
||||
uint32 first;
|
||||
uint32 last;
|
||||
} anybounds;
|
||||
|
||||
struct
|
||||
{
|
||||
char *data; /* for bool, numeric and string/key */
|
||||
int32 datalen; /* filled only for string/key */
|
||||
} value;
|
||||
|
||||
struct
|
||||
{
|
||||
int32 expr;
|
||||
char *pattern;
|
||||
int32 patternlen;
|
||||
uint32 flags;
|
||||
} like_regex;
|
||||
} content;
|
||||
} JsonPathItem;
|
||||
|
||||
#define jspHasNext(jsp) ((jsp)->nextPos > 0)
|
||||
|
||||
extern void jspInit(JsonPathItem *v, JsonPath *js);
|
||||
extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
|
||||
extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
|
||||
extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
|
||||
extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
|
||||
extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
|
||||
extern Numeric jspGetNumeric(JsonPathItem *v);
|
||||
extern bool jspGetBool(JsonPathItem *v);
|
||||
extern char *jspGetString(JsonPathItem *v, int32 *len);
|
||||
extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
|
||||
JsonPathItem *to, int i);
|
||||
|
||||
extern const char *jspOperationName(JsonPathItemType type);
|
||||
|
||||
/*
|
||||
* Parsing support data structures.
|
||||
*/
|
||||
|
||||
typedef struct JsonPathParseItem JsonPathParseItem;
|
||||
|
||||
struct JsonPathParseItem
|
||||
{
|
||||
JsonPathItemType type;
|
||||
JsonPathParseItem *next; /* next in path */
|
||||
|
||||
union
|
||||
{
|
||||
|
||||
/* classic operator with two operands: and, or etc */
|
||||
struct
|
||||
{
|
||||
JsonPathParseItem *left;
|
||||
JsonPathParseItem *right;
|
||||
} args;
|
||||
|
||||
/* any unary operation */
|
||||
JsonPathParseItem *arg;
|
||||
|
||||
/* storage for jpiIndexArray: indexes of array */
|
||||
struct
|
||||
{
|
||||
int nelems;
|
||||
struct
|
||||
{
|
||||
JsonPathParseItem *from;
|
||||
JsonPathParseItem *to;
|
||||
} *elems;
|
||||
} array;
|
||||
|
||||
/* jpiAny: levels */
|
||||
struct
|
||||
{
|
||||
uint32 first;
|
||||
uint32 last;
|
||||
} anybounds;
|
||||
|
||||
struct
|
||||
{
|
||||
JsonPathParseItem *expr;
|
||||
char *pattern; /* could not be not null-terminated */
|
||||
uint32 patternlen;
|
||||
uint32 flags;
|
||||
} like_regex;
|
||||
|
||||
/* scalars */
|
||||
Numeric numeric;
|
||||
bool boolean;
|
||||
struct
|
||||
{
|
||||
uint32 len;
|
||||
char *val; /* could not be not null-terminated */
|
||||
} string;
|
||||
} value;
|
||||
};
|
||||
|
||||
typedef struct JsonPathParseResult
|
||||
{
|
||||
JsonPathParseItem *expr;
|
||||
bool lax;
|
||||
} JsonPathParseResult;
|
||||
|
||||
extern JsonPathParseResult *parsejsonpath(const char *str, int len);
|
||||
|
||||
extern int jspConvertRegexFlags(uint32 xflags);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user