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_INT64_FIELD(fldname) \
73 token = pg_strtok(&length); \
74 token = pg_strtok(&length); \
75 local_node->fldname = strtoi64(token, NULL, 10)
76
77
78#define READ_UINT64_FIELD(fldname) \
79 token = pg_strtok(&length); \
80 token = pg_strtok(&length); \
81 local_node->fldname = strtou64(token, NULL, 10)
82
83
84#define READ_LONG_FIELD(fldname) \
85 token = pg_strtok(&length); \
86 token = pg_strtok(&length); \
87 local_node->fldname = atol(token)
88
89
90#define READ_OID_FIELD(fldname) \
91 token = pg_strtok(&length); \
92 token = pg_strtok(&length); \
93 local_node->fldname = atooid(token)
94
95
96#define READ_CHAR_FIELD(fldname) \
97 token = pg_strtok(&length); \
98 token = pg_strtok(&length); \
99 \
100 local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
101
102
103#define READ_ENUM_FIELD(fldname, enumtype) \
104 token = pg_strtok(&length); \
105 token = pg_strtok(&length); \
106 local_node->fldname = (enumtype) atoi(token)
107
108
109#define READ_FLOAT_FIELD(fldname) \
110 token = pg_strtok(&length); \
111 token = pg_strtok(&length); \
112 local_node->fldname = atof(token)
113
114
115#define READ_BOOL_FIELD(fldname) \
116 token = pg_strtok(&length); \
117 token = pg_strtok(&length); \
118 local_node->fldname = strtobool(token)
119
120
121#define READ_STRING_FIELD(fldname) \
122 token = pg_strtok(&length); \
123 token = pg_strtok(&length); \
124 local_node->fldname = nullable_string(token, length)
125
126
127#ifdef DEBUG_NODE_TESTS_ENABLED
128#define READ_LOCATION_FIELD(fldname) \
129 token = pg_strtok(&length); \
130 token = pg_strtok(&length); \
131 local_node->fldname = restore_location_fields ? atoi(token) : -1
132#else
133#define READ_LOCATION_FIELD(fldname) \
134 token = pg_strtok(&length); \
135 token = pg_strtok(&length); \
136 (void) token; \
137 local_node->fldname = -1
138#endif
139
140
141#define READ_NODE_FIELD(fldname) \
142 token = pg_strtok(&length); \
143 (void) token; \
144 local_node->fldname = nodeRead(NULL, 0)
145
146
147#define READ_BITMAPSET_FIELD(fldname) \
148 token = pg_strtok(&length); \
149 (void) token; \
150 local_node->fldname = _readBitmapset()
151
152
153#define READ_ATTRNUMBER_ARRAY(fldname, len) \
154 token = pg_strtok(&length); \
155 local_node->fldname = readAttrNumberCols(len)
156
157
158#define READ_OID_ARRAY(fldname, len) \
159 token = pg_strtok(&length); \
160 local_node->fldname = readOidCols(len)
161
162
163#define READ_INT_ARRAY(fldname, len) \
164 token = pg_strtok(&length); \
165 local_node->fldname = readIntCols(len)
166
167
168#define READ_BOOL_ARRAY(fldname, len) \
169 token = pg_strtok(&length); \
170 local_node->fldname = readBoolCols(len)
171
172
173#define READ_DONE() \
174 return local_node
175
176
177
178
179
180
181
182
183#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
184
185#define strtobool(x) ((*(x) == 't') ? true : false)
186
187static char *
189{
190
191 if (length == 0)
192 return NULL;
193
194 if (length == 2 && token[0] == '"' && token[1] == '"')
196
198}
199
200
201
202
203
204
205
206
207
210{
212
214
216 if (token == NULL)
217 elog(ERROR, "incomplete Bitmapset structure");
218 if (length != 1 || token[0] != '(')
219 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
220
222 if (token == NULL)
223 elog(ERROR, "incomplete Bitmapset structure");
224 if (length != 1 || token[0] != 'b')
225 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
226
227 for (;;)
228 {
230 char *endptr;
231
233 if (token == NULL)
234 elog(ERROR, "unterminated Bitmapset structure");
235 if (length == 1 && token[0] == ')')
236 break;
237 val = (int) strtol(token, &endptr, 10);
238 if (endptr != token + length)
239 elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
241 }
242
243 return result;
244}
245
246
247
248
249
252{
254}
255
256#include "readfuncs.funcs.c"
257
258
259
260
261
262
263
266{
268
276
278 if (local_node->constisnull)
280 else
281 local_node->constvalue = readDatum(local_node->constbyval);
282
284}
285
288{
290
291
294 if (length == 3 && strncmp(token, "and", 3) == 0)
295 local_node->boolop = AND_EXPR;
296 else if (length == 2 && strncmp(token, "or", 2) == 0)
297 local_node->boolop = OR_EXPR;
298 else if (length == 3 && strncmp(token, "not", 3) == 0)
299 local_node->boolop = NOT_EXPR;
300 else
301 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
302
305
307}
308
311{
313
314
316 if (length == 4 && strncmp(token, "NULL", 4) == 0)
317 local_node->isnull = true;
318 else
319 {
321
322
324 {
325 case T_Integer:
326 memcpy(&local_node->val, tmp, sizeof(Integer));
327 break;
328 case T_Float:
329 memcpy(&local_node->val, tmp, sizeof(Float));
330 break;
331 case T_Boolean:
332 memcpy(&local_node->val, tmp, sizeof(Boolean));
333 break;
334 case T_String:
335 memcpy(&local_node->val, tmp, sizeof(String));
336 break;
337 case T_BitString:
338 memcpy(&local_node->val, tmp, sizeof(BitString));
339 break;
340 default:
341 elog(ERROR, "unrecognized node type: %d",
343 break;
344 }
345 }
346
348
350}
351
354{
356
360
361 switch (local_node->rtekind)
362 {
370 break;
374
380 break;
388 break;
392 break;
395
396 if (local_node->tablefunc)
397 {
398 TableFunc *tf = local_node->tablefunc;
399
400 local_node->coltypes = tf->coltypes;
401 local_node->coltypmods = tf->coltypmods;
402 local_node->colcollations = tf->colcollations;
403 }
404 break;
410 break;
418 break;
425
427 break;
429
430 break;
433 break;
434 default:
435 elog(ERROR, "unrecognized RTE kind: %d",
436 (int) local_node->rtekind);
437 break;
438 }
439
443
445}
446
449{
451
453
454 if (length == 3 && strncmp(token, "ANY", 3) == 0)
455 {
458 }
459 else if (length == 3 && strncmp(token, "ALL", 3) == 0)
460 {
463 }
464 else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
465 {
468 }
469 else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
470 {
473 }
474 else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
475 {
478 }
479 else if (length == 2 && strncmp(token, "IN", 2) == 0)
480 {
483 }
484 else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
485 {
488 }
489 else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
490 {
493 }
494 else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
495 {
498 }
499 else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
500 {
503 }
504 else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
505 {
508 }
509 else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
510 {
513 }
514 else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
515 {
518 }
519 else if (length == 5 && strncmp(token, ":name", 5) == 0)
520 {
522 local_node->name = nodeRead(NULL, 0);
523 }
524 else
525 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
526
532
534}
535
538{
541 const char *extnodename;
542
544
547
549 if (!extnodename)
550 elog(ERROR, "extnodename has to be supplied");
552
554 T_ExtensibleNode);
556
557
558 methods->nodeRead(local_node);
559
561}
562
563
564
565
566
567
568
569
570
571
574{
576
577
579
581
582#define MATCH(tokname, namelen) \
583 (length == namelen && memcmp(token, tokname, namelen) == 0)
584
585#include "readfuncs.switch.c"
586
587 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
588 return NULL;
589}
590
591
592
593
594
595
596
597
598
601{
603 int tokenLength;
604 const char *token;
606 char *s;
607
608
609
610
613
615 if (token == NULL || token[0] != '[')
616 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
618
619 if (typbyval)
620 {
621 if (length > (Size) sizeof(Datum))
622 elog(ERROR, "byval datum but length = %zu", length);
624 s = (char *) (&res);
626 {
628 s[i] = (char) atoi(token);
629 }
630 }
631 else if (length <= 0)
633 else
634 {
635 s = (char *) palloc(length);
636 for (Size i = 0; i < length; i++)
637 {
639 s[i] = (char) atoi(token);
640 }
642 }
643
645 if (token == NULL || token[0] != ']')
646 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
648
649 return res;
650}
651
652
653
654
655
656
657
658
659
660#define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \
661datatype * \
662fnname(int numCols) \
663{ \
664 datatype *vals; \
665 READ_TEMP_LOCALS(); \
666 token = pg_strtok(&length); \
667 if (token == NULL) \
668 elog(ERROR, "incomplete scalar array"); \
669 if (length == 0) \
670 return NULL; \
671 if (length != 1 || token[0] != '(') \
672 elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \
673 vals = (datatype *) palloc(numCols * sizeof(datatype)); \
674 for (int i = 0; i < numCols; i++) \
675 { \
676 token = pg_strtok(&length); \
677 if (token == NULL || token[0] == ')') \
678 elog(ERROR, "incomplete scalar array"); \
679 vals[i] = convfunc(token); \
680 } \
681 token = pg_strtok(&length); \
682 if (token == NULL || length != 1 || token[0] != ')') \
683 elog(ERROR, "incomplete scalar array"); \
684 return vals; \
685}
686
687
688
689
690
693
694
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)