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-2024, 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  * 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 WRITE_READ_PARSE_PLAN_TREES
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 
181 static char *
182 nullable_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  */
202 static 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  */
244 Bitmapset *
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 
258 static 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 
280 static 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 
303 static 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 
346 static 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;
413  case RTE_NAMEDTUPLESTORE:
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  default:
426  elog(ERROR, "unrecognized RTE kind: %d",
427  (int) local_node->rtekind);
428  break;
429  }
430 
431  READ_BOOL_FIELD(lateral);
432  READ_BOOL_FIELD(inFromCl);
433  READ_NODE_FIELD(securityQuals);
434 
435  READ_DONE();
436 }
437 
438 static A_Expr *
440 {
442 
443  token = pg_strtok(&length);
444 
445  if (length == 3 && strncmp(token, "ANY", 3) == 0)
446  {
447  local_node->kind = AEXPR_OP_ANY;
449  }
450  else if (length == 3 && strncmp(token, "ALL", 3) == 0)
451  {
452  local_node->kind = AEXPR_OP_ALL;
454  }
455  else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
456  {
457  local_node->kind = AEXPR_DISTINCT;
459  }
460  else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
461  {
462  local_node->kind = AEXPR_NOT_DISTINCT;
464  }
465  else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
466  {
467  local_node->kind = AEXPR_NULLIF;
469  }
470  else if (length == 2 && strncmp(token, "IN", 2) == 0)
471  {
472  local_node->kind = AEXPR_IN;
474  }
475  else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
476  {
477  local_node->kind = AEXPR_LIKE;
479  }
480  else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
481  {
482  local_node->kind = AEXPR_ILIKE;
484  }
485  else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
486  {
487  local_node->kind = AEXPR_SIMILAR;
489  }
490  else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
491  {
492  local_node->kind = AEXPR_BETWEEN;
494  }
495  else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
496  {
497  local_node->kind = AEXPR_NOT_BETWEEN;
499  }
500  else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
501  {
502  local_node->kind = AEXPR_BETWEEN_SYM;
504  }
505  else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
506  {
507  local_node->kind = AEXPR_NOT_BETWEEN_SYM;
509  }
510  else if (length == 5 && strncmp(token, ":name", 5) == 0)
511  {
512  local_node->kind = AEXPR_OP;
513  local_node->name = nodeRead(NULL, 0);
514  }
515  else
516  elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
517 
518  READ_NODE_FIELD(lexpr);
519  READ_NODE_FIELD(rexpr);
520  READ_LOCATION_FIELD(location);
521 
522  READ_DONE();
523 }
524 
525 static ExtensibleNode *
527 {
528  const ExtensibleNodeMethods *methods;
529  ExtensibleNode *local_node;
530  const char *extnodename;
531 
533 
534  token = pg_strtok(&length); /* skip :extnodename */
535  token = pg_strtok(&length); /* get extnodename */
536 
537  extnodename = nullable_string(token, length);
538  if (!extnodename)
539  elog(ERROR, "extnodename has to be supplied");
540  methods = GetExtensibleNodeMethods(extnodename, false);
541 
542  local_node = (ExtensibleNode *) newNode(methods->node_size,
543  T_ExtensibleNode);
544  local_node->extnodename = extnodename;
545 
546  /* deserialize the private fields */
547  methods->nodeRead(local_node);
548 
549  READ_DONE();
550 }
551 
552 
553 /*
554  * parseNodeString
555  *
556  * Given a character string representing a node tree, parseNodeString creates
557  * the internal node structure.
558  *
559  * The string to be read must already have been loaded into pg_strtok().
560  */
561 Node *
563 {
565 
566  /* Guard against stack overflow due to overly complex expressions */
568 
569  token = pg_strtok(&length);
570 
571 #define MATCH(tokname, namelen) \
572  (length == namelen && memcmp(token, tokname, namelen) == 0)
573 
574 #include "readfuncs.switch.c"
575 
576  elog(ERROR, "badly formatted node string \"%.32s\"...", token);
577  return NULL; /* keep compiler quiet */
578 }
579 
580 
581 /*
582  * readDatum
583  *
584  * Given a string representation of a constant, recreate the appropriate
585  * Datum. The string representation embeds length info, but not byValue,
586  * so we must be told that.
587  */
588 Datum
589 readDatum(bool typbyval)
590 {
591  Size length,
592  i;
593  int tokenLength;
594  const char *token;
595  Datum res;
596  char *s;
597 
598  /*
599  * read the actual length of the value
600  */
601  token = pg_strtok(&tokenLength);
602  length = atoui(token);
603 
604  token = pg_strtok(&tokenLength); /* read the '[' */
605  if (token == NULL || token[0] != '[')
606  elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
607  token ? token : "[NULL]", length);
608 
609  if (typbyval)
610  {
611  if (length > (Size) sizeof(Datum))
612  elog(ERROR, "byval datum but length = %zu", length);
613  res = (Datum) 0;
614  s = (char *) (&res);
615  for (i = 0; i < (Size) sizeof(Datum); i++)
616  {
617  token = pg_strtok(&tokenLength);
618  s[i] = (char) atoi(token);
619  }
620  }
621  else if (length <= 0)
622  res = (Datum) NULL;
623  else
624  {
625  s = (char *) palloc(length);
626  for (i = 0; i < length; i++)
627  {
628  token = pg_strtok(&tokenLength);
629  s[i] = (char) atoi(token);
630  }
631  res = PointerGetDatum(s);
632  }
633 
634  token = pg_strtok(&tokenLength); /* read the ']' */
635  if (token == NULL || token[0] != ']')
636  elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
637  token ? token : "[NULL]", length);
638 
639  return res;
640 }
641 
642 /*
643  * common implementation for scalar-array-reading functions
644  *
645  * The data format is either "<>" for a NULL pointer (in which case numCols
646  * is ignored) or "(item item item)" where the number of items must equal
647  * numCols. The convfunc must be okay with stopping at whitespace or a
648  * right parenthesis, since pg_strtok won't null-terminate the token.
649  */
650 #define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \
651 datatype * \
652 fnname(int numCols) \
653 { \
654  datatype *vals; \
655  READ_TEMP_LOCALS(); \
656  token = pg_strtok(&length); \
657  if (token == NULL) \
658  elog(ERROR, "incomplete scalar array"); \
659  if (length == 0) \
660  return NULL; /* it was "<>", so return NULL pointer */ \
661  if (length != 1 || token[0] != '(') \
662  elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \
663  vals = (datatype *) palloc(numCols * sizeof(datatype)); \
664  for (int i = 0; i < numCols; i++) \
665  { \
666  token = pg_strtok(&length); \
667  if (token == NULL || token[0] == ')') \
668  elog(ERROR, "incomplete scalar array"); \
669  vals[i] = convfunc(token); \
670  } \
671  token = pg_strtok(&length); \
672  if (token == NULL || length != 1 || token[0] != ')') \
673  elog(ERROR, "incomplete scalar array"); \
674  return vals; \
675 }
676 
677 /*
678  * Note: these functions are exported in nodes.h for possible use by
679  * extensions, so don't mess too much with their names or API.
680  */
683 /* outfuncs.c has writeIndexCols, but we don't yet need that here */
684 /* READ_SCALAR_ARRAY(readIndexCols, Index, atoui) */
685 READ_SCALAR_ARRAY(readIntCols, int, atoi)
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:815
signed short int16
Definition: c.h:493
size_t Size
Definition: c.h:605
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
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:670
int i
Definition: isn.c:73
char * pstrdup(const char *in)
Definition: mcxt.c:1695
void * palloc(Size size)
Definition: mcxt.c:1316
static Node * newNode(size_t size, NodeTag tag)
Definition: nodes.h:144
#define nodeTag(nodeptr)
Definition: nodes.h:133
int * readIntCols(int numCols)
bool * readBoolCols(int numCols)
Oid * readOidCols(int numCols)
int16 * readAttrNumberCols(int numCols)
JoinType
Definition: nodes.h:288
@ AEXPR_BETWEEN
Definition: parsenodes.h:323
@ AEXPR_NULLIF
Definition: parsenodes.h:318
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:317
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:325
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:326
@ AEXPR_ILIKE
Definition: parsenodes.h:321
@ AEXPR_IN
Definition: parsenodes.h:319
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:324
@ AEXPR_DISTINCT
Definition: parsenodes.h:316
@ AEXPR_SIMILAR
Definition: parsenodes.h:322
@ AEXPR_LIKE
Definition: parsenodes.h:320
@ AEXPR_OP
Definition: parsenodes.h:313
@ AEXPR_OP_ANY
Definition: parsenodes.h:314
@ AEXPR_OP_ALL
Definition: parsenodes.h:315
RTEKind
Definition: parsenodes.h:1027
@ RTE_JOIN
Definition: parsenodes.h:1030
@ RTE_CTE
Definition: parsenodes.h:1034
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1035
@ RTE_VALUES
Definition: parsenodes.h:1033
@ RTE_SUBQUERY
Definition: parsenodes.h:1029
@ RTE_RESULT
Definition: parsenodes.h:1036
@ RTE_FUNCTION
Definition: parsenodes.h:1031
@ RTE_TABLEFUNC
Definition: parsenodes.h:1032
@ RTE_RELATION
Definition: parsenodes.h:1028
void check_stack_depth(void)
Definition: postgres.c:3531
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
#define atooid(x)
Definition: postgres_ext.h:42
@ AND_EXPR
Definition: primnodes.h:931
@ OR_EXPR
Definition: primnodes.h:931
@ NOT_EXPR
Definition: primnodes.h:931
const char * pg_strtok(int *length)
Definition: read.c:153
char * debackslash(const char *token, int length)
Definition: read.c:214
void * nodeRead(const char *token, int tok_len)
Definition: read.c:320
static A_Const * _readA_Const(void)
Definition: readfuncs.c:304
#define READ_INT_FIELD(fldname)
Definition: readfuncs.c:60
static char * nullable_string(const char *token, int length)
Definition: readfuncs.c:182
#define READ_UINT_FIELD(fldname)
Definition: readfuncs.c:66
#define READ_NODE_FIELD(fldname)
Definition: readfuncs.c:135
static RangeTblEntry * _readRangeTblEntry(void)
Definition: readfuncs.c:347
#define READ_CHAR_FIELD(fldname)
Definition: readfuncs.c:90
#define READ_SCALAR_ARRAY(fnname, datatype, convfunc)
Definition: readfuncs.c:650
Node * parseNodeString(void)
Definition: readfuncs.c:562
static Const * _readConst(void)
Definition: readfuncs.c:259
#define READ_OID_FIELD(fldname)
Definition: readfuncs.c:84
#define READ_LOCATION_FIELD(fldname)
Definition: readfuncs.c:127
#define READ_STRING_FIELD(fldname)
Definition: readfuncs.c:115
static BoolExpr * _readBoolExpr(void)
Definition: readfuncs.c:281
#define READ_FLOAT_FIELD(fldname)
Definition: readfuncs.c:103
Datum readDatum(bool typbyval)
Definition: readfuncs.c:589
static ExtensibleNode * _readExtensibleNode(void)
Definition: readfuncs.c:526
#define READ_BOOL_FIELD(fldname)
Definition: readfuncs.c:109
Bitmapset * readBitmapset(void)
Definition: readfuncs.c:245
#define atoui(x)
Definition: readfuncs.c:177
#define strtobool(x)
Definition: readfuncs.c:179
static A_Expr * _readA_Expr(void)
Definition: readfuncs.c:439
static Bitmapset * _readBitmapset(void)
Definition: readfuncs.c:203
#define READ_ENUM_FIELD(fldname, enumtype)
Definition: readfuncs.c:97
#define READ_TEMP_LOCALS()
Definition: readfuncs.c:50
#define READ_LOCALS(nodeTypeName)
Definition: readfuncs.c:55
#define READ_DONE()
Definition: readfuncs.c:167
static const struct fns functions
Definition: regcomp.c:356
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