2
0

jsonpath.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*-------------------------------------------------------------------------
  2. *
  3. * jsonpath.h
  4. * Definitions for jsonpath datatype
  5. *
  6. * Copyright (c) 2019-2022, PostgreSQL Global Development Group
  7. *
  8. * IDENTIFICATION
  9. * src/include/utils/jsonpath.h
  10. *
  11. *-------------------------------------------------------------------------
  12. */
  13. #ifndef JSONPATH_H
  14. #define JSONPATH_H
  15. #include "fmgr.h"
  16. #include "nodes/pg_list.h"
  17. #include "utils/jsonb.h"
  18. typedef struct
  19. {
  20. int32 vl_len_; /* varlena header (do not touch directly!) */
  21. uint32 header; /* version and flags (see below) */
  22. char data[FLEXIBLE_ARRAY_MEMBER];
  23. } JsonPath;
  24. #define JSONPATH_VERSION (0x01)
  25. #define JSONPATH_LAX (0x80000000)
  26. #define JSONPATH_HDRSZ (offsetof(JsonPath, data))
  27. #define DatumGetJsonPathP(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM(d)))
  28. #define DatumGetJsonPathPCopy(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM_COPY(d)))
  29. #define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x))
  30. #define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x))
  31. #define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p)
  32. #define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool)
  33. /*
  34. * All node's type of jsonpath expression
  35. */
  36. typedef enum JsonPathItemType
  37. {
  38. jpiNull = jbvNull, /* NULL literal */
  39. jpiString = jbvString, /* string literal */
  40. jpiNumeric = jbvNumeric, /* numeric literal */
  41. jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */
  42. jpiAnd, /* predicate && predicate */
  43. jpiOr, /* predicate || predicate */
  44. jpiNot, /* ! predicate */
  45. jpiIsUnknown, /* (predicate) IS UNKNOWN */
  46. jpiEqual, /* expr == expr */
  47. jpiNotEqual, /* expr != expr */
  48. jpiLess, /* expr < expr */
  49. jpiGreater, /* expr > expr */
  50. jpiLessOrEqual, /* expr <= expr */
  51. jpiGreaterOrEqual, /* expr >= expr */
  52. jpiAdd, /* expr + expr */
  53. jpiSub, /* expr - expr */
  54. jpiMul, /* expr * expr */
  55. jpiDiv, /* expr / expr */
  56. jpiMod, /* expr % expr */
  57. jpiPlus, /* + expr */
  58. jpiMinus, /* - expr */
  59. jpiAnyArray, /* [*] */
  60. jpiAnyKey, /* .* */
  61. jpiIndexArray, /* [subscript, ...] */
  62. jpiAny, /* .** */
  63. jpiKey, /* .key */
  64. jpiCurrent, /* @ */
  65. jpiRoot, /* $ */
  66. jpiVariable, /* $variable */
  67. jpiFilter, /* ? (predicate) */
  68. jpiExists, /* EXISTS (expr) predicate */
  69. jpiType, /* .type() item method */
  70. jpiSize, /* .size() item method */
  71. jpiAbs, /* .abs() item method */
  72. jpiFloor, /* .floor() item method */
  73. jpiCeiling, /* .ceiling() item method */
  74. jpiDouble, /* .double() item method */
  75. jpiDatetime, /* .datetime() item method */
  76. jpiKeyValue, /* .keyvalue() item method */
  77. jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */
  78. jpiLast, /* LAST array subscript */
  79. jpiStartsWith, /* STARTS WITH predicate */
  80. jpiLikeRegex, /* LIKE_REGEX predicate */
  81. } JsonPathItemType;
  82. /* XQuery regex mode flags for LIKE_REGEX predicate */
  83. #define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */
  84. #define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */
  85. #define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */
  86. #define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */
  87. #define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */
  88. /*
  89. * Support functions to parse/construct binary value.
  90. * Unlike many other representation of expression the first/main
  91. * node is not an operation but left operand of expression. That
  92. * allows to implement cheap follow-path descending in jsonb
  93. * structure and then execute operator with right operand
  94. */
  95. typedef struct JsonPathItem
  96. {
  97. JsonPathItemType type;
  98. /* position form base to next node */
  99. int32 nextPos;
  100. /*
  101. * pointer into JsonPath value to current node, all positions of current
  102. * are relative to this base
  103. */
  104. char *base;
  105. union
  106. {
  107. /* classic operator with two operands: and, or etc */
  108. struct
  109. {
  110. int32 left;
  111. int32 right;
  112. } args;
  113. /* any unary operation */
  114. int32 arg;
  115. /* storage for jpiIndexArray: indexes of array */
  116. struct
  117. {
  118. int32 nelems;
  119. struct
  120. {
  121. int32 from;
  122. int32 to;
  123. } *elems;
  124. } array;
  125. /* jpiAny: levels */
  126. struct
  127. {
  128. uint32 first;
  129. uint32 last;
  130. } anybounds;
  131. struct
  132. {
  133. char *data; /* for bool, numeric and string/key */
  134. int32 datalen; /* filled only for string/key */
  135. } value;
  136. struct
  137. {
  138. int32 expr;
  139. char *pattern;
  140. int32 patternlen;
  141. uint32 flags;
  142. } like_regex;
  143. } content;
  144. } JsonPathItem;
  145. #define jspHasNext(jsp) ((jsp)->nextPos > 0)
  146. extern void jspInit(JsonPathItem *v, JsonPath *js);
  147. extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos);
  148. extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a);
  149. extern void jspGetArg(JsonPathItem *v, JsonPathItem *a);
  150. extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a);
  151. extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a);
  152. extern Numeric jspGetNumeric(JsonPathItem *v);
  153. extern bool jspGetBool(JsonPathItem *v);
  154. extern char *jspGetString(JsonPathItem *v, int32 *len);
  155. extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from,
  156. JsonPathItem *to, int i);
  157. extern const char *jspOperationName(JsonPathItemType type);
  158. /*
  159. * Parsing support data structures.
  160. */
  161. typedef struct JsonPathParseItem JsonPathParseItem;
  162. struct JsonPathParseItem
  163. {
  164. JsonPathItemType type;
  165. JsonPathParseItem *next; /* next in path */
  166. union
  167. {
  168. /* classic operator with two operands: and, or etc */
  169. struct
  170. {
  171. JsonPathParseItem *left;
  172. JsonPathParseItem *right;
  173. } args;
  174. /* any unary operation */
  175. JsonPathParseItem *arg;
  176. /* storage for jpiIndexArray: indexes of array */
  177. struct
  178. {
  179. int nelems;
  180. struct
  181. {
  182. JsonPathParseItem *from;
  183. JsonPathParseItem *to;
  184. } *elems;
  185. } array;
  186. /* jpiAny: levels */
  187. struct
  188. {
  189. uint32 first;
  190. uint32 last;
  191. } anybounds;
  192. struct
  193. {
  194. JsonPathParseItem *expr;
  195. char *pattern; /* could not be not null-terminated */
  196. uint32 patternlen;
  197. uint32 flags;
  198. } like_regex;
  199. /* scalars */
  200. Numeric numeric;
  201. bool boolean;
  202. struct
  203. {
  204. uint32 len;
  205. char *val; /* could not be not null-terminated */
  206. } string;
  207. } value;
  208. };
  209. typedef struct JsonPathParseResult
  210. {
  211. JsonPathParseItem *expr;
  212. bool lax;
  213. } JsonPathParseResult;
  214. extern JsonPathParseResult *parsejsonpath(const char *str, int len);
  215. extern int jspConvertRegexFlags(uint32 xflags);
  216. #endif