PostgreSQL Source Code git master
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-2025, 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 <math.h>
30
31#include "miscadmin.h"
32#include "nodes/bitmapset.h"
33#include "nodes/readfuncs.h"
34
35
36/*
37 * Macros to simplify reading of different kinds of fields. Use these
38 * wherever possible to reduce the chance for silly typos. Note that these
39 * hard-wire conventions about the names of the local variables in a Read
40 * routine.
41 */
42
43/* Macros for declaring appropriate local variables */
44
45/* A few guys need only local_node */
46#define READ_LOCALS_NO_FIELDS(nodeTypeName) \
47 nodeTypeName *local_node = makeNode(nodeTypeName)
48
49/* And a few guys need only the pg_strtok support fields */
50#define READ_TEMP_LOCALS() \
51 const char *token; \
52 int length
53
54/* ... but most need both */
55#define READ_LOCALS(nodeTypeName) \
56 READ_LOCALS_NO_FIELDS(nodeTypeName); \
57 READ_TEMP_LOCALS()
58
59/* Read an integer field (anything written as ":fldname %d") */
60#define READ_INT_FIELD(fldname) \
61 token = pg_strtok(&length); /* skip :fldname */ \
62 token = pg_strtok(&length); /* get field value */ \
63 local_node->fldname = atoi(token)
64
65/* Read an unsigned integer field (anything written as ":fldname %u") */
66#define READ_UINT_FIELD(fldname) \
67 token = pg_strtok(&length); /* skip :fldname */ \
68 token = pg_strtok(&length); /* get field value */ \
69 local_node->fldname = atoui(token)
70
71/* Read an unsigned integer field (anything written using UINT64_FORMAT) */
72#define READ_UINT64_FIELD(fldname) \
73 token = pg_strtok(&length); /* skip :fldname */ \
74 token = pg_strtok(&length); /* get field value */ \
75 local_node->fldname = strtou64(token, NULL, 10)
76
77/* Read a long integer field (anything written as ":fldname %ld") */
78#define READ_LONG_FIELD(fldname) \
79 token = pg_strtok(&length); /* skip :fldname */ \
80 token = pg_strtok(&length); /* get field value */ \
81 local_node->fldname = atol(token)
82
83/* Read an OID field (don't hard-wire assumption that OID is same as uint) */
84#define READ_OID_FIELD(fldname) \
85 token = pg_strtok(&length); /* skip :fldname */ \
86 token = pg_strtok(&length); /* get field value */ \
87 local_node->fldname = atooid(token)
88
89/* Read a char field (ie, one ascii character) */
90#define READ_CHAR_FIELD(fldname) \
91 token = pg_strtok(&length); /* skip :fldname */ \
92 token = pg_strtok(&length); /* get field value */ \
93 /* avoid overhead of calling debackslash() for one char */ \
94 local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
95
96/* Read an enumerated-type field that was written as an integer code */
97#define READ_ENUM_FIELD(fldname, enumtype) \
98 token = pg_strtok(&length); /* skip :fldname */ \
99 token = pg_strtok(&length); /* get field value */ \
100 local_node->fldname = (enumtype) atoi(token)
101
102/* Read a float field */
103#define READ_FLOAT_FIELD(fldname) \
104 token = pg_strtok(&length); /* skip :fldname */ \
105 token = pg_strtok(&length); /* get field value */ \
106 local_node->fldname = atof(token)
107
108/* Read a boolean field */
109#define READ_BOOL_FIELD(fldname) \
110 token = pg_strtok(&length); /* skip :fldname */ \
111 token = pg_strtok(&length); /* get field value */ \
112 local_node->fldname = strtobool(token)
113
114/* Read a character-string field */
115#define READ_STRING_FIELD(fldname) \
116 token = pg_strtok(&length); /* skip :fldname */ \
117 token = pg_strtok(&length); /* get field value */ \
118 local_node->fldname = nullable_string(token, length)
119
120/* Read a parse location field (and possibly throw away the value) */
121#ifdef DEBUG_NODE_TESTS_ENABLED
122#define READ_LOCATION_FIELD(fldname) \
123 token = pg_strtok(&length); /* skip :fldname */ \
124 token = pg_strtok(&length); /* get field value */ \
125 local_node->fldname = restore_location_fields ? atoi(token) : -1
126#else
127#define READ_LOCATION_FIELD(fldname) \
128 token = pg_strtok(&length); /* skip :fldname */ \
129 token = pg_strtok(&length); /* get field value */ \
130 (void) token; /* in case not used elsewhere */ \
131 local_node->fldname = -1 /* set field to "unknown" */
132#endif
133
134/* Read a Node field */
135#define READ_NODE_FIELD(fldname) \
136 token = pg_strtok(&length); /* skip :fldname */ \
137 (void) token; /* in case not used elsewhere */ \
138 local_node->fldname = nodeRead(NULL, 0)
139
140/* Read a bitmapset field */
141#define READ_BITMAPSET_FIELD(fldname) \
142 token = pg_strtok(&length); /* skip :fldname */ \
143 (void) token; /* in case not used elsewhere */ \
144 local_node->fldname = _readBitmapset()
145
146/* Read an attribute number array */
147#define READ_ATTRNUMBER_ARRAY(fldname, len) \
148 token = pg_strtok(&length); /* skip :fldname */ \
149 local_node->fldname = readAttrNumberCols(len)
150
151/* Read an oid array */
152#define READ_OID_ARRAY(fldname, len) \
153 token = pg_strtok(&length); /* skip :fldname */ \
154 local_node->fldname = readOidCols(len)
155
156/* Read an int array */
157#define READ_INT_ARRAY(fldname, len) \
158 token = pg_strtok(&length); /* skip :fldname */ \
159 local_node->fldname = readIntCols(len)
160
161/* Read a bool array */
162#define READ_BOOL_ARRAY(fldname, len) \
163 token = pg_strtok(&length); /* skip :fldname */ \
164 local_node->fldname = readBoolCols(len)
165
166/* Routine exit */
167#define READ_DONE() \
168 return local_node
169
170
171/*
172 * NOTE: use atoi() to read values written with %d, or atoui() to read
173 * values written with %u in outfuncs.c. An exception is OID values,
174 * for which use atooid(). (As of 7.1, outfuncs.c writes OIDs as %u,
175 * but this will probably change in the future.)
176 */
177#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
178
179#define strtobool(x) ((*(x) == 't') ? true : false)
180
181static char *
182nullable_string(const char *token, int length)
183{
184 /* outToken emits <> for NULL, and pg_strtok makes that an empty string */
185 if (length == 0)
186 return NULL;
187 /* outToken emits "" for empty string */
188 if (length == 2 && token[0] == '"' && token[1] == '"')
189 return pstrdup("");
190 /* otherwise, we must remove protective backslashes added by outToken */
191 return debackslash(token, length);
192}
193
194
195/*
196 * _readBitmapset
197 *
198 * Note: this code is used in contexts where we know that a Bitmapset
199 * is expected. There is equivalent code in nodeRead() that can read a
200 * Bitmapset when we come across one in other contexts.
201 */
202static Bitmapset *
204{
205 Bitmapset *result = NULL;
206
208
209 token = pg_strtok(&length);
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
215 token = pg_strtok(&length);
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 {
223 int val;
224 char *endptr;
225
226 token = pg_strtok(&length);
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);
234 result = bms_add_member(result, val);
235 }
236
237 return result;
238}
239
240/*
241 * We export this function for use by extensions that define extensible nodes.
242 * That's somewhat historical, though, because calling nodeRead() will work.
243 */
244Bitmapset *
246{
247 return _readBitmapset();
248}
249
250#include "readfuncs.funcs.c"
251
252
253/*
254 * Support functions for nodes with custom_read_write attribute or
255 * special_read_write attribute
256 */
257
258static Const *
260{
262
263 READ_OID_FIELD(consttype);
264 READ_INT_FIELD(consttypmod);
265 READ_OID_FIELD(constcollid);
266 READ_INT_FIELD(constlen);
267 READ_BOOL_FIELD(constbyval);
268 READ_BOOL_FIELD(constisnull);
269 READ_LOCATION_FIELD(location);
270
271 token = pg_strtok(&length); /* skip :constvalue */
272 if (local_node->constisnull)
273 token = pg_strtok(&length); /* skip "<>" */
274 else
275 local_node->constvalue = readDatum(local_node->constbyval);
276
277 READ_DONE();
278}
279
280static BoolExpr *
282{
284
285 /* do-it-yourself enum representation */
286 token = pg_strtok(&length); /* skip :boolop */
287 token = pg_strtok(&length); /* get field value */
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
298 READ_LOCATION_FIELD(location);
299
300 READ_DONE();
301}
302
303static A_Const *
305{
307
308 /* We expect either NULL or :val here */
309 token = pg_strtok(&length);
310 if (length == 4 && strncmp(token, "NULL", 4) == 0)
311 local_node->isnull = true;
312 else
313 {
314 union ValUnion *tmp = nodeRead(NULL, 0);
315
316 /* To forestall valgrind complaints, copy only the valid data */
317 switch (nodeTag(tmp))
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",
336 (int) nodeTag(tmp));
337 break;
338 }
339 }
340
341 READ_LOCATION_FIELD(location);
342
343 READ_DONE();
344}
345
346static RangeTblEntry *
348{
350
351 READ_NODE_FIELD(alias);
352 READ_NODE_FIELD(eref);
353 READ_ENUM_FIELD(rtekind, RTEKind);
354
355 switch (local_node->rtekind)
356 {
357 case RTE_RELATION:
358 READ_OID_FIELD(relid);
359 READ_BOOL_FIELD(inh);
360 READ_CHAR_FIELD(relkind);
361 READ_INT_FIELD(rellockmode);
362 READ_UINT_FIELD(perminfoindex);
363 READ_NODE_FIELD(tablesample);
364 break;
365 case RTE_SUBQUERY:
366 READ_NODE_FIELD(subquery);
367 READ_BOOL_FIELD(security_barrier);
368 /* we re-use these RELATION fields, too: */
369 READ_OID_FIELD(relid);
370 READ_BOOL_FIELD(inh);
371 READ_CHAR_FIELD(relkind);
372 READ_INT_FIELD(rellockmode);
373 READ_UINT_FIELD(perminfoindex);
374 break;
375 case RTE_JOIN:
376 READ_ENUM_FIELD(jointype, JoinType);
377 READ_INT_FIELD(joinmergedcols);
378 READ_NODE_FIELD(joinaliasvars);
379 READ_NODE_FIELD(joinleftcols);
380 READ_NODE_FIELD(joinrightcols);
381 READ_NODE_FIELD(join_using_alias);
382 break;
383 case RTE_FUNCTION:
385 READ_BOOL_FIELD(funcordinality);
386 break;
387 case RTE_TABLEFUNC:
388 READ_NODE_FIELD(tablefunc);
389 /* The RTE must have a copy of the column type info, if any */
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;
399 case RTE_VALUES:
400 READ_NODE_FIELD(values_lists);
401 READ_NODE_FIELD(coltypes);
402 READ_NODE_FIELD(coltypmods);
403 READ_NODE_FIELD(colcollations);
404 break;
405 case RTE_CTE:
406 READ_STRING_FIELD(ctename);
407 READ_UINT_FIELD(ctelevelsup);
408 READ_BOOL_FIELD(self_reference);
409 READ_NODE_FIELD(coltypes);
410 READ_NODE_FIELD(coltypmods);
411 READ_NODE_FIELD(colcollations);
412 break;
414 READ_STRING_FIELD(enrname);
415 READ_FLOAT_FIELD(enrtuples);
416 READ_NODE_FIELD(coltypes);
417 READ_NODE_FIELD(coltypmods);
418 READ_NODE_FIELD(colcollations);
419 /* we re-use these RELATION fields, too: */
420 READ_OID_FIELD(relid);
421 break;
422 case RTE_RESULT:
423 /* no extra fields */
424 break;
425 case RTE_GROUP:
426 READ_NODE_FIELD(groupexprs);
427 break;
428 default:
429 elog(ERROR, "unrecognized RTE kind: %d",
430 (int) local_node->rtekind);
431 break;
432 }
433
434 READ_BOOL_FIELD(lateral);
435 READ_BOOL_FIELD(inFromCl);
436 READ_NODE_FIELD(securityQuals);
437
438 READ_DONE();
439}
440
441static A_Expr *
443{
445
446 token = pg_strtok(&length);
447
448 if (length == 3 && strncmp(token, "ANY", 3) == 0)
449 {
450 local_node->kind = AEXPR_OP_ANY;
452 }
453 else if (length == 3 && strncmp(token, "ALL", 3) == 0)
454 {
455 local_node->kind = AEXPR_OP_ALL;
457 }
458 else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
459 {
460 local_node->kind = AEXPR_DISTINCT;
462 }
463 else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
464 {
465 local_node->kind = AEXPR_NOT_DISTINCT;
467 }
468 else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
469 {
470 local_node->kind = AEXPR_NULLIF;
472 }
473 else if (length == 2 && strncmp(token, "IN", 2) == 0)
474 {
475 local_node->kind = AEXPR_IN;
477 }
478 else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
479 {
480 local_node->kind = AEXPR_LIKE;
482 }
483 else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
484 {
485 local_node->kind = AEXPR_ILIKE;
487 }
488 else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
489 {
490 local_node->kind = AEXPR_SIMILAR;
492 }
493 else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
494 {
495 local_node->kind = AEXPR_BETWEEN;
497 }
498 else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
499 {
500 local_node->kind = AEXPR_NOT_BETWEEN;
502 }
503 else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
504 {
505 local_node->kind = AEXPR_BETWEEN_SYM;
507 }
508 else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
509 {
510 local_node->kind = AEXPR_NOT_BETWEEN_SYM;
512 }
513 else if (length == 5 && strncmp(token, ":name", 5) == 0)
514 {
515 local_node->kind = AEXPR_OP;
516 local_node->name = nodeRead(NULL, 0);
517 }
518 else
519 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
520
521 READ_NODE_FIELD(lexpr);
522 READ_NODE_FIELD(rexpr);
523 READ_LOCATION_FIELD(location);
524
525 READ_DONE();
526}
527
528static ExtensibleNode *
530{
531 const ExtensibleNodeMethods *methods;
532 ExtensibleNode *local_node;
533 const char *extnodename;
534
536
537 token = pg_strtok(&length); /* skip :extnodename */
538 token = pg_strtok(&length); /* get extnodename */
539
540 extnodename = nullable_string(token, length);
541 if (!extnodename)
542 elog(ERROR, "extnodename has to be supplied");
543 methods = GetExtensibleNodeMethods(extnodename, false);
544
545 local_node = (ExtensibleNode *) newNode(methods->node_size,
546 T_ExtensibleNode);
547 local_node->extnodename = extnodename;
548
549 /* deserialize the private fields */
550 methods->nodeRead(local_node);
551
552 READ_DONE();
553}
554
555
556/*
557 * parseNodeString
558 *
559 * Given a character string representing a node tree, parseNodeString creates
560 * the internal node structure.
561 *
562 * The string to be read must already have been loaded into pg_strtok().
563 */
564Node *
566{
568
569 /* Guard against stack overflow due to overly complex expressions */
571
572 token = pg_strtok(&length);
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; /* keep compiler quiet */
581}
582
583
584/*
585 * readDatum
586 *
587 * Given a string representation of a constant, recreate the appropriate
588 * Datum. The string representation embeds length info, but not byValue,
589 * so we must be told that.
590 */
591Datum
592readDatum(bool typbyval)
593{
594 Size length,
595 i;
596 int tokenLength;
597 const char *token;
598 Datum res;
599 char *s;
600
601 /*
602 * read the actual length of the value
603 */
604 token = pg_strtok(&tokenLength);
605 length = atoui(token);
606
607 token = pg_strtok(&tokenLength); /* read the '[' */
608 if (token == NULL || token[0] != '[')
609 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
610 token ? token : "[NULL]", length);
611
612 if (typbyval)
613 {
614 if (length > (Size) sizeof(Datum))
615 elog(ERROR, "byval datum but length = %zu", length);
616 res = (Datum) 0;
617 s = (char *) (&res);
618 for (i = 0; i < (Size) sizeof(Datum); i++)
619 {
620 token = pg_strtok(&tokenLength);
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 {
631 token = pg_strtok(&tokenLength);
632 s[i] = (char) atoi(token);
633 }
634 res = PointerGetDatum(s);
635 }
636
637 token = pg_strtok(&tokenLength); /* read the ']' */
638 if (token == NULL || token[0] != ']')
639 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
640 token ? token : "[NULL]", length);
641
642 return res;
643}
644
645/*
646 * common implementation for scalar-array-reading functions
647 *
648 * The data format is either "<>" for a NULL pointer (in which case numCols
649 * is ignored) or "(item item item)" where the number of items must equal
650 * numCols. The convfunc must be okay with stopping at whitespace or a
651 * right parenthesis, since pg_strtok won't null-terminate the token.
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; /* it was "<>", so return NULL pointer */ \
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 * Note: these functions are exported in nodes.h for possible use by
682 * extensions, so don't mess too much with their names or API.
683 */
686/* outfuncs.c has writeIndexCols, but we don't yet need that here */
687/* READ_SCALAR_ARRAY(readIndexCols, Index, atoui) */
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
int16_t int16
Definition: c.h:483
size_t Size
Definition: c.h:562
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
const ExtensibleNodeMethods * GetExtensibleNodeMethods(const char *extnodename, bool missing_ok)
Definition: extensible.c:125
#define token
Definition: indent_globs.h:126
long val
Definition: informix.c:689
int i
Definition: isn.c:72
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void * palloc(Size size)
Definition: mcxt.c:1317
#define nodeTag(nodeptr)
Definition: nodes.h:133
int * readIntCols(int numCols)
static Node * newNode(size_t size, NodeTag tag)
Definition: nodes.h:144
Oid * readOidCols(int numCols)
JoinType
Definition: nodes.h:288
int16 * readAttrNumberCols(int numCols)
bool * readBoolCols(int numCols)
@ AEXPR_BETWEEN
Definition: parsenodes.h:334
@ AEXPR_NULLIF
Definition: parsenodes.h:329
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:328
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:336
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:337
@ AEXPR_ILIKE
Definition: parsenodes.h:332
@ AEXPR_IN
Definition: parsenodes.h:330
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:335
@ AEXPR_DISTINCT
Definition: parsenodes.h:327
@ AEXPR_SIMILAR
Definition: parsenodes.h:333
@ AEXPR_LIKE
Definition: parsenodes.h:331
@ AEXPR_OP
Definition: parsenodes.h:324
@ AEXPR_OP_ANY
Definition: parsenodes.h:325
@ AEXPR_OP_ALL
Definition: parsenodes.h:326
RTEKind
Definition: parsenodes.h:1025
@ RTE_JOIN
Definition: parsenodes.h:1028
@ RTE_CTE
Definition: parsenodes.h:1032
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1033
@ RTE_VALUES
Definition: parsenodes.h:1031
@ RTE_SUBQUERY
Definition: parsenodes.h:1027
@ RTE_RESULT
Definition: parsenodes.h:1034
@ RTE_FUNCTION
Definition: parsenodes.h:1029
@ RTE_TABLEFUNC
Definition: parsenodes.h:1030
@ RTE_GROUP
Definition: parsenodes.h:1037
@ RTE_RELATION
Definition: parsenodes.h:1026
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
unsigned int Oid
Definition: postgres_ext.h:32
#define atooid(x)
Definition: postgres_ext.h:43
@ AND_EXPR
Definition: primnodes.h:947
@ OR_EXPR
Definition: primnodes.h:947
@ NOT_EXPR
Definition: primnodes.h:947
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:60
#define READ_UINT_FIELD(fldname)
Definition: readfuncs.c:66
#define READ_NODE_FIELD(fldname)
Definition: readfuncs.c:135
static ExtensibleNode * _readExtensibleNode(void)
Definition: readfuncs.c:529
#define READ_CHAR_FIELD(fldname)
Definition: readfuncs.c:90
static char * nullable_string(const char *token, int length)
Definition: readfuncs.c:182
#define READ_SCALAR_ARRAY(fnname, datatype, convfunc)
Definition: readfuncs.c:653
Node * parseNodeString(void)
Definition: readfuncs.c:565
#define READ_OID_FIELD(fldname)
Definition: readfuncs.c:84
#define READ_LOCATION_FIELD(fldname)
Definition: readfuncs.c:127
static Bitmapset * _readBitmapset(void)
Definition: readfuncs.c:203
static A_Const * _readA_Const(void)
Definition: readfuncs.c:304
static Const * _readConst(void)
Definition: readfuncs.c:259
#define READ_STRING_FIELD(fldname)
Definition: readfuncs.c:115
#define READ_FLOAT_FIELD(fldname)
Definition: readfuncs.c:103
Datum readDatum(bool typbyval)
Definition: readfuncs.c:592
#define READ_BOOL_FIELD(fldname)
Definition: readfuncs.c:109
#define atoui(x)
Definition: readfuncs.c:177
#define strtobool(x)
Definition: readfuncs.c:179
static BoolExpr * _readBoolExpr(void)
Definition: readfuncs.c:281
#define READ_ENUM_FIELD(fldname, enumtype)
Definition: readfuncs.c:97
#define READ_TEMP_LOCALS()
Definition: readfuncs.c:50
static A_Expr * _readA_Expr(void)
Definition: readfuncs.c:442
Bitmapset * readBitmapset(void)
Definition: readfuncs.c:245
#define READ_LOCALS(nodeTypeName)
Definition: readfuncs.c:55
#define READ_DONE()
Definition: readfuncs.c:167
static RangeTblEntry * _readRangeTblEntry(void)
Definition: readfuncs.c:347
static const struct fns functions
Definition: regcomp.c:358
void check_stack_depth(void)
Definition: stack_depth.c:95
Definition: value.h:56
void(* nodeRead)(struct ExtensibleNode *node)
Definition: extensible.h:72
const char * extnodename
Definition: extensible.h:37
Definition: value.h:48
Definition: value.h:29
Definition: nodes.h:129
Definition: value.h:64
const char * name