PostgreSQL Source Code git master
Loading...
Searching...
No Matches
readfuncs.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * readfuncs.c
4 * Reader functions for Postgres tree nodes.
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/nodes/readfuncs.c
12 *
13 * NOTES
14 * Parse location fields are written out by outfuncs.c, but only for
15 * debugging use. When reading a location field, we normally discard
16 * the stored value and set the location field to -1 (ie, "unknown").
17 * This is because nodes coming from a stored rule should not be thought
18 * to have a known location in the current query's text.
19 *
20 * However, if restore_location_fields is true, we do restore location
21 * fields from the string. This is currently intended only for use by the
22 * debug_write_read_parse_plan_trees test code, which doesn't want to cause
23 * any change in the node contents.
24 *
25 *-------------------------------------------------------------------------
26 */
27#include "postgres.h"
28
29#include "miscadmin.h"
30#include "nodes/bitmapset.h"
31#include "nodes/readfuncs.h"
32
33
34/*
35 * Macros to simplify reading of different kinds of fields. Use these
36 * wherever possible to reduce the chance for silly typos. Note that these
37 * hard-wire conventions about the names of the local variables in a Read
38 * routine.
39 */
40
41/* Macros for declaring appropriate local variables */
42
43/* A few guys need only local_node */
44#define READ_LOCALS_NO_FIELDS(nodeTypeName) \
45 nodeTypeName *local_node = makeNode(nodeTypeName)
46
47/* And a few guys need only the pg_strtok support fields */
48#define READ_TEMP_LOCALS() \
49 const char *token; \
50 int length
51
52/* ... but most need both */
53#define READ_LOCALS(nodeTypeName) \
54 READ_LOCALS_NO_FIELDS(nodeTypeName); \
55 READ_TEMP_LOCALS()
56
57/* Read an integer field (anything written as ":fldname %d") */
58#define READ_INT_FIELD(fldname) \
59 token = pg_strtok(&length); /* skip :fldname */ \
60 token = pg_strtok(&length); /* get field value */ \
61 local_node->fldname = atoi(token)
62
63/* Read an unsigned integer field (anything written as ":fldname %u") */
64#define READ_UINT_FIELD(fldname) \
65 token = pg_strtok(&length); /* skip :fldname */ \
66 token = pg_strtok(&length); /* get field value */ \
67 local_node->fldname = atoui(token)
68
69/* Read a signed integer field (anything written using INT64_FORMAT) */
70#define READ_INT64_FIELD(fldname) \
71 token = pg_strtok(&length); /* skip :fldname */ \
72 token = pg_strtok(&length); /* get field value */ \
73 local_node->fldname = strtoi64(token, NULL, 10)
74
75/* Read an unsigned integer field (anything written using UINT64_FORMAT) */
76#define READ_UINT64_FIELD(fldname) \
77 token = pg_strtok(&length); /* skip :fldname */ \
78 token = pg_strtok(&length); /* get field value */ \
79 local_node->fldname = strtou64(token, NULL, 10)
80
81/* Read a long integer field (anything written as ":fldname %ld") */
82#define READ_LONG_FIELD(fldname) \
83 token = pg_strtok(&length); /* skip :fldname */ \
84 token = pg_strtok(&length); /* get field value */ \
85 local_node->fldname = atol(token)
86
87/* Read an OID field (don't hard-wire assumption that OID is same as uint) */
88#define READ_OID_FIELD(fldname) \
89 token = pg_strtok(&length); /* skip :fldname */ \
90 token = pg_strtok(&length); /* get field value */ \
91 local_node->fldname = atooid(token)
92
93/* Read a char field (ie, one ascii character) */
94#define READ_CHAR_FIELD(fldname) \
95 token = pg_strtok(&length); /* skip :fldname */ \
96 token = pg_strtok(&length); /* get field value */ \
97 /* avoid overhead of calling debackslash() for one char */ \
98 local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
99
100/* Read an enumerated-type field that was written as an integer code */
101#define READ_ENUM_FIELD(fldname, enumtype) \
102 token = pg_strtok(&length); /* skip :fldname */ \
103 token = pg_strtok(&length); /* get field value */ \
104 local_node->fldname = (enumtype) atoi(token)
105
106/* Read a float field */
107#define READ_FLOAT_FIELD(fldname) \
108 token = pg_strtok(&length); /* skip :fldname */ \
109 token = pg_strtok(&length); /* get field value */ \
110 local_node->fldname = atof(token)
111
112/* Read a boolean field */
113#define READ_BOOL_FIELD(fldname) \
114 token = pg_strtok(&length); /* skip :fldname */ \
115 token = pg_strtok(&length); /* get field value */ \
116 local_node->fldname = strtobool(token)
117
118/* Read a character-string field */
119#define READ_STRING_FIELD(fldname) \
120 token = pg_strtok(&length); /* skip :fldname */ \
121 token = pg_strtok(&length); /* get field value */ \
122 local_node->fldname = nullable_string(token, length)
123
124/* Read a parse location field (and possibly throw away the value) */
125#ifdef DEBUG_NODE_TESTS_ENABLED
126#define READ_LOCATION_FIELD(fldname) \
127 token = pg_strtok(&length); /* skip :fldname */ \
128 token = pg_strtok(&length); /* get field value */ \
129 local_node->fldname = restore_location_fields ? atoi(token) : -1
130#else
131#define READ_LOCATION_FIELD(fldname) \
132 token = pg_strtok(&length); /* skip :fldname */ \
133 token = pg_strtok(&length); /* get field value */ \
134 (void) token; /* in case not used elsewhere */ \
135 local_node->fldname = -1 /* set field to "unknown" */
136#endif
137
138/* Read a Node field */
139#define READ_NODE_FIELD(fldname) \
140 token = pg_strtok(&length); /* skip :fldname */ \
141 (void) token; /* in case not used elsewhere */ \
142 local_node->fldname = nodeRead(NULL, 0)
143
144/* Read a bitmapset field */
145#define READ_BITMAPSET_FIELD(fldname) \
146 token = pg_strtok(&length); /* skip :fldname */ \
147 (void) token; /* in case not used elsewhere */ \
148 local_node->fldname = _readBitmapset()
149
150/* Read an attribute number array */
151#define READ_ATTRNUMBER_ARRAY(fldname, len) \
152 token = pg_strtok(&length); /* skip :fldname */ \
153 local_node->fldname = readAttrNumberCols(len)
154
155/* Read an oid array */
156#define READ_OID_ARRAY(fldname, len) \
157 token = pg_strtok(&length); /* skip :fldname */ \
158 local_node->fldname = readOidCols(len)
159
160/* Read an int array */
161#define READ_INT_ARRAY(fldname, len) \
162 token = pg_strtok(&length); /* skip :fldname */ \
163 local_node->fldname = readIntCols(len)
164
165/* Read a bool array */
166#define READ_BOOL_ARRAY(fldname, len) \
167 token = pg_strtok(&length); /* skip :fldname */ \
168 local_node->fldname = readBoolCols(len)
169
170/* Routine exit */
171#define READ_DONE() \
172 return local_node
173
174
175/*
176 * NOTE: use atoi() to read values written with %d, or atoui() to read
177 * values written with %u in outfuncs.c. An exception is OID values,
178 * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u,
179 * but this will probably change in the future.)
180 */
181#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
182
183#define strtobool(x) ((*(x) == 't') ? true : false)
184
185static char *
186nullable_string(const char *token, int length)
187{
188 /* outToken emits <> for NULL, and pg_strtok makes that an empty string */
189 if (length == 0)
190 return NULL;
191 /* outToken emits "" for empty string */
192 if (length == 2 && token[0] == '"' && token[1] == '"')
193 return pstrdup("");
194 /* otherwise, we must remove protective backslashes added by outToken */
195 return debackslash(token, length);
196}
197
198
199/*
200 * _readBitmapset
201 *
202 * Note: this code is used in contexts where we know that a Bitmapset
203 * is expected. There is equivalent code in nodeRead() that can read a
204 * Bitmapset when we come across one in other contexts.
205 */
206static Bitmapset *
208{
209 Bitmapset *result = NULL;
210
212
213 token = pg_strtok(&length);
214 if (token == NULL)
215 elog(ERROR, "incomplete Bitmapset structure");
216 if (length != 1 || token[0] != '(')
217 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
218
219 token = pg_strtok(&length);
220 if (token == NULL)
221 elog(ERROR, "incomplete Bitmapset structure");
222 if (length != 1 || token[0] != 'b')
223 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
224
225 for (;;)
226 {
227 int val;
228 char *endptr;
229
230 token = pg_strtok(&length);
231 if (token == NULL)
232 elog(ERROR, "unterminated Bitmapset structure");
233 if (length == 1 && token[0] == ')')
234 break;
235 val = (int) strtol(token, &endptr, 10);
236 if (endptr != token + length)
237 elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
238 result = bms_add_member(result, val);
239 }
240
241 return result;
242}
243
244/*
245 * We export this function for use by extensions that define extensible nodes.
246 * That's somewhat historical, though, because calling nodeRead() will work.
247 */
248Bitmapset *
250{
251 return _readBitmapset();
252}
253
254#include "readfuncs.funcs.c"
255
256
257/*
258 * Support functions for nodes with custom_read_write attribute or
259 * special_read_write attribute
260 */
261
262static Const *
264{
266
267 READ_OID_FIELD(consttype);
273 READ_LOCATION_FIELD(location);
274
275 token = pg_strtok(&length); /* skip :constvalue */
276 if (local_node->constisnull)
277 token = pg_strtok(&length); /* skip "<>" */
278 else
279 local_node->constvalue = readDatum(local_node->constbyval);
280
281 READ_DONE();
282}
283
284static BoolExpr *
286{
288
289 /* do-it-yourself enum representation */
290 token = pg_strtok(&length); /* skip :boolop */
291 token = pg_strtok(&length); /* get field value */
292 if (length == 3 && strncmp(token, "and", 3) == 0)
293 local_node->boolop = AND_EXPR;
294 else if (length == 2 && strncmp(token, "or", 2) == 0)
295 local_node->boolop = OR_EXPR;
296 else if (length == 3 && strncmp(token, "not", 3) == 0)
297 local_node->boolop = NOT_EXPR;
298 else
299 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
300
301 READ_NODE_FIELD(args);
302 READ_LOCATION_FIELD(location);
303
304 READ_DONE();
305}
306
307static A_Const *
309{
311
312 /* We expect either NULL or :val here */
313 token = pg_strtok(&length);
314 if (length == 4 && strncmp(token, "NULL", 4) == 0)
315 local_node->isnull = true;
316 else
317 {
318 union ValUnion *tmp = nodeRead(NULL, 0);
319
320 /* To forestall valgrind complaints, copy only the valid data */
321 switch (nodeTag(tmp))
322 {
323 case T_Integer:
324 memcpy(&local_node->val, tmp, sizeof(Integer));
325 break;
326 case T_Float:
327 memcpy(&local_node->val, tmp, sizeof(Float));
328 break;
329 case T_Boolean:
330 memcpy(&local_node->val, tmp, sizeof(Boolean));
331 break;
332 case T_String:
333 memcpy(&local_node->val, tmp, sizeof(String));
334 break;
335 case T_BitString:
336 memcpy(&local_node->val, tmp, sizeof(BitString));
337 break;
338 default:
339 elog(ERROR, "unrecognized node type: %d",
340 (int) nodeTag(tmp));
341 break;
342 }
343 }
344
345 READ_LOCATION_FIELD(location);
346
347 READ_DONE();
348}
349
350static RangeTblEntry *
352{
354
355 READ_NODE_FIELD(alias);
357 READ_ENUM_FIELD(rtekind, RTEKind);
358
359 switch (local_node->rtekind)
360 {
361 case RTE_RELATION:
362 READ_OID_FIELD(relid);
363 READ_BOOL_FIELD(inh);
364 READ_CHAR_FIELD(relkind);
367 READ_NODE_FIELD(tablesample);
368 break;
369 case RTE_SUBQUERY:
370 READ_NODE_FIELD(subquery);
371 READ_BOOL_FIELD(security_barrier);
372 /* we re-use these RELATION fields, too: */
373 READ_OID_FIELD(relid);
374 READ_BOOL_FIELD(inh);
375 READ_CHAR_FIELD(relkind);
378 break;
379 case RTE_JOIN:
380 READ_ENUM_FIELD(jointype, JoinType);
386 break;
387 case RTE_FUNCTION:
389 READ_BOOL_FIELD(funcordinality);
390 break;
391 case RTE_TABLEFUNC:
392 READ_NODE_FIELD(tablefunc);
393 /* The RTE must have a copy of the column type info, if any */
394 if (local_node->tablefunc)
395 {
396 TableFunc *tf = local_node->tablefunc;
397
398 local_node->coltypes = tf->coltypes;
399 local_node->coltypmods = tf->coltypmods;
400 local_node->colcollations = tf->colcollations;
401 }
402 break;
403 case RTE_VALUES:
404 READ_NODE_FIELD(values_lists);
408 break;
409 case RTE_CTE:
410 READ_STRING_FIELD(ctename);
411 READ_UINT_FIELD(ctelevelsup);
416 break;
418 READ_STRING_FIELD(enrname);
419 READ_FLOAT_FIELD(enrtuples);
423 /* we re-use these RELATION fields, too: */
424 READ_OID_FIELD(relid);
425 break;
426 case RTE_RESULT:
427 /* no extra fields */
428 break;
429 case RTE_GROUP:
430 READ_NODE_FIELD(groupexprs);
431 break;
432 default:
433 elog(ERROR, "unrecognized RTE kind: %d",
434 (int) local_node->rtekind);
435 break;
436 }
437
438 READ_BOOL_FIELD(lateral);
441
442 READ_DONE();
443}
444
445static A_Expr *
447{
449
450 token = pg_strtok(&length);
451
452 if (length == 3 && strncmp(token, "ANY", 3) == 0)
453 {
454 local_node->kind = AEXPR_OP_ANY;
456 }
457 else if (length == 3 && strncmp(token, "ALL", 3) == 0)
458 {
459 local_node->kind = AEXPR_OP_ALL;
461 }
462 else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
463 {
466 }
467 else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
468 {
471 }
472 else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
473 {
474 local_node->kind = AEXPR_NULLIF;
476 }
477 else if (length == 2 && strncmp(token, "IN", 2) == 0)
478 {
479 local_node->kind = AEXPR_IN;
481 }
482 else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
483 {
484 local_node->kind = AEXPR_LIKE;
486 }
487 else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
488 {
489 local_node->kind = AEXPR_ILIKE;
491 }
492 else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
493 {
496 }
497 else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
498 {
501 }
502 else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
503 {
506 }
507 else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
508 {
511 }
512 else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
513 {
516 }
517 else if (length == 5 && strncmp(token, ":name", 5) == 0)
518 {
519 local_node->kind = AEXPR_OP;
520 local_node->name = nodeRead(NULL, 0);
521 }
522 else
523 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
524
525 READ_NODE_FIELD(lexpr);
526 READ_NODE_FIELD(rexpr);
527 READ_LOCATION_FIELD(rexpr_list_start);
528 READ_LOCATION_FIELD(rexpr_list_end);
529 READ_LOCATION_FIELD(location);
530
531 READ_DONE();
532}
533
534static ExtensibleNode *
536{
537 const ExtensibleNodeMethods *methods;
539 const char *extnodename;
540
542
543 token = pg_strtok(&length); /* skip :extnodename */
544 token = pg_strtok(&length); /* get extnodename */
545
546 extnodename = nullable_string(token, length);
547 if (!extnodename)
548 elog(ERROR, "extnodename has to be supplied");
549 methods = GetExtensibleNodeMethods(extnodename, false);
550
553 local_node->extnodename = extnodename;
554
555 /* deserialize the private fields */
556 methods->nodeRead(local_node);
557
558 READ_DONE();
559}
560
561
562/*
563 * parseNodeString
564 *
565 * Given a character string representing a node tree, parseNodeString creates
566 * the internal node structure.
567 *
568 * The string to be read must already have been loaded into pg_strtok().
569 */
570Node *
572{
574
575 /* Guard against stack overflow due to overly complex expressions */
577
578 token = pg_strtok(&length);
579
580#define MATCH(tokname, namelen) \
581 (length == namelen && memcmp(token, tokname, namelen) == 0)
582
583#include "readfuncs.switch.c"
584
585 elog(ERROR, "badly formatted node string \"%.32s\"...", token);
586 return NULL; /* keep compiler quiet */
587}
588
589
590/*
591 * readDatum
592 *
593 * Given a string representation of a constant, recreate the appropriate
594 * Datum. The string representation embeds length info, but not byValue,
595 * so we must be told that.
596 */
597Datum
598readDatum(bool typbyval)
599{
600 Size length;
601 int tokenLength;
602 const char *token;
603 Datum res;
604 char *s;
605
606 /*
607 * read the actual length of the value
608 */
610 length = atoui(token);
611
612 token = pg_strtok(&tokenLength); /* read the '[' */
613 if (token == NULL || token[0] != '[')
614 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
615 token ? token : "[NULL]", length);
616
617 if (typbyval)
618 {
619 if (length > (Size) sizeof(Datum))
620 elog(ERROR, "byval datum but length = %zu", length);
621 res = (Datum) 0;
622 s = (char *) (&res);
623 for (Size i = 0; i < (Size) sizeof(Datum); i++)
624 {
626 s[i] = (char) atoi(token);
627 }
628 }
629 else if (length <= 0)
630 res = (Datum) 0;
631 else
632 {
633 s = (char *) palloc(length);
634 for (Size i = 0; i < length; i++)
635 {
637 s[i] = (char) atoi(token);
638 }
639 res = PointerGetDatum(s);
640 }
641
642 token = pg_strtok(&tokenLength); /* read the ']' */
643 if (token == NULL || token[0] != ']')
644 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
645 token ? token : "[NULL]", length);
646
647 return res;
648}
649
650/*
651 * common implementation for scalar-array-reading functions
652 *
653 * The data format is either "<>" for a NULL pointer (in which case numCols
654 * is ignored) or "(item item item)" where the number of items must equal
655 * numCols. The convfunc must be okay with stopping at whitespace or a
656 * right parenthesis, since pg_strtok won't null-terminate the token.
657 */
658#define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \
659datatype * \
660fnname(int numCols) \
661{ \
662 datatype *vals; \
663 READ_TEMP_LOCALS(); \
664 token = pg_strtok(&length); \
665 if (token == NULL) \
666 elog(ERROR, "incomplete scalar array"); \
667 if (length == 0) \
668 return NULL; /* it was "<>", so return NULL pointer */ \
669 if (length != 1 || token[0] != '(') \
670 elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \
671 vals = (datatype *) palloc(numCols * sizeof(datatype)); \
672 for (int i = 0; i < numCols; i++) \
673 { \
674 token = pg_strtok(&length); \
675 if (token == NULL || token[0] == ')') \
676 elog(ERROR, "incomplete scalar array"); \
677 vals[i] = convfunc(token); \
678 } \
679 token = pg_strtok(&length); \
680 if (token == NULL || length != 1 || token[0] != ')') \
681 elog(ERROR, "incomplete scalar array"); \
682 return vals; \
683}
684
685/*
686 * Note: these functions are exported in nodes.h for possible use by
687 * extensions, so don't mess too much with their names or API.
688 */
691/* outfuncs.c has writeIndexCols, but we don't yet need that here */
692/* READ_SCALAR_ARRAY(readIndexCols, Index, atoui) */
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:814
int16_t int16
Definition c.h:541
size_t Size
Definition c.h:619
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
Definition extensible.c:125
#define token
long val
Definition informix.c:689
int i
Definition isn.c:77
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * palloc(Size size)
Definition mcxt.c:1387
#define nodeTag(nodeptr)
Definition nodes.h:139
int * readIntCols(int numCols)
static Node * newNode(size_t size, NodeTag tag)
Definition nodes.h:150
Oid * readOidCols(int numCols)
JoinType
Definition nodes.h:298
int16 * readAttrNumberCols(int numCols)
bool * readBoolCols(int numCols)
@ AEXPR_BETWEEN
Definition parsenodes.h:340
@ AEXPR_NULLIF
Definition parsenodes.h:335
@ AEXPR_NOT_DISTINCT
Definition parsenodes.h:334
@ AEXPR_BETWEEN_SYM
Definition parsenodes.h:342
@ AEXPR_NOT_BETWEEN_SYM
Definition parsenodes.h:343
@ AEXPR_ILIKE
Definition parsenodes.h:338
@ AEXPR_IN
Definition parsenodes.h:336
@ AEXPR_NOT_BETWEEN
Definition parsenodes.h:341
@ AEXPR_DISTINCT
Definition parsenodes.h:333
@ AEXPR_SIMILAR
Definition parsenodes.h:339
@ AEXPR_LIKE
Definition parsenodes.h:337
@ AEXPR_OP
Definition parsenodes.h:330
@ AEXPR_OP_ANY
Definition parsenodes.h:331
@ AEXPR_OP_ALL
Definition parsenodes.h:332
RTEKind
@ RTE_JOIN
@ RTE_CTE
@ RTE_NAMEDTUPLESTORE
@ RTE_VALUES
@ RTE_SUBQUERY
@ RTE_RESULT
@ RTE_FUNCTION
@ RTE_TABLEFUNC
@ RTE_GROUP
@ RTE_RELATION
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
#define atooid(x)
static int fb(int x)
@ AND_EXPR
Definition primnodes.h:963
@ OR_EXPR
Definition primnodes.h:963
@ NOT_EXPR
Definition primnodes.h:963
char * debackslash(const char *token, int length)
Definition read.c:214
void * nodeRead(const char *token, int tok_len)
Definition read.c:320
const char * pg_strtok(int *length)
Definition read.c:153
#define READ_INT_FIELD(fldname)
Definition readfuncs.c:58
#define READ_UINT_FIELD(fldname)
Definition readfuncs.c:64
#define READ_NODE_FIELD(fldname)
Definition readfuncs.c:139
static ExtensibleNode * _readExtensibleNode(void)
Definition readfuncs.c:535
#define READ_CHAR_FIELD(fldname)
Definition readfuncs.c:94
static char * nullable_string(const char *token, int length)
Definition readfuncs.c:186
#define READ_SCALAR_ARRAY(fnname, datatype, convfunc)
Definition readfuncs.c:658
Node * parseNodeString(void)
Definition readfuncs.c:571
#define READ_OID_FIELD(fldname)
Definition readfuncs.c:88
#define READ_LOCATION_FIELD(fldname)
Definition readfuncs.c:131
static Bitmapset * _readBitmapset(void)
Definition readfuncs.c:207
static A_Const * _readA_Const(void)
Definition readfuncs.c:308
static Const * _readConst(void)
Definition readfuncs.c:263
#define READ_STRING_FIELD(fldname)
Definition readfuncs.c:119
#define READ_FLOAT_FIELD(fldname)
Definition readfuncs.c:107
Datum readDatum(bool typbyval)
Definition readfuncs.c:598
#define READ_BOOL_FIELD(fldname)
Definition readfuncs.c:113
#define atoui(x)
Definition readfuncs.c:181
#define strtobool(x)
Definition readfuncs.c:183
static BoolExpr * _readBoolExpr(void)
Definition readfuncs.c:285
#define READ_ENUM_FIELD(fldname, enumtype)
Definition readfuncs.c:101
#define READ_TEMP_LOCALS()
Definition readfuncs.c:48
static A_Expr * _readA_Expr(void)
Definition readfuncs.c:446
Bitmapset * readBitmapset(void)
Definition readfuncs.c:249
#define READ_LOCALS(nodeTypeName)
Definition readfuncs.c:53
#define READ_DONE()
Definition readfuncs.c:171
static RangeTblEntry * _readRangeTblEntry(void)
Definition readfuncs.c:351
static const struct fns functions
Definition regcomp.c:358
void check_stack_depth(void)
Definition stack_depth.c:95
void(* nodeRead)(struct ExtensibleNode *node)
Definition extensible.h:72
Definition value.h:48
Definition nodes.h:135
Definition value.h:64
const char * name