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