Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
outfuncs.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * outfuncs.c
4 * Output 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/outfuncs.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <ctype.h>
18
19#include "access/attnum.h"
20#include "common/shortest_dec.h"
21#include "lib/stringinfo.h"
22#include "miscadmin.h"
23#include "nodes/bitmapset.h"
24#include "nodes/nodes.h"
25#include "nodes/pg_list.h"
26#include "utils/datum.h"
27
28/* State flag that determines how nodeToStringInternal() should treat location fields */
29static bool write_location_fields = false;
30
31static void outChar(StringInfo str, char c);
32static void outDouble(StringInfo str, double d);
33
34
35/*
36 * Macros to simplify output of different kinds of fields. Use these
37 * wherever possible to reduce the chance for silly typos. Note that these
38 * hard-wire conventions about the names of the local variables in an Out
39 * routine.
40 */
41
42/* Write the label for the node type */
43#define WRITE_NODE_TYPE(nodelabel) \
44 appendStringInfoString(str, nodelabel)
45
46/* Write an integer field (anything written as ":fldname %d") */
47#define WRITE_INT_FIELD(fldname) \
48 appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
49
50/* Write an unsigned integer field (anything written as ":fldname %u") */
51#define WRITE_UINT_FIELD(fldname) \
52 appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
53
54/* Write a signed integer field (anything written with INT64_FORMAT) */
55#define WRITE_INT64_FIELD(fldname) \
56 appendStringInfo(str, \
57 " :" CppAsString(fldname) " " INT64_FORMAT, \
58 node->fldname)
59
60/* Write an unsigned integer field (anything written with UINT64_FORMAT) */
61#define WRITE_UINT64_FIELD(fldname) \
62 appendStringInfo(str, " :" CppAsString(fldname) " " UINT64_FORMAT, \
63 node->fldname)
64
65/* Write an OID field (don't hard-wire assumption that OID is same as uint) */
66#define WRITE_OID_FIELD(fldname) \
67 appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
68
69/* Write a long-integer field */
70#define WRITE_LONG_FIELD(fldname) \
71 appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)
72
73/* Write a char field (ie, one ascii character) */
74#define WRITE_CHAR_FIELD(fldname) \
75 (appendStringInfo(str, " :" CppAsString(fldname) " "), \
76 outChar(str, node->fldname))
77
78/* Write an enumerated-type field as an integer code */
79#define WRITE_ENUM_FIELD(fldname, enumtype) \
80 appendStringInfo(str, " :" CppAsString(fldname) " %d", \
81 (int) node->fldname)
82
83/* Write a float field (actually, they're double) */
84#define WRITE_FLOAT_FIELD(fldname) \
85 (appendStringInfo(str, " :" CppAsString(fldname) " "), \
86 outDouble(str, node->fldname))
87
88/* Write a boolean field */
89#define WRITE_BOOL_FIELD(fldname) \
90 appendStringInfo(str, " :" CppAsString(fldname) " %s", \
91 booltostr(node->fldname))
92
93/* Write a character-string (possibly NULL) field */
94#define WRITE_STRING_FIELD(fldname) \
95 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
96 outToken(str, node->fldname))
97
98/* Write a parse location field (actually same as INT case) */
99#define WRITE_LOCATION_FIELD(fldname) \
100 appendStringInfo(str, " :" CppAsString(fldname) " %d", write_location_fields ? node->fldname : -1)
101
102/* Write a Node field */
103#define WRITE_NODE_FIELD(fldname) \
104 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
105 outNode(str, node->fldname))
106
107/* Write a bitmapset field */
108#define WRITE_BITMAPSET_FIELD(fldname) \
109 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
110 outBitmapset(str, node->fldname))
111
112/* Write a variable-length array (not a List) of Node pointers */
113#define WRITE_NODE_ARRAY(fldname, len) \
114 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
115 writeNodeArray(str, (const Node * const *) node->fldname, len))
116
117/* Write a variable-length array of AttrNumber */
118#define WRITE_ATTRNUMBER_ARRAY(fldname, len) \
119 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
120 writeAttrNumberCols(str, node->fldname, len))
121
122/* Write a variable-length array of Oid */
123#define WRITE_OID_ARRAY(fldname, len) \
124 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
125 writeOidCols(str, node->fldname, len))
126
127/* Write a variable-length array of Index */
128#define WRITE_INDEX_ARRAY(fldname, len) \
129 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
130 writeIndexCols(str, node->fldname, len))
131
132/* Write a variable-length array of int */
133#define WRITE_INT_ARRAY(fldname, len) \
134 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
135 writeIntCols(str, node->fldname, len))
136
137/* Write a variable-length array of bool */
138#define WRITE_BOOL_ARRAY(fldname, len) \
139 (appendStringInfoString(str, " :" CppAsString(fldname) " "), \
140 writeBoolCols(str, node->fldname, len))
141
142#define booltostr(x) ((x) ? "true" : "false")
143
144
145/*
146 * outToken
147 * Convert an ordinary string (eg, an identifier) into a form that
148 * will be decoded back to a plain token by read.c's functions.
149 *
150 * If a null string pointer is given, it is encoded as '<>'.
151 * An empty string is encoded as '""'. To avoid ambiguity, input
152 * strings beginning with '<' or '"' receive a leading backslash.
153 */
154void
155outToken(StringInfo str, const char *s)
156{
157 if (s == NULL)
158 {
160 return;
161 }
162 if (*s == '\0')
163 {
165 return;
166 }
167
168 /*
169 * Look for characters or patterns that are treated specially by read.c
170 * (either in pg_strtok() or in nodeRead()), and therefore need a
171 * protective backslash.
172 */
173 /* These characters only need to be quoted at the start of the string */
174 if (*s == '<' ||
175 *s == '"' ||
176 isdigit((unsigned char) *s) ||
177 ((*s == '+' || *s == '-') &&
178 (isdigit((unsigned char) s[1]) || s[1] == '.')))
180 while (*s)
181 {
182 /* These chars must be backslashed anywhere in the string */
183 if (*s == ' ' || *s == '\n' || *s == '\t' ||
184 *s == '(' || *s == ')' || *s == '{' || *s == '}' ||
185 *s == '\\')
188 }
189}
190
191/*
192 * Convert one char. Goes through outToken() so that special characters are
193 * escaped.
194 */
195static void
197{
198 char in[2];
199
200 /* Traditionally, we've represented \0 as <>, so keep doing that */
201 if (c == '\0')
202 {
204 return;
205 }
206
207 in[0] = c;
208 in[1] = '\0';
209
210 outToken(str, in);
211}
212
213/*
214 * Convert a double value, attempting to ensure the value is preserved exactly.
215 */
216static void
218{
220
223}
224
225/*
226 * common implementation for scalar-array-writing functions
227 *
228 * The data format is either "<>" for a NULL pointer or "(item item item)".
229 * fmtstr must include a leading space, and the rest of it must produce
230 * something that will be seen as a single simple token by pg_strtok().
231 * convfunc can be empty, or the name of a conversion macro or function.
232 */
233#define WRITE_SCALAR_ARRAY(fnname, datatype, fmtstr, convfunc) \
234static void \
235fnname(StringInfo str, const datatype *arr, int len) \
236{ \
237 if (arr != NULL) \
238 { \
239 appendStringInfoChar(str, '('); \
240 for (int i = 0; i < len; i++) \
241 appendStringInfo(str, fmtstr, convfunc(arr[i])); \
242 appendStringInfoChar(str, ')'); \
243 } \
244 else \
245 appendStringInfoString(str, "<>"); \
246}
247
248WRITE_SCALAR_ARRAY(writeAttrNumberCols, AttrNumber, " %d",)
249WRITE_SCALAR_ARRAY(writeOidCols, Oid, " %u",)
250WRITE_SCALAR_ARRAY(writeIndexCols, Index, " %u",)
251WRITE_SCALAR_ARRAY(writeIntCols, int, " %d",)
252WRITE_SCALAR_ARRAY(writeBoolCols, bool, " %s", booltostr)
253
254/*
255 * Print an array (not a List) of Node pointers.
256 *
257 * The decoration is identical to that of scalar arrays, but we can't
258 * quite use appendStringInfo() in the loop.
259 */
260static void
261writeNodeArray(StringInfo str, const Node *const *arr, int len)
262{
263 if (arr != NULL)
264 {
266 for (int i = 0; i < len; i++)
267 {
269 outNode(str, arr[i]);
270 }
272 }
273 else
275}
276
277/*
278 * Print a List.
279 */
280static void
282{
283 const ListCell *lc;
284
286
287 if (IsA(node, IntList))
289 else if (IsA(node, OidList))
291 else if (IsA(node, XidList))
293
294 foreach(lc, node)
295 {
296 /*
297 * For the sake of backward compatibility, we emit a slightly
298 * different whitespace format for lists of nodes vs. other types of
299 * lists. XXX: is this necessary?
300 */
301 if (IsA(node, List))
302 {
303 outNode(str, lfirst(lc));
304 if (lnext(node, lc))
306 }
307 else if (IsA(node, IntList))
308 appendStringInfo(str, " %d", lfirst_int(lc));
309 else if (IsA(node, OidList))
310 appendStringInfo(str, " %u", lfirst_oid(lc));
311 else if (IsA(node, XidList))
312 appendStringInfo(str, " %u", lfirst_xid(lc));
313 else
314 elog(ERROR, "unrecognized list node type: %d",
315 (int) node->type);
316 }
317
319}
320
321/*
322 * outBitmapset -
323 * converts a bitmap set of integers
324 *
325 * Note: the output format is "(b int int ...)", similar to an integer List.
326 *
327 * We export this function for use by extensions that define extensible nodes.
328 * That's somewhat historical, though, because calling outNode() will work.
329 */
330void
332{
333 int x;
334
337 x = -1;
338 while ((x = bms_next_member(bms, x)) >= 0)
339 appendStringInfo(str, " %d", x);
341}
342
343/*
344 * Print the value of a Datum given its type.
345 */
346void
347outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
348{
349 Size length,
350 i;
351 char *s;
352
353 length = datumGetSize(value, typbyval, typlen);
354
355 if (typbyval)
356 {
357 s = (char *) (&value);
358 appendStringInfo(str, "%u [ ", (unsigned int) length);
359 for (i = 0; i < (Size) sizeof(Datum); i++)
360 appendStringInfo(str, "%d ", (int) (s[i]));
362 }
363 else
364 {
365 s = (char *) DatumGetPointer(value);
366 if (!s)
367 appendStringInfoString(str, "0 [ ]");
368 else
369 {
370 appendStringInfo(str, "%u [ ", (unsigned int) length);
371 for (i = 0; i < length; i++)
372 appendStringInfo(str, "%d ", (int) (s[i]));
374 }
375 }
376}
377
378
379#include "outfuncs.funcs.c"
380
381
382/*
383 * Support functions for nodes with custom_read_write attribute or
384 * special_read_write attribute
385 */
386
387static void
389{
390 WRITE_NODE_TYPE("CONST");
391
392 WRITE_OID_FIELD(consttype);
393 WRITE_INT_FIELD(consttypmod);
394 WRITE_OID_FIELD(constcollid);
395 WRITE_INT_FIELD(constlen);
396 WRITE_BOOL_FIELD(constbyval);
397 WRITE_BOOL_FIELD(constisnull);
398 WRITE_LOCATION_FIELD(location);
399
400 appendStringInfoString(str, " :constvalue ");
401 if (node->constisnull)
403 else
404 outDatum(str, node->constvalue, node->constlen, node->constbyval);
405}
406
407static void
409{
410 char *opstr = NULL;
411
412 WRITE_NODE_TYPE("BOOLEXPR");
413
414 /* do-it-yourself enum representation */
415 switch (node->boolop)
416 {
417 case AND_EXPR:
418 opstr = "and";
419 break;
420 case OR_EXPR:
421 opstr = "or";
422 break;
423 case NOT_EXPR:
424 opstr = "not";
425 break;
426 }
427 appendStringInfoString(str, " :boolop ");
428 outToken(str, opstr);
429
431 WRITE_LOCATION_FIELD(location);
432}
433
434static void
436{
437 int i;
438
439 WRITE_NODE_TYPE("FOREIGNKEYOPTINFO");
440
441 WRITE_UINT_FIELD(con_relid);
442 WRITE_UINT_FIELD(ref_relid);
443 WRITE_INT_FIELD(nkeys);
444 WRITE_ATTRNUMBER_ARRAY(conkey, node->nkeys);
445 WRITE_ATTRNUMBER_ARRAY(confkey, node->nkeys);
446 WRITE_OID_ARRAY(conpfeqop, node->nkeys);
447 WRITE_INT_FIELD(nmatched_ec);
448 WRITE_INT_FIELD(nconst_ec);
449 WRITE_INT_FIELD(nmatched_rcols);
450 WRITE_INT_FIELD(nmatched_ri);
451 /* for compactness, just print the number of matches per column: */
452 appendStringInfoString(str, " :eclass");
453 for (i = 0; i < node->nkeys; i++)
454 appendStringInfo(str, " %d", (node->eclass[i] != NULL));
455 appendStringInfoString(str, " :rinfos");
456 for (i = 0; i < node->nkeys; i++)
457 appendStringInfo(str, " %d", list_length(node->rinfos[i]));
458}
459
460static void
462{
463 /*
464 * To simplify reading, we just chase up to the topmost merged EC and
465 * print that, without bothering to show the merge-ees separately.
466 */
467 while (node->ec_merged)
468 node = node->ec_merged;
469
470 WRITE_NODE_TYPE("EQUIVALENCECLASS");
471
472 WRITE_NODE_FIELD(ec_opfamilies);
473 WRITE_OID_FIELD(ec_collation);
474 WRITE_INT_FIELD(ec_childmembers_size);
475 WRITE_NODE_FIELD(ec_members);
476 WRITE_NODE_ARRAY(ec_childmembers, node->ec_childmembers_size);
477 WRITE_NODE_FIELD(ec_sources);
478 /* Only ec_derives_list is written; hash is not serialized. */
479 WRITE_NODE_FIELD(ec_derives_list);
480 WRITE_BITMAPSET_FIELD(ec_relids);
481 WRITE_BOOL_FIELD(ec_has_const);
482 WRITE_BOOL_FIELD(ec_has_volatile);
483 WRITE_BOOL_FIELD(ec_broken);
484 WRITE_UINT_FIELD(ec_sortref);
485 WRITE_UINT_FIELD(ec_min_security);
486 WRITE_UINT_FIELD(ec_max_security);
487}
488
489static void
491{
492 const ExtensibleNodeMethods *methods;
493
494 methods = GetExtensibleNodeMethods(node->extnodename, false);
495
496 WRITE_NODE_TYPE("EXTENSIBLENODE");
497
498 WRITE_STRING_FIELD(extnodename);
499
500 /* serialize the private fields */
501 methods->nodeOut(str, node);
502}
503
504static void
506{
507 WRITE_NODE_TYPE("RANGETBLENTRY");
508
509 WRITE_NODE_FIELD(alias);
510 WRITE_NODE_FIELD(eref);
511 WRITE_ENUM_FIELD(rtekind, RTEKind);
512
513 switch (node->rtekind)
514 {
515 case RTE_RELATION:
516 WRITE_OID_FIELD(relid);
517 WRITE_BOOL_FIELD(inh);
518 WRITE_CHAR_FIELD(relkind);
519 WRITE_INT_FIELD(rellockmode);
520 WRITE_UINT_FIELD(perminfoindex);
521 WRITE_NODE_FIELD(tablesample);
522 break;
523 case RTE_SUBQUERY:
524 WRITE_NODE_FIELD(subquery);
525 WRITE_BOOL_FIELD(security_barrier);
526 /* we re-use these RELATION fields, too: */
527 WRITE_OID_FIELD(relid);
528 WRITE_BOOL_FIELD(inh);
529 WRITE_CHAR_FIELD(relkind);
530 WRITE_INT_FIELD(rellockmode);
531 WRITE_UINT_FIELD(perminfoindex);
532 break;
533 case RTE_JOIN:
534 WRITE_ENUM_FIELD(jointype, JoinType);
535 WRITE_INT_FIELD(joinmergedcols);
536 WRITE_NODE_FIELD(joinaliasvars);
537 WRITE_NODE_FIELD(joinleftcols);
538 WRITE_NODE_FIELD(joinrightcols);
539 WRITE_NODE_FIELD(join_using_alias);
540 break;
541 case RTE_FUNCTION:
543 WRITE_BOOL_FIELD(funcordinality);
544 break;
545 case RTE_TABLEFUNC:
546 WRITE_NODE_FIELD(tablefunc);
547 break;
548 case RTE_VALUES:
549 WRITE_NODE_FIELD(values_lists);
550 WRITE_NODE_FIELD(coltypes);
551 WRITE_NODE_FIELD(coltypmods);
552 WRITE_NODE_FIELD(colcollations);
553 break;
554 case RTE_CTE:
555 WRITE_STRING_FIELD(ctename);
556 WRITE_UINT_FIELD(ctelevelsup);
557 WRITE_BOOL_FIELD(self_reference);
558 WRITE_NODE_FIELD(coltypes);
559 WRITE_NODE_FIELD(coltypmods);
560 WRITE_NODE_FIELD(colcollations);
561 break;
563 WRITE_STRING_FIELD(enrname);
564 WRITE_FLOAT_FIELD(enrtuples);
565 WRITE_NODE_FIELD(coltypes);
566 WRITE_NODE_FIELD(coltypmods);
567 WRITE_NODE_FIELD(colcollations);
568 /* we re-use these RELATION fields, too: */
569 WRITE_OID_FIELD(relid);
570 break;
571 case RTE_RESULT:
572 /* no extra fields */
573 break;
574 case RTE_GROUP:
575 WRITE_NODE_FIELD(groupexprs);
576 break;
577 default:
578 elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind);
579 break;
580 }
581
582 WRITE_BOOL_FIELD(lateral);
583 WRITE_BOOL_FIELD(inFromCl);
584 WRITE_NODE_FIELD(securityQuals);
585}
586
587static void
589{
590 WRITE_NODE_TYPE("A_EXPR");
591
592 switch (node->kind)
593 {
594 case AEXPR_OP:
596 break;
597 case AEXPR_OP_ANY:
600 break;
601 case AEXPR_OP_ALL:
604 break;
605 case AEXPR_DISTINCT:
606 appendStringInfoString(str, " DISTINCT");
608 break;
610 appendStringInfoString(str, " NOT_DISTINCT");
612 break;
613 case AEXPR_NULLIF:
614 appendStringInfoString(str, " NULLIF");
616 break;
617 case AEXPR_IN:
620 break;
621 case AEXPR_LIKE:
622 appendStringInfoString(str, " LIKE");
624 break;
625 case AEXPR_ILIKE:
626 appendStringInfoString(str, " ILIKE");
628 break;
629 case AEXPR_SIMILAR:
630 appendStringInfoString(str, " SIMILAR");
632 break;
633 case AEXPR_BETWEEN:
634 appendStringInfoString(str, " BETWEEN");
636 break;
638 appendStringInfoString(str, " NOT_BETWEEN");
640 break;
642 appendStringInfoString(str, " BETWEEN_SYM");
644 break;
646 appendStringInfoString(str, " NOT_BETWEEN_SYM");
648 break;
649 default:
650 elog(ERROR, "unrecognized A_Expr_Kind: %d", (int) node->kind);
651 break;
652 }
653
654 WRITE_NODE_FIELD(lexpr);
655 WRITE_NODE_FIELD(rexpr);
656 WRITE_LOCATION_FIELD(rexpr_list_start);
657 WRITE_LOCATION_FIELD(rexpr_list_end);
658 WRITE_LOCATION_FIELD(location);
659}
660
661static void
663{
664 appendStringInfo(str, "%d", node->ival);
665}
666
667static void
669{
670 /*
671 * We assume the value is a valid numeric literal and so does not need
672 * quoting.
673 */
675}
676
677static void
679{
680 appendStringInfoString(str, node->boolval ? "true" : "false");
681}
682
683static void
685{
686 /*
687 * We use outToken to provide escaping of the string's content, but we
688 * don't want it to convert an empty string to '""', because we're putting
689 * double quotes around the string already.
690 */
692 if (node->sval[0] != '\0')
693 outToken(str, node->sval);
695}
696
697static void
699{
700 /*
701 * The lexer will always produce a string starting with 'b' or 'x'. There
702 * might be characters following that that need escaping, but outToken
703 * won't escape the 'b' or 'x'. This is relied on by nodeTokenType.
704 */
705 Assert(node->bsval[0] == 'b' || node->bsval[0] == 'x');
706 outToken(str, node->bsval);
707}
708
709static void
711{
712 WRITE_NODE_TYPE("A_CONST");
713
714 if (node->isnull)
715 appendStringInfoString(str, " NULL");
716 else
717 {
718 appendStringInfoString(str, " :val ");
719 outNode(str, &node->val);
720 }
721 WRITE_LOCATION_FIELD(location);
722}
723
724
725/*
726 * outNode -
727 * converts a Node into ascii string and append it to 'str'
728 */
729void
730outNode(StringInfo str, const void *obj)
731{
732 /* Guard against stack overflow due to overly complex expressions */
734
735 if (obj == NULL)
737 else if (IsA(obj, List) || IsA(obj, IntList) || IsA(obj, OidList) ||
738 IsA(obj, XidList))
739 _outList(str, obj);
740 /* nodeRead does not want to see { } around these! */
741 else if (IsA(obj, Integer))
742 _outInteger(str, (Integer *) obj);
743 else if (IsA(obj, Float))
744 _outFloat(str, (Float *) obj);
745 else if (IsA(obj, Boolean))
746 _outBoolean(str, (Boolean *) obj);
747 else if (IsA(obj, String))
748 _outString(str, (String *) obj);
749 else if (IsA(obj, BitString))
750 _outBitString(str, (BitString *) obj);
751 else if (IsA(obj, Bitmapset))
752 outBitmapset(str, (Bitmapset *) obj);
753 else
754 {
756 switch (nodeTag(obj))
757 {
758#include "outfuncs.switch.c"
759
760 default:
761
762 /*
763 * This should be an ERROR, but it's too useful to be able to
764 * dump structures that outNode only understands part of.
765 */
766 elog(WARNING, "could not dump unrecognized node type: %d",
767 (int) nodeTag(obj));
768 break;
769 }
771 }
772}
773
774/*
775 * nodeToString -
776 * returns the ascii representation of the Node as a palloc'd string
777 *
778 * write_loc_fields determines whether location fields are output with their
779 * actual value rather than -1. The actual value can be useful for debugging,
780 * but for most uses, the actual value is not useful, since the original query
781 * string is no longer available.
782 */
783static char *
784nodeToStringInternal(const void *obj, bool write_loc_fields)
785{
787 bool save_write_location_fields;
788
789 save_write_location_fields = write_location_fields;
790 write_location_fields = write_loc_fields;
791
792 /* see stringinfo.h for an explanation of this maneuver */
794 outNode(&str, obj);
795
796 write_location_fields = save_write_location_fields;
797
798 return str.data;
799}
800
801/*
802 * Externally visible entry points
803 */
804char *
805nodeToString(const void *obj)
806{
807 return nodeToStringInternal(obj, false);
808}
809
810char *
812{
813 return nodeToStringInternal(obj, true);
814}
815
816
817/*
818 * bmsToString -
819 * returns the ascii representation of the Bitmapset as a palloc'd string
820 */
821char *
823{
825
826 /* see stringinfo.h for an explanation of this maneuver */
828 outBitmapset(&str, bms);
829 return str.data;
830}
int16 AttrNumber
Definition: attnum.h:21
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1306
unsigned int Index
Definition: c.h:620
size_t Size
Definition: c.h:611
int double_to_shortest_decimal_buf(double f, char *result)
Definition: d2s.c:1053
Size datumGetSize(Datum value, bool typByVal, int typLen)
Definition: datum.c:65
#define WARNING
Definition: elog.h:36
#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
Assert(PointerIsAligned(start, uint64))
const char * str
static struct @166 value
int x
Definition: isn.c:75
int i
Definition: isn.c:77
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define nodeTag(nodeptr)
Definition: nodes.h:139
JoinType
Definition: nodes.h:298
static void _outString(StringInfo str, const String *node)
Definition: outfuncs.c:684
#define WRITE_NODE_ARRAY(fldname, len)
Definition: outfuncs.c:113
#define WRITE_OID_FIELD(fldname)
Definition: outfuncs.c:66
#define WRITE_BITMAPSET_FIELD(fldname)
Definition: outfuncs.c:108
void outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
Definition: outfuncs.c:347
#define booltostr(x)
Definition: outfuncs.c:142
static void outChar(StringInfo str, char c)
Definition: outfuncs.c:196
static void _outExtensibleNode(StringInfo str, const ExtensibleNode *node)
Definition: outfuncs.c:490
static void _outA_Const(StringInfo str, const A_Const *node)
Definition: outfuncs.c:710
static void _outBoolExpr(StringInfo str, const BoolExpr *node)
Definition: outfuncs.c:408
#define WRITE_ENUM_FIELD(fldname, enumtype)
Definition: outfuncs.c:79
static void _outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node)
Definition: outfuncs.c:435
static void outDouble(StringInfo str, double d)
Definition: outfuncs.c:217
#define WRITE_ATTRNUMBER_ARRAY(fldname, len)
Definition: outfuncs.c:118
#define WRITE_FLOAT_FIELD(fldname)
Definition: outfuncs.c:84
char * nodeToStringWithLocations(const void *obj)
Definition: outfuncs.c:811
#define WRITE_NODE_FIELD(fldname)
Definition: outfuncs.c:103
#define WRITE_SCALAR_ARRAY(fnname, datatype, fmtstr, convfunc)
Definition: outfuncs.c:233
#define WRITE_NODE_TYPE(nodelabel)
Definition: outfuncs.c:43
static void _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
Definition: outfuncs.c:505
static void _outConst(StringInfo str, const Const *node)
Definition: outfuncs.c:388
#define WRITE_BOOL_FIELD(fldname)
Definition: outfuncs.c:89
void outToken(StringInfo str, const char *s)
Definition: outfuncs.c:155
static void _outInteger(StringInfo str, const Integer *node)
Definition: outfuncs.c:662
#define WRITE_UINT_FIELD(fldname)
Definition: outfuncs.c:51
char * nodeToString(const void *obj)
Definition: outfuncs.c:805
#define WRITE_OID_ARRAY(fldname, len)
Definition: outfuncs.c:123
static void _outA_Expr(StringInfo str, const A_Expr *node)
Definition: outfuncs.c:588
static void _outList(StringInfo str, const List *node)
Definition: outfuncs.c:281
char * bmsToString(const Bitmapset *bms)
Definition: outfuncs.c:822
#define WRITE_CHAR_FIELD(fldname)
Definition: outfuncs.c:74
static bool write_location_fields
Definition: outfuncs.c:29
void outNode(StringInfo str, const void *obj)
Definition: outfuncs.c:730
#define WRITE_LOCATION_FIELD(fldname)
Definition: outfuncs.c:99
static void _outFloat(StringInfo str, const Float *node)
Definition: outfuncs.c:668
#define WRITE_STRING_FIELD(fldname)
Definition: outfuncs.c:94
#define WRITE_INT_FIELD(fldname)
Definition: outfuncs.c:47
static char * nodeToStringInternal(const void *obj, bool write_loc_fields)
Definition: outfuncs.c:784
static void _outBitString(StringInfo str, const BitString *node)
Definition: outfuncs.c:698
static void _outBoolean(StringInfo str, const Boolean *node)
Definition: outfuncs.c:678
static void writeNodeArray(StringInfo str, const Node *const *arr, int len)
Definition: outfuncs.c:261
static void _outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
Definition: outfuncs.c:461
void outBitmapset(StringInfo str, const Bitmapset *bms)
Definition: outfuncs.c:331
@ AEXPR_BETWEEN
Definition: parsenodes.h:339
@ AEXPR_NULLIF
Definition: parsenodes.h:334
@ AEXPR_NOT_DISTINCT
Definition: parsenodes.h:333
@ AEXPR_BETWEEN_SYM
Definition: parsenodes.h:341
@ AEXPR_NOT_BETWEEN_SYM
Definition: parsenodes.h:342
@ AEXPR_ILIKE
Definition: parsenodes.h:337
@ AEXPR_IN
Definition: parsenodes.h:335
@ AEXPR_NOT_BETWEEN
Definition: parsenodes.h:340
@ AEXPR_DISTINCT
Definition: parsenodes.h:332
@ AEXPR_SIMILAR
Definition: parsenodes.h:338
@ AEXPR_LIKE
Definition: parsenodes.h:336
@ AEXPR_OP
Definition: parsenodes.h:329
@ AEXPR_OP_ANY
Definition: parsenodes.h:330
@ AEXPR_OP_ALL
Definition: parsenodes.h:331
RTEKind
Definition: parsenodes.h:1040
@ RTE_JOIN
Definition: parsenodes.h:1043
@ RTE_CTE
Definition: parsenodes.h:1047
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1048
@ RTE_VALUES
Definition: parsenodes.h:1046
@ RTE_SUBQUERY
Definition: parsenodes.h:1042
@ RTE_RESULT
Definition: parsenodes.h:1049
@ RTE_FUNCTION
Definition: parsenodes.h:1044
@ RTE_TABLEFUNC
Definition: parsenodes.h:1045
@ RTE_GROUP
Definition: parsenodes.h:1052
@ RTE_RELATION
Definition: parsenodes.h:1041
const void size_t len
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define lfirst_int(lc)
Definition: pg_list.h:173
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
#define lfirst_oid(lc)
Definition: pg_list.h:174
#define lfirst_xid(lc)
Definition: pg_list.h:175
static char * buf
Definition: pg_test_fsync.c:72
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
unsigned int Oid
Definition: postgres_ext.h:32
char * c
@ AND_EXPR
Definition: primnodes.h:950
@ OR_EXPR
Definition: primnodes.h:950
@ NOT_EXPR
Definition: primnodes.h:950
static const struct fns functions
Definition: regcomp.c:358
#define DOUBLE_SHORTEST_DECIMAL_LEN
Definition: shortest_dec.h:44
void check_stack_depth(void)
Definition: stack_depth.c:95
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
bool isnull
Definition: parsenodes.h:387
union ValUnion val
Definition: parsenodes.h:386
A_Expr_Kind kind
Definition: parsenodes.h:350
char * bsval
Definition: value.h:76
BoolExprType boolop
Definition: primnodes.h:958
Definition: value.h:56
bool boolval
Definition: value.h:60
int ec_childmembers_size
Definition: pathnodes.h:1474
struct EquivalenceClass * ec_merged
Definition: pathnodes.h:1490
void(* nodeOut)(struct StringInfoData *str, const struct ExtensibleNode *node)
Definition: extensible.h:70
const char * extnodename
Definition: extensible.h:37
Definition: value.h:48
char * fval
Definition: value.h:52
struct EquivalenceClass * eclass[INDEX_MAX_KEYS]
Definition: pathnodes.h:1309
List * rinfos[INDEX_MAX_KEYS]
Definition: pathnodes.h:1313
Definition: value.h:29
int ival
Definition: value.h:33
Definition: pg_list.h:54
NodeTag type
Definition: pg_list.h:55
Definition: nodes.h:135
RTEKind rtekind
Definition: parsenodes.h:1076
Definition: value.h:64
char * sval
Definition: value.h:68
const char * name