PostgreSQL Source Code: src/backend/nodes/readfuncs.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
28
29#include <math.h>
30
34
35
36
37
38
39
40
41
42
43
44
45
46#define READ_LOCALS_NO_FIELDS(nodeTypeName) \
47 nodeTypeName *local_node = makeNode(nodeTypeName)
48
49
50#define READ_TEMP_LOCALS() \
51 const char *token; \
52 int length
53
54
55#define READ_LOCALS(nodeTypeName) \
56 READ_LOCALS_NO_FIELDS(nodeTypeName); \
57 READ_TEMP_LOCALS()
58
59
60#define READ_INT_FIELD(fldname) \
61 token = pg_strtok(&length); \
62 token = pg_strtok(&length); \
63 local_node->fldname = atoi(token)
64
65
66#define READ_UINT_FIELD(fldname) \
67 token = pg_strtok(&length); \
68 token = pg_strtok(&length); \
69 local_node->fldname = atoui(token)
70
71
72#define READ_UINT64_FIELD(fldname) \
73 token = pg_strtok(&length); \
74 token = pg_strtok(&length); \
75 local_node->fldname = strtou64(token, NULL, 10)
76
77
78#define READ_LONG_FIELD(fldname) \
79 token = pg_strtok(&length); \
80 token = pg_strtok(&length); \
81 local_node->fldname = atol(token)
82
83
84#define READ_OID_FIELD(fldname) \
85 token = pg_strtok(&length); \
86 token = pg_strtok(&length); \
87 local_node->fldname = atooid(token)
88
89
90#define READ_CHAR_FIELD(fldname) \
91 token = pg_strtok(&length); \
92 token = pg_strtok(&length); \
93 \
94 local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
95
96
97#define READ_ENUM_FIELD(fldname, enumtype) \
98 token = pg_strtok(&length); \
99 token = pg_strtok(&length); \
100 local_node->fldname = (enumtype) atoi(token)
101
102
103#define READ_FLOAT_FIELD(fldname) \
104 token = pg_strtok(&length); \
105 token = pg_strtok(&length); \
106 local_node->fldname = atof(token)
107
108
109#define READ_BOOL_FIELD(fldname) \
110 token = pg_strtok(&length); \
111 token = pg_strtok(&length); \
112 local_node->fldname = strtobool(token)
113
114
115#define READ_STRING_FIELD(fldname) \
116 token = pg_strtok(&length); \
117 token = pg_strtok(&length); \
118 local_node->fldname = nullable_string(token, length)
119
120
121#ifdef DEBUG_NODE_TESTS_ENABLED
122#define READ_LOCATION_FIELD(fldname) \
123 token = pg_strtok(&length); \
124 token = pg_strtok(&length); \
125 local_node->fldname = restore_location_fields ? atoi(token) : -1
126#else
127#define READ_LOCATION_FIELD(fldname) \
128 token = pg_strtok(&length); \
129 token = pg_strtok(&length); \
130 (void) token; \
131 local_node->fldname = -1
132#endif
133
134
135#define READ_NODE_FIELD(fldname) \
136 token = pg_strtok(&length); \
137 (void) token; \
138 local_node->fldname = nodeRead(NULL, 0)
139
140
141#define READ_BITMAPSET_FIELD(fldname) \
142 token = pg_strtok(&length); \
143 (void) token; \
144 local_node->fldname = _readBitmapset()
145
146
147#define READ_ATTRNUMBER_ARRAY(fldname, len) \
148 token = pg_strtok(&length); \
149 local_node->fldname = readAttrNumberCols(len)
150
151
152#define READ_OID_ARRAY(fldname, len) \
153 token = pg_strtok(&length); \
154 local_node->fldname = readOidCols(len)
155
156
157#define READ_INT_ARRAY(fldname, len) \
158 token = pg_strtok(&length); \
159 local_node->fldname = readIntCols(len)
160
161
162#define READ_BOOL_ARRAY(fldname, len) \
163 token = pg_strtok(&length); \
164 local_node->fldname = readBoolCols(len)
165
166
167#define READ_DONE() \
168 return local_node
169
170
171
172
173
174
175
176
177#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
178
179#define strtobool(x) ((*(x) == 't') ? true : false)
180
181static char *
183{
184
185 if (length == 0)
186 return NULL;
187
188 if (length == 2 && token[0] == '"' && token[1] == '"')
190
192}
193
194
195
196
197
198
199
200
201
204{
206
208
210 if (token == NULL)
211 elog(ERROR, "incomplete Bitmapset structure");
212 if (length != 1 || token[0] != '(')
213 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
214
216 if (token == NULL)
217 elog(ERROR, "incomplete Bitmapset structure");
218 if (length != 1 || token[0] != 'b')
219 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
220
221 for (;;)
222 {
224 char *endptr;
225
227 if (token == NULL)
228 elog(ERROR, "unterminated Bitmapset structure");
229 if (length == 1 && token[0] == ')')
230 break;
231 val = (int) strtol(token, &endptr, 10);
232 if (endptr != token + length)
233 elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
235 }
236
237 return result;
238}
239
240
241
242
243
246{
248}
249
250#include "readfuncs.funcs.c"
251
252
253
254
255
256
257
260{
262
270
272 if (local_node->constisnull)
274 else
275 local_node->constvalue = readDatum(local_node->constbyval);
276
278}
279
282{
284
285
288 if (length == 3 && strncmp(token, "and", 3) == 0)
289 local_node->boolop = AND_EXPR;
290 else if (length == 2 && strncmp(token, "or", 2) == 0)
291 local_node->boolop = OR_EXPR;
292 else if (length == 3 && strncmp(token, "not", 3) == 0)
293 local_node->boolop = NOT_EXPR;
294 else
295 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
296
299
301}
302
305{
307
308
310 if (length == 4 && strncmp(token, "NULL", 4) == 0)
311 local_node->isnull = true;
312 else
313 {
315
316
318 {
319 case T_Integer:
320 memcpy(&local_node->val, tmp, sizeof(Integer));
321 break;
322 case T_Float:
323 memcpy(&local_node->val, tmp, sizeof(Float));
324 break;
325 case T_Boolean:
326 memcpy(&local_node->val, tmp, sizeof(Boolean));
327 break;
328 case T_String:
329 memcpy(&local_node->val, tmp, sizeof(String));
330 break;
331 case T_BitString:
332 memcpy(&local_node->val, tmp, sizeof(BitString));
333 break;
334 default:
335 elog(ERROR, "unrecognized node type: %d",
337 break;
338 }
339 }
340
342
344}
345
348{
350
354
355 switch (local_node->rtekind)
356 {
364 break;
368
374 break;
382 break;
386 break;
389
390 if (local_node->tablefunc)
391 {
392 TableFunc *tf = local_node->tablefunc;
393
394 local_node->coltypes = tf->coltypes;
395 local_node->coltypmods = tf->coltypmods;
396 local_node->colcollations = tf->colcollations;
397 }
398 break;
404 break;
412 break;
419
421 break;
423
424 break;
427 break;
428 default:
429 elog(ERROR, "unrecognized RTE kind: %d",
430 (int) local_node->rtekind);
431 break;
432 }
433
437
439}
440
443{
445
447
448 if (length == 3 && strncmp(token, "ANY", 3) == 0)
449 {
452 }
453 else if (length == 3 && strncmp(token, "ALL", 3) == 0)
454 {
457 }
458 else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
459 {
462 }
463 else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
464 {
467 }
468 else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
469 {
472 }
473 else if (length == 2 && strncmp(token, "IN", 2) == 0)
474 {
477 }
478 else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
479 {
482 }
483 else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
484 {
487 }
488 else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
489 {
492 }
493 else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
494 {
497 }
498 else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
499 {
502 }
503 else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
504 {
507 }
508 else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
509 {
512 }
513 else if (length == 5 && strncmp(token, ":name", 5) == 0)
514 {
516 local_node->name = nodeRead(NULL, 0);
517 }
518 else
519 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
520
524
526}
527
530{
533 const char *extnodename;
534
536
539
541 if (!extnodename)
542 elog(ERROR, "extnodename has to be supplied");
544
546 T_ExtensibleNode);
548
549
550 methods->nodeRead(local_node);
551
553}
554
555
556
557
558
559
560
561
562
563
566{
568
569
571
573
574#define MATCH(tokname, namelen) \
575 (length == namelen && memcmp(token, tokname, namelen) == 0)
576
577#include "readfuncs.switch.c"
578
579 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
580 return NULL;
581}
582
583
584
585
586
587
588
589
590
593{
595 i;
596 int tokenLength;
597 const char *token;
599 char *s;
600
601
602
603
606
608 if (token == NULL || token[0] != '[')
609 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
611
612 if (typbyval)
613 {
614 if (length > (Size) sizeof(Datum))
615 elog(ERROR, "byval datum but length = %zu", length);
617 s = (char *) (&res);
619 {
621 s[i] = (char) atoi(token);
622 }
623 }
624 else if (length <= 0)
625 res = (Datum) NULL;
626 else
627 {
628 s = (char *) palloc(length);
629 for (i = 0; i < length; i++)
630 {
632 s[i] = (char) atoi(token);
633 }
635 }
636
638 if (token == NULL || token[0] != ']')
639 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
641
642 return res;
643}
644
645
646
647
648
649
650
651
652
653#define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \
654datatype * \
655fnname(int numCols) \
656{ \
657 datatype *vals; \
658 READ_TEMP_LOCALS(); \
659 token = pg_strtok(&length); \
660 if (token == NULL) \
661 elog(ERROR, "incomplete scalar array"); \
662 if (length == 0) \
663 return NULL; \
664 if (length != 1 || token[0] != '(') \
665 elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \
666 vals = (datatype *) palloc(numCols * sizeof(datatype)); \
667 for (int i = 0; i < numCols; i++) \
668 { \
669 token = pg_strtok(&length); \
670 if (token == NULL || token[0] == ')') \
671 elog(ERROR, "incomplete scalar array"); \
672 vals[i] = convfunc(token); \
673 } \
674 token = pg_strtok(&length); \
675 if (token == NULL || length != 1 || token[0] != ')') \
676 elog(ERROR, "incomplete scalar array"); \
677 return vals; \
678}
679
680
681
682
683
686
687
Bitmapset * bms_add_member(Bitmapset *a, int x)
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
char * pstrdup(const char *in)
int * readIntCols(int numCols)
static Node * newNode(size_t size, NodeTag tag)
Oid * readOidCols(int numCols)
int16 * readAttrNumberCols(int numCols)
bool * readBoolCols(int numCols)
static Datum PointerGetDatum(const void *X)
char * debackslash(const char *token, int length)
void * nodeRead(const char *token, int tok_len)
const char * pg_strtok(int *length)
#define READ_INT_FIELD(fldname)
#define READ_UINT_FIELD(fldname)
#define READ_NODE_FIELD(fldname)
static ExtensibleNode * _readExtensibleNode(void)
#define READ_CHAR_FIELD(fldname)
static char * nullable_string(const char *token, int length)
#define READ_SCALAR_ARRAY(fnname, datatype, convfunc)
Node * parseNodeString(void)
#define READ_OID_FIELD(fldname)
#define READ_LOCATION_FIELD(fldname)
static Bitmapset * _readBitmapset(void)
static A_Const * _readA_Const(void)
static Const * _readConst(void)
#define READ_STRING_FIELD(fldname)
#define READ_FLOAT_FIELD(fldname)
Datum readDatum(bool typbyval)
#define READ_BOOL_FIELD(fldname)
static BoolExpr * _readBoolExpr(void)
#define READ_ENUM_FIELD(fldname, enumtype)
#define READ_TEMP_LOCALS()
static A_Expr * _readA_Expr(void)
Bitmapset * readBitmapset(void)
#define READ_LOCALS(nodeTypeName)
static RangeTblEntry * _readRangeTblEntry(void)
static const struct fns functions
void check_stack_depth(void)
void(* nodeRead)(struct ExtensibleNode *node)