PostgreSQL Source Code: src/backend/utils/adt/jsonpath.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
65
72#include "utils/fmgrprotos.h"
76
77
80 int estimated_len);
82 struct Node *escontext,
84 int nestingLevel, bool insideArraySubscript);
88 bool printBracketes);
90
91
92
93
94
95
96
99{
101 int len = strlen(in);
102
104}
105
106
107
108
109
110
111
112
113
116{
119 char *str;
120 int nbytes;
121
124 else
125 elog(ERROR, "unsupported jsonpath version number: %d", version);
126
128}
129
130
131
132
135{
137
139}
140
141
142
143
144
145
148{
153
156
161
163}
164
165
166
167
168
169
170
171
174{
178
180 return (Datum) 0;
181
182 if (!jsonpath)
184 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
185 errmsg("invalid input syntax for type %s: \"%s\"", "jsonpath",
186 in)));
187
190
192
194 jsonpath->expr, 0, false))
195 return (Datum) 0;
196
200 if (jsonpath->lax)
202
204}
205
206
207
208
209
210
211
212static char *
214{
217
218 if (!out)
219 {
220 out = &buf;
222 }
224
227
230
231 return out->data;
232}
233
234
235
236
237
238static bool
241 bool insideArraySubscript)
242{
243
247 int argNestingLevel = 0;
248
251
253
254
255
256
257
258
260
261
262
263
264
266
267 switch (item->type)
268 {
277 break;
281 break;
285 break;
301 {
302
303
304
305
306
309
311 chld = pos;
314 nestingLevel + argNestingLevel,
315 insideArraySubscript))
316 return false;
317 *(int32 *) (buf->data + left) = chld - pos;
318
320 chld = pos;
323 nestingLevel + argNestingLevel,
324 insideArraySubscript))
325 return false;
326 *(int32 *) (buf->data + right) = chld - pos;
327 }
328 break;
330 {
332
343
346 nestingLevel,
347 insideArraySubscript))
348 return false;
349 *(int32 *) (buf->data + offs) = chld - pos;
350 }
351 break;
353 argNestingLevel++;
354
365 {
367
369 chld = pos;
372 nestingLevel + argNestingLevel,
373 insideArraySubscript))
374 return false;
375 *(int32 *) (buf->data + arg) = chld - pos;
376 }
377 break;
379 break;
381 break;
384 break;
386 if (nestingLevel <= 0)
387 ereturn(escontext, false,
388 (errcode(ERRCODE_SYNTAX_ERROR),
389 errmsg("@ is not allowed in root expressions")));
390 break;
392 if (!insideArraySubscript)
393 ereturn(escontext, false,
394 (errcode(ERRCODE_SYNTAX_ERROR),
395 errmsg("LAST is allowed only in array subscripts")));
396 break;
398 {
400 int offset;
401 int i;
402
404
405 offset = buf->len;
406
408
409 for (i = 0; i < nelems; i++)
410 {
414
417 nestingLevel, true))
418 return false;
419 frompos -= pos;
420
422 {
425 nestingLevel, true))
426 return false;
427 topos -= pos;
428 }
429 else
430 topos = 0;
431
432 ppos = (int32 *) &buf->data[offset + i * 2 * sizeof(int32)];
433
434 ppos[0] = frompos;
435 ppos[1] = topos;
436 }
437 }
438 break;
446 break;
460 break;
461 default:
462 elog(ERROR, "unrecognized jsonpath item type: %d", item->type);
463 }
464
465 if (item->next)
466 {
468 item->next, nestingLevel,
469 insideArraySubscript))
470 return false;
471 chld -= pos;
473 }
474
475 if (result)
476 *result = pos;
477 return true;
478}
479
480
481
482
483static void
485{
487 {
488 case 3:
490
491 case 2:
493
494 case 1:
496
497 default:
498 break;
499 }
500}
501
502
503
504
505
508{
511
513
514 return pos;
515}
516
517
518
519
520static void
522 bool printBracketes)
523{
525 int i;
527 char *str;
528
531
532 switch (v->type)
533 {
536 break;
540 break;
549 break;
553 else
555 break;
570 if (printBracketes)
583 if (printBracketes)
585 break;
591 break;
597 break;
600 if (printBracketes)
607 if (printBracketes)
609 break;
612 break;
614 if (inKey)
617 break;
621 {
625
626 if (i)
628
630
632 {
635 }
636 }
638 break;
640 if (inKey)
642
647 {
650 else
653 }
660 else
664 break;
666 if (inKey)
670 break;
674 break;
678 break;
683 break;
689 break;
695 break;
698 break;
701 break;
704 break;
707 break;
710 break;
713 break;
717 {
720 }
722 break;
725 break;
728 break;
730 if (printBracketes)
732
737
739
743
745 {
747
758
760 }
761
762 if (printBracketes)
764 break;
767 break;
770 break;
773 break;
777 {
780 }
782 {
786 }
788 break;
791 break;
794 break;
797 break;
801 {
804 }
806 break;
810 {
813 }
815 break;
819 {
822 }
824 break;
828 {
831 }
833 break;
834 default:
835 elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
836 }
837
840}
841
842const char *
844{
845 switch (type)
846 {
848 return "&&";
850 return "||";
852 return "==";
854 return "!=";
856 return "<";
858 return ">";
860 return "<=";
862 return ">=";
865 return "+";
868 return "-";
870 return "*";
872 return "/";
874 return "%";
876 return "type";
878 return "size";
880 return "abs";
882 return "floor";
884 return "ceiling";
886 return "double";
888 return "datetime";
890 return "keyvalue";
892 return "starts with";
894 return "like_regex";
896 return "bigint";
898 return "boolean";
900 return "date";
902 return "decimal";
904 return "integer";
906 return "number";
908 return "string";
910 return "time";
912 return "time_tz";
914 return "timestamp";
916 return "timestamp_tz";
917 default:
918 elog(ERROR, "unrecognized jsonpath item type: %d", type);
919 return NULL;
920 }
921}
922
923static int
925{
926 switch (op)
927 {
929 return 0;
931 return 1;
939 return 2;
942 return 3;
946 return 4;
949 return 5;
950 default:
951 return 6;
952 }
953}
954
955
956
957
958
959
960
961#define read_byte(v, b, p) do { \
962 (v) = *(uint8*)((b) + (p)); \
963 (p) += 1; \
964} while(0) \
965
966#define read_int32(v, b, p) do { \
967 (v) = *(uint32*)((b) + (p)); \
968 (p) += sizeof(int32); \
969} while(0) \
970
971#define read_int32_n(v, b, p, n) do { \
972 (v) = (void *)((b) + (p)); \
973 (p) += sizeof(int32) * (n); \
974} while(0) \
975
976
977
978
979void
981{
984}
985
986
987
988
989void
991{
992 v->base = base + pos;
993
995 pos = INTALIGN((uintptr_t) (base + pos)) - (uintptr_t) base;
997
998 switch (v->type)
999 {
1019 break;
1024
1028 break;
1046 break;
1059 break;
1064 break;
1068 break;
1074 break;
1075 default:
1076 elog(ERROR, "unrecognized jsonpath item type: %d", v->type);
1077 }
1078}
1079
1080void
1082{
1094
1096}
1097
1098bool
1100{
1102 {
1156
1157 if (a)
1159 return true;
1160 }
1161
1162 return false;
1163}
1164
1165void
1167{
1183
1185}
1186
1187void
1189{
1205
1207}
1208
1209bool
1211{
1213
1215}
1216
1219{
1221
1223}
1224
1225char *
1227{
1231
1232 if (len)
1235}
1236
1237bool
1239 int i)
1240{
1242
1244
1246 return false;
1247
1249
1250 return true;
1251}
1252
1253
1255{
1260};
1261
1262
1264{
1269 bool mutable;
1270};
1271
1274
1275
1276
1277
1278
1279bool
1281{
1284
1290
1293
1295}
1296
1297
1298
1299
1302{
1305
1307 {
1311
1312 switch (jpi->type)
1313 {
1316 break;
1317
1321 break;
1322
1324 {
1326
1330
1331 cxt->current = prevStatus;
1332 break;
1333 }
1334
1336 {
1341
1343
1345 {
1348
1350 continue;
1351
1353 {
1354 case DATEOID:
1355 case TIMEOID:
1356 case TIMESTAMPOID:
1358 break;
1359
1360 case TIMETZOID:
1361 case TIMESTAMPTZOID:
1363 break;
1364
1365 default:
1367 break;
1368 }
1369
1370 break;
1371 }
1372 break;
1373 }
1374
1384
1387
1388
1389
1390
1391
1396 leftStatus != rightStatus))
1398 break;
1399
1408 break;
1409
1423 break;
1424
1427 {
1430
1433
1435 }
1436
1437
1439 if (!cxt->lax)
1441 break;
1442
1446 break;
1447
1450 {
1451 char *template;
1452
1455 {
1457 break;
1458 }
1459
1463 else
1465 }
1466 else
1467 {
1469 }
1470 break;
1471
1476 break;
1477
1478
1483 break;
1484
1487
1490
1505 break;
1506
1512 break;
1513
1518 break;
1519
1520 }
1521
1523 break;
1524
1525 jpi = &next;
1526 }
1527
1528 return status;
1529}
Datum numeric_out(PG_FUNCTION_ARGS)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define PG_RETURN_BYTEA_P(x)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_CSTRING(n)
bool datetime_format_has_tz(const char *fmt_str)
Assert(PointerIsAligned(start, uint64))
void escape_json_with_len(StringInfo buf, const char *str, int len)
bool jspIsMutable(JsonPath *path, List *varnames, List *varexprs)
static enum JsonPathDatatypeStatus jspIsMutableWalker(JsonPathItem *jpi, struct JsonPathMutableContext *cxt)
void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a)
void jspGetArg(JsonPathItem *v, JsonPathItem *a)
static Datum jsonPathFromCstring(char *in, int len, struct Node *escontext)
Datum jsonpath_send(PG_FUNCTION_ARGS)
#define read_byte(v, b, p)
#define read_int32_n(v, b, p, n)
Datum jsonpath_out(PG_FUNCTION_ARGS)
static void alignStringInfoInt(StringInfo buf)
void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos)
bool jspGetBool(JsonPathItem *v)
void jspInit(JsonPathItem *v, JsonPath *js)
static bool flattenJsonPathParseItem(StringInfo buf, int *result, struct Node *escontext, JsonPathParseItem *item, int nestingLevel, bool insideArraySubscript)
char * jspGetString(JsonPathItem *v, int32 *len)
Numeric jspGetNumeric(JsonPathItem *v)
bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, int i)
static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, bool printBracketes)
#define read_int32(v, b, p)
const char * jspOperationName(JsonPathItemType type)
bool jspGetNext(JsonPathItem *v, JsonPathItem *a)
static int operationPriority(JsonPathItemType op)
Datum jsonpath_recv(PG_FUNCTION_ARGS)
Datum jsonpath_in(PG_FUNCTION_ARGS)
void jspGetRightArg(JsonPathItem *v, JsonPathItem *a)
static int32 reserveSpaceForItemPointer(StringInfo buf)
static char * jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len)
#define PG_RETURN_JSONPATH_P(p)
#define PG_GETARG_JSONPATH_P(x)
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
#define SOFT_ERROR_OCCURRED(escontext)
Oid exprType(const Node *expr)
static Datum NumericGetDatum(Numeric X)
#define lfirst_node(type, lc)
#define forboth(cell1, list1, cell2, list2)
static char * DatumGetCString(Datum X)
unsigned int pq_getmsgint(StringInfo msg, int b)
void pq_sendtext(StringInfo buf, const char *str, int slen)
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
void pq_begintypsend(StringInfo buf)
bytea * pq_endtypsend(StringInfo buf)
static void pq_sendint8(StringInfo buf, uint8 i)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
void check_stack_depth(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void enlargeStringInfo(StringInfo str, int needed)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoSpaces(StringInfo str, int count)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
StringInfoData * StringInfo
#define appendStringInfoCharMacro(str, ch)
struct JsonPathItem::@147::@149::@153 * elems
struct JsonPathItem::@147::@151 value
struct JsonPathItem::@147::@148 args
union JsonPathItem::@147 content
struct JsonPathItem::@147::@149 array
struct JsonPathItem::@147::@150 anybounds
struct JsonPathItem::@147::@152 like_regex
enum JsonPathDatatypeStatus current
struct JsonPathParseItem::@154::@157 anybounds
JsonPathParseItem * right
struct JsonPathParseItem::@154::@156 array
struct JsonPathParseItem::@154::@158 like_regex
struct JsonPathParseItem::@154::@156::@160 * elems
struct JsonPathParseItem::@154::@155 args
struct JsonPathParseItem::@154::@159 string
union JsonPathParseItem::@154 value
char data[FLEXIBLE_ARRAY_MEMBER]
#define SET_VARSIZE(PTR, len)