1 /*-------------------------------------------------------------------------
2 *
3 * outfuncs.c
4 * Output functions for Postgres tree nodes.
5 *
6 * Portions Copyright (c) 2003-2020, PgPool Global Development Group
7 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
9 *
10 *
11 * IDENTIFICATION
12 * src/backend/nodes/outfuncs.c
13 *
14 * NOTES
15 * Every node type that can appear in stored rules' parsetrees *must*
16 * have an output function defined here (as well as an input function
17 * in readfuncs.c). For use in debugging, we also provide output
18 * functions for nodes that appear in raw parsetrees, path, and plan trees.
19 * These nodes however need not have input functions.
20 *
21 *-------------------------------------------------------------------------
22 */
23 #include <string.h>
24 #include <limits.h>
25 #include "pool_type.h"
26 #include "utils/palloc.h"
27 #include "utils/elog.h"
28 #include "parser.h"
29 #include "extensible.h"
30 #include "pool_string.h"
31 #include "pg_list.h"
32 #include "parsenodes.h"
33 #include "pg_class.h"
34 #include "pg_trigger.h"
35 #include "value.h"
36
37 #define booltostr(x) ((x) ? "true" : "false")
38
39 void _outNode(String * str, void *obj);
40
41 static void _outList(String * str, List *node);
42 static void _outIdList(String * str, List *node);
43 static void _outAlias(String * str, Alias *node);
44 static void _outRangeVar(String * str, RangeVar *node);
45 static void _outVar(String * str, Var *node);
46 static void _outConst(String * str, Const *node);
47 static void _outParam(String * str, Param *node);
48 static void _outAggref(String * str, Aggref *node);
49 static void _outGroupingFunc(String * str, GroupingFunc *node);
50 static void _outSubscriptingRef(String * str, SubscriptingRef *node);
51 static void _outFuncExpr(String * str, FuncExpr *node);
52 static void _outNamedArgExpr(String * str, NamedArgExpr *node);
53 static void _outOpExpr(String * str, OpExpr *node);
54 static void _outDistinctExpr(String * str, DistinctExpr *node);
55 static void _outScalarArrayOpExpr(String * str, ScalarArrayOpExpr *node);
56 static void _outBoolExpr(String * str, BoolExpr *node);
57 static void _outSubLink(String * str, SubLink *node);
58 static void _outSubPlan(String * str, SubPlan *node);
59 static void _outFieldSelect(String * str, FieldSelect *node);
60 static void _outFieldStore(String * str, FieldStore *node);
61 static void _outRelabelType(String * str, RelabelType *node);
62 static void _outConvertRowtypeExpr(String * str, ConvertRowtypeExpr *node);
63 static void _outCaseExpr(String * str, CaseExpr *node);
64 static void _outCaseWhen(String * str, CaseWhen *node);
65 static void _outCaseTestExpr(String * str, CaseTestExpr *node);
66 static void _outArrayExpr(String * str, ArrayExpr *node);
67 static void _outRowExpr(String * str, RowExpr *node);
68 static void _outCoalesceExpr(String * str, CoalesceExpr *node);
69 static void _outMinMaxExpr(String * str, MinMaxExpr *node);
70 static void _outNullIfExpr(String * str, NullIfExpr *node);
71 static void _outNullTest(String * str, NullTest *node);
72 static void _outBooleanTest(String * str, BooleanTest *node);
73 static void _outCoerceToDomain(String * str, CoerceToDomain *node);
74 static void _outCoerceToDomainValue(String * str, CoerceToDomainValue *node);
75 static void _outSetToDefault(String * str, SetToDefault *node);
76 static void _outCurrentOfExpr(String * str, CurrentOfExpr *node);
77 static void _outInferenceElem(String * str, InferenceElem *node);
78 static void _outTargetEntry(String * str, TargetEntry *node);
79 static void _outRangeTblRef(String * str, RangeTblRef *node);
80 static void _outJoinExpr(String * str, JoinExpr *node);
81 static void _outFromExpr(String * str, FromExpr *node);
82 static void _outCreateStmt(String * str, CreateStmt *node);
83 static void _outCreateTableAsStmt(String * str, CreateTableAsStmt *node);
84 static void _outCreateForeignTableStmt(String * str, CreateForeignTableStmt *node);
85 static void _outImportForeignSchemaStmt(String * str, ImportForeignSchemaStmt *node);
86 static void _outIndexStmt(String * str, IndexStmt *node);
87 static void _outNotifyStmt(String * str, NotifyStmt *node);
88 static void _outDeclareCursorStmt(String * str, DeclareCursorStmt *node);
89 static void _outSelectStmt(String * str, SelectStmt *node);
90 static void _outFuncCall(String * str, FuncCall *node);
91 static void _outDefElem(String * str, DefElem *node);
92 static void _outLockingClause(String * str, LockingClause *node);
93 static void _outReturnStmt(String * str, ReturnStmt *node);
94 static void _outPLAssignStmt(String * str, PLAssignStmt *node);
95 static void _outColumnDef(String * str, ColumnDef *node);
96 static void _outTypeName(String * str, TypeName *node);
97 static void _outTypeCast(String * str, TypeCast *node);
98 static void _outIndexElem(String * str, IndexElem *node);
99 static void _outGroupingSet(String * str, GroupingSet *node);
100 static void _outWithClause(String * str, WithClause *node);
101 static void _outCTESearchClause(String * str, CTESearchClause *node);
102 static void _outCTECycleClause(String * str, CTECycleClause *node);
103 static void _outCommonTableExpr(String * str, CommonTableExpr *node);
104 static void _outSetOperationStmt(String * str, SetOperationStmt *node);
105 static void _outTableSampleClause(String * str, TableSampleClause *node);
106 static void _outAExpr(String * str, A_Expr *node);
107 static void _outValue(String * str, Value *value);
108 static void _outColumnRef(String * str, ColumnRef *node);
109 static void _outParamRef(String * str, ParamRef *node);
110 static void _outAConst(String * str, A_Const *node);
111 static void _outA_Indices(String * str, A_Indices *node);
112 static void _outA_Indirection(String * str, A_Indirection *node);
113 static void _outResTarget(String * str, ResTarget *node);
114 static void _outMultiAssignRef(String * str, MultiAssignRef *node);
115 static void _outA_ArrayExpr(String * str, A_ArrayExpr *node);
116 static void _outWindowDef(String * str, WindowDef *node);
117 static void _outConstraint(String * str, Constraint *node);
118
119 static void _outSortBy(String * str, SortBy *node);
120 static void _outInsertStmt(String * str, InsertStmt *node);
121 static void _outSetClause(String * str, List *node);
122 static void _outUpdateStmt(String * str, UpdateStmt *node);
123 static void _outDeleteStmt(String * str, DeleteStmt *node);
124 static void _outTransactionStmt(String * str, TransactionStmt *node);
125 static void _outTruncateStmt(String * str, TruncateStmt *node);
126 static void _outVacuumStmt(String * str, VacuumStmt *node);
127 static void _outExplainStmt(String * str, ExplainStmt *node);
128 static void _outClusterStmt(String * str, ClusterStmt *node);
129 static void _outCheckPointStmt(String * str, CheckPointStmt *node);
130 static void _outClosePortalStmt(String * str, ClosePortalStmt *node);
131 static void _outListenStmt(String * str, ListenStmt *node);
132 static void _outUnlistenStmt(String * str, UnlistenStmt *node);
133 static void _outLoadStmt(String * str, LoadStmt *node);
134 static void _outCopyStmt(String * str, CopyStmt *node);
135 static void _outDeallocateStmt(String * str, DeallocateStmt *node);
136 static void _outRenameStmt(String * str, RenameStmt *node);
137 static void _outCreateRoleStmt(String * str, CreateRoleStmt *node);
138 static void _outAlterRoleStmt(String * str, AlterRoleStmt *node);
139 static void _outDropRoleStmt(String * str, DropRoleStmt *node);
140 static void _outCreateSchemaStmt(String * str, CreateSchemaStmt *node);
141 static void _outVariableSetStmt(String * str, VariableSetStmt *node);
142 static void _outVariableShowStmt(String * str, VariableShowStmt *node);
143 static void _outConstraintsSetStmt(String * str, ConstraintsSetStmt *node);
144 static void _outAlterTableStmt(String * str, AlterTableStmt *node);
145 static void _outCreateSeqStmt(String * str, CreateSeqStmt *node);
146 static void _outAlterSeqStmt(String * str, AlterSeqStmt *node);
147 static void _outCreatePLangStmt(String * str, CreatePLangStmt *node);
148 static void _outCreateTableSpaceStmt(String * str, CreateTableSpaceStmt *node);
149 static void _outDropTableSpaceStmt(String * str, DropTableSpaceStmt *node);
150 static void _outCreateTrigStmt(String * str, CreateTrigStmt *node);
151 static void _outDefineStmt(String * str, DefineStmt *node);
152 static void _outCreateOpClassStmt(String * str, CreateOpClassStmt *node);
153 static void _outDropStmt(String * str, DropStmt *node);
154 static void _outFetchStmt(String * str, FetchStmt *node);
155 static void _outGrantStmt(String * str, GrantStmt *node);
156 static void _outGrantRoleStmt(String * str, GrantRoleStmt *node);
157 static void _outCreateFunctionStmt(String * str, CreateFunctionStmt *node);
158 static void _outAlterFunctionStmt(String * str, AlterFunctionStmt *node);
159 static void _outCreateCastStmt(String * str, CreateCastStmt *node);
160 static void _outReindexStmt(String * str, ReindexStmt *node);
161 static void _outRuleStmt(String * str, RuleStmt *node);
162 static void _outViewStmt(String * str, ViewStmt *node);
163 static void _outCreatedbStmt(String * str, CreatedbStmt *node);
164 static void _outAlterDatabaseStmt(String * str, AlterDatabaseStmt *node);
165 static void _outAlterDatabaseSetStmt(String * str, AlterDatabaseSetStmt *node);
166 static void _outDropdbStmt(String * str, DropdbStmt *node);
167 static void _outCreateDomainStmt(String * str, CreateDomainStmt *node);
168 static void _outAlterDomainStmt(String * str, AlterDomainStmt *node);
169 static void _outCreateConversionStmt(String * str, CreateConversionStmt *node);
170 static void _outPrepareStmt(String * str, PrepareStmt *node);
171 static void _outExecuteStmt(String * str, ExecuteStmt *node);
172 static void _outLockStmt(String * str, LockStmt *node);
173 static void _outCommentStmt(String * str, CommentStmt *node);
174 static void _outDiscardStmt(String * str, DiscardStmt *node);
175 static void _outCreateOpFamilyStmt(String * str, CreateOpFamilyStmt *node);
176 static void _outAlterOpFamilyStmt(String * str, AlterOpFamilyStmt *node);
177 static void _outCreateEnumStmt(String * str, CreateEnumStmt *node);
178 static void _outDropOwnedStmt(String * str, DropOwnedStmt *node);
179 static void _outReassignOwnedStmt(String * str, ReassignOwnedStmt *node);
180 static void _outAlterTSDictionaryStmt(String * str, AlterTSDictionaryStmt *node);
181 static void _outAlterTSConfigurationStmt(String * str, AlterTSConfigurationStmt *node);
182 static void _outXmlExpr(String * str, XmlExpr *node);
183 static void _outXmlSerialize(String * str, XmlSerialize *node);
184
185 static void _outFuncName(String * str, List *func_name);
186 static void _outSetRest(String * str, VariableSetStmt *node);
187 static void _outSetTransactionModeList(String * str, List *list);
188 static void _outAlterTableCmd(String * str, AlterTableCmd *node);
189 static void _outOptSeqList(String * str, List *options);
190 static void _outObjectWithArgs(String * str, ObjectWithArgs *node);
191 static void _outFunctionParameter(String * str, FunctionParameter *node);
192 static void _outPrivilegeList(String * str, List *list);
193 static void _outFuncOptList(String * str, List *list);
194 static void _outCreatedbOptList(String * str, List *options);
195 static void _outOperatorArgTypes(String * str, List *args);
196 static void _outRangeFunction(String * str, RangeFunction *node);
197 static void _outRangeTableSample(String * str, RangeTableSample *node);
198 static void _outWithDefinition(String * str, List *def_list);
199 static void _outOnConflictClause(String * str, OnConflictClause *node);
200
201
202 /*
203 * Borrowed from backend/catalog/namespace.c
204 * NameListToString
205 * Utility routine to convert a qualified-name list into a string.
206 *
207 * This is used primarily to form error messages, and so we do not quote
208 * the list elements, for the sake of legibility.
209 *
210 * In most scenarios the list elements should always be Value strings,
211 * but we also allow A_Star for the convenience of ColumnRef processing.
212 */
213 char *
NameListToString(List * names)214 NameListToString(List *names)
215 {
216 StringInfoData string;
217 ListCell *l;
218
219 initStringInfo(&string);
220
221 foreach(l, names)
222 {
223 Node *name = (Node *) lfirst(l);
224
225 if (l != list_head(names))
226 appendStringInfoChar(&string, '.');
227
228 if (IsA(name, String))
229 appendStringInfoString(&string, strVal(name));
230 else if (IsA(name, A_Star))
231 appendStringInfoString(&string, "*");
232 else
233 elog(ERROR, "unexpected node type in name list: %d",
234 (int) nodeTag(name));
235 }
236
237 return string.data;
238 }
239
240
241 static char *
escape_string(char * str)242 escape_string(char *str)
243 {
244 int len = strlen(str),
245 i,
246 j;
247 char *es = palloc0(len * 2 + 1);
248
249 if (es == NULL)
250 {
251 return NULL;
252 }
253
254 for (i = 0, j = 0; i < len; i++, j++)
255 {
256 if (str[i] == '\'')
257 {
258 es[j++] = '\'';
259 }
260 else if (str[i] == '\\')
261 {
262 if (!standard_conforming_strings)
263 es[j++] = '\\';
264 }
265 es[j] = str[i];
266 }
267
268 return es;
269 }
270
271 static void
_outIdList(String * str,List * node)272 _outIdList(String * str, List *node)
273 {
274 ListCell *lc;
275 char first = 0;
276
277 foreach(lc, node)
278 {
279 Value *v = lfirst(lc);
280
281 if (first == 0)
282 first = 1;
283 else
284 string_append_char(str, ", ");
285
286 string_append_char(str, "\"");
287 string_append_char(str, v->val.str);
288 string_append_char(str, "\"");
289 }
290 }
291
292 static void
_outListWith(String * str,List * node,char * op)293 _outListWith(String * str, List *node, char *op)
294 {
295 ListCell *lc;
296 char first = 0;
297
298 foreach(lc, node)
299 {
300 if (first == 0)
301 first = 1;
302 else
303 {
304 if (lfirst(lc) != NIL && !IsA(lfirst(lc), A_Indices))
305 string_append_char(str, op);
306 }
307 _outNode(str, lfirst(lc));
308 }
309 }
310
311 static void
_outList(String * str,List * node)312 _outList(String * str, List *node)
313 {
314 _outListWith(str, node, ",");
315 }
316
317
318
319 /*****************************************************************************
320 *
321 * Stuff from primnodes.h.
322 *
323 *****************************************************************************/
324
325 #ifdef NOT_USED_IN_PGPOOL
326 /* for use by extensions which define extensible nodes */
327 void
outToken(StringInfo str,const char * s)328 outToken(StringInfo str, const char *s)
329 {
330 _outToken(str, s);
331 }
332 #endif
333
334 static void
_outAlias(String * str,Alias * node)335 _outAlias(String * str, Alias *node)
336 {
337 string_append_char(str, " AS \"");
338 string_append_char(str, node->aliasname);
339 string_append_char(str, "\"");
340
341 if (node->colnames)
342 {
343 string_append_char(str, "(");
344 _outNode(str, node->colnames);
345 string_append_char(str, ")");
346 }
347 }
348
349 static void
_outRangeVar(String * str,RangeVar * node)350 _outRangeVar(String * str, RangeVar *node)
351 {
352 if (node->catalogname)
353 {
354 string_append_char(str, "\"");
355 string_append_char(str, node->catalogname);
356 string_append_char(str, "\".");
357 }
358
359 if (node->schemaname)
360 {
361 string_append_char(str, "\"");
362 string_append_char(str, node->schemaname);
363 string_append_char(str, "\".");
364 }
365
366 string_append_char(str, "\"");
367 string_append_char(str, node->relname);
368 string_append_char(str, "\"");
369
370 if (node->alias)
371 _outNode(str, node->alias);
372 }
373
374 static void
_outVar(String * str,Var * node)375 _outVar(String * str, Var *node)
376 {
377
378 }
379
380 static void
_outConst(String * str,Const * node)381 _outConst(String * str, Const *node)
382 {
383
384 }
385
386 static void
_outParam(String * str,Param * node)387 _outParam(String * str, Param *node)
388 {
389
390 }
391
392 static void
_outAggref(String * str,Aggref * node)393 _outAggref(String * str, Aggref *node)
394 {
395
396 }
397
398 static void
_outGroupingFunc(String * str,GroupingFunc * node)399 _outGroupingFunc(String * str, GroupingFunc *node)
400 {
401 string_append_char(str, "GROUPING (");
402 _outNode(str, node->args);
403 string_append_char(str, ")");
404
405 }
406
407 static void
_outSubscriptingRef(String * str,SubscriptingRef * node)408 _outSubscriptingRef(String * str, SubscriptingRef *node)
409 {
410
411 }
412
413 static void
_outFuncExpr(String * str,FuncExpr * node)414 _outFuncExpr(String * str, FuncExpr *node)
415 {
416
417 }
418
419 static void
_outNamedArgExpr(String * str,NamedArgExpr * node)420 _outNamedArgExpr(String * str, NamedArgExpr *node)
421 {
422 string_append_char(str, node->name);
423 string_append_char(str, " := ");
424 _outNode(str, node->arg);
425 }
426
427 static void
_outOpExpr(String * str,OpExpr * node)428 _outOpExpr(String * str, OpExpr *node)
429 {
430
431 }
432
433 static void
_outDistinctExpr(String * str,DistinctExpr * node)434 _outDistinctExpr(String * str, DistinctExpr *node)
435 {
436
437 }
438
439 static void
_outScalarArrayOpExpr(String * str,ScalarArrayOpExpr * node)440 _outScalarArrayOpExpr(String * str, ScalarArrayOpExpr *node)
441 {
442
443 }
444
445 static void
_outBoolExpr(String * str,BoolExpr * node)446 _outBoolExpr(String * str, BoolExpr *node)
447 {
448 switch (node->boolop)
449 {
450 case AND_EXPR:
451 string_append_char(str, " (");
452 _outListWith(str, node->args, " AND ");
453 string_append_char(str, ")");
454 break;
455
456 case OR_EXPR:
457 string_append_char(str, " (");
458 _outListWith(str, node->args, " OR ");
459 string_append_char(str, ")");
460 break;
461
462 case NOT_EXPR:
463 string_append_char(str, " (NOT ");
464 _outList(str, node->args);
465 string_append_char(str, ")");
466 break;
467 }
468 }
469
470 static void
_outSubLink(String * str,SubLink * node)471 _outSubLink(String * str, SubLink *node)
472 {
473 _outNode(str, node->testexpr);
474
475 /*
476 * If the source was "x IN (select)", convert to "x = ANY (select)".
477 */
478 if (node->subLinkType == ANY_SUBLINK && node->operName == NIL)
479 node->operName = list_make1(makeString("="));
480
481 if (node->operName != NIL)
482 {
483 Value *v = linitial(node->operName);
484
485 if (strcmp(v->val.str, "=") == 0)
486 string_append_char(str, " IN ");
487 else
488 {
489 string_append_char(str, v->val.str);
490 }
491 }
492
493 switch (node->subLinkType)
494 {
495 case EXISTS_SUBLINK:
496 string_append_char(str, " EXISTS ");
497 break;
498
499 case ARRAY_SUBLINK:
500 string_append_char(str, " ARRAY ");
501 break;
502
503 case ANY_SUBLINK:
504 if (node->operName != NIL)
505 {
506 Value *v = linitial(node->operName);
507
508 if (strcmp(v->val.str, "=") != 0)
509 {
510 string_append_char(str, v->val.str);
511 string_append_char(str, " ANY ");
512 }
513 }
514 break;
515
516 case ALL_SUBLINK:
517 string_append_char(str, " ALL ");
518 break;
519
520 default:
521 break;
522 }
523
524
525 if (node->subselect)
526 {
527 string_append_char(str, "(");
528 _outNode(str, node->subselect);
529 string_append_char(str, ")");
530 }
531 }
532
533 static void
_outSubPlan(String * str,SubPlan * node)534 _outSubPlan(String * str, SubPlan *node)
535 {
536
537 }
538
539 static void
_outFieldSelect(String * str,FieldSelect * node)540 _outFieldSelect(String * str, FieldSelect *node)
541 {
542
543 }
544
545 static void
_outFieldStore(String * str,FieldStore * node)546 _outFieldStore(String * str, FieldStore *node)
547 {
548
549 }
550
551 static void
_outRelabelType(String * str,RelabelType * node)552 _outRelabelType(String * str, RelabelType *node)
553 {
554
555 }
556
557 static void
_outConvertRowtypeExpr(String * str,ConvertRowtypeExpr * node)558 _outConvertRowtypeExpr(String * str, ConvertRowtypeExpr *node)
559 {
560
561 }
562
563 static void
_outCaseExpr(String * str,CaseExpr * node)564 _outCaseExpr(String * str, CaseExpr *node)
565 {
566 ListCell *lc;
567
568 string_append_char(str, "CASE ");
569 if (node->arg)
570 _outNode(str, node->arg);
571
572 foreach(lc, node->args)
573 {
574 _outNode(str, lfirst(lc));
575 }
576
577 if (node->defresult)
578 {
579 string_append_char(str, " ELSE ");
580 _outNode(str, node->defresult);
581 }
582
583 string_append_char(str, " END");
584 }
585
586 static void
_outCaseWhen(String * str,CaseWhen * node)587 _outCaseWhen(String * str, CaseWhen *node)
588 {
589 string_append_char(str, " WHEN ");
590 _outNode(str, node->expr);
591 string_append_char(str, " THEN ");
592 _outNode(str, node->result);
593 }
594
595 static void
_outCaseTestExpr(String * str,CaseTestExpr * node)596 _outCaseTestExpr(String * str, CaseTestExpr *node)
597 {
598
599 }
600
601 static void
_outArrayExpr(String * str,ArrayExpr * node)602 _outArrayExpr(String * str, ArrayExpr *node)
603 {
604 string_append_char(str, "[");
605 _outNode(str, node->elements);
606 string_append_char(str, "]");
607 }
608
609 static void
_outRowExpr(String * str,RowExpr * node)610 _outRowExpr(String * str, RowExpr *node)
611 {
612 if (node->row_format == COERCE_EXPLICIT_CAST)
613 string_append_char(str, "ROW (");
614 else
615 string_append_char(str, "(");
616
617 if (node->args != NIL)
618 _outNode(str, node->args);
619
620 string_append_char(str, ")");
621 }
622
623 static void
_outCoalesceExpr(String * str,CoalesceExpr * node)624 _outCoalesceExpr(String * str, CoalesceExpr *node)
625 {
626 string_append_char(str, "COALESCE (");
627 _outNode(str, node->args);
628 string_append_char(str, ")");
629 }
630
631 static void
_outMinMaxExpr(String * str,MinMaxExpr * node)632 _outMinMaxExpr(String * str, MinMaxExpr *node)
633 {
634 if (node->op == IS_GREATEST)
635 {
636 string_append_char(str, "GREATEST (");
637 _outNode(str, node->args);
638 string_append_char(str, ")");
639 }
640 else if (node->op == IS_LEAST)
641 {
642 string_append_char(str, "LEAST (");
643 _outNode(str, node->args);
644 string_append_char(str, ")");
645 }
646 }
647
648 static void
_outNullIfExpr(String * str,NullIfExpr * node)649 _outNullIfExpr(String * str, NullIfExpr *node)
650 {
651
652 }
653
654 static void
_outNullTest(String * str,NullTest * node)655 _outNullTest(String * str, NullTest *node)
656 {
657 _outNode(str, node->arg);
658 if (node->nulltesttype == IS_NOT_NULL)
659 string_append_char(str, " IS NOT NULL");
660 else
661 string_append_char(str, " IS NULL");
662 }
663
664 static void
_outBooleanTest(String * str,BooleanTest * node)665 _outBooleanTest(String * str, BooleanTest *node)
666 {
667 _outNode(str, node->arg);
668
669 switch (node->booltesttype)
670 {
671 case IS_TRUE:
672 string_append_char(str, " IS TRUE");
673 break;
674
675 case IS_NOT_TRUE:
676 string_append_char(str, " IS NOT TRUE");
677 break;
678
679 case IS_FALSE:
680 string_append_char(str, " IS FALSE");
681 break;
682
683 case IS_NOT_FALSE:
684 string_append_char(str, " IS NOT FALSE");
685 break;
686
687 case IS_UNKNOWN:
688 string_append_char(str, " IS UNKNOWN");
689 break;
690
691 case IS_NOT_UNKNOWN:
692 string_append_char(str, " IS NOT UNKNOWN");
693 break;
694 }
695 }
696
697 static void
_outCoerceToDomain(String * str,CoerceToDomain * node)698 _outCoerceToDomain(String * str, CoerceToDomain *node)
699 {
700
701 }
702
703 static void
_outCoerceToDomainValue(String * str,CoerceToDomainValue * node)704 _outCoerceToDomainValue(String * str, CoerceToDomainValue *node)
705 {
706
707 }
708
709 static void
_outSetToDefault(String * str,SetToDefault * node)710 _outSetToDefault(String * str, SetToDefault *node)
711 {
712 string_append_char(str, "DEFAULT");
713 }
714
715 static void
_outCurrentOfExpr(String * str,CurrentOfExpr * node)716 _outCurrentOfExpr(String * str, CurrentOfExpr *node)
717 {
718 string_append_char(str, "CURRENT OF ");
719 if (node->cursor_name == NULL)
720 {
721 char n[10];
722
723 snprintf(n, sizeof(n), "$%d", node->cursor_param);
724 string_append_char(str, n);
725 }
726 else
727 string_append_char(str, node->cursor_name);
728 }
729
730 static void
_outInferenceElem(String * str,InferenceElem * node)731 _outInferenceElem(String * str, InferenceElem *node)
732 {
733
734 }
735
736 static void
_outTargetEntry(String * str,TargetEntry * node)737 _outTargetEntry(String * str, TargetEntry *node)
738 {
739
740 }
741
742 static void
_outRangeTblRef(String * str,RangeTblRef * node)743 _outRangeTblRef(String * str, RangeTblRef *node)
744 {
745
746 }
747
748 static void
_outJoinExpr(String * str,JoinExpr * node)749 _outJoinExpr(String * str, JoinExpr *node)
750 {
751 _outNode(str, node->larg);
752
753 if (node->isNatural == TRUE)
754 string_append_char(str, " NATURAL");
755
756 if (node->jointype == JOIN_INNER)
757 {
758 if (node->usingClause == NIL && node->quals == NULL && !node->isNatural)
759 string_append_char(str, " CROSS JOIN ");
760 else
761 string_append_char(str, " JOIN ");
762 }
763 else if (node->jointype == JOIN_INNER)
764 string_append_char(str, " JOIN ");
765 else if (node->jointype == JOIN_LEFT)
766 string_append_char(str, " LEFT OUTER JOIN ");
767 else if (node->jointype == JOIN_FULL)
768 string_append_char(str, " FULL OUTER JOIN ");
769 else if (node->jointype == JOIN_RIGHT)
770 string_append_char(str, " RIGHT OUTER JOIN ");
771
772 _outNode(str, node->rarg);
773
774 if (node->usingClause != NIL && IsA(node->usingClause, List))
775 {
776 ListCell *lc;
777 char comma = 0;
778
779 string_append_char(str, " USING(");
780
781 foreach(lc, node->usingClause)
782 {
783 Value *value;
784
785 if (comma == 0)
786 comma = 1;
787 else
788 string_append_char(str, ",");
789
790 value = lfirst(lc);
791 string_append_char(str, "\"");
792 string_append_char(str, value->val.str);
793 string_append_char(str, "\"");
794 }
795
796 string_append_char(str, ")");
797
798 if (node->join_using_alias)
799 _outAlias(str, node->join_using_alias);
800
801 }
802
803 if (node->quals)
804 {
805 string_append_char(str, " ON ");
806 _outNode(str, node->quals);
807 }
808 }
809
810 static void
_outFromExpr(String * str,FromExpr * node)811 _outFromExpr(String * str, FromExpr *node)
812 {
813
814 }
815
816 static void
_outOnConflictExpr(String * str,const OnConflictExpr * node)817 _outOnConflictExpr(String * str, const OnConflictExpr *node)
818 {
819
820 }
821
822 #ifdef NOT_USED
823 /*****************************************************************************
824 *
825 * Stuff from extensible.h
826 *
827 *****************************************************************************/
828
829 static void
_outExtensibleNode(StringInfo str,const ExtensibleNode * node)830 _outExtensibleNode(StringInfo str, const ExtensibleNode *node)
831 {
832 const ExtensibleNodeMethods *methods;
833
834 methods = GetExtensibleNodeMethods(node->extnodename, false);
835
836 WRITE_NODE_TYPE("EXTENSIBLENODE");
837
838 WRITE_STRING_FIELD(extnodename);
839
840 /* serialize the private fields */
841 methods->nodeOut(str, node);
842 }
843 #endif
844
845 /*****************************************************************************
846 *
847 * Stuff from parsenodes.h.
848 *
849 *****************************************************************************/
850
851 static void
_outCreateStmt(String * str,CreateStmt * node)852 _outCreateStmt(String * str, CreateStmt *node)
853 {
854 string_append_char(str, "CREATE ");
855 if (node->relation->relpersistence == RELPERSISTENCE_TEMP)
856 string_append_char(str, "TEMP ");
857 string_append_char(str, "TABLE ");
858 _outNode(str, node->relation);
859 string_append_char(str, " (");
860 _outNode(str, node->tableElts);
861 string_append_char(str, ") ");
862
863 if (node->inhRelations != NIL)
864 {
865 string_append_char(str, "INHERITS (");
866 _outNode(str, node->inhRelations);
867 string_append_char(str, ")");
868 }
869
870 if (node->options)
871 _outWithDefinition(str, node->options);
872
873 switch (node->oncommit)
874 {
875 case ONCOMMIT_DROP:
876 string_append_char(str, " ON COMMIT DROP");
877 break;
878
879 case ONCOMMIT_DELETE_ROWS:
880 string_append_char(str, " ON COMMIT DELETE ROWS");
881 break;
882
883 case ONCOMMIT_PRESERVE_ROWS:
884 string_append_char(str, " ON COMMIT PRESERVE ROWS");
885 break;
886
887 default:
888 break;
889 }
890
891 if (node->tablespacename)
892 {
893 string_append_char(str, " TABLESPACE \"");
894 string_append_char(str, node->tablespacename);
895 string_append_char(str, "\"");
896 }
897 }
898
899 static void
_outCreateTableAsStmt(String * str,CreateTableAsStmt * node)900 _outCreateTableAsStmt(String * str, CreateTableAsStmt *node)
901 {
902 string_append_char(str, "CREATE ");
903 if (node->into->rel->relpersistence == RELPERSISTENCE_TEMP)
904 string_append_char(str, "TEMP ");
905 string_append_char(str, "TABLE ");
906 _outNode(str, node->into->rel);
907
908 if (node->into->colNames)
909 {
910 string_append_char(str, " (");
911 _outIdList(str, node->into->colNames);
912 string_append_char(str, ") ");
913 }
914
915 if (node->into->options)
916 _outWithDefinition(str, node->into->options);
917
918 switch (node->into->onCommit)
919 {
920 case ONCOMMIT_DROP:
921 string_append_char(str, " ON COMMIT DROP");
922 break;
923
924 case ONCOMMIT_DELETE_ROWS:
925 string_append_char(str, " ON COMMIT DELETE ROWS");
926 break;
927
928 case ONCOMMIT_PRESERVE_ROWS:
929 string_append_char(str, " ON COMMIT PRESERVE ROWS");
930 break;
931
932 default:
933 break;
934 }
935
936 if (node->into->tableSpaceName)
937 {
938 string_append_char(str, " TABLESPACE \"");
939 string_append_char(str, node->into->tableSpaceName);
940 string_append_char(str, "\"");
941 }
942
943 if (node->query)
944 {
945 string_append_char(str, " AS");
946 _outSelectStmt(str, (SelectStmt *) node->query);
947 }
948 }
949
950 static void
_outCreateForeignTableStmt(String * str,CreateForeignTableStmt * node)951 _outCreateForeignTableStmt(String * str, CreateForeignTableStmt *node)
952 {
953
954 }
955
956 static void
_outImportForeignSchemaStmt(String * str,ImportForeignSchemaStmt * node)957 _outImportForeignSchemaStmt(String * str, ImportForeignSchemaStmt *node)
958 {
959
960 }
961
962 static void
_outIndexStmt(String * str,IndexStmt * node)963 _outIndexStmt(String * str, IndexStmt *node)
964 {
965 string_append_char(str, "CREATE ");
966
967 if (node->unique == TRUE)
968 string_append_char(str, "UNIQUE ");
969
970 if (node->concurrent == true)
971 string_append_char(str, "INDEX CONCURRENTLY ");
972 else
973 string_append_char(str, "INDEX ");
974 if (node->idxname)
975 {
976 string_append_char(str, "\"");
977 string_append_char(str, node->idxname);
978 string_append_char(str, "\" ");
979 }
980 string_append_char(str, "ON ");
981 _outNode(str, node->relation);
982
983 if (strcmp(node->accessMethod, DEFAULT_INDEX_TYPE))
984 {
985 string_append_char(str, " USING ");
986 string_append_char(str, node->accessMethod);
987 }
988
989 string_append_char(str, "(");
990 _outNode(str, node->indexParams);
991 string_append_char(str, ")");
992
993 if (node->tableSpace)
994 {
995 string_append_char(str, " TABLESPACE \"");
996 string_append_char(str, node->tableSpace);
997 string_append_char(str, "\"");
998 }
999
1000 if (node->whereClause)
1001 {
1002 string_append_char(str, " WHERE ");
1003 _outNode(str, node->whereClause);
1004 }
1005 }
1006
1007 static void
_outCreateStatsStmt(String * str,CreateStatsStmt * node)1008 _outCreateStatsStmt(String * str, CreateStatsStmt *node)
1009 {
1010 }
1011
1012 static void
_outAlterStatsStmt(String * str,const AlterStatsStmt * node)1013 _outAlterStatsStmt(String * str, const AlterStatsStmt *node)
1014 {
1015 }
1016
1017 static void
_outNotifyStmt(String * str,NotifyStmt * node)1018 _outNotifyStmt(String * str, NotifyStmt *node)
1019 {
1020 string_append_char(str, "NOTIFY ");
1021 string_append_char(str, "\"");
1022 string_append_char(str, node->conditionname);
1023 string_append_char(str, "\"");
1024 }
1025
1026 static void
_outDeclareCursorStmt(String * str,DeclareCursorStmt * node)1027 _outDeclareCursorStmt(String * str, DeclareCursorStmt *node)
1028 {
1029 string_append_char(str, "DECLARE \"");
1030 string_append_char(str, node->portalname);
1031 string_append_char(str, "\" ");
1032
1033 if (node->options & CURSOR_OPT_SCROLL)
1034 string_append_char(str, "SCROLL ");
1035 if (node->options & CURSOR_OPT_BINARY)
1036 string_append_char(str, "BINARY ");
1037 if (node->options & CURSOR_OPT_INSENSITIVE)
1038 string_append_char(str, "INSENSITIVE ");
1039
1040 string_append_char(str, "CURSOR ");
1041 if (node->options & CURSOR_OPT_HOLD)
1042 string_append_char(str, "WITH HOLD ");
1043 string_append_char(str, "FOR");
1044 _outNode(str, node->query);
1045 }
1046
1047 static void
_outSelectStmt(String * str,SelectStmt * node)1048 _outSelectStmt(String * str, SelectStmt *node)
1049 {
1050 if (node->larg) /* SETOP */
1051 {
1052 string_append_char(str, "(");
1053 _outNode(str, node->larg);
1054 string_append_char(str, ") ");
1055
1056 switch (node->op)
1057 {
1058 case SETOP_UNION:
1059 string_append_char(str, " UNION ");
1060 break;
1061
1062 case SETOP_INTERSECT:
1063 string_append_char(str, " INTERSECT ");
1064 break;
1065
1066 case SETOP_EXCEPT:
1067 string_append_char(str, " EXCEPT ");
1068
1069 default:
1070 break;
1071 }
1072
1073 if (node->all)
1074 string_append_char(str, "ALL ");
1075
1076 if (node->rarg)
1077 {
1078 string_append_char(str, "(");
1079 _outNode(str, node->rarg);
1080 string_append_char(str, ") ");
1081 }
1082 }
1083 else if (node->valuesLists) /* VALUES ... */
1084 {
1085 ListCell *lc;
1086 int comma = 0;
1087
1088 string_append_char(str, " VALUES");
1089 foreach(lc, node->valuesLists)
1090 {
1091 if (comma == 0)
1092 comma = 1;
1093 else
1094 string_append_char(str, ",");
1095
1096 string_append_char(str, " (");
1097 _outNode(str, lfirst(lc));
1098 string_append_char(str, ")");
1099 }
1100 }
1101 else
1102 {
1103 if (node->intoClause)
1104 {
1105 IntoClause *into = (IntoClause *) node->intoClause;
1106 RangeVar *rel = (RangeVar *) into->rel;
1107
1108 string_append_char(str, "CREATE ");
1109 if (rel->relpersistence == RELPERSISTENCE_TEMP)
1110 string_append_char(str, "TEMP ");
1111 string_append_char(str, "TABLE ");
1112 _outNode(str, into->rel);
1113
1114 if (into->colNames)
1115 {
1116 string_append_char(str, " (");
1117 _outNode(str, into->colNames);
1118 string_append_char(str, ") ");
1119 }
1120
1121 if (into->options)
1122 _outWithDefinition(str, into->options);
1123
1124 switch (into->onCommit)
1125 {
1126 case ONCOMMIT_DROP:
1127 string_append_char(str, " ON COMMIT DROP");
1128 break;
1129
1130 case ONCOMMIT_DELETE_ROWS:
1131 string_append_char(str, " ON COMMIT DELETE ROWS");
1132 break;
1133
1134 case ONCOMMIT_PRESERVE_ROWS:
1135 string_append_char(str, " ON COMMIT PRESERVE ROWS");
1136 break;
1137
1138 default:
1139 break;
1140 }
1141
1142 string_append_char(str, " AS");
1143 }
1144
1145 if (node->withClause)
1146 _outWithClause(str, node->withClause);
1147
1148 string_append_char(str, " SELECT ");
1149
1150 if (node->distinctClause)
1151 {
1152 string_append_char(str, "DISTINCT ");
1153 if (lfirst(list_head(node->distinctClause)) != NIL)
1154 {
1155 string_append_char(str, "ON (");
1156 _outNode(str, node->distinctClause);
1157 string_append_char(str, " ) ");
1158 }
1159 }
1160
1161 _outNode(str, node->targetList);
1162
1163 if (node->fromClause)
1164 {
1165 string_append_char(str, " FROM ");
1166 _outNode(str, node->fromClause);
1167 }
1168
1169 if (node->whereClause)
1170 {
1171 string_append_char(str, " WHERE ");
1172 _outNode(str, node->whereClause);
1173 }
1174
1175 if (node->groupClause)
1176 {
1177 string_append_char(str, " GROUP BY ");
1178
1179 if (node->groupDistinct)
1180 string_append_char(str, "DISTINCT ");
1181
1182 _outNode(str, node->groupClause);
1183 }
1184
1185 if (node->havingClause)
1186 {
1187 string_append_char(str, " HAVING ");
1188 _outNode(str, node->havingClause);
1189 }
1190
1191 if (node->windowClause)
1192 {
1193 string_append_char(str, " WINDOW ");
1194 _outNode(str, node->windowClause);
1195 }
1196 }
1197
1198 if (node->sortClause)
1199 {
1200 string_append_char(str, " ORDER BY ");
1201 _outNode(str, node->sortClause);
1202 }
1203
1204 if (node->limitOffset)
1205 {
1206 string_append_char(str, " OFFSET ");
1207 _outNode(str, node->limitOffset);
1208 }
1209
1210 if (node->limitCount)
1211 {
1212 string_append_char(str, " LIMIT ");
1213 if (IsA(node->limitCount, A_Const) &&
1214 ((A_Const *) node->limitCount)->val.type == T_Null)
1215 {
1216 string_append_char(str, "ALL ");
1217 }
1218 else
1219 {
1220 _outNode(str, node->limitCount);
1221 }
1222 }
1223
1224 _outNode(str, node->lockingClause);
1225 }
1226
1227 static void
_outFuncCall(String * str,FuncCall * node)1228 _outFuncCall(String * str, FuncCall *node)
1229 {
1230 char *funcname;
1231
1232 _outFuncName(str, node->funcname);
1233
1234 funcname = strVal(lfirst(list_head(node->funcname)));
1235
1236 if (strcmp(funcname, "user") == 0 ||
1237 strcmp(funcname, "current_user") == 0 ||
1238 strcmp(funcname, "session_user") == 0 ||
1239 strcmp(funcname, "current_role") == 0)
1240 return;
1241
1242 string_append_char(str, "(");
1243
1244 if (node->func_variadic == TRUE)
1245 string_append_char(str, "VARIADIC ");
1246
1247 if (node->agg_distinct == TRUE)
1248 string_append_char(str, "DISTINCT ");
1249
1250 if (node->agg_star == TRUE)
1251 string_append_char(str, "*");
1252 else
1253 _outNode(str, node->args);
1254
1255 if (node->agg_order != NIL)
1256 {
1257 string_append_char(str, " ORDER BY ");
1258 _outNode(str, node->agg_order);
1259 }
1260
1261 string_append_char(str, ")");
1262
1263 if (node->over)
1264 {
1265 string_append_char(str, " OVER ");
1266 if (node->over->name)
1267 {
1268 string_append_char(str, "\"");
1269 string_append_char(str, node->over->name);
1270 string_append_char(str, "\"");
1271 }
1272 else
1273 _outWindowDef(str, node->over);
1274 }
1275 }
1276
1277 static void
_outDefElem(String * str,DefElem * node)1278 _outDefElem(String * str, DefElem *node)
1279 {
1280
1281 }
1282
1283 static void
_outLockingClause(String * str,LockingClause * node)1284 _outLockingClause(String * str, LockingClause *node)
1285 {
1286 if (node == NULL)
1287 return;
1288
1289 switch (node->strength)
1290 {
1291 case LCS_FORKEYSHARE:
1292 string_append_char(str, " FOR KEY SHARE");
1293 break;
1294 case LCS_FORSHARE:
1295 string_append_char(str, " FOR SHARE");
1296 break;
1297 case LCS_FORNOKEYUPDATE:
1298 string_append_char(str, " FOR NO KEY UPDATE");
1299 break;
1300 case LCS_FORUPDATE:
1301 string_append_char(str, " FOR UPDATE");
1302 break;
1303 case LCS_NONE:
1304 break;
1305 }
1306
1307 if (node->lockedRels)
1308 {
1309 string_append_char(str, " OF ");
1310 _outNode(str, node->lockedRels);
1311 }
1312
1313 switch (node->waitPolicy)
1314 {
1315 case LockWaitError:
1316 string_append_char(str, " NOWAIT");
1317 break;
1318 case LockWaitSkip:
1319 string_append_char(str, " SKIP LOCKED");
1320 break;
1321 case LockWaitBlock:
1322 break;
1323 }
1324 }
1325
1326 static void
_outTriggerTransition(String * str,TriggerTransition * node)1327 _outTriggerTransition(String * str, TriggerTransition *node)
1328 {
1329 }
1330
1331 static void
_outReturnStmt(String * str,ReturnStmt * node)1332 _outReturnStmt(String * str, ReturnStmt *node)
1333 {
1334 }
1335
1336 static void
_outPLAssignStmt(String * str,PLAssignStmt * node)1337 _outPLAssignStmt(String * str, PLAssignStmt *node)
1338 {
1339 }
1340
1341 static void
_outColumnDef(String * str,ColumnDef * node)1342 _outColumnDef(String * str, ColumnDef *node)
1343 {
1344 string_append_char(str, "\"");
1345 string_append_char(str, node->colname);
1346 string_append_char(str, "\" ");
1347 _outNode(str, node->typeName);
1348 _outNode(str, node->constraints);
1349 }
1350
1351 static void
_outTypeName(String * str,TypeName * node)1352 _outTypeName(String * str, TypeName *node)
1353 {
1354
1355 /*
1356 * don't quote SystemType name, because 1. char is not "char". 2. in 8.4,
1357 * interval with fields cause error. =# SELECT '1'::"interval" year;
1358 * ERROR: syntax error at or near "year" LINE 1: SELECT '1'::"interval"
1359 * year;
1360 */
1361 if (list_length(node->names) == 2 &&
1362 strcmp("pg_catalog", strVal(linitial(node->names))) == 0)
1363 {
1364 string_append_char(str, strVal(lsecond(node->names)));
1365
1366 if (strcmp("interval", strVal(lsecond(node->names))) == 0)
1367 {
1368 if (node->typmods != NIL)
1369 {
1370 A_Const *v = (A_Const *) linitial(node->typmods);
1371 int mask = v->val.val.ival;
1372
1373 /*
1374 * precision for SECOND field. backward compatibility. use
1375 * `'1.2 second'::interval(0) second' not `'1.2
1376 * second'::interval second(0)'(standard for 8.4).
1377 */
1378 if ((INTERVAL_MASK(SECOND) & mask) &&
1379 list_length(node->typmods) == 2)
1380 {
1381 string_append_char(str, "(");
1382 _outAConst(str, lsecond(node->typmods));
1383 string_append_char(str, ")");
1384 }
1385
1386 /* optional fields */
1387 if (mask == INTERVAL_MASK(YEAR))
1388 string_append_char(str, " YEAR");
1389 else if (mask == INTERVAL_MASK(MONTH))
1390 string_append_char(str, " MONTH");
1391 else if (mask == INTERVAL_MASK(DAY))
1392 string_append_char(str, " DAY");
1393 else if (mask == INTERVAL_MASK(HOUR))
1394 string_append_char(str, " HOUR");
1395 else if (mask == INTERVAL_MASK(MINUTE))
1396 string_append_char(str, " MINUTE");
1397 else if (mask == INTERVAL_MASK(SECOND))
1398 string_append_char(str, " SECOND");
1399 else if (mask == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1400 string_append_char(str, " YEAR TO MONTH");
1401 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR)))
1402 string_append_char(str, " DAY TO HOUR");
1403 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
1404 INTERVAL_MASK(MINUTE)))
1405 string_append_char(str, " DAY TO MINUTE");
1406 else if (mask == (INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
1407 INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND)))
1408 string_append_char(str, " DAY TO SECOND");
1409 else if (mask == (INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE)))
1410 string_append_char(str, " HOUR TO MINUTE");
1411 else if (mask == (INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) |
1412 INTERVAL_MASK(SECOND)))
1413 string_append_char(str, " HOUR TO SECOND");
1414 else if (mask == (INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND)))
1415 string_append_char(str, " MINUTE TO SECOND");
1416 }
1417
1418 return;
1419 }
1420 }
1421 else
1422 {
1423 ListCell *lc;
1424 char dot = 0;
1425
1426 foreach(lc, node->names)
1427 {
1428 Value *v = (Value *) lfirst(lc);
1429 char *typename = v->val.str;
1430
1431 if (dot == 0)
1432 dot = 1;
1433 else
1434 string_append_char(str, ".");
1435 if (node->typemod < 0)
1436 {
1437 string_append_char(str, "\"");
1438 string_append_char(str, typename);
1439 string_append_char(str, "\"");
1440 }
1441 else
1442 string_append_char(str, typename);
1443 }
1444 }
1445
1446 /* precisions */
1447 if (node->typmods)
1448 {
1449 string_append_char(str, "(");
1450 _outList(str, node->typmods);
1451 string_append_char(str, ")");
1452 }
1453
1454 if (node->arrayBounds != NIL)
1455 {
1456 ListCell *lc;
1457
1458 foreach(lc, node->arrayBounds)
1459 {
1460 if (intVal(lfirst(lc)) == -1)
1461 string_append_char(str, "[]");
1462 else
1463 {
1464 string_append_char(str, "[");
1465 _outNode(str, lfirst(lc));
1466 string_append_char(str, "]");
1467 }
1468 }
1469 }
1470 }
1471
1472 static void
_outTypeCast(String * str,TypeCast * node)1473 _outTypeCast(String * str, TypeCast *node)
1474 {
1475 _outNode(str, node->arg);
1476 string_append_char(str, "::");
1477 _outNode(str, node->typeName);
1478
1479 }
1480
1481 static void
_outCollateClause(String * str,const CollateClause * node)1482 _outCollateClause(String * str, const CollateClause *node)
1483 {
1484 if (node->arg)
1485 _outNode(str, node->arg);
1486 string_append_char(str, " COLLATE ");
1487 string_append_char(str, "\"");
1488 string_append_char(str, ((Value *) linitial(node->collname))->val.str);
1489 string_append_char(str, "\"");
1490 }
1491
1492 static void
_outIndexElem(String * str,IndexElem * node)1493 _outIndexElem(String * str, IndexElem *node)
1494 {
1495 if (node->name)
1496 {
1497 string_append_char(str, "\"");
1498 string_append_char(str, node->name);
1499 string_append_char(str, "\"");
1500 if (node->opclass != NIL)
1501 _outNode(str, node->opclass);
1502 }
1503 else
1504 {
1505 string_append_char(str, "(");
1506 _outNode(str, node->expr);
1507 string_append_char(str, ")");
1508 if (node->opclass != NIL)
1509 _outNode(str, node->opclass);
1510 }
1511 }
1512
1513 static void
_outGroupingSet(String * str,GroupingSet * node)1514 _outGroupingSet(String * str, GroupingSet *node)
1515 {
1516 switch (node->kind)
1517 {
1518 case GROUPING_SET_EMPTY:
1519 string_append_char(str, " (");
1520 break;
1521 case GROUPING_SET_ROLLUP:
1522 string_append_char(str, " ROLLUP (");
1523 _outNode(str, node->content);
1524 break;
1525 case GROUPING_SET_CUBE:
1526 string_append_char(str, " CUBE (");
1527 _outNode(str, node->content);
1528 break;
1529 case GROUPING_SET_SETS:
1530 string_append_char(str, " GROUPING SETS (");
1531 _outNode(str, node->content);
1532 break;
1533 default:
1534 break;
1535 }
1536
1537 string_append_char(str, " )");
1538
1539 }
1540
1541 static void
_outWithClause(String * str,WithClause * node)1542 _outWithClause(String * str, WithClause *node)
1543 {
1544 string_append_char(str, " WITH ");
1545 if (node->recursive)
1546 string_append_char(str, "RECURSIVE ");
1547
1548 _outList(str, node->ctes);
1549 }
1550
1551 static void
_outCTESearchClause(String * str,CTESearchClause * node)1552 _outCTESearchClause(String * str, CTESearchClause *node)
1553 {
1554 }
1555
1556 static void
_outCTECycleClause(String * str,CTECycleClause * node)1557 _outCTECycleClause(String * str, CTECycleClause *node)
1558 {
1559 }
1560
1561 static void
_outCommonTableExpr(String * str,CommonTableExpr * node)1562 _outCommonTableExpr(String * str, CommonTableExpr *node)
1563 {
1564 string_append_char(str, "\"");
1565 string_append_char(str, node->ctename);
1566 string_append_char(str, "\" ");
1567
1568 if (node->aliascolnames)
1569 {
1570 string_append_char(str, "(");
1571 _outIdList(str, node->aliascolnames);
1572 string_append_char(str, ") ");
1573 }
1574
1575 string_append_char(str, "AS ");
1576
1577 if (node->ctematerialized & CTEMaterializeAlways)
1578 string_append_char(str, "MATERIALIZED ");
1579 else if (node->ctematerialized & CTEMaterializeNever)
1580 string_append_char(str, "NOT MATERIALIZED ");
1581
1582 string_append_char(str, "(");
1583 _outNode(str, node->ctequery);
1584 string_append_char(str, ")");
1585 }
1586
1587 static void
_outSetOperationStmt(String * str,SetOperationStmt * node)1588 _outSetOperationStmt(String * str, SetOperationStmt *node)
1589 {
1590
1591 }
1592
1593
1594 static void
_outTableSampleClause(String * str,TableSampleClause * node)1595 _outTableSampleClause(String * str, TableSampleClause *node)
1596 {
1597
1598 }
1599
1600 static void
_outAExpr(String * str,A_Expr * node)1601 _outAExpr(String * str, A_Expr *node)
1602 {
1603 Value *v;
1604
1605 switch (node->kind)
1606 {
1607 case AEXPR_OP:
1608 if (list_length(node->name) == 1)
1609 {
1610 Value *op = (Value *) lfirst(list_head(node->name));
1611
1612 string_append_char(str, " (");
1613 _outNode(str, node->lexpr);
1614 string_append_char(str, op->val.str);
1615 _outNode(str, node->rexpr);
1616 string_append_char(str, " )");
1617 }
1618 break;
1619
1620 case AEXPR_OP_ANY:
1621 _outNode(str, node->lexpr);
1622 v = linitial(node->name);
1623 string_append_char(str, v->val.str);
1624 string_append_char(str, "ANY(");
1625 _outNode(str, node->rexpr);
1626 string_append_char(str, ")");
1627 break;
1628
1629 case AEXPR_OP_ALL:
1630 _outNode(str, node->lexpr);
1631 v = linitial(node->name);
1632 string_append_char(str, v->val.str);
1633 string_append_char(str, "ALL(");
1634 _outNode(str, node->rexpr);
1635 string_append_char(str, ")");
1636 break;
1637
1638 case AEXPR_DISTINCT:
1639 string_append_char(str, " (");
1640 _outNode(str, node->lexpr);
1641 string_append_char(str, " IS DISTINCT FROM ");
1642 _outNode(str, node->rexpr);
1643 string_append_char(str, ")");
1644 break;
1645
1646 case AEXPR_NOT_DISTINCT:
1647 string_append_char(str, " (");
1648 _outNode(str, node->lexpr);
1649 string_append_char(str, " IS NOT DISTINCT FROM ");
1650 _outNode(str, node->rexpr);
1651 string_append_char(str, ")");
1652 break;
1653
1654 case AEXPR_NULLIF:
1655 string_append_char(str, " NULLIF(");
1656 _outNode(str, node->lexpr);
1657 string_append_char(str, ", ");
1658 _outNode(str, node->rexpr);
1659 string_append_char(str, ")");
1660 break;
1661
1662 case AEXPR_IN:
1663 _outNode(str, node->lexpr);
1664 v = (Value *) lfirst(list_head(node->name));
1665 if (v->val.str[0] == '=')
1666 string_append_char(str, " IN (");
1667 else
1668 string_append_char(str, " NOT IN (");
1669 _outNode(str, node->rexpr);
1670 string_append_char(str, ")");
1671 break;
1672
1673 case AEXPR_LIKE:
1674 _outNode(str, node->lexpr);
1675 v = (Value *) lfirst(list_head(node->name));
1676 if (!strcmp(v->val.str, "~~"))
1677 string_append_char(str, " LIKE ");
1678 else
1679 string_append_char(str, " NOT LIKE ");
1680 if (IsA(node->rexpr, FuncCall))
1681 {
1682 FuncCall *rexpr = (FuncCall *) node->rexpr;
1683
1684 _outNode(str, linitial(rexpr->args));
1685 string_append_char(str, " ESCAPE ");
1686 _outNode(str, lsecond(rexpr->args));
1687 }
1688 else
1689 _outNode(str, node->rexpr);
1690 break;
1691
1692 case AEXPR_ILIKE:
1693 _outNode(str, node->lexpr);
1694 v = (Value *) lfirst(list_head(node->name));
1695 if (!strcmp(v->val.str, "~~*"))
1696 string_append_char(str, " ILIKE ");
1697 else
1698 string_append_char(str, " NOT ILIKE ");
1699 if (IsA(node->rexpr, FuncCall))
1700 {
1701 FuncCall *rexpr = (FuncCall *) node->rexpr;
1702
1703 _outNode(str, linitial(rexpr->args));
1704 string_append_char(str, " ESCAPE ");
1705 _outNode(str, lsecond(rexpr->args));
1706 }
1707 else
1708 _outNode(str, node->rexpr);
1709 break;
1710
1711 case AEXPR_SIMILAR:
1712 _outNode(str, node->lexpr);
1713 v = (Value *) lfirst(list_head(node->name));
1714 if (!strcmp(v->val.str, "~"))
1715 string_append_char(str, " SIMILAR TO ");
1716 else
1717 string_append_char(str, " NOT SIMILAR TO ");
1718 if (IsA(node->rexpr, FuncCall))
1719 {
1720 FuncCall *rexpr = (FuncCall *) node->rexpr;
1721
1722 _outNode(str, linitial(rexpr->args));
1723 string_append_char(str, " ESCAPE ");
1724 _outNode(str, lsecond(rexpr->args));
1725 }
1726 else
1727 _outNode(str, node->rexpr);
1728 break;
1729
1730 case AEXPR_BETWEEN:
1731 _outNode(str, node->lexpr);
1732 string_append_char(str, " BETWEEN ");
1733 _outNode(str, linitial((List *) node->rexpr));
1734 string_append_char(str, " AND ");
1735 _outNode(str, lsecond((List *) node->rexpr));
1736 break;
1737
1738 case AEXPR_NOT_BETWEEN:
1739 _outNode(str, node->lexpr);
1740 string_append_char(str, " NOT BETWEEN ");
1741 _outNode(str, linitial((List *) node->rexpr));
1742 string_append_char(str, " AND ");
1743 _outNode(str, lsecond((List *) node->rexpr));
1744 break;
1745
1746 case AEXPR_BETWEEN_SYM:
1747 _outNode(str, node->lexpr);
1748 string_append_char(str, " BETWEEN SYMMETRIC ");
1749 _outNode(str, linitial((List *) node->rexpr));
1750 string_append_char(str, " AND ");
1751 _outNode(str, lsecond((List *) node->rexpr));
1752 break;
1753
1754 case AEXPR_NOT_BETWEEN_SYM:
1755 _outNode(str, node->lexpr);
1756 string_append_char(str, " NOT BETWEEN SYMMETRIC ");
1757 _outNode(str, linitial((List *) node->rexpr));
1758 string_append_char(str, " AND ");
1759 _outNode(str, lsecond((List *) node->rexpr));
1760 break;
1761
1762 default:
1763 break;
1764 }
1765 }
1766
1767 /*
1768 * Node types found in raw parse trees (supported for debug purposes)
1769 */
1770
1771 static void
_outRawStmt(String * str,const RawStmt * node)1772 _outRawStmt(String * str, const RawStmt *node)
1773 {
1774 }
1775
1776 static void
_outValue(String * str,Value * value)1777 _outValue(String * str, Value *value)
1778 {
1779 char buf[16];
1780 char *p;
1781
1782 switch (value->type)
1783 {
1784 case T_Integer:
1785 sprintf(buf, "%d", value->val.ival);
1786 string_append_char(str, buf);
1787 break;
1788
1789 case T_Float:
1790 string_append_char(str, value->val.str);
1791 break;
1792
1793 case T_String:
1794 string_append_char(str, "'");
1795 p = escape_string(value->val.str);
1796 string_append_char(str, p);
1797 pfree(p);
1798 string_append_char(str, "'");
1799 break;
1800
1801 case T_Null:
1802 string_append_char(str, "NULL");
1803 break;
1804
1805 default:
1806 break;
1807 }
1808 }
1809
1810 static void
_outColumnRef(String * str,ColumnRef * node)1811 _outColumnRef(String * str, ColumnRef *node)
1812 {
1813 ListCell *c;
1814 char first = 0;
1815
1816 foreach(c, node->fields)
1817 {
1818 Node *n = (Node *) lfirst(c);
1819
1820 if (IsA(n, String))
1821 {
1822 Value *v = (Value *) lfirst(c);
1823
1824 if (first == 0)
1825 first = 1;
1826 else
1827 string_append_char(str, ".");
1828
1829 string_append_char(str, "\"");
1830 string_append_char(str, v->val.str);
1831 string_append_char(str, "\"");
1832 }
1833 else if (IsA(n, A_Star))
1834 {
1835 if (first == 0)
1836 first = 1;
1837 else
1838 string_append_char(str, ".");
1839
1840 string_append_char(str, "*");
1841 }
1842 }
1843 }
1844
1845 static void
_outParamRef(String * str,ParamRef * node)1846 _outParamRef(String * str, ParamRef *node)
1847 {
1848 char buf[16];
1849
1850 snprintf(buf, 16, "%d", node->number);
1851 string_append_char(str, "$");
1852 string_append_char(str, buf);
1853 }
1854
1855 static void
_outAConst(String * str,A_Const * node)1856 _outAConst(String * str, A_Const *node)
1857 {
1858 char buf[16];
1859 char *p;
1860
1861 switch (node->val.type)
1862 {
1863 case T_Integer:
1864 sprintf(buf, "%d", node->val.val.ival);
1865 string_append_char(str, buf);
1866 break;
1867
1868 case T_Float:
1869 string_append_char(str, node->val.val.str);
1870 break;
1871
1872 case T_String:
1873 string_append_char(str, "'");
1874 p = escape_string(node->val.val.str);
1875 string_append_char(str, p);
1876 pfree(p);
1877 string_append_char(str, "'");
1878 break;
1879
1880 case T_Null:
1881 string_append_char(str, "NULL");
1882 break;
1883
1884 default:
1885 break;
1886 }
1887 }
1888
1889 static void
_outA_Indices(String * str,A_Indices * node)1890 _outA_Indices(String * str, A_Indices *node)
1891 {
1892 string_append_char(str, "[");
1893 if (node->lidx)
1894 {
1895 _outNode(str, node->lidx);
1896 string_append_char(str, ":");
1897 }
1898 _outNode(str, node->uidx);
1899 string_append_char(str, "]");
1900 }
1901
1902 static void
_outA_Indirection(String * str,A_Indirection * node)1903 _outA_Indirection(String * str, A_Indirection *node)
1904 {
1905 ListCell *lc;
1906
1907 if (node->indirection != NIL)
1908 {
1909 if (IsA(node->arg, ParamRef))
1910 /* "$1[1]" OR "$1.foo" */
1911 _outParamRef(str, (ParamRef *) node->arg);
1912 else
1913 {
1914 /* "(ARRAY[1])[1]" */
1915 string_append_char(str, "(");
1916 _outNode(str, node->arg);
1917 string_append_char(str, ")");
1918 }
1919
1920 foreach(lc, node->indirection)
1921 {
1922 Node *ind = lfirst(lc);
1923
1924 if (IsA(ind, A_Star))
1925 /* foo.* */
1926 string_append_char(str, ".*");
1927 else if (IsA(ind, String))
1928 {
1929 /* foo.bar */
1930 string_append_char(str, ".\"");
1931 string_append_char(str, strVal(ind));
1932 string_append_char(str, "\"");
1933 }
1934 else
1935 /* foo[1] (A_Indices) */
1936 _outNode(str, ind);
1937 }
1938 }
1939 }
1940
1941 static void
_outA_ArrayExpr(String * str,A_ArrayExpr * node)1942 _outA_ArrayExpr(String * str, A_ArrayExpr *node)
1943 {
1944 string_append_char(str, "ARRAY [");
1945 _outNode(str, node->elements);
1946 string_append_char(str, "]");
1947 }
1948
1949 static void
_outResTarget(String * str,ResTarget * node)1950 _outResTarget(String * str, ResTarget *node)
1951 {
1952 if (node->indirection != NIL)
1953 {
1954 string_append_char(str, "\"");
1955 string_append_char(str, node->name);
1956 string_append_char(str, "\"=");
1957 _outNode(str, node->val);
1958 }
1959 else
1960 {
1961 _outNode(str, node->val);
1962
1963 if (node->name)
1964 {
1965 string_append_char(str, " AS ");
1966 string_append_char(str, "\"");
1967 string_append_char(str, node->name);
1968 string_append_char(str, "\" ");
1969 }
1970 }
1971 }
1972
1973
1974 static void
_outMultiAssignRef(String * str,MultiAssignRef * node)1975 _outMultiAssignRef(String * str, MultiAssignRef *node)
1976 {
1977 _outNode(str, node->source);
1978 }
1979
1980 static void
_outWindowDef(String * str,WindowDef * node)1981 _outWindowDef(String * str, WindowDef *node)
1982 {
1983 if (node->name)
1984 {
1985 string_append_char(str, "\"");
1986 string_append_char(str, node->name);
1987 string_append_char(str, "\" AS ");
1988 }
1989 string_append_char(str, "(");
1990
1991 if (node->refname)
1992 {
1993 string_append_char(str, "\"");
1994 string_append_char(str, node->refname);
1995 string_append_char(str, "\" ");
1996 }
1997
1998 if (node->partitionClause)
1999 {
2000 string_append_char(str, " PARTITION BY ");
2001 _outNode(str, node->partitionClause);
2002 }
2003
2004 if (node->orderClause)
2005 {
2006 string_append_char(str, " ORDER BY ");
2007 _outNode(str, node->orderClause);
2008 }
2009
2010 if (node->frameOptions != FRAMEOPTION_DEFAULTS)
2011 {
2012 if (node->frameOptions & FRAMEOPTION_RANGE)
2013 string_append_char(str, " RANGE");
2014 else if (node->frameOptions & FRAMEOPTION_ROWS)
2015 string_append_char(str, " ROWS");
2016 else if (node->frameOptions & FRAMEOPTION_GROUPS)
2017 string_append_char(str, " GROUPS");
2018
2019 if (node->frameOptions & FRAMEOPTION_BETWEEN)
2020 string_append_char(str, " BETWEEN");
2021
2022 if (node->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)
2023 string_append_char(str, " UNBOUNDED PRECEDING");
2024 else if (node->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
2025 string_append_char(str, " UNBOUNDED FOLLOWING");
2026 else if (node->frameOptions & FRAMEOPTION_START_CURRENT_ROW)
2027 string_append_char(str, " UNBOUNDED CURRENT ROW");
2028 else if (node->frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING)
2029 {
2030 string_append_char(str, " ");
2031 _outNode(str, node->startOffset);
2032 string_append_char(str, " PRECEDING");
2033 }
2034 else if (node->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING)
2035 {
2036 string_append_char(str, " ");
2037 _outNode(str, node->startOffset);
2038 string_append_char(str, " FOLLOWING");
2039 }
2040
2041 if (node->frameOptions & FRAMEOPTION_BETWEEN)
2042 {
2043 string_append_char(str, " AND");
2044 if (node->frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
2045 string_append_char(str, " UNBOUNDED PRECEDING");
2046 else if (node->frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)
2047 string_append_char(str, " UNBOUNDED FOLLOWING");
2048 else if (node->frameOptions & FRAMEOPTION_END_CURRENT_ROW)
2049 string_append_char(str, " UNBOUNDED CURRENT ROW");
2050 else if (node->frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING)
2051 {
2052 string_append_char(str, " ");
2053 _outNode(str, node->endOffset);
2054 string_append_char(str, " PRECEDING");
2055 }
2056 else if (node->frameOptions & FRAMEOPTION_END_OFFSET_FOLLOWING)
2057 {
2058 string_append_char(str, " ");
2059 _outNode(str, node->endOffset);
2060 string_append_char(str, " FOLLOWING");
2061 }
2062 }
2063
2064 if (node->frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW)
2065 {
2066 string_append_char(str, " EXCLUDE CURRENT ROW");
2067 }
2068 else if (node->frameOptions & FRAMEOPTION_EXCLUDE_GROUP)
2069 {
2070 string_append_char(str, " EXCLUDE GROUP");
2071 }
2072 else if (node->frameOptions & FRAMEOPTION_EXCLUDE_TIES)
2073 {
2074 string_append_char(str, " EXCLUDE TIES");
2075 }
2076 }
2077 string_append_char(str, ")");
2078 }
2079
2080 static void
_outConstraint(String * str,Constraint * node)2081 _outConstraint(String * str, Constraint *node)
2082 {
2083 if (node->conname)
2084 {
2085 string_append_char(str, "CONSTRAINT \"");
2086 string_append_char(str, node->conname);
2087 string_append_char(str, "\"");
2088 }
2089
2090 switch (node->contype)
2091 {
2092 case CONSTR_CHECK:
2093 string_append_char(str, " CHECK (");
2094 _outNode(str, node->raw_expr);
2095 string_append_char(str, ")");
2096 break;
2097
2098 case CONSTR_UNIQUE:
2099 string_append_char(str, " UNIQUE");
2100 if (node->keys)
2101 {
2102 string_append_char(str, "(");
2103 _outIdList(str, node->keys);
2104 string_append_char(str, ")");
2105 }
2106
2107 if (node->options)
2108 {
2109 _outWithDefinition(str, node->options);
2110 }
2111
2112 if (node->indexspace)
2113 {
2114 string_append_char(str, " USING INDEX TABLESPACE \"");
2115 string_append_char(str, node->indexspace);
2116 string_append_char(str, "\"");
2117 }
2118 break;
2119
2120 case CONSTR_PRIMARY:
2121 string_append_char(str, " PRIMARY KEY");
2122 if (node->keys)
2123 {
2124 string_append_char(str, "(");
2125 _outIdList(str, node->keys);
2126 string_append_char(str, ")");
2127 }
2128 if (node->options)
2129 ;
2130
2131 if (node->indexspace)
2132 {
2133 string_append_char(str, " USING INDEX TABLESPACE \"");
2134 string_append_char(str, node->indexspace);
2135 string_append_char(str, "\"");
2136 }
2137 break;
2138
2139 case CONSTR_FOREIGN:
2140 if (node->fk_attrs != NIL)
2141 {
2142 string_append_char(str, " FOREIGN KEY(");
2143 _outIdList(str, node->fk_attrs);
2144 string_append_char(str, ")");
2145 }
2146
2147 string_append_char(str, " REFERENCES ");
2148 _outNode(str, node->pktable);
2149
2150 if (node->pk_attrs != NIL)
2151 {
2152 string_append_char(str, "(");
2153 _outIdList(str, node->pk_attrs);
2154 string_append_char(str, ")");
2155 }
2156
2157 switch (node->fk_matchtype)
2158 {
2159 case FKCONSTR_MATCH_FULL:
2160 string_append_char(str, " MATCH FULL");
2161 break;
2162
2163 case FKCONSTR_MATCH_PARTIAL:
2164 string_append_char(str, " MATCH PARTIAL");
2165 break;
2166
2167 default:
2168 break;
2169 }
2170
2171 switch (node->fk_upd_action)
2172 {
2173 case FKCONSTR_ACTION_RESTRICT:
2174 string_append_char(str, " ON UPDATE RESTRICT");
2175 break;
2176
2177 case FKCONSTR_ACTION_CASCADE:
2178 string_append_char(str, " ON UPDATE CASCADE");
2179 break;
2180
2181 case FKCONSTR_ACTION_SETNULL:
2182 string_append_char(str, " ON UPDATE SET NULL");
2183 break;
2184
2185 case FKCONSTR_ACTION_SETDEFAULT:
2186 string_append_char(str, " ON UPDATE SET DEFAULT");
2187 break;
2188
2189 default:
2190 break;
2191 }
2192
2193 switch (node->fk_del_action)
2194 {
2195 case FKCONSTR_ACTION_RESTRICT:
2196 string_append_char(str, " ON DELETE RESTRICT");
2197 break;
2198
2199 case FKCONSTR_ACTION_CASCADE:
2200 string_append_char(str, " ON DELETE CASCADE");
2201 break;
2202
2203 case FKCONSTR_ACTION_SETNULL:
2204 string_append_char(str, " ON DELETE SET NULL");
2205 break;
2206
2207 case FKCONSTR_ACTION_SETDEFAULT:
2208 string_append_char(str, " ON DELETE SET DEFAULT");
2209 break;
2210
2211 default:
2212 break;
2213 }
2214
2215 if (node->deferrable)
2216 string_append_char(str, " DEFERRABLE");
2217
2218 if (node->initdeferred)
2219 string_append_char(str, " INITIALLY DEFERRED");
2220 break;
2221
2222 case CONSTR_NOTNULL:
2223 string_append_char(str, " NOT NULL");
2224 break;
2225
2226 case CONSTR_NULL:
2227 string_append_char(str, " NULL");
2228 break;
2229
2230 case CONSTR_DEFAULT:
2231 string_append_char(str, "DEFAULT ");
2232 _outNode(str, node->raw_expr);
2233 break;
2234
2235 default:
2236 break;
2237 }
2238 }
2239
2240
2241 static void
_outSortBy(String * str,SortBy * node)2242 _outSortBy(String * str, SortBy *node)
2243 {
2244 _outNode(str, node->node);
2245
2246 if (node->sortby_dir == SORTBY_USING)
2247 {
2248 string_append_char(str, " USING ");
2249 _outNode(str, node->useOp);
2250 }
2251 else if (node->sortby_dir == SORTBY_DESC)
2252 string_append_char(str, " DESC ");
2253
2254 if (node->sortby_nulls == SORTBY_NULLS_FIRST)
2255 string_append_char(str, " NULLS FIRST ");
2256 else if (node->sortby_nulls == SORTBY_NULLS_LAST)
2257 string_append_char(str, " NULLS LAST ");
2258 }
2259
2260 static void
_outInsertStmt(String * str,InsertStmt * node)2261 _outInsertStmt(String * str, InsertStmt *node)
2262 {
2263 if (node->withClause)
2264 _outWithClause(str, node->withClause);
2265
2266 string_append_char(str, "INSERT INTO ");
2267 _outNode(str, node->relation);
2268
2269 if (node->cols == NIL && node->selectStmt == NULL)
2270 string_append_char(str, " DEFAULT VALUES");
2271
2272 if (node->cols)
2273 {
2274 char comma = 0;
2275 ListCell *lc;
2276
2277 string_append_char(str, "(");
2278
2279 foreach(lc, node->cols)
2280 {
2281 ResTarget *node = lfirst(lc);
2282 ListCell *lc_ind;
2283
2284 if (comma == 0)
2285 comma = 1;
2286 else
2287 string_append_char(str, ", ");
2288
2289 string_append_char(str, "\"");
2290 string_append_char(str, node->name);
2291 string_append_char(str, "\"");
2292
2293 foreach(lc_ind, node->indirection)
2294 {
2295 Node *ind = lfirst(lc_ind);
2296
2297 if (IsA(ind, String))
2298 {
2299 /* foo.bar */
2300 string_append_char(str, ".\"");
2301 string_append_char(str, strVal(ind));
2302 string_append_char(str, "\"");
2303 }
2304 else
2305 /* foo[1] (A_Indices) */
2306 _outNode(str, ind);
2307 }
2308 }
2309 string_append_char(str, ")");
2310 }
2311
2312 if (node->selectStmt)
2313 {
2314 _outNode(str, node->selectStmt);
2315 }
2316
2317 if (node->onConflictClause)
2318 {
2319 _outOnConflictClause(str, node->onConflictClause);
2320 }
2321
2322 if (node->returningList)
2323 {
2324 string_append_char(str, " RETURNING ");
2325 _outNode(str, node->returningList);
2326 }
2327 }
2328
2329 static void
_outSetClause(String * str,List * node)2330 _outSetClause(String * str, List *node)
2331 {
2332 ListCell *lc;
2333 char comma = 0;
2334
2335 ResTarget *first = linitial(node);
2336
2337 string_append_char(str, " SET ");
2338
2339 if (IsA(first->val, MultiAssignRef))
2340 {
2341 string_append_char(str, "(");
2342 foreach(lc, node)
2343 {
2344 ResTarget *node = lfirst(lc);
2345 ListCell *lc_ind;
2346
2347 if (comma == 0)
2348 comma = 1;
2349 else
2350 string_append_char(str, ", ");
2351
2352 string_append_char(str, "\"");
2353 string_append_char(str, node->name);
2354 string_append_char(str, "\"");
2355
2356 foreach(lc_ind, node->indirection)
2357 {
2358 Node *ind = lfirst(lc_ind);
2359
2360 if (IsA(ind, String))
2361 {
2362 string_append_char(str, ".\"");
2363 string_append_char(str, strVal(ind));
2364 string_append_char(str, "\"");
2365 }
2366 else
2367 /* foo[1] (A_Indices) */
2368 _outNode(str, ind);
2369 }
2370 }
2371 string_append_char(str, ") = ");
2372
2373 _outNode(str, first->val);
2374
2375 }
2376 else
2377 {
2378 foreach(lc, node)
2379 {
2380 ResTarget *node = lfirst(lc);
2381 ListCell *lc_ind;
2382
2383 if (comma == 0)
2384 comma = 1;
2385 else
2386 string_append_char(str, ", ");
2387
2388 string_append_char(str, "\"");
2389 string_append_char(str, node->name);
2390 string_append_char(str, "\"");
2391
2392 foreach(lc_ind, node->indirection)
2393 {
2394 Node *ind = lfirst(lc_ind);
2395
2396 if (IsA(ind, String))
2397 {
2398 string_append_char(str, ".\"");
2399 string_append_char(str, strVal(ind));
2400 string_append_char(str, "\"");
2401 }
2402 else
2403 /* foo[1] (A_Indices) */
2404 _outNode(str, ind);
2405 }
2406
2407 string_append_char(str, " = ");
2408 _outNode(str, node->val);
2409 }
2410 }
2411 }
2412
2413 static void
_outUpdateStmt(String * str,UpdateStmt * node)2414 _outUpdateStmt(String * str, UpdateStmt *node)
2415 {
2416 if (node->withClause)
2417 _outWithClause(str, node->withClause);
2418
2419 string_append_char(str, "UPDATE ");
2420
2421 _outNode(str, node->relation);
2422
2423 _outSetClause(str, node->targetList);
2424
2425 if (node->fromClause)
2426 {
2427 string_append_char(str, " FROM ");
2428 _outNode(str, node->fromClause);
2429 }
2430
2431 if (node->whereClause)
2432 {
2433 string_append_char(str, " WHERE ");
2434 _outNode(str, node->whereClause);
2435 }
2436
2437 if (node->returningList)
2438 {
2439 string_append_char(str, " RETURNING ");
2440 _outNode(str, node->returningList);
2441 }
2442 }
2443
2444 static void
_outDeleteStmt(String * str,DeleteStmt * node)2445 _outDeleteStmt(String * str, DeleteStmt *node)
2446 {
2447 if (node->withClause)
2448 _outWithClause(str, node->withClause);
2449
2450 string_append_char(str, "DELETE FROM ");
2451
2452 _outNode(str, node->relation);
2453
2454 if (node->usingClause)
2455 {
2456 string_append_char(str, " USING ");
2457 _outNode(str, node->usingClause);
2458 }
2459
2460 if (node->whereClause)
2461 {
2462 string_append_char(str, " WHERE ");
2463 _outNode(str, node->whereClause);
2464 }
2465
2466 if (node->returningList)
2467 {
2468 string_append_char(str, " RETURNING ");
2469 _outNode(str, node->returningList);
2470 }
2471 }
2472
2473 static void
_outTransactionStmt(String * str,TransactionStmt * node)2474 _outTransactionStmt(String * str, TransactionStmt *node)
2475 {
2476 switch (node->kind)
2477 {
2478 case TRANS_STMT_BEGIN:
2479 string_append_char(str, "BEGIN ");
2480 break;
2481
2482 case TRANS_STMT_START:
2483 string_append_char(str, "START TRANSACTION ");
2484 break;
2485
2486 case TRANS_STMT_COMMIT:
2487 string_append_char(str, "COMMIT ");
2488 break;
2489
2490 case TRANS_STMT_ROLLBACK:
2491 string_append_char(str, "ABORT ");
2492 break;
2493
2494 case TRANS_STMT_SAVEPOINT:
2495 string_append_char(str, "SAVEPOINT ");
2496 break;
2497
2498 case TRANS_STMT_RELEASE:
2499 string_append_char(str, "RELEASE ");
2500 break;
2501
2502 case TRANS_STMT_ROLLBACK_TO:
2503 string_append_char(str, "ROLLBACK TO ");
2504 break;
2505
2506 case TRANS_STMT_PREPARE:
2507 string_append_char(str, "PREPARE TRANSACTION ");
2508 break;
2509
2510 case TRANS_STMT_COMMIT_PREPARED:
2511 string_append_char(str, "COMMIT PREPARED ");
2512 break;
2513
2514 case TRANS_STMT_ROLLBACK_PREPARED:
2515 string_append_char(str, "ROLLBACK PREPARED ");
2516 break;
2517
2518 default:
2519 break;
2520 }
2521
2522 if (node->options)
2523 _outSetTransactionModeList(str, node->options);
2524
2525 if (node->gid)
2526 string_append_char(str, node->gid);
2527 }
2528
2529
2530 static void
_outTruncateStmt(String * str,TruncateStmt * node)2531 _outTruncateStmt(String * str, TruncateStmt *node)
2532 {
2533 string_append_char(str, "TRUNCATE ");
2534 _outNode(str, node->relations);
2535 }
2536
2537 static void
_outVacuumStmt(String * str,VacuumStmt * node)2538 _outVacuumStmt(String * str, VacuumStmt *node)
2539 {
2540
2541 VacuumParams params;
2542 params.options = node->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE;
2543
2544 if (params.options & VACOPT_VACUUM)
2545 string_append_char(str, "VACUUM ");
2546 else
2547 string_append_char(str, "ANALYZE ");
2548
2549 if (params.options & VACOPT_FULL)
2550 string_append_char(str, "FULL ");
2551
2552 if (params.options & VACOPT_FREEZE)
2553 string_append_char(str, "FREEZE ");
2554
2555 if (params.options & VACOPT_VERBOSE)
2556 string_append_char(str, "VERBOSE ");
2557
2558 if (params.options & VACOPT_VACUUM && params.options & VACOPT_ANALYZE)
2559 string_append_char(str, "ANALYZE ");
2560
2561 if (params.options & VACOPT_DISABLE_PAGE_SKIPPING)
2562 string_append_char(str, "DISABLE_PAGE_SKIPPING ");
2563
2564 if (params.options & VACOPT_SKIP_LOCKED)
2565 string_append_char(str, "SKIP_LOCKED ");
2566
2567 ListCell *lc;
2568 foreach(lc, node->rels)
2569 {
2570 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);
2571
2572 _outNode(str, vrel->relation);
2573 if (vrel->va_cols)
2574 {
2575 string_append_char(str, "(");
2576 _outIdList(str, vrel->va_cols);
2577 string_append_char(str, ") ");
2578 }
2579 }
2580 }
2581
2582 static void
_outExplainStmt(String * str,ExplainStmt * node)2583 _outExplainStmt(String * str, ExplainStmt *node)
2584 {
2585 ListCell *lc;
2586
2587 string_append_char(str, "EXPLAIN ");
2588
2589 if (server_version_num < 90000)
2590 {
2591 foreach(lc, node->options)
2592 {
2593 DefElem *opt = (DefElem *) lfirst(lc);
2594
2595 if (strcmp(opt->defname, "analyze") == 0)
2596 string_append_char(str, "ANALYZE ");
2597 else if (strcmp(opt->defname, "verbose") == 0)
2598 string_append_char(str, "VERBOSE ");
2599 }
2600 }
2601 else
2602 {
2603 if (node->options)
2604 {
2605 string_append_char(str, "(");
2606 foreach(lc, node->options)
2607 {
2608 DefElem *opt = (DefElem *) lfirst(lc);
2609
2610 if (list_head(node->options) != lc)
2611 string_append_char(str, ", ");
2612
2613 string_append_char(str, opt->defname);
2614 string_append_char(str, " ");
2615 if (opt->arg)
2616 _outValue(str, (Value *) opt->arg);
2617 }
2618 string_append_char(str, ")");
2619 }
2620 }
2621
2622 _outNode(str, node->query);
2623 }
2624
2625 static void
_outClusterStmt(String * str,ClusterStmt * node)2626 _outClusterStmt(String * str, ClusterStmt *node)
2627 {
2628 string_append_char(str, "CLUSTER ");
2629
2630 if (node->indexname)
2631 {
2632 string_append_char(str, "\"");
2633 string_append_char(str, node->indexname);
2634 string_append_char(str, "\" ON ");
2635 }
2636 if (node->relation)
2637 _outNode(str, node->relation);
2638 }
2639
2640 static void
_outCheckPointStmt(String * str,CheckPointStmt * node)2641 _outCheckPointStmt(String * str, CheckPointStmt *node)
2642 {
2643 string_append_char(str, "CHECKPOINT");
2644 }
2645
2646 static void
_outClosePortalStmt(String * str,ClosePortalStmt * node)2647 _outClosePortalStmt(String * str, ClosePortalStmt *node)
2648 {
2649 string_append_char(str, "CLOSE ");
2650 string_append_char(str, "\"");
2651 string_append_char(str, node->portalname);
2652 string_append_char(str, "\"");
2653 }
2654
2655 static void
_outListenStmt(String * str,ListenStmt * node)2656 _outListenStmt(String * str, ListenStmt *node)
2657 {
2658 string_append_char(str, "LISTEN ");
2659 string_append_char(str, "\"");
2660 string_append_char(str, node->conditionname);
2661 string_append_char(str, "\"");
2662 }
2663
2664 static void
_outUnlistenStmt(String * str,UnlistenStmt * node)2665 _outUnlistenStmt(String * str, UnlistenStmt *node)
2666 {
2667 string_append_char(str, "UNLISTEN ");
2668 if (node->conditionname == NULL)
2669 string_append_char(str, "*");
2670 else
2671 {
2672 string_append_char(str, "\"");
2673 string_append_char(str, node->conditionname);
2674 string_append_char(str, "\"");
2675 }
2676 }
2677
2678 static void
_outLoadStmt(String * str,LoadStmt * node)2679 _outLoadStmt(String * str, LoadStmt *node)
2680 {
2681 string_append_char(str, "LOAD '");
2682 string_append_char(str, node->filename);
2683 string_append_char(str, "'");
2684 }
2685
2686 static void
_outCopyStmt(String * str,CopyStmt * node)2687 _outCopyStmt(String * str, CopyStmt *node)
2688 {
2689 ListCell *lc;
2690
2691 string_append_char(str, "COPY ");
2692
2693 if (node->query)
2694 {
2695 string_append_char(str, "(");
2696 _outNode(str, node->query);
2697 string_append_char(str, ")");
2698 }
2699
2700 _outNode(str, node->relation);
2701
2702 if (node->attlist)
2703 {
2704 string_append_char(str, "(");
2705 _outIdList(str, node->attlist);
2706 string_append_char(str, ")");
2707 }
2708
2709 if (node->is_from == TRUE)
2710 string_append_char(str, " FROM ");
2711 else
2712 string_append_char(str, " TO ");
2713
2714 if (node->filename)
2715 {
2716 string_append_char(str, "'");
2717 string_append_char(str, node->filename);
2718 string_append_char(str, "' ");
2719 }
2720 else
2721 string_append_char(str, node->is_from == TRUE ? "STDIN " : "STDOUT ");
2722
2723 if (server_version_num < 90000)
2724 {
2725 foreach(lc, node->options)
2726 {
2727 DefElem *e = lfirst(lc);
2728
2729 if (strcmp(e->defname, "format") == 0)
2730 {
2731 char *fmt = strVal(e->arg);
2732
2733 if (strcmp(fmt, "text") == 0)
2734 ;
2735 else if (strcmp(fmt, "binary") == 0)
2736 string_append_char(str, "BINARY ");
2737 else if (strcmp(fmt, "csv") == 0)
2738 string_append_char(str, "CSV ");
2739 }
2740 else if (strcmp(e->defname, "oids") == 0)
2741 string_append_char(str, "OIDS ");
2742 else if (strcmp(e->defname, "delimiter") == 0)
2743 {
2744 string_append_char(str, "DELIMITERS ");
2745 _outValue(str, (Value *) e->arg);
2746 string_append_char(str, " ");
2747 }
2748 else if (strcmp(e->defname, "null") == 0)
2749 {
2750 string_append_char(str, "NULL ");
2751 _outValue(str, (Value *) e->arg);
2752 string_append_char(str, " ");
2753 }
2754 else if (strcmp(e->defname, "header") == 0)
2755 string_append_char(str, "HEADER ");
2756 else if (strcmp(e->defname, "quote") == 0)
2757 {
2758 string_append_char(str, "QUOTE ");
2759 _outValue(str, (Value *) e->arg);
2760 string_append_char(str, " ");
2761 }
2762 else if (strcmp(e->defname, "escape") == 0)
2763 {
2764 string_append_char(str, "ESCAPE ");
2765 _outValue(str, (Value *) e->arg);
2766 string_append_char(str, " ");
2767 }
2768 else if (strcmp(e->defname, "force_quote") == 0)
2769 {
2770 string_append_char(str, "FORCE QUOTE ");
2771 _outIdList(str, (List *) e->arg);
2772 }
2773 else if (strcmp(e->defname, "force_not_null") == 0)
2774 {
2775 string_append_char(str, "FORCE NOT NULL ");
2776 _outIdList(str, (List *) e->arg);
2777 }
2778 }
2779 }
2780 else
2781 {
2782 /* version_num >= 90000 */
2783 if (node->options)
2784 {
2785 string_append_char(str, "(");
2786
2787 foreach(lc, node->options)
2788 {
2789 DefElem *e = lfirst(lc);
2790
2791 if (list_head(node->options) != lc)
2792 string_append_char(str, ", ");
2793
2794 string_append_char(str, e->defname);
2795 string_append_char(str, " ");
2796
2797 if (strcmp(e->defname, "format") == 0
2798 || strcmp(e->defname, "oids") == 0
2799 || strcmp(e->defname, "delimiter") == 0
2800 || strcmp(e->defname, "null") == 0
2801 || strcmp(e->defname, "header") == 0
2802 || strcmp(e->defname, "quote") == 0
2803 || strcmp(e->defname, "escape") == 0)
2804 _outValue(str, (Value *) e->arg);
2805 else if (strcmp(e->defname, "force_not_null") == 0)
2806 {
2807 string_append_char(str, "(");
2808 _outIdList(str, (List *) e->arg);
2809 string_append_char(str, ")");
2810 }
2811 else if (strcmp(e->defname, "force_quote") == 0)
2812 {
2813 if (IsA(e->arg, A_Star))
2814 string_append_char(str, "*");
2815 else if (IsA(e->arg, List))
2816 {
2817 string_append_char(str, "(");
2818 _outIdList(str, (List *) e->arg);
2819 string_append_char(str, ")");
2820 }
2821 }
2822 }
2823 string_append_char(str, ")");
2824 }
2825 }
2826
2827 if (node->whereClause)
2828 {
2829 string_append_char(str, " WHERE ");
2830 _outNode(str, node->whereClause);
2831 }
2832 }
2833
2834 static void
_outDeallocateStmt(String * str,DeallocateStmt * node)2835 _outDeallocateStmt(String * str, DeallocateStmt *node)
2836 {
2837 string_append_char(str, "DEALLOCATE \"");
2838 string_append_char(str, node->name);
2839 string_append_char(str, "\"");
2840 }
2841
2842 static void
_outRenameStmt(String * str,RenameStmt * node)2843 _outRenameStmt(String * str, RenameStmt *node)
2844 {
2845 ListCell *lc;
2846 char comma = 0;
2847
2848 string_append_char(str, "ALTER ");
2849
2850 switch (node->renameType)
2851 {
2852 case OBJECT_AGGREGATE:
2853 string_append_char(str, "AGGREGATE ");
2854 _outNode(str, node->object);
2855 string_append_char(str, " (");
2856 string_append_char(str, ") RENAME TO \"");
2857 string_append_char(str, node->newname);
2858 string_append_char(str, "\"");
2859 break;
2860
2861 case OBJECT_CONVERSION:
2862 string_append_char(str, "CONVERSION ");
2863 _outNode(str, node->object);
2864 string_append_char(str, " RENAME TO \"");
2865 string_append_char(str, node->newname);
2866 string_append_char(str, "\"");
2867 break;
2868
2869 case OBJECT_DATABASE:
2870 string_append_char(str, "DATABASE \"");
2871 string_append_char(str, node->subname);
2872 string_append_char(str, "\" RENAME TO \"");
2873 string_append_char(str, node->newname);
2874 string_append_char(str, "\"");
2875 break;
2876
2877 case OBJECT_FUNCTION:
2878 string_append_char(str, "FUNCTION ");
2879
2880 foreach(lc, castNode(List, node->object))
2881 {
2882 Node *n = lfirst(lc);
2883
2884 if (IsA(n, String))
2885 {
2886 Value *value = (Value *) n;
2887
2888 if (comma == 0)
2889 comma = 1;
2890 else
2891 string_append_char(str, ".");
2892 string_append_char(str, "\"");
2893 string_append_char(str, value->val.str);
2894 string_append_char(str, "\"");
2895 }
2896 else
2897 _outNode(str, n);
2898 }
2899
2900 string_append_char(str, "(");
2901 string_append_char(str, ")");
2902 string_append_char(str, " RENAME TO \"");
2903 string_append_char(str, node->newname);
2904 string_append_char(str, "\"");
2905 break;
2906
2907 case OBJECT_ROLE:
2908 string_append_char(str, "ROLE \"");
2909 string_append_char(str, node->subname);
2910 string_append_char(str, "\" RENAME TO \"");
2911 string_append_char(str, node->newname);
2912 string_append_char(str, "\"");
2913 break;
2914
2915 case OBJECT_LANGUAGE:
2916 string_append_char(str, "LANGUAGE \"");
2917 string_append_char(str, node->subname);
2918 string_append_char(str, "\" RENAME TO \"");
2919 string_append_char(str, node->newname);
2920 string_append_char(str, "\"");
2921 break;
2922
2923 case OBJECT_OPCLASS:
2924 string_append_char(str, "OPERATOR CLASS ");
2925 _outNode(str, node->object);
2926 string_append_char(str, " USING ");
2927 string_append_char(str, node->subname);
2928 string_append_char(str, " RENAME TO \"");
2929 string_append_char(str, node->newname);
2930 string_append_char(str, "\"");
2931 break;
2932
2933 case OBJECT_SCHEMA:
2934 string_append_char(str, "SCHEMA \"");
2935 string_append_char(str, node->subname);
2936 string_append_char(str, "\" RENAME TO \"");
2937 string_append_char(str, node->newname);
2938 string_append_char(str, "\"");
2939 break;
2940
2941 case OBJECT_TABLE:
2942 string_append_char(str, "TABLE ");
2943 _outNode(str, node->relation);
2944 string_append_char(str, " RENAME TO \"");
2945 string_append_char(str, node->newname);
2946 string_append_char(str, "\"");
2947 break;
2948
2949 case OBJECT_INDEX:
2950 string_append_char(str, "INDEX ");
2951 _outNode(str, node->relation);
2952 string_append_char(str, " RENAME TO \"");
2953 string_append_char(str, node->newname);
2954 string_append_char(str, "\"");
2955 break;
2956
2957 case OBJECT_COLUMN:
2958 string_append_char(str, "TABLE ");
2959 _outNode(str, node->relation);
2960 string_append_char(str, " RENAME \"");
2961 string_append_char(str, node->subname);
2962 string_append_char(str, "\" TO \"");
2963 string_append_char(str, node->newname);
2964 string_append_char(str, "\"");
2965 break;
2966
2967 case OBJECT_TRIGGER:
2968 string_append_char(str, "TRIGGER \"");
2969 string_append_char(str, node->subname);
2970 string_append_char(str, "\" ON ");
2971 _outNode(str, node->relation);
2972 string_append_char(str, " RENAME TO \"");
2973 string_append_char(str, node->newname);
2974 string_append_char(str, "\"");
2975 break;
2976
2977 case OBJECT_TABLESPACE:
2978 string_append_char(str, "TABLESPACE \"");
2979 string_append_char(str, node->subname);
2980 string_append_char(str, "\" RENAME TO \"");
2981 string_append_char(str, node->newname);
2982 string_append_char(str, "\"");
2983 break;
2984
2985 default:
2986 break;
2987 }
2988 }
2989
2990 static void
_outOptRoleList(String * str,List * options)2991 _outOptRoleList(String * str, List *options)
2992 {
2993 ListCell *lc;
2994
2995 foreach(lc, options)
2996 {
2997 DefElem *elem = lfirst(lc);
2998 Value *value = (Value *) elem->arg;
2999
3000 if (strcmp(elem->defname, "password") == 0)
3001 {
3002 if (value == NULL)
3003 string_append_char(str, " PASSWORD NULL");
3004 else
3005 {
3006 string_append_char(str, " PASSWORD '");
3007 string_append_char(str, value->val.str);
3008 string_append_char(str, "'");
3009 }
3010 }
3011 else if (strcmp(elem->defname, "encryptedPassword") == 0)
3012 {
3013 string_append_char(str, " ENCRYPTED PASSWORD '");
3014 string_append_char(str, value->val.str);
3015 string_append_char(str, "'");
3016 }
3017 else if (strcmp(elem->defname, "unencryptedPassword") == 0)
3018 {
3019 string_append_char(str, " UNENCRYPTED PASSWORD '");
3020 string_append_char(str, value->val.str);
3021 string_append_char(str, "'");
3022 }
3023 else if (strcmp(elem->defname, "superuser") == 0)
3024 {
3025 if (value->val.ival == TRUE)
3026 string_append_char(str, " SUPERUSER");
3027 else
3028 string_append_char(str, " NOSUPERUSER");
3029 }
3030 else if (strcmp(elem->defname, "inherit") == 0)
3031 {
3032 if (value->val.ival == TRUE)
3033 string_append_char(str, " INHERIT");
3034 else
3035 string_append_char(str, " NOINHERIT");
3036 }
3037 else if (strcmp(elem->defname, "createdb") == 0)
3038 {
3039 if (value->val.ival == TRUE)
3040 string_append_char(str, " CREATEDB");
3041 else
3042 string_append_char(str, " NOCREATEDB");
3043 }
3044 else if (strcmp(elem->defname, "createrole") == 0)
3045 {
3046 if (value->val.ival == TRUE)
3047 string_append_char(str, " CREATEROLE");
3048 else
3049 string_append_char(str, " NOCREATEROLE");
3050 }
3051 else if (strcmp(elem->defname, "canlogin") == 0)
3052 {
3053 if (value->val.ival == TRUE)
3054 string_append_char(str, " LOGIN");
3055 else
3056 string_append_char(str, " NOLOGIN");
3057 }
3058 else if (strcmp(elem->defname, "connectionlimit") == 0)
3059 {
3060 char buf[16];
3061
3062 string_append_char(str, " CONNECTION LIMIT ");
3063 snprintf(buf, 16, "%d", value->val.ival);
3064 string_append_char(str, buf);
3065 }
3066 else if (strcmp(elem->defname, "validUntil") == 0)
3067 {
3068 string_append_char(str, " VALID UNTIL '");
3069 string_append_char(str, value->val.str);
3070 string_append_char(str, "'");
3071 }
3072 else if (strcmp(elem->defname, "rolemembers") == 0)
3073 {
3074 string_append_char(str, " ROLE ");
3075 _outIdList(str, (List *) elem->arg);
3076 }
3077 else if (strcmp(elem->defname, "sysid") == 0)
3078 {
3079 char buf[16];
3080
3081 string_append_char(str, " SYSID ");
3082 snprintf(buf, 16, "%d", value->val.ival);
3083 string_append_char(str, buf);
3084 }
3085 else if (strcmp(elem->defname, "adminmembers") == 0)
3086 {
3087 string_append_char(str, " ADMIN ");
3088 _outIdList(str, (List *) elem->arg);
3089 }
3090 else if (strcmp(elem->defname, "addroleto") == 0)
3091 {
3092 string_append_char(str, " IN ROLE ");
3093 _outIdList(str, (List *) elem->arg);
3094 }
3095 }
3096 }
3097
3098 static void
_outCreateRoleStmt(String * str,CreateRoleStmt * node)3099 _outCreateRoleStmt(String * str, CreateRoleStmt *node)
3100 {
3101 string_append_char(str, "CREATE ");
3102 switch (node->stmt_type)
3103 {
3104 case ROLESTMT_ROLE:
3105 string_append_char(str, "ROLE \"");
3106 break;
3107
3108 case ROLESTMT_USER:
3109 string_append_char(str, "USER \"");
3110 break;
3111
3112 case ROLESTMT_GROUP:
3113 string_append_char(str, "GROUP \"");
3114 break;
3115 }
3116 _outNode(str, node->role);
3117 string_append_char(str, "\"");
3118
3119 _outOptRoleList(str, node->options);
3120 }
3121
3122 static void
_outAlterRoleStmt(String * str,AlterRoleStmt * node)3123 _outAlterRoleStmt(String * str, AlterRoleStmt *node)
3124 {
3125 string_append_char(str, "ALTER ROLE \"");
3126 _outNode(str, node->role);
3127 string_append_char(str, "\"");
3128
3129 if (node->options)
3130 _outOptRoleList(str, node->options);
3131 }
3132
3133 static void
_outAlterRoleSetStmt(String * str,AlterRoleSetStmt * node)3134 _outAlterRoleSetStmt(String * str, AlterRoleSetStmt *node)
3135 {
3136 string_append_char(str, "ALTER ROLE \"");
3137 _outNode(str, node->role);
3138 string_append_char(str, "\" ");
3139
3140 if (node->setstmt)
3141 {
3142 _outNode(str, node->setstmt);
3143 }
3144 }
3145 static void
_outRoleSpec(String * str,RoleSpec * node)3146 _outRoleSpec(String * str, RoleSpec *node)
3147 {
3148 string_append_char(str, node->rolename);
3149 }
3150
3151 static void
_outSetTransactionModeList(String * str,List * list)3152 _outSetTransactionModeList(String * str, List *list)
3153 {
3154 ListCell *lc;
3155 char comma = 0;
3156
3157 foreach(lc, list)
3158 {
3159 DefElem *elem = lfirst(lc);
3160
3161 if (comma == 0)
3162 comma = 1;
3163 else
3164 string_append_char(str, ",");
3165
3166 if (strcmp(elem->defname, "transaction_isolation") == 0)
3167 {
3168 A_Const *v = (A_Const *) elem->arg;
3169
3170 string_append_char(str, " ISOLATION LEVEL ");
3171 string_append_char(str, v->val.val.str);
3172 }
3173 else if (strcmp(elem->defname, "transaction_read_only") == 0)
3174 {
3175 A_Const *n = (A_Const *) elem->arg;
3176
3177 if (n->val.val.ival == TRUE)
3178 string_append_char(str, "READ ONLY ");
3179 else
3180 string_append_char(str, "READ WRITE ");
3181 }
3182 }
3183 }
3184
3185
3186 static void
_outSetRest(String * str,VariableSetStmt * node)3187 _outSetRest(String * str, VariableSetStmt *node)
3188 {
3189 if (strcmp(node->name, "timezone") == 0)
3190 {
3191 string_append_char(str, "TIME ZONE ");
3192 if (node->kind != VAR_RESET)
3193 _outNode(str, node->args);
3194 }
3195 else if (strcmp(node->name, "TRANSACTION") == 0)
3196 {
3197 string_append_char(str, "TRANSACTION ");
3198 _outSetTransactionModeList(str, node->args);
3199 }
3200 else if (strcmp(node->name, "SESSION CHARACTERISTICS") == 0)
3201 {
3202 string_append_char(str, "SESSION CHARACTERISTICS AS TRANSACTION ");
3203 _outSetTransactionModeList(str, node->args);
3204 }
3205 else if (strcmp(node->name, "role") == 0)
3206 {
3207 string_append_char(str, "ROLE ");
3208 if (node->kind != VAR_RESET)
3209 _outNode(str, node->args);
3210 }
3211 else if (strcmp(node->name, "session_authorization") == 0)
3212 {
3213 string_append_char(str, "SESSION AUTHORIZATION ");
3214 if (node->args == NIL && node->kind != VAR_RESET)
3215 string_append_char(str, "DEFAULT");
3216 else
3217 _outNode(str, node->args);
3218 }
3219 else if (strcmp(node->name, "transaction_isolation") == 0)
3220 {
3221 string_append_char(str, "TRANSACTION ISOLATION LEVEL");
3222 if (node->kind != VAR_RESET)
3223 _outSetTransactionModeList(str, node->args);
3224 }
3225 else if (strcmp(node->name, "xmloption") == 0)
3226 {
3227 A_Const *v = linitial(node->args);
3228
3229 string_append_char(str, "XML OPTION ");
3230 string_append_char(str, v->val.val.str);
3231 }
3232 else
3233 {
3234 string_append_char(str, node->name);
3235 if (node->kind != VAR_RESET)
3236 {
3237 if (node->kind == VAR_SET_CURRENT)
3238 {
3239 string_append_char(str, " FROM CURRENT");
3240 }
3241 else
3242 {
3243 string_append_char(str, " TO ");
3244 if (node->args == NULL)
3245 {
3246 string_append_char(str, "DEFAULT");
3247 }
3248 else
3249 _outNode(str, node->args);
3250 }
3251 }
3252 }
3253 }
3254
3255 static void
_outDropRoleStmt(String * str,DropRoleStmt * node)3256 _outDropRoleStmt(String * str, DropRoleStmt *node)
3257 {
3258 string_append_char(str, "DROP ROLE ");
3259 if (node->missing_ok == TRUE)
3260 string_append_char(str, "IF EXISTS ");
3261 _outIdList(str, node->roles);
3262 }
3263
3264 static void
_outCreateSchemaStmt(String * str,CreateSchemaStmt * node)3265 _outCreateSchemaStmt(String * str, CreateSchemaStmt *node)
3266 {
3267 string_append_char(str, "CREATE SCHEMA \"");
3268 string_append_char(str, node->schemaname);
3269 string_append_char(str, "\"");
3270 if (node->authrole)
3271 {
3272 string_append_char(str, "AUTHORIZATION \"");
3273 _outNode(str, node->authrole);
3274 string_append_char(str, "\" ");
3275 }
3276 _outNode(str, node->schemaElts);
3277 }
3278
3279 static void
_outVariableSetStmt(String * str,VariableSetStmt * node)3280 _outVariableSetStmt(String * str, VariableSetStmt *node)
3281 {
3282 if (node->kind == VAR_RESET_ALL)
3283 {
3284 string_append_char(str, "RESET ALL");
3285 return;
3286 }
3287
3288 if (node->kind == VAR_RESET)
3289 string_append_char(str, "RESET ");
3290 else
3291 string_append_char(str, "SET ");
3292
3293 if (node->is_local)
3294 string_append_char(str, "LOCAL ");
3295
3296 _outSetRest(str, node);
3297 }
3298
3299 static void
_outVariableShowStmt(String * str,VariableShowStmt * node)3300 _outVariableShowStmt(String * str, VariableShowStmt *node)
3301 {
3302 if (strcmp(node->name, "timezone") == 0)
3303 string_append_char(str, "SHOW TIME ZONE");
3304 else if (strcmp(node->name, "transaction_isolation") == 0)
3305 string_append_char(str, "SHOW TRANSACTION ISOLATION LEVEL");
3306 else if (strcmp(node->name, "session_authorization") == 0)
3307 string_append_char(str, "SHOW SESSION AUTHORIZATION");
3308 else if (strcmp(node->name, "all") == 0)
3309 string_append_char(str, "SHOW ALL");
3310 else
3311 {
3312 string_append_char(str, "SHOW ");
3313 string_append_char(str, node->name);
3314 }
3315 }
3316
3317 static void
_outConstraintsSetStmt(String * str,ConstraintsSetStmt * node)3318 _outConstraintsSetStmt(String * str, ConstraintsSetStmt *node)
3319 {
3320 string_append_char(str, "SET CONSTRAINTS ");
3321
3322 if (node->constraints == NIL)
3323 string_append_char(str, "ALL");
3324 else
3325 _outNode(str, node->constraints);
3326
3327 string_append_char(str, node->deferred == TRUE ? " DEFERRED" : " IMMEDIATE");
3328 }
3329
3330 static void
_outAlterTableCmd(String * str,AlterTableCmd * node)3331 _outAlterTableCmd(String * str, AlterTableCmd *node)
3332 {
3333 char buf[16];
3334
3335 switch (node->subtype)
3336 {
3337 case AT_AddColumn:
3338 string_append_char(str, "ADD ");
3339 _outNode(str, node->def);
3340 break;
3341
3342 case AT_ColumnDefault:
3343 string_append_char(str, "ALTER \"");
3344 string_append_char(str, node->name);
3345 string_append_char(str, "\" ");
3346 if (node->def == NULL)
3347 string_append_char(str, "DROP DEFAULT");
3348 else
3349 {
3350 string_append_char(str, "SET DEFAULT ");
3351 _outNode(str, node->def);
3352 }
3353 break;
3354
3355 case AT_DropNotNull:
3356 string_append_char(str, "ALTER \"");
3357 string_append_char(str, node->name);
3358 string_append_char(str, "\" DROP NOT NULL");
3359 break;
3360
3361 case AT_SetNotNull:
3362 string_append_char(str, "ALTER \"");
3363 string_append_char(str, node->name);
3364 string_append_char(str, "\" SET NOT NULL");
3365 break;
3366
3367 case AT_SetStatistics:
3368 string_append_char(str, "ALTER \"");
3369 string_append_char(str, node->name);
3370 string_append_char(str, "\" SET STATISTICS ");
3371 snprintf(buf, 16, "%d", ((Value *) node->def)->val.ival);
3372 string_append_char(str, buf);
3373 break;
3374
3375 case AT_SetStorage:
3376 string_append_char(str, "ALTER \"");
3377 string_append_char(str, node->name);
3378 string_append_char(str, "\" SET STORAGE ");
3379 string_append_char(str, ((Value *) node->def)->val.str);
3380 break;
3381
3382 case AT_DropColumn:
3383 string_append_char(str, "DROP \"");
3384 string_append_char(str, node->name);
3385 string_append_char(str, "\" ");
3386 if (node->behavior == DROP_CASCADE)
3387 string_append_char(str, "CASCADE");
3388 break;
3389
3390 case AT_AlterColumnType:
3391 string_append_char(str, "ALTER \"");
3392 string_append_char(str, node->name);
3393 string_append_char(str, "\" TYPE ");
3394 _outNode(str, node->def);
3395 break;
3396
3397 case AT_AddConstraint:
3398 string_append_char(str, "ADD ");
3399 _outNode(str, node->def);
3400 break;
3401
3402 case AT_DropConstraint:
3403 string_append_char(str, "DROP CONSTRAINT \"");
3404 string_append_char(str, node->name);
3405 string_append_char(str, "\"");
3406 if (node->behavior == DROP_CASCADE)
3407 string_append_char(str, " CASCADE");
3408 break;
3409
3410 case AT_DropOids:
3411 string_append_char(str, "SET WITHOUT OIDS");
3412 break;
3413
3414 case AT_ClusterOn:
3415 string_append_char(str, "CLUSTER ON \"");
3416 string_append_char(str, node->name);
3417 string_append_char(str, "\"");
3418 break;
3419
3420 case AT_DropCluster:
3421 string_append_char(str, "SET WITHOUT CLUSTER");
3422 break;
3423
3424 case AT_EnableTrig:
3425 string_append_char(str, "ENABLE TRIGGER \"");
3426 string_append_char(str, node->name);
3427 string_append_char(str, "\"");
3428 break;
3429
3430 case AT_EnableAlwaysTrig:
3431 /* not implemented */
3432 break;
3433
3434 case AT_EnableReplicaTrig:
3435 /* not implemented */
3436 break;
3437
3438 case AT_EnableTrigAll:
3439 string_append_char(str, "ENABLE TRIGGER ALL");
3440 break;
3441
3442 case AT_EnableTrigUser:
3443 string_append_char(str, "ENABLE TRIGGER USER");
3444 break;
3445
3446 case AT_DisableTrig:
3447 string_append_char(str, "DISABLE TRIGGER \"");
3448 string_append_char(str, node->name);
3449 string_append_char(str, "\"");
3450 break;
3451
3452 case AT_DisableTrigAll:
3453 string_append_char(str, "DISABLE TRIGGER ALL");
3454 break;
3455
3456 case AT_DisableTrigUser:
3457 string_append_char(str, "DISABLE TRIGGER USER");
3458 break;
3459
3460 case AT_EnableRule:
3461 /* not implemented */
3462 break;
3463
3464 case AT_EnableReplicaRule:
3465 /* not implemented */
3466 break;
3467
3468 case AT_EnableAlwaysRule:
3469 /* not implemented */
3470 break;
3471
3472 case AT_DisableRule:
3473 /* not implemented */
3474 break;
3475
3476 case AT_AddInherit:
3477 /* not implemented */
3478 break;
3479
3480 case AT_ChangeOwner:
3481 string_append_char(str, "OWNER TO \"");
3482 string_append_char(str, node->name);
3483 string_append_char(str, "\"");
3484 break;
3485
3486 case AT_SetTableSpace:
3487 string_append_char(str, "SET TABLESPACE \"");
3488 string_append_char(str, node->name);
3489 string_append_char(str, "\"");
3490 break;
3491
3492 case AT_SetRelOptions:
3493 /* not implemented */
3494 break;
3495
3496 case AT_ResetRelOptions:
3497 /* not implemented */
3498 break;
3499
3500 default:
3501 break;
3502 }
3503 }
3504
3505 static void
_outAlterTableStmt(String * str,AlterTableStmt * node)3506 _outAlterTableStmt(String * str, AlterTableStmt *node)
3507 {
3508 if (node->objtype == OBJECT_TABLE)
3509 string_append_char(str, "ALTER TABLE ");
3510 else
3511 string_append_char(str, "ALTER INDEX ");
3512
3513 _outNode(str, node->relation);
3514 string_append_char(str, " ");
3515 _outNode(str, node->cmds);
3516 }
3517
3518 static void
_outOptSeqList(String * str,List * options)3519 _outOptSeqList(String * str, List *options)
3520 {
3521 ListCell *lc;
3522
3523 foreach(lc, options)
3524 {
3525 DefElem *e = lfirst(lc);
3526 Value *v = (Value *) e->arg;
3527 char buf[16];
3528
3529 if (strcmp(e->defname, "cycle") == 0)
3530 {
3531 if (v->val.ival == TRUE)
3532 string_append_char(str, " CYCLE");
3533 else
3534 string_append_char(str, " NO CYCLE");
3535 }
3536 else if (strcmp(e->defname, "minvalue") == 0 && !v)
3537 string_append_char(str, " NO MINVALUE");
3538 else if (strcmp(e->defname, "maxvalue") == 0 && !v)
3539 string_append_char(str, " NO MAXVALUE");
3540 else if (strcmp(e->defname, "owned_by") == 0)
3541 {
3542 string_append_char(str, " OWNED BY ");
3543 _outIdList(str, (List *) e->arg);
3544 }
3545 else
3546 {
3547 if (strcmp(e->defname, "cache") == 0)
3548 string_append_char(str, " CACHE ");
3549 else if (strcmp(e->defname, "increment") == 0)
3550 string_append_char(str, " INCREMENT ");
3551 else if (strcmp(e->defname, "maxvalue") == 0 && v)
3552 string_append_char(str, " MAXVALUE ");
3553 else if (strcmp(e->defname, "minvalue") == 0 && v)
3554 string_append_char(str, " MINVALUE ");
3555 else if (strcmp(e->defname, "start") == 0)
3556 string_append_char(str, " START ");
3557 else if (strcmp(e->defname, "restart") == 0)
3558 string_append_char(str, " RESTART ");
3559
3560 if (IsA(e->arg, String))
3561 string_append_char(str, v->val.str);
3562 else
3563 {
3564 snprintf(buf, 16, "%d", v->val.ival);
3565 string_append_char(str, buf);
3566 }
3567 }
3568 }
3569 }
3570
3571 static void
_outCreateSeqStmt(String * str,CreateSeqStmt * node)3572 _outCreateSeqStmt(String * str, CreateSeqStmt *node)
3573 {
3574 string_append_char(str, "CREATE ");
3575 if (node->sequence->relpersistence == RELPERSISTENCE_TEMP)
3576 string_append_char(str, "TEMP ");
3577 string_append_char(str, "SEQUENCE ");
3578 _outNode(str, node->sequence);
3579
3580 _outOptSeqList(str, node->options);
3581 }
3582
3583 static void
_outAlterSeqStmt(String * str,AlterSeqStmt * node)3584 _outAlterSeqStmt(String * str, AlterSeqStmt *node)
3585 {
3586 string_append_char(str, "ALTER SEQUENCE ");
3587 _outNode(str, node->sequence);
3588 _outOptSeqList(str, node->options);
3589 }
3590
3591 static void
_outCreatePLangStmt(String * str,CreatePLangStmt * node)3592 _outCreatePLangStmt(String * str, CreatePLangStmt *node)
3593 {
3594 string_append_char(str, "CREATE ");
3595 if (node->pltrusted == true)
3596 string_append_char(str, "TRUSTED ");
3597 string_append_char(str, "LANGUAGE \"");
3598 string_append_char(str, node->plname);
3599 string_append_char(str, "\"");
3600
3601 if (node->plhandler != NIL)
3602 {
3603 ListCell *lc;
3604 char dot = 0;
3605
3606 string_append_char(str, " HANDLER ");
3607 foreach(lc, node->plhandler)
3608 {
3609 Value *v = lfirst(lc);
3610
3611 if (dot == 0)
3612 dot = 1;
3613 else
3614 string_append_char(str, ".");
3615
3616 string_append_char(str, "\"");
3617 string_append_char(str, v->val.str);
3618 string_append_char(str, "\"");
3619 }
3620 }
3621
3622 if (node->plvalidator != NIL)
3623 {
3624 ListCell *lc;
3625 char dot = 0;
3626
3627 string_append_char(str, " VALIDATOR ");
3628 foreach(lc, node->plvalidator)
3629 {
3630 Value *v = lfirst(lc);
3631
3632 if (dot == 0)
3633 dot = 1;
3634 else
3635 string_append_char(str, ".");
3636
3637 string_append_char(str, "\"");
3638 string_append_char(str, v->val.str);
3639 string_append_char(str, "\"");
3640 }
3641 }
3642 }
3643
3644
3645 static void
_outCreateTableSpaceStmt(String * str,CreateTableSpaceStmt * node)3646 _outCreateTableSpaceStmt(String * str, CreateTableSpaceStmt *node)
3647 {
3648 string_append_char(str, "CREATE TABLESPACE \"");
3649 string_append_char(str, node->tablespacename);
3650 string_append_char(str, "\" ");
3651
3652 if (node->owner)
3653 {
3654 string_append_char(str, "OWNER \"");
3655 _outNode(str, node->owner);
3656 string_append_char(str, "\" ");
3657 }
3658
3659 string_append_char(str, "LOCATION '");
3660 string_append_char(str, node->location);
3661 string_append_char(str, "'");
3662 }
3663
3664 static void
_outDropTableSpaceStmt(String * str,DropTableSpaceStmt * node)3665 _outDropTableSpaceStmt(String * str, DropTableSpaceStmt *node)
3666 {
3667 string_append_char(str, "DROP TABLESPACE \"");
3668 string_append_char(str, node->tablespacename);
3669 string_append_char(str, "\"");
3670 }
3671
3672 static void
_outFuncName(String * str,List * func_name)3673 _outFuncName(String * str, List *func_name)
3674 {
3675 ListCell *lc;
3676 Value *v;
3677 char dot = 0;
3678
3679 if (func_name == NULL)
3680 return;
3681
3682 foreach(lc, func_name)
3683 {
3684 v = (Value *) lfirst(lc);
3685
3686 if (dot == 0)
3687 dot = 1;
3688 else
3689 string_append_char(str, ".");
3690
3691 if (IsA(v, String))
3692 {
3693 string_append_char(str, "\"");
3694 string_append_char(str, v->val.str);
3695 string_append_char(str, "\"");
3696 }
3697 else
3698 {
3699 _outNode(str, v);
3700 }
3701 }
3702 }
3703
3704 static void
_outCreateTrigStmt(String * str,CreateTrigStmt * node)3705 _outCreateTrigStmt(String * str, CreateTrigStmt *node)
3706 {
3707 bool has_events = false;
3708
3709 if (node->isconstraint == TRUE)
3710 string_append_char(str, "CREATE CONSTRAINT TRIGGER \"");
3711 else
3712 string_append_char(str, "CREATE TRIGGER \"");
3713 string_append_char(str, node->trigname);
3714 string_append_char(str, "\" ");
3715
3716 if (TRIGGER_FOR_BEFORE(node->timing))
3717 string_append_char(str, "BEFORE ");
3718 if (TRIGGER_FOR_AFTER(node->timing))
3719 string_append_char(str, "AFTER ");
3720
3721 if (node->events & TRIGGER_TYPE_INSERT)
3722 {
3723 string_append_char(str, "INSERT ");
3724 has_events = true;
3725 }
3726 if (node->events & TRIGGER_TYPE_DELETE)
3727 {
3728 if (has_events)
3729 string_append_char(str, "OR ");
3730 string_append_char(str, "DELETE ");
3731 has_events = true;
3732 }
3733 if (node->events & TRIGGER_TYPE_UPDATE)
3734 {
3735 if (has_events)
3736 string_append_char(str, "OR ");
3737 string_append_char(str, "UPDATE ");
3738 has_events = true;
3739 }
3740 if (node->events & TRIGGER_TYPE_TRUNCATE)
3741 {
3742 if (has_events)
3743 string_append_char(str, "OR ");
3744 string_append_char(str, "TRUNCATE ");
3745 has_events = true;
3746 }
3747
3748 string_append_char(str, "ON ");
3749 _outNode(str, node->relation);
3750
3751 if (node->constrrel)
3752 {
3753 string_append_char(str, " FROM ");
3754 _outNode(str, node->constrrel);
3755 }
3756
3757 if (node->deferrable)
3758 string_append_char(str, " DEFERRABLE");
3759 if (node->initdeferred)
3760 string_append_char(str, " INITIALLY DEFERRED");
3761
3762 if (node->row == TRUE)
3763 string_append_char(str, " FOR EACH ROW ");
3764 else
3765 string_append_char(str, " FOR EACH STATEMENT ");
3766
3767 string_append_char(str, "EXECUTE PROCEDURE ");
3768
3769 _outFuncName(str, node->funcname);
3770 string_append_char(str, "(");
3771 _outNode(str, node->args);
3772 string_append_char(str, ")");
3773 }
3774
3775 static void
_outDefinition(String * str,List * definition)3776 _outDefinition(String * str, List *definition)
3777 {
3778 ListCell *lc;
3779 char comma = 0;
3780
3781 if (definition == NIL)
3782 return;
3783
3784 string_append_char(str, "(");
3785 foreach(lc, definition)
3786 {
3787 DefElem *e = lfirst(lc);
3788
3789 if (comma == 0)
3790 comma = 1;
3791 else
3792 string_append_char(str, ", ");
3793
3794 string_append_char(str, "\"");
3795 string_append_char(str, e->defname);
3796 string_append_char(str, "\"");
3797
3798 if (e->arg)
3799 {
3800 string_append_char(str, "=");
3801 _outNode(str, e->arg);
3802 }
3803 }
3804 string_append_char(str, ")");
3805 }
3806
3807 static void
_outDefineStmt(String * str,DefineStmt * node)3808 _outDefineStmt(String * str, DefineStmt *node)
3809 {
3810 ListCell *lc;
3811 char dot = 0;
3812
3813 switch (node->kind)
3814 {
3815 case OBJECT_AGGREGATE:
3816 string_append_char(str, "CREATE AGGREGATE ");
3817 _outFuncName(str, node->defnames);
3818 string_append_char(str, " ");
3819 _outDefinition(str, node->definition);
3820 break;
3821
3822 case OBJECT_OPERATOR:
3823 string_append_char(str, "CREATE OPERATOR ");
3824
3825 foreach(lc, node->defnames)
3826 {
3827 Value *v = lfirst(lc);
3828
3829 if (dot == 0)
3830 dot = 1;
3831 else
3832 string_append_char(str, ".");
3833
3834 string_append_char(str, v->val.str);
3835 }
3836
3837 string_append_char(str, " ");
3838 _outDefinition(str, node->definition);
3839 break;
3840
3841 case OBJECT_TYPE:
3842 string_append_char(str, "CREATE TYPE");
3843 _outFuncName(str, node->defnames);
3844 string_append_char(str, " ");
3845 _outDefinition(str, node->definition);
3846 break;
3847
3848 case OBJECT_TSPARSER:
3849 string_append_char(str, "CREATE TEXT SEARCH PARSER ");
3850 _outIdList(str, node->defnames);
3851 _outDefinition(str, node->definition);
3852 break;
3853
3854 case OBJECT_TSDICTIONARY:
3855 string_append_char(str, "CREATE TEXT SEARCH DICTIONARY ");
3856 _outIdList(str, node->defnames);
3857 _outDefinition(str, node->definition);
3858 break;
3859
3860 case OBJECT_TSTEMPLATE:
3861 string_append_char(str, "CREATE TEXT SEARCH TEMPLATE ");
3862 _outIdList(str, node->defnames);
3863 _outDefinition(str, node->definition);
3864 break;
3865
3866 case OBJECT_TSCONFIGURATION:
3867 string_append_char(str, "CREATE TEXT SEARCH CONFIGURATION ");
3868 _outIdList(str, node->defnames);
3869 _outDefinition(str, node->definition);
3870 break;
3871
3872 default:
3873 break;
3874 }
3875 }
3876
3877 static void
_outOperatorName(String * str,List * list)3878 _outOperatorName(String * str, List *list)
3879 {
3880 char dot = 0;
3881 ListCell *lc;
3882
3883 foreach(lc, list)
3884 {
3885 Value *v = lfirst(lc);
3886
3887 if (dot == 0)
3888 dot = 1;
3889 else
3890 string_append_char(str, ".");
3891
3892 string_append_char(str, v->val.str);
3893 }
3894 }
3895
3896 static void
_outCreateOpClassItem(String * str,CreateOpClassItem * node)3897 _outCreateOpClassItem(String * str, CreateOpClassItem *node)
3898 {
3899 char buf[16];
3900
3901 switch (node->itemtype)
3902 {
3903 case OPCLASS_ITEM_OPERATOR:
3904 string_append_char(str, "OPERATOR ");
3905 snprintf(buf, 16, "%d", node->number);
3906 string_append_char(str, buf);
3907 string_append_char(str, " ");
3908 _outOperatorName(str, node->name->objname);
3909
3910 if (node->name->objname != NIL)
3911 {
3912 string_append_char(str, "(");
3913 _outNode(str, node->name->objname);
3914 string_append_char(str, ")");
3915 }
3916
3917 /*
3918 * if (node->recheck == TRUE) string_append_char(str, " RECHECK");
3919 */
3920 break;
3921
3922 case OPCLASS_ITEM_FUNCTION:
3923 string_append_char(str, "FUNCTION ");
3924 snprintf(buf, 16, "%d", node->number);
3925 string_append_char(str, buf);
3926 string_append_char(str, " ");
3927 _outFuncName(str, node->name->objname);
3928 string_append_char(str, "(");
3929 _outNode(str, node->name->objname);
3930 string_append_char(str, ")");
3931 break;
3932
3933 case OPCLASS_ITEM_STORAGETYPE:
3934 string_append_char(str, "STORAGE ");
3935 _outNode(str, node->storedtype);
3936 break;
3937
3938 default:
3939 break;
3940 }
3941
3942 }
3943
3944 static void
_outCreateOpClassStmt(String * str,CreateOpClassStmt * node)3945 _outCreateOpClassStmt(String * str, CreateOpClassStmt *node)
3946 {
3947 string_append_char(str, "CREATE OPERATOR CLASS ");
3948 _outFuncName(str, node->opclassname);
3949
3950 if (node->isDefault == TRUE)
3951 string_append_char(str, " DEFAULT");
3952
3953 string_append_char(str, " FOR TYPE ");
3954 _outNode(str, node->datatype);
3955 string_append_char(str, " USING ");
3956 string_append_char(str, node->amname);
3957 string_append_char(str, " AS ");
3958 _outNode(str, node->items);
3959 }
3960
3961 /*
3962 * Handle drop statements. As of pgpool-II 3.3(derived parser from
3963 * PostgreSQL 9.2), following types are supported:
3964 *
3965 * DROP TABLE, DROP SEQUENCE, DROP VIEW, DROP INDEX, DROP FOREIGN
3966 * TABLE, DROP TYPE, DROP DOMAIN, DROP COLLATION, DROP CONVERSION,
3967 * DROP SCHEMA, DROP TEXT SEARCH PARSER, DROP TEXT SEARCH DICTIONARY,
3968 * DROP TEXT SEARCH CONFIGURATION, DROP LANGUAGE, DROP RULE, DROP
3969 * OPERATOR, DROP OPERATOR CLASS
3970 */
3971
3972 static void
add_function_like_objs(String * str,DropStmt * node)3973 add_function_like_objs(String * str, DropStmt *node)
3974 {
3975 ListCell *lc;
3976 char comma = 0;
3977
3978 if (node->concurrent)
3979 string_append_char(str, "CONCURRENTLY ");
3980 if (node->missing_ok)
3981 string_append_char(str, "IF EXISTS ");
3982
3983 foreach(lc, node->objects)
3984 {
3985 if (comma == 0)
3986 comma = 1;
3987 else
3988 string_append_char(str, ", ");
3989 _outFuncName(str, lfirst(lc));
3990 }
3991 }
3992
3993 static void
_outDropStmt(String * str,DropStmt * node)3994 _outDropStmt(String * str, DropStmt *node)
3995 {
3996 List *objname;
3997 char *p;
3998 char *p1;
3999 List *l;
4000
4001 string_append_char(str, "DROP ");
4002 switch (node->removeType)
4003 {
4004 case OBJECT_TABLE:
4005 string_append_char(str, "TABLE ");
4006 add_function_like_objs(str, node);
4007 break;
4008
4009 case OBJECT_SEQUENCE:
4010 string_append_char(str, "SEQUENCE ");
4011 add_function_like_objs(str, node);
4012 break;
4013
4014 case OBJECT_VIEW:
4015 string_append_char(str, "VIEW ");
4016 add_function_like_objs(str, node);
4017 break;
4018
4019 case OBJECT_INDEX:
4020 string_append_char(str, "INDEX ");
4021 add_function_like_objs(str, node);
4022 break;
4023
4024 case OBJECT_FOREIGN_TABLE:
4025 string_append_char(str, "FOREIGN TABLE ");
4026 add_function_like_objs(str, node);
4027 break;
4028
4029 case OBJECT_FDW:
4030 string_append_char(str, "FOREIGN DATA WRAPPER ");
4031 add_function_like_objs(str, node);
4032 break;
4033
4034 case OBJECT_TYPE:
4035 string_append_char(str, "TYPE ");
4036 add_function_like_objs(str, node);
4037 break;
4038
4039 case OBJECT_DOMAIN:
4040 string_append_char(str, "DOMAIN ");
4041 add_function_like_objs(str, node);
4042 break;
4043
4044 case OBJECT_COLLATION:
4045 string_append_char(str, "COLLATION ");
4046 add_function_like_objs(str, node);
4047 break;
4048
4049 case OBJECT_CONVERSION:
4050 string_append_char(str, "CONVERSION ");
4051 add_function_like_objs(str, node);
4052 break;
4053
4054 case OBJECT_SCHEMA:
4055 string_append_char(str, "SCHEMA ");
4056 add_function_like_objs(str, node);
4057 break;
4058
4059 case OBJECT_EXTENSION:
4060 string_append_char(str, "EXTENSION ");
4061 add_function_like_objs(str, node);
4062 break;
4063
4064 case OBJECT_TSPARSER:
4065 string_append_char(str, "TEXT SEARCH PARSER ");
4066 add_function_like_objs(str, node);
4067 break;
4068
4069 case OBJECT_TSDICTIONARY:
4070 string_append_char(str, "TEXT SEARCH DICTIONARY ");
4071 add_function_like_objs(str, node);
4072 break;
4073
4074 case OBJECT_TSTEMPLATE:
4075 string_append_char(str, "TEXT SEARCH TEMPLATE ");
4076 add_function_like_objs(str, node);
4077 break;
4078
4079 case OBJECT_TSCONFIGURATION:
4080 string_append_char(str, "TEXT SEARCH CONFIGURATION ");
4081 add_function_like_objs(str, node);
4082 break;
4083
4084 case OBJECT_LANGUAGE:
4085 string_append_char(str, "PROCEDURAL LANGUAGE ");
4086 add_function_like_objs(str, node);
4087 break;
4088
4089 case OBJECT_RULE:
4090 string_append_char(str, "DROP RULE ");
4091 if (node->missing_ok)
4092 string_append_char(str, "IF EXISTS ");
4093 objname = lfirst(list_head(node->objects));
4094 string_append_char(str, strVal(llast(objname)));
4095 string_append_char(str, " ON ");
4096 l = list_truncate(list_copy(objname),
4097 list_length(objname) - 1);
4098 p = NameListToString(l);
4099 string_append_char(str, p);
4100 pfree(p);
4101 list_free(l);
4102 break;
4103
4104 case OBJECT_OPERATOR:
4105 string_append_char(str, "OPERATOR ");
4106 add_function_like_objs(str, node);
4107 break;
4108
4109 case OBJECT_OPCLASS:
4110 string_append_char(str, "DROP OPERATOR CLASS ");
4111 if (node->missing_ok)
4112 string_append_char(str, "IF EXISTS ");
4113 objname = lfirst(list_head(node->objects));
4114 string_append_char(str, strVal(llast(objname)));
4115 string_append_char(str, " USING ");
4116 string_append_char(str, "'");
4117 l = list_truncate(list_copy(objname),
4118 list_length(objname) - 1);
4119 p = NameListToString(l);
4120 p1 = escape_string(p);
4121 string_append_char(str, p1);
4122 pfree(p1);
4123 pfree(p);
4124 list_free(l);
4125 string_append_char(str, "'");
4126 break;
4127
4128 case OBJECT_CAST:
4129 string_append_char(str, "DROP CAST ");
4130 if (node->missing_ok)
4131 string_append_char(str, "IF EXISTS ");
4132 string_append_char(str, "(");
4133 objname = linitial(node->objects);
4134 _outNode(str, linitial(objname));
4135 string_append_char(str, " AS ");
4136 _outNode(str, linitial(objname));
4137 string_append_char(str, ")");
4138 break;
4139
4140 case OBJECT_OPFAMILY:
4141 string_append_char(str, "OPERATOR FAMILY ");
4142 if (node->missing_ok)
4143 string_append_char(str, "IF EXISTS ");
4144 objname = linitial(node->objects);
4145 _outIdList(str, objname);
4146 string_append_char(str, " USING ");
4147 _outIdList(str, objname);
4148 break;
4149
4150 default:
4151 break;
4152 }
4153
4154 if (node->behavior == DROP_CASCADE)
4155 string_append_char(str, " CASCADE");
4156 }
4157
4158 static void
_outFetchStmt(String * str,FetchStmt * node)4159 _outFetchStmt(String * str, FetchStmt *node)
4160 {
4161 char buf[16];
4162
4163 snprintf(buf, 16, "%ld", node->howMany);
4164
4165 if (node->ismove == TRUE)
4166 string_append_char(str, "MOVE ");
4167 else
4168 string_append_char(str, "FETCH ");
4169
4170 switch (node->direction)
4171 {
4172 case FETCH_FORWARD:
4173 string_append_char(str, "FORWARD ");
4174 if (node->howMany == FETCH_ALL)
4175 string_append_char(str, "ALL ");
4176 else
4177 {
4178 string_append_char(str, buf);
4179 string_append_char(str, " ");
4180 }
4181 break;
4182
4183 case FETCH_BACKWARD:
4184 string_append_char(str, "BACKWARD ");
4185 if (node->howMany == FETCH_ALL)
4186 string_append_char(str, "ALL ");
4187 else
4188 {
4189 string_append_char(str, buf);
4190 string_append_char(str, " ");
4191 }
4192 break;
4193
4194 case FETCH_ABSOLUTE:
4195 if (node->howMany == 1)
4196 string_append_char(str, "FIRST ");
4197 else if (node->howMany == -1)
4198 string_append_char(str, "LAST ");
4199 else
4200 {
4201 string_append_char(str, "ABSOLUTE ");
4202 string_append_char(str, buf);
4203 string_append_char(str, " ");
4204 }
4205 break;
4206
4207 case FETCH_RELATIVE:
4208 string_append_char(str, "RELATIVE ");
4209 string_append_char(str, buf);
4210 string_append_char(str, " ");
4211 break;
4212 }
4213
4214 string_append_char(str, "IN \"");
4215 string_append_char(str, node->portalname);
4216 string_append_char(str, "\"");
4217 }
4218
4219 static void
_outPrivilegeList(String * str,List * list)4220 _outPrivilegeList(String * str, List *list)
4221 {
4222 ListCell *lc;
4223 char comma = 0;
4224
4225 if (list == NIL)
4226 string_append_char(str, "ALL");
4227 else
4228 {
4229 foreach(lc, list)
4230 {
4231 Value *v = lfirst(lc);
4232
4233 if (comma == 0)
4234 comma = 1;
4235 else
4236 string_append_char(str, ", ");
4237
4238 string_append_char(str, v->val.str);
4239 }
4240 }
4241 }
4242
4243 static void
_outFunctionParameter(String * str,FunctionParameter * node)4244 _outFunctionParameter(String * str, FunctionParameter *node)
4245 {
4246 switch (node->mode)
4247 {
4248 case FUNC_PARAM_OUT:
4249 string_append_char(str, "OUT ");
4250 break;
4251
4252 case FUNC_PARAM_INOUT:
4253 string_append_char(str, "INOUT ");
4254 break;
4255
4256 default:
4257 break;
4258 }
4259
4260 /* function name */
4261 if (node->name)
4262 {
4263 string_append_char(str, "\"");
4264 string_append_char(str, node->name);
4265 string_append_char(str, "\" ");
4266 }
4267
4268 _outNode(str, node->argType);
4269 }
4270
4271 static void
_outObjectWithArgs(String * str,ObjectWithArgs * node)4272 _outObjectWithArgs(String * str, ObjectWithArgs *node)
4273 {
4274 _outFuncName(str, node->objname);
4275 string_append_char(str, "(");
4276 _outNode(str, node->objargs);
4277 string_append_char(str, ")");
4278 }
4279
4280 static void
_outGrantStmt(String * str,GrantStmt * node)4281 _outGrantStmt(String * str, GrantStmt *node)
4282 {
4283 if (node->is_grant == true)
4284 string_append_char(str, "GRANT ");
4285 else
4286 {
4287 string_append_char(str, "REVOKE ");
4288 if (node->grant_option == true)
4289 string_append_char(str, "GRANT OPTION FOR ");
4290 }
4291
4292 _outPrivilegeList(str, node->privileges);
4293
4294 string_append_char(str, " ON ");
4295
4296 switch (node->objtype)
4297 {
4298 case OBJECT_TABLE:
4299 _outNode(str, node->objects);
4300 break;
4301
4302 case OBJECT_SEQUENCE:
4303 string_append_char(str, "SEQUENCE ");
4304 _outNode(str, node->objects);
4305 break;
4306
4307 case OBJECT_FUNCTION:
4308 string_append_char(str, "FUNCTION ");
4309 _outNode(str, node->objects);
4310 break;
4311
4312 case OBJECT_DATABASE:
4313 string_append_char(str, "DATABASE ");
4314 _outIdList(str, node->objects);
4315 break;
4316
4317 case OBJECT_LANGUAGE:
4318 string_append_char(str, "LANGUAGE ");
4319 _outIdList(str, node->objects);
4320 break;
4321
4322 case OBJECT_SCHEMA:
4323 string_append_char(str, "SCHEMA ");
4324 _outIdList(str, node->objects);
4325 break;
4326
4327 case OBJECT_TABLESPACE:
4328 string_append_char(str, "TABLESPACE ");
4329 _outIdList(str, node->objects);
4330 break;
4331
4332 case OBJECT_FDW:
4333 string_append_char(str, "FOREIGN DATA WRAPPER ");
4334 _outIdList(str, node->objects);
4335 break;
4336
4337 case OBJECT_FOREIGN_SERVER:
4338 string_append_char(str, "FOREIGN SERVER ");
4339 _outIdList(str, node->objects);
4340 break;
4341
4342 case OBJECT_COLUMN:
4343 case OBJECT_DOMAIN:
4344 case OBJECT_LARGEOBJECT:
4345 case OBJECT_TYPE:
4346 case OBJECT_ACCESS_METHOD:
4347 case OBJECT_AGGREGATE:
4348 case OBJECT_AMOP:
4349 case OBJECT_AMPROC:
4350 case OBJECT_ATTRIBUTE:
4351 case OBJECT_CAST:
4352 case OBJECT_COLLATION:
4353 case OBJECT_CONVERSION:
4354 case OBJECT_DEFAULT:
4355 case OBJECT_DEFACL:
4356 case OBJECT_DOMCONSTRAINT:
4357 case OBJECT_EVENT_TRIGGER:
4358 case OBJECT_EXTENSION:
4359 case OBJECT_FOREIGN_TABLE:
4360 case OBJECT_INDEX:
4361 case OBJECT_MATVIEW:
4362 case OBJECT_OPCLASS:
4363 case OBJECT_OPERATOR:
4364 case OBJECT_OPFAMILY:
4365 case OBJECT_POLICY:
4366 case OBJECT_PROCEDURE:
4367 case OBJECT_PUBLICATION:
4368 case OBJECT_PUBLICATION_REL:
4369 case OBJECT_ROLE:
4370 case OBJECT_ROUTINE:
4371 case OBJECT_RULE:
4372 case OBJECT_SUBSCRIPTION:
4373 case OBJECT_STATISTIC_EXT:
4374 case OBJECT_TABCONSTRAINT:
4375 case OBJECT_TRANSFORM:
4376 case OBJECT_TRIGGER:
4377 case OBJECT_TSCONFIGURATION:
4378 case OBJECT_TSDICTIONARY:
4379 case OBJECT_TSPARSER:
4380 case OBJECT_TSTEMPLATE:
4381 case OBJECT_USER_MAPPING:
4382 case OBJECT_VIEW:
4383 break;
4384 }
4385
4386 if (node->is_grant == true)
4387 string_append_char(str, " TO ");
4388 else
4389 string_append_char(str, " FROM ");
4390 _outNode(str, node->grantees);
4391
4392 if (node->is_grant == true && node->grant_option == TRUE)
4393 string_append_char(str, " WITH GRANT OPTION");
4394
4395 if (node->behavior == DROP_CASCADE)
4396 string_append_char(str, " CASCADE");
4397 }
4398
4399 static void
_outGrantRoleStmt(String * str,GrantRoleStmt * node)4400 _outGrantRoleStmt(String * str, GrantRoleStmt *node)
4401 {
4402 if (node->is_grant == true)
4403 string_append_char(str, "GRANT ");
4404 else
4405 {
4406 string_append_char(str, "REVOKE ");
4407 if (node->admin_opt == true)
4408 string_append_char(str, "ADMIN OPTION FOR ");
4409 }
4410
4411 _outIdList(str, node->granted_roles);
4412
4413 string_append_char(str, node->is_grant == true ? " TO " : " FROM ");
4414
4415 _outIdList(str, node->grantee_roles);
4416
4417 if (node->admin_opt == true && node->is_grant == true)
4418 string_append_char(str, " WITH ADMIN OPTION");
4419
4420 if (node->grantor != NULL)
4421 {
4422 string_append_char(str, " GRANTED BY \"");
4423 _outNode(str, node->grantor);
4424 string_append_char(str, "\"");
4425 }
4426
4427 if (node->behavior == DROP_CASCADE)
4428 string_append_char(str, " CASCADE");
4429 }
4430
4431 static void
_outFuncOptList(String * str,List * list)4432 _outFuncOptList(String * str, List *list)
4433 {
4434 ListCell *lc;
4435
4436 foreach(lc, list)
4437 {
4438 DefElem *e = lfirst(lc);
4439 Value *v = (Value *) e->arg;
4440
4441 if (strcmp(e->defname, "strict") == 0)
4442 {
4443 if (v->val.ival == TRUE)
4444 string_append_char(str, " STRICT");
4445 else
4446 string_append_char(str, " CALLED ON NULL INPUT");
4447 }
4448 else if (strcmp(e->defname, "volatility") == 0)
4449 {
4450 char *s = v->val.str;
4451
4452 if (strcmp(s, "immutable") == 0)
4453 string_append_char(str, " IMMUTABLE");
4454 else if (strcmp(s, "stable") == 0)
4455 string_append_char(str, " STABLE");
4456 else if (strcmp(s, "volatile") == 0)
4457 string_append_char(str, " VOLATILE");
4458 }
4459 else if (strcmp(e->defname, "security") == 0)
4460 {
4461 if (v->val.ival == TRUE)
4462 string_append_char(str, " SECURITY DEFINER");
4463 else
4464 string_append_char(str, " SECURITY INVOKER");
4465 }
4466 else if (strcmp(e->defname, "as") == 0)
4467 {
4468 string_append_char(str, " AS ");
4469 _outNode(str, e->arg);
4470 }
4471 else if (strcmp(e->defname, "language") == 0)
4472 {
4473 string_append_char(str, " LANGUAGE '");
4474 string_append_char(str, v->val.str);
4475 string_append_char(str, "'");
4476 }
4477 }
4478 }
4479
4480 static void
_outCreateFunctionStmt(String * str,CreateFunctionStmt * node)4481 _outCreateFunctionStmt(String * str, CreateFunctionStmt *node)
4482 {
4483 string_append_char(str, "CREATE ");
4484 if (node->replace == true)
4485 string_append_char(str, "OR REPLACE ");
4486 string_append_char(str, "FUNCTION ");
4487
4488 _outFuncName(str, node->funcname);
4489
4490 string_append_char(str, " (");
4491 _outNode(str, node->parameters);
4492 string_append_char(str, ")");
4493
4494 if (node->returnType)
4495 {
4496 string_append_char(str, " RETURNS ");
4497 _outNode(str, node->returnType);
4498 }
4499
4500 _outFuncOptList(str, node->options);
4501 }
4502
4503 static void
_outAlterFunctionStmt(String * str,AlterFunctionStmt * node)4504 _outAlterFunctionStmt(String * str, AlterFunctionStmt *node)
4505 {
4506 string_append_char(str, "ALTER FUNCTION ");
4507 _outNode(str, node->func);
4508 _outFuncOptList(str, node->actions);
4509 }
4510
4511
4512 static void
_outCreateCastStmt(String * str,CreateCastStmt * node)4513 _outCreateCastStmt(String * str, CreateCastStmt *node)
4514 {
4515 string_append_char(str, "CREATE CAST (");
4516 _outNode(str, node->sourcetype);
4517 string_append_char(str, " AS ");
4518 _outNode(str, node->targettype);
4519 string_append_char(str, ") WITH FUNCTION ");
4520 _outNode(str, node->func);
4521
4522 switch (node->context)
4523 {
4524 case COERCION_IMPLICIT:
4525 string_append_char(str, " AS IMPLICIT");
4526 break;
4527
4528 case COERCION_ASSIGNMENT:
4529 string_append_char(str, " AS ASSIGNMENT");
4530 break;
4531
4532 default:
4533 break;
4534 }
4535 }
4536
4537 static void
_outReindexStmt(String * str,ReindexStmt * node)4538 _outReindexStmt(String * str, ReindexStmt *node)
4539 {
4540 string_append_char(str, "REINDEX ");
4541
4542 switch (node->kind)
4543 {
4544 case REINDEX_OBJECT_SYSTEM:
4545 string_append_char(str, "SYSTEM ");
4546 break;
4547
4548 case REINDEX_OBJECT_DATABASE:
4549 string_append_char(str, "DATABASE ");
4550 break;
4551
4552 case REINDEX_OBJECT_INDEX:
4553 string_append_char(str, "INDEX ");
4554 break;
4555
4556 case REINDEX_OBJECT_TABLE:
4557 string_append_char(str, "TABLE ");
4558 break;
4559
4560 default:
4561 break;
4562 }
4563
4564 if (node->relation)
4565 _outNode(str, node->relation);
4566
4567 if (node->name)
4568 {
4569 string_append_char(str, "\"");
4570 string_append_char(str, (char *) node->name);
4571 string_append_char(str, "\"");
4572 }
4573 }
4574
4575 static void
_outAlterObjectSchemaStmt(String * str,AlterObjectSchemaStmt * node)4576 _outAlterObjectSchemaStmt(String * str, AlterObjectSchemaStmt *node)
4577 {
4578 string_append_char(str, "ALTER ");
4579
4580 ObjectWithArgs *owa = castNode(ObjectWithArgs, node);
4581
4582 switch (node->objectType)
4583 {
4584 case OBJECT_AGGREGATE:
4585 string_append_char(str, "AGGREGATE ");
4586 _outFuncName(str, owa->objname);
4587 string_append_char(str, "(");
4588 if (lfirst(list_head(owa->objargs)) == NULL)
4589 string_append_char(str, "*");
4590 else
4591 _outNode(str, lfirst(list_head(owa->objargs)));
4592 string_append_char(str, ") SET SCHEME \"");
4593 string_append_char(str, node->newschema);
4594 string_append_char(str, "\"");
4595 break;
4596
4597 case OBJECT_DOMAIN:
4598 string_append_char(str, "DOMAIN ");
4599 _outFuncName(str, owa->objname);
4600 string_append_char(str, " SET SCHEMA \"");
4601 string_append_char(str, node->newschema);
4602 string_append_char(str, "\"");
4603 break;
4604
4605 case OBJECT_FUNCTION:
4606 string_append_char(str, "FUNCTION ");
4607 _outFuncName(str, owa->objname);
4608 string_append_char(str, "(");
4609 string_append_char(str, ") SET SCHEMA \"");
4610 string_append_char(str, node->newschema);
4611 string_append_char(str, "\"");
4612 break;
4613
4614 case OBJECT_SEQUENCE:
4615 string_append_char(str, "SEQUENCE ");
4616 _outNode(str, node->relation);
4617 string_append_char(str, " SET SCHEMA \"");
4618 string_append_char(str, node->newschema);
4619 string_append_char(str, "\"");
4620 break;
4621
4622 case OBJECT_TABLE:
4623 string_append_char(str, "TABLE ");
4624 _outNode(str, node->relation);
4625 string_append_char(str, " SET SCHEMA \"");
4626 string_append_char(str, node->newschema);
4627 string_append_char(str, "\"");
4628 break;
4629
4630 case OBJECT_TYPE:
4631 string_append_char(str, "TYPE ");
4632 _outFuncName(str, owa->objname);
4633 string_append_char(str, " SET SCHEMA \"");
4634 string_append_char(str, node->newschema);
4635 string_append_char(str, "\"");
4636 break;
4637
4638 default:
4639 break;
4640 }
4641 }
4642
4643 static void
_outAlterOwnerStmt(String * str,AlterOwnerStmt * node)4644 _outAlterOwnerStmt(String * str, AlterOwnerStmt *node)
4645 {
4646 string_append_char(str, "ALTER ");
4647
4648 ObjectWithArgs *owa = castNode(ObjectWithArgs, node);
4649
4650 switch (node->objectType)
4651 {
4652 case OBJECT_AGGREGATE:
4653 string_append_char(str, "AGGREGATE ");
4654 _outFuncName(str, owa->objname);
4655 string_append_char(str, "(");
4656 if (lfirst(list_head(owa->objargs)) == NULL)
4657 string_append_char(str, "*");
4658 else
4659 _outNode(str, lfirst(list_head(owa->objargs)));
4660 string_append_char(str, ") OWNER TO \"");
4661 _outNode(str, node->newowner);
4662 string_append_char(str, "\"");
4663 break;
4664
4665 case OBJECT_CONVERSION:
4666 string_append_char(str, "CONVERSION \"");
4667 string_append_char(str, strVal(linitial(owa->objname)));
4668 string_append_char(str, "\" OWNER TO \"");
4669 _outNode(str, node->newowner);
4670 string_append_char(str, "\"");
4671 break;
4672
4673 case OBJECT_DATABASE:
4674 string_append_char(str, "DATABASE \"");
4675 string_append_char(str, strVal(linitial(owa->objname)));
4676 string_append_char(str, "\" OWNER TO \"");
4677 _outNode(str, node->newowner);
4678 string_append_char(str, "\"");
4679 break;
4680
4681 case OBJECT_DOMAIN:
4682 string_append_char(str, "DOMAIN \"");
4683 string_append_char(str, strVal(linitial(owa->objname)));
4684 string_append_char(str, "\" OWNER TO \"");
4685 _outNode(str, node->newowner);
4686 string_append_char(str, "\"");
4687 break;
4688
4689 case OBJECT_FUNCTION:
4690 string_append_char(str, "FUNCTION ");
4691 _outFuncName(str, owa->objname);
4692 string_append_char(str, "(");
4693 _outNode(str, owa->objargs);
4694 string_append_char(str, ") OWNER TO \"");
4695 _outNode(str, node->newowner);
4696 string_append_char(str, "\"");
4697 break;
4698
4699 case OBJECT_LANGUAGE:
4700 string_append_char(str, "LANGUAGE \"");
4701 string_append_char(str, strVal(linitial(owa->objname)));
4702 string_append_char(str, "\" OWNER TO \"");
4703 _outNode(str, node->newowner);
4704 string_append_char(str, "\"");
4705 break;
4706
4707 case OBJECT_OPERATOR:
4708 string_append_char(str, "OPERATOR ");
4709 _outOperatorName(str, owa->objname);
4710 string_append_char(str, "(");
4711 string_append_char(str, ") OWNER TO \"");
4712 _outNode(str, node->newowner);
4713 string_append_char(str, "\"");
4714 break;
4715
4716 case OBJECT_OPCLASS:
4717 string_append_char(str, "OPERATOR CLASS ");
4718 _outFuncName(str, owa->objname);
4719 string_append_char(str, " USING ");
4720 string_append_char(str, strVal(linitial(owa->objargs)));
4721 string_append_char(str, " OWNER TO \"");
4722 _outNode(str, node->newowner);
4723 string_append_char(str, "\"");
4724 break;
4725
4726 case OBJECT_OPFAMILY:
4727 string_append_char(str, "OPERATOR FAMILY ");
4728 _outFuncName(str, owa->objname);
4729 string_append_char(str, " USING ");
4730 string_append_char(str, strVal(linitial(owa->objargs)));
4731 string_append_char(str, " OWNER TO \"");
4732 _outNode(str, node->newowner);
4733 string_append_char(str, "\"");
4734 break;
4735
4736 case OBJECT_SCHEMA:
4737 string_append_char(str, "SCHEMA \"");
4738 string_append_char(str, strVal(linitial(owa->objname)));
4739 string_append_char(str, "\" OWNER TO \"");
4740 _outNode(str, node->newowner);
4741 string_append_char(str, "\"");
4742 break;
4743
4744 case OBJECT_TYPE:
4745 string_append_char(str, "TYPE \"");
4746 string_append_char(str, strVal(linitial(owa->objname)));
4747 string_append_char(str, "\" OWNER TO \"");
4748 _outNode(str, node->newowner);
4749 string_append_char(str, "\"");
4750 break;
4751
4752 case OBJECT_TABLESPACE:
4753 string_append_char(str, "TABLESPACE \"");
4754 string_append_char(str, strVal(linitial(owa->objname)));
4755 string_append_char(str, "\" OWNER TO \"");
4756 _outNode(str, node->newowner);
4757 string_append_char(str, "\"");
4758 break;
4759
4760 case OBJECT_TSDICTIONARY:
4761 string_append_char(str, "TEXT SEARCH DICTIONARY \"");
4762 string_append_char(str, strVal(linitial(owa->objname)));
4763 string_append_char(str, "\" OWNER TO \"");
4764 _outNode(str, node->newowner);
4765 string_append_char(str, "\"");
4766 break;
4767
4768 case OBJECT_TSCONFIGURATION:
4769 string_append_char(str, "TEXT SEARCH CONFIGURATION \"");
4770 string_append_char(str, strVal(linitial(owa->objname)));
4771 string_append_char(str, "\" OWNER TO \"");
4772 _outNode(str, node->newowner);
4773 string_append_char(str, "\"");
4774 break;
4775
4776 case OBJECT_FDW:
4777 string_append_char(str, "FOREIGN DATA WRAPPER \"");
4778 string_append_char(str, strVal(linitial(owa->objname)));
4779 string_append_char(str, "\" OWNER TO \"");
4780 _outNode(str, node->newowner);
4781 string_append_char(str, "\"");
4782 break;
4783
4784 case OBJECT_FOREIGN_SERVER:
4785 string_append_char(str, "SERVER \"");
4786 string_append_char(str, strVal(linitial(owa->objname)));
4787 string_append_char(str, "\" OWNER TO \"");
4788 _outNode(str, node->newowner);
4789 string_append_char(str, "\"");
4790 break;
4791
4792 default:
4793 break;
4794 }
4795 }
4796
4797 static void
_outRuleStmt(String * str,RuleStmt * node)4798 _outRuleStmt(String * str, RuleStmt *node)
4799 {
4800 string_append_char(str, "CREATE ");
4801 if (node->replace)
4802 string_append_char(str, "OR REPLACE ");
4803 string_append_char(str, "RULE \"");
4804 string_append_char(str, node->rulename);
4805 string_append_char(str, "\" AS ON ");
4806
4807 switch (node->event)
4808 {
4809 case CMD_SELECT:
4810 string_append_char(str, "SELECT");
4811 break;
4812
4813 case CMD_UPDATE:
4814 string_append_char(str, "UPDATE");
4815 break;
4816
4817 case CMD_DELETE:
4818 string_append_char(str, "DELETE");
4819 break;
4820
4821 case CMD_INSERT:
4822 string_append_char(str, "INSERT");
4823 break;
4824
4825 default:
4826 break;
4827 }
4828
4829 string_append_char(str, " TO ");
4830 _outNode(str, node->relation);
4831
4832 if (node->whereClause)
4833 {
4834 string_append_char(str, " WHERE ");
4835 _outNode(str, node->whereClause);
4836 }
4837
4838 string_append_char(str, " DO ");
4839
4840 if (node->instead)
4841 string_append_char(str, "INSTEAD ");
4842
4843 if (node->actions == NIL)
4844 string_append_char(str, "NOTHING");
4845 else if (list_length(node->actions) == 1)
4846 _outNode(str, linitial(node->actions));
4847 else
4848 {
4849 ListCell *lc;
4850 char semi = 0;
4851
4852 string_append_char(str, "(");
4853
4854 foreach(lc, node->actions)
4855 {
4856 if (semi == 0)
4857 semi = 1;
4858 else
4859 string_append_char(str, ";");
4860
4861 _outNode(str, lfirst(lc));
4862 }
4863
4864 string_append_char(str, ")");
4865 }
4866 }
4867
4868 static void
_outViewStmt(String * str,ViewStmt * node)4869 _outViewStmt(String * str, ViewStmt *node)
4870 {
4871 if (node->replace)
4872 string_append_char(str, "CREATE OR REPLACE ");
4873 else
4874 string_append_char(str, "CREATE ");
4875
4876 if (node->view->relpersistence == RELPERSISTENCE_TEMP)
4877 string_append_char(str, "TEMP ");
4878
4879 string_append_char(str, "VIEW ");
4880 _outNode(str, node->view);
4881
4882 if (node->aliases)
4883 {
4884 string_append_char(str, "(");
4885 _outIdList(str, node->aliases);
4886 string_append_char(str, ")");
4887 }
4888
4889 string_append_char(str, " AS");
4890 _outNode(str, node->query);
4891 }
4892
4893 static void
_outCreatedbOptList(String * str,List * options)4894 _outCreatedbOptList(String * str, List *options)
4895 {
4896 ListCell *lc;
4897
4898 foreach(lc, options)
4899 {
4900 DefElem *e = lfirst(lc);
4901 Value *v = (Value *) e->arg;
4902
4903 /* keyword */
4904 if (strcmp(e->defname, "template") == 0)
4905 string_append_char(str, " TEMPLATE ");
4906 else if (strcmp(e->defname, "location") == 0)
4907 {
4908 string_append_char(str, " LOCATION ");
4909 }
4910 else if (strcmp(e->defname, "tablespace") == 0)
4911 string_append_char(str, " TABLESPACE ");
4912 else if (strcmp(e->defname, "encoding") == 0)
4913 {
4914 string_append_char(str, " ENCODING ");
4915 }
4916 else if (strcmp(e->defname, "owner") == 0)
4917 string_append_char(str, " OWNER ");
4918 else if (strcmp(e->defname, "connectionlimit") == 0)
4919 string_append_char(str, " CONNECTION LIMIT ");
4920
4921 /* value */
4922 if (v == NULL)
4923 string_append_char(str, "DEFAULT");
4924 else if (IsA((Node *) v, String))
4925 {
4926 string_append_char(str, "'");
4927 string_append_char(str, v->val.str);
4928 string_append_char(str, "'");
4929 }
4930 else
4931 {
4932 char buf[16];
4933
4934 snprintf(buf, sizeof(buf), "%d", v->val.ival);
4935 string_append_char(str, buf);
4936 }
4937 }
4938 }
4939
4940 static void
_outCreatedbStmt(String * str,CreatedbStmt * node)4941 _outCreatedbStmt(String * str, CreatedbStmt *node)
4942 {
4943 string_append_char(str, "CREATE DATABASE \"");
4944 string_append_char(str, node->dbname);
4945 string_append_char(str, "\"");
4946
4947 _outCreatedbOptList(str, node->options);
4948 }
4949
4950 static void
_outAlterDatabaseStmt(String * str,AlterDatabaseStmt * node)4951 _outAlterDatabaseStmt(String * str, AlterDatabaseStmt *node)
4952 {
4953 string_append_char(str, "ALTER DATABASE \"");
4954 string_append_char(str, node->dbname);
4955 string_append_char(str, "\" ");
4956
4957 _outCreatedbOptList(str, node->options);
4958 }
4959
4960 static void
_outAlterDatabaseSetStmt(String * str,AlterDatabaseSetStmt * node)4961 _outAlterDatabaseSetStmt(String * str, AlterDatabaseSetStmt *node)
4962 {
4963 string_append_char(str, "ALTER DATABASE \"");
4964 string_append_char(str, node->dbname);
4965 string_append_char(str, "\" ");
4966
4967 _outNode(str, node->setstmt);
4968 }
4969
4970 static void
_outDropdbStmt(String * str,DropdbStmt * node)4971 _outDropdbStmt(String * str, DropdbStmt *node)
4972 {
4973 string_append_char(str, "DROP DATABASE \"");
4974 string_append_char(str, node->dbname);
4975 string_append_char(str, "\"");
4976 }
4977
4978 static void
_outCreateDomainStmt(String * str,CreateDomainStmt * node)4979 _outCreateDomainStmt(String * str, CreateDomainStmt *node)
4980 {
4981 ListCell *lc;
4982
4983 string_append_char(str, "CREATE DOMAIN ");
4984 _outFuncName(str, node->domainname);
4985 string_append_char(str, " ");
4986 _outNode(str, node->typeName);
4987
4988
4989 foreach(lc, node->constraints)
4990 {
4991 string_append_char(str, " ");
4992 _outNode(str, lfirst(lc));
4993 }
4994 }
4995
4996 static void
_outAlterDomainStmt(String * str,AlterDomainStmt * node)4997 _outAlterDomainStmt(String * str, AlterDomainStmt *node)
4998 {
4999 string_append_char(str, "ALTER DOMAIN ");
5000 _outFuncName(str, node->typeName);
5001
5002 switch (node->subtype)
5003 {
5004 case 'T':
5005 if (node->def)
5006 {
5007 string_append_char(str, " SET DEFAULT ");
5008 _outNode(str, node->def);
5009 }
5010 else
5011 string_append_char(str, " DROP DEFAULT");
5012 break;
5013
5014 case 'N':
5015 string_append_char(str, " DROP NOT NULL");
5016 break;
5017
5018 case 'O':
5019 string_append_char(str, " SET NOT NULL");
5020 break;
5021
5022 case 'C':
5023 string_append_char(str, " ADD ");
5024 _outNode(str, node->def);
5025 break;
5026
5027 case 'X':
5028 string_append_char(str, " DROP CONSTRAINT \"");
5029 string_append_char(str, node->name);
5030 string_append_char(str, "\"");
5031 if (node->behavior == DROP_CASCADE)
5032 string_append_char(str, " CASCADE");
5033 break;
5034 }
5035 }
5036
5037 static void
_outCreateConversionStmt(String * str,CreateConversionStmt * node)5038 _outCreateConversionStmt(String * str, CreateConversionStmt *node)
5039 {
5040 string_append_char(str, "CREATE ");
5041
5042 if (node->def == TRUE)
5043 string_append_char(str, "DEFAULT ");
5044
5045 string_append_char(str, "CONVERSION ");
5046
5047 _outFuncName(str, node->conversion_name);
5048
5049 string_append_char(str, " FOR '");
5050 string_append_char(str, node->for_encoding_name);
5051 string_append_char(str, "' TO '");
5052 string_append_char(str, node->to_encoding_name);
5053 string_append_char(str, " FROM ");
5054 _outFuncName(str, node->func_name);
5055 }
5056
5057 static void
_outPrepareStmt(String * str,PrepareStmt * node)5058 _outPrepareStmt(String * str, PrepareStmt *node)
5059 {
5060 string_append_char(str, "PREPARE \"");
5061 string_append_char(str, node->name);
5062 string_append_char(str, "\" ");
5063
5064 if (node->argtypes != NIL)
5065 {
5066 string_append_char(str, "(");
5067 _outNode(str, node->argtypes);
5068 string_append_char(str, ") ");
5069 }
5070
5071 string_append_char(str, "AS ");
5072 _outNode(str, node->query);
5073 }
5074
5075 static void
_outExecuteStmt(String * str,ExecuteStmt * node)5076 _outExecuteStmt(String * str, ExecuteStmt *node)
5077 {
5078 string_append_char(str, "EXECUTE \"");
5079 string_append_char(str, node->name);
5080 string_append_char(str, "\" ");
5081
5082 if (node->params != NIL)
5083 {
5084 string_append_char(str, "(");
5085 _outNode(str, node->params);
5086 string_append_char(str, ")");
5087 }
5088 }
5089
5090 static void
_outLockStmt(String * str,LockStmt * node)5091 _outLockStmt(String * str, LockStmt *node)
5092 {
5093 string_append_char(str, "LOCK TABLE ");
5094 _outNode(str, node->relations);
5095
5096 string_append_char(str, " IN ");
5097 switch (node->mode)
5098 {
5099 case AccessShareLock:
5100 string_append_char(str, "ACCESS SHARE ");
5101 break;
5102
5103 case RowShareLock:
5104 string_append_char(str, "ROW SHARE ");
5105 break;
5106
5107 case RowExclusiveLock:
5108 string_append_char(str, "ROW EXCLUSIVE ");
5109 break;
5110
5111 case ShareUpdateExclusiveLock:
5112 string_append_char(str, "SHARE UPDATE EXCLUSIVE ");
5113 break;
5114
5115 case ShareLock:
5116 string_append_char(str, "SHARE ");
5117 break;
5118
5119 case ShareRowExclusiveLock:
5120 string_append_char(str, "SHARE ROW EXCLUSIVE ");
5121 break;
5122
5123 case ExclusiveLock:
5124 string_append_char(str, "EXCLUSIVE ");
5125 break;
5126
5127 case AccessExclusiveLock:
5128 string_append_char(str, "ACCESS EXCLUSIVE ");
5129 break;
5130 }
5131 string_append_char(str, "MODE");
5132
5133 if (node->nowait == TRUE)
5134 string_append_char(str, " NOWAIT");
5135 }
5136
5137 static void
_outOperatorArgTypes(String * str,List * args)5138 _outOperatorArgTypes(String * str, List *args)
5139 {
5140 TypeName *left,
5141 *right;
5142
5143 left = linitial(args);
5144 right = lsecond(args);
5145
5146 if (left)
5147 _outNode(str, left);
5148 else
5149 string_append_char(str, "NONE");
5150 string_append_char(str, ", ");
5151 if (right)
5152 _outNode(str, right);
5153 else
5154 string_append_char(str, "NONE");
5155 }
5156
5157 static void
_outCommentStmt(String * str,CommentStmt * node)5158 _outCommentStmt(String * str, CommentStmt *node)
5159 {
5160 TypeName *t;
5161 Value *v;
5162 char buf[16];
5163
5164 string_append_char(str, "COMMENT ON ");
5165
5166 ObjectWithArgs *owa = castNode(ObjectWithArgs, node);
5167
5168 switch (node->objtype)
5169 {
5170 case OBJECT_AGGREGATE:
5171 string_append_char(str, "AGGREGATE ");
5172 _outFuncName(str, owa->objname);
5173 string_append_char(str, "(");
5174
5175 t = linitial(owa->objargs);
5176 if (t)
5177 _outNode(str, t);
5178 else
5179 string_append_char(str, "*");
5180 string_append_char(str, ")");
5181 break;
5182
5183 case OBJECT_FUNCTION:
5184 string_append_char(str, "FUNCTION ");
5185 _outFuncName(str, owa->objname);
5186 string_append_char(str, "(");
5187 _outNode(str, owa->objargs);
5188 string_append_char(str, ")");
5189 break;
5190
5191 case OBJECT_OPERATOR:
5192 string_append_char(str, "OPERATOR ");
5193 _outOperatorName(str, owa->objname);
5194 string_append_char(str, "(");
5195 _outOperatorArgTypes(str, owa->objargs);
5196 string_append_char(str, ")");
5197 break;
5198
5199 case OBJECT_TABCONSTRAINT:
5200 case OBJECT_DOMCONSTRAINT:
5201 string_append_char(str, "CONSTRAINT \"");
5202 v = lsecond(owa->objname);
5203 string_append_char(str, v->val.str);
5204 string_append_char(str, "\" ON ");
5205 _outFuncName(str, linitial(owa->objargs));
5206 break;
5207
5208 case OBJECT_RULE:
5209 string_append_char(str, "RULE \"");
5210 v = lsecond(owa->objname);
5211 string_append_char(str, v->val.str);
5212 string_append_char(str, "\" ON ");
5213 _outFuncName(str, linitial(owa->objargs));
5214 break;
5215
5216 case OBJECT_TRIGGER:
5217 string_append_char(str, "TRIGGER \"");
5218 v = lsecond(owa->objname);
5219 string_append_char(str, v->val.str);
5220 string_append_char(str, "\" ON ");
5221 _outFuncName(str, linitial(owa->objargs));
5222 break;
5223
5224 case OBJECT_OPCLASS:
5225 string_append_char(str, "OPERATOR CLASS ");
5226 _outFuncName(str, owa->objname);
5227 string_append_char(str, " USING ");
5228 v = linitial(owa->objargs);
5229 string_append_char(str, v->val.str);
5230 break;
5231
5232 case OBJECT_LARGEOBJECT:
5233 string_append_char(str, "LARGE OBJECT ");
5234 v = linitial(owa->objname);
5235 if (IsA(v, String))
5236 string_append_char(str, v->val.str);
5237 else if (IsA(v, Integer))
5238 {
5239 snprintf(buf, 16, "%d", v->val.ival);
5240 string_append_char(str, buf);
5241 }
5242 break;
5243
5244 case OBJECT_CAST:
5245 string_append_char(str, "CAST (");
5246 _outNode(str, linitial(owa->objname));
5247 string_append_char(str, " AS ");
5248 _outNode(str, linitial(owa->objargs));
5249 string_append_char(str, ")");
5250 break;
5251
5252 case OBJECT_LANGUAGE:
5253 string_append_char(str, "LANGUAGE ");
5254 _outFuncName(str, owa->objname);
5255 break;
5256
5257 default:
5258 switch (node->objtype)
5259 {
5260 case OBJECT_COLUMN:
5261 string_append_char(str, "COLUMN ");
5262 break;
5263 case OBJECT_DATABASE:
5264 string_append_char(str, "DATABASE ");
5265 break;
5266 case OBJECT_SCHEMA:
5267 string_append_char(str, "SCHEMA ");
5268 break;
5269 case OBJECT_INDEX:
5270 string_append_char(str, "INDEX ");
5271 break;
5272 case OBJECT_SEQUENCE:
5273 string_append_char(str, "SEQUENCE ");
5274 break;
5275 case OBJECT_TABLE:
5276 string_append_char(str, "TABLE ");
5277 break;
5278 case OBJECT_DOMAIN:
5279 string_append_char(str, "DOMAIN ");
5280 break;
5281 case OBJECT_TYPE:
5282 string_append_char(str, "TYPE ");
5283 break;
5284 case OBJECT_VIEW:
5285 string_append_char(str, "VIEW ");
5286 break;
5287 default:
5288 break;
5289 }
5290 _outFuncName(str, owa->objname);
5291 break;
5292 }
5293
5294 string_append_char(str, " IS ");
5295 if (node->comment)
5296 {
5297 string_append_char(str, "'");
5298 string_append_char(str, node->comment);
5299 string_append_char(str, "'");
5300 }
5301 else
5302 string_append_char(str, "NULL");
5303 }
5304
5305 static void
_outRangeSubselect(String * str,RangeSubselect * node)5306 _outRangeSubselect(String * str, RangeSubselect *node)
5307 {
5308 string_append_char(str, "(");
5309 _outNode(str, node->subquery);
5310 string_append_char(str, ")");
5311
5312 _outNode(str, node->alias);
5313 }
5314
5315 /*TODO*/
5316 static void
_outRangeFunction(String * str,RangeFunction * node)5317 _outRangeFunction(String * str, RangeFunction *node)
5318 {
5319 _outNode(str, node->functions);
5320 //TODO
5321 if (node->alias)
5322 {
5323 _outNode(str, node->alias);
5324 }
5325
5326 if (node->coldeflist)
5327 {
5328 string_append_char(str, " (");
5329 _outNode(str, node->coldeflist);
5330 string_append_char(str, ")");
5331 }
5332 }
5333
5334 static void
_outRangeTableSample(String * str,RangeTableSample * node)5335 _outRangeTableSample(String * str, RangeTableSample *node)
5336 {
5337 _outNode(str, node->relation);
5338 string_append_char(str, " TABLESAMPLE ");
5339 _outFuncName(str, node->method);
5340 string_append_char(str, " (");
5341 _outNode(str, node->args);
5342 string_append_char(str, ")");
5343
5344 if (node->repeatable)
5345 {
5346 string_append_char(str, " REPEATABLE (");
5347 _outNode(str, node->repeatable);
5348 string_append_char(str, ")");
5349 }
5350 }
5351
5352 static void
_outRangeTableFunc(String * str,RangeTableFunc * node)5353 _outRangeTableFunc(String * str, RangeTableFunc *node)
5354 {
5355 }
5356
5357 static void
_outRangeTableFuncCol(String * str,RangeTableFuncCol * node)5358 _outRangeTableFuncCol(String * str, RangeTableFuncCol *node)
5359 {
5360 }
5361
5362 static void
_outDiscardStmt(String * str,DiscardStmt * node)5363 _outDiscardStmt(String * str, DiscardStmt *node)
5364 {
5365 switch (node->target)
5366 {
5367 case DISCARD_ALL:
5368 string_append_char(str, "DISCARD ALL");
5369 break;
5370
5371 case DISCARD_TEMP:
5372 string_append_char(str, "DISCARD TEMP");
5373 break;
5374
5375 case DISCARD_PLANS:
5376 string_append_char(str, "DISCARD PLANS");
5377 break;
5378
5379 default:
5380 break;
5381 }
5382 }
5383
5384 static void
_outCreateOpFamilyStmt(String * str,CreateOpFamilyStmt * node)5385 _outCreateOpFamilyStmt(String * str, CreateOpFamilyStmt *node)
5386 {
5387 string_append_char(str, "CREATE OPERATOR FAMILY ");
5388 _outIdList(str, node->opfamilyname);
5389 string_append_char(str, " USING \"");
5390 string_append_char(str, node->amname);
5391 string_append_char(str, "\"");
5392 }
5393
5394 static void
_outAlterOpFamilyStmt(String * str,AlterOpFamilyStmt * node)5395 _outAlterOpFamilyStmt(String * str, AlterOpFamilyStmt *node)
5396 {
5397 }
5398
5399 static void
_outCreateEnumStmt(String * str,CreateEnumStmt * node)5400 _outCreateEnumStmt(String * str, CreateEnumStmt *node)
5401 {
5402 string_append_char(str, "CREATE TYPE ");
5403 _outIdList(str, node->typeName);
5404 string_append_char(str, " AS ENUM (");
5405 _outNode(str, node->vals);
5406 string_append_char(str, ")");
5407 }
5408
5409 static void
_outDropOwnedStmt(String * str,DropOwnedStmt * node)5410 _outDropOwnedStmt(String * str, DropOwnedStmt *node)
5411 {
5412 string_append_char(str, "DROP OWNED BY ");
5413 _outIdList(str, node->roles);
5414 if (node->behavior == DROP_CASCADE)
5415 string_append_char(str, " CASCADE");
5416 }
5417
5418 static void
_outReassignOwnedStmt(String * str,ReassignOwnedStmt * node)5419 _outReassignOwnedStmt(String * str, ReassignOwnedStmt *node)
5420 {
5421 string_append_char(str, "REASSIGN OWNED BY ");
5422 _outIdList(str, node->roles);
5423 string_append_char(str, " TO \"");
5424 _outNode(str, node->newrole);
5425 string_append_char(str, "\"");
5426 }
5427
5428 static void
_outAlterTSDictionaryStmt(String * str,AlterTSDictionaryStmt * node)5429 _outAlterTSDictionaryStmt(String * str, AlterTSDictionaryStmt *node)
5430 {
5431 string_append_char(str, "ALTER TEXT SEARCH DICTIONARY ");
5432 _outIdList(str, node->dictname);
5433 string_append_char(str, "(");
5434 _outNode(str, node->options);
5435 string_append_char(str, ")");
5436 }
5437
5438 static void
_outAlterTSConfigurationStmt(String * str,AlterTSConfigurationStmt * node)5439 _outAlterTSConfigurationStmt(String * str, AlterTSConfigurationStmt *node)
5440 {
5441 string_append_char(str, "ALTER TEXT SEARCH CONFIGURATION ");
5442 _outIdList(str, node->cfgname);
5443 if (node->override == false && node->replace == false)
5444 {
5445 string_append_char(str, "ADD MAPPING FOR ");
5446 _outIdList(str, node->tokentype);
5447 string_append_char(str, " WITH ");
5448 _outIdList(str, node->dicts);
5449 }
5450 else if (node->override == true && node->replace == false)
5451 {
5452 string_append_char(str, "ALTER MAPPING FOR ");
5453 _outIdList(str, node->tokentype);
5454 string_append_char(str, " WITH ");
5455 _outIdList(str, node->dicts);
5456 }
5457 else if (node->override == false && node->replace == true)
5458 {
5459 if (node->tokentype == NIL)
5460 string_append_char(str, "ALTER MAPPING ");
5461 else
5462 {
5463 string_append_char(str, "ALTER MAPPING FOR ");
5464 _outIdList(str, node->tokentype);
5465 }
5466 string_append_char(str, "REPLACE ");
5467 _outNode(str, linitial(node->dicts));
5468 string_append_char(str, " WITH ");
5469 _outNode(str, lsecond(node->dicts));
5470 }
5471 else if (node->missing_ok == false)
5472 {
5473 string_append_char(str, " DROP MAPPING FOR ");
5474 _outIdList(str, node->tokentype);
5475 }
5476 else if (node->missing_ok == true)
5477 {
5478 string_append_char(str, " DROP MAPPING IF EXISTS FOR ");
5479 _outIdList(str, node->tokentype);
5480 }
5481 }
5482
5483 static void
_outXmlExpr(String * str,XmlExpr * node)5484 _outXmlExpr(String * str, XmlExpr *node)
5485 {
5486 A_Const *n;
5487
5488 switch (node->op)
5489 {
5490 case IS_DOCUMENT:
5491 _outNode(str, node->args);
5492 string_append_char(str, " IS DOCUMENT");
5493 break;
5494
5495 case IS_XMLCONCAT:
5496 string_append_char(str, "XMLCONCAT (");
5497 _outNode(str, node->args);
5498 string_append_char(str, ")");
5499 break;
5500
5501 case IS_XMLELEMENT:
5502 string_append_char(str, "XMLELEMENT (");
5503 if (node->name)
5504 {
5505 string_append_char(str, "NAME \"");
5506 string_append_char(str, node->name);
5507 string_append_char(str, "\"");
5508 if (node->named_args != NIL)
5509 {
5510 string_append_char(str, ",");
5511 _outIdList(str, node->named_args);
5512 }
5513 }
5514 if (node->args != NIL)
5515 {
5516 string_append_char(str, ",");
5517 _outNode(str, node->args);
5518 }
5519 string_append_char(str, ")");
5520 break;
5521
5522 case IS_XMLFOREST:
5523 string_append_char(str, "XMLFOREST (");
5524 _outNode(str, node->named_args);
5525 string_append_char(str, ")");
5526 break;
5527
5528 case IS_XMLPARSE:
5529 string_append_char(str, "XMLPARSE (");
5530 if (node->xmloption == XMLOPTION_DOCUMENT)
5531 string_append_char(str, "DOCUMENT ");
5532 else
5533 string_append_char(str, "CONTENT ");
5534
5535 _outNode(str, linitial(node->args));
5536 n = lsecond(node->args);
5537 {
5538 Node *arg = ((TypeCast *) n)->arg;
5539
5540 if (((A_Const *) arg)->val.val.str[0] == 't')
5541 string_append_char(str, " PRESERVE WHITESPACE");
5542 }
5543
5544 string_append_char(str, ")");
5545 break;
5546
5547
5548 default:
5549 break;
5550 }
5551 }
5552
5553 static void
_outXmlSerialize(String * str,XmlSerialize * node)5554 _outXmlSerialize(String * str, XmlSerialize *node)
5555 {
5556
5557 }
5558
5559 static void
_outWithDefinition(String * str,List * def_list)5560 _outWithDefinition(String * str, List *def_list)
5561 {
5562 int oid = 0;
5563
5564 if (list_length(def_list) == 1)
5565 {
5566 DefElem *elem;
5567
5568 elem = linitial(def_list);
5569 if (strcmp(elem->defname, "oids") == 0)
5570 {
5571 Value *v = (Value *) elem->arg;
5572
5573 if (v->val.ival == 1)
5574 string_append_char(str, " WITH OIDS ");
5575 else
5576 string_append_char(str, " WITHOUT OIDS ");
5577 oid = 1;
5578 }
5579 }
5580
5581 if (oid == 1)
5582 return;
5583
5584 string_append_char(str, " WITH ");
5585 _outDefinition(str, def_list);
5586 }
5587
5588 static void
_outOnConflictClause(String * str,OnConflictClause * node)5589 _outOnConflictClause(String * str, OnConflictClause *node)
5590 {
5591 string_append_char(str, " ON CONFLICT ");
5592
5593 if (node->infer)
5594 {
5595 if (node->infer->indexElems != NIL)
5596 {
5597 string_append_char(str, " ( ");
5598 _outList(str, node->infer->indexElems);
5599 string_append_char(str, " ) ");
5600
5601 if (node->infer->whereClause)
5602 {
5603 string_append_char(str, " WHERE ");
5604 _outNode(str, node->infer->whereClause);
5605 }
5606 }
5607 else
5608 {
5609 string_append_char(str, " ON CONSTRAINT ");
5610 string_append_char(str, node->infer->conname);
5611 }
5612 }
5613
5614 switch (node->action)
5615 {
5616 case ONCONFLICT_UPDATE:
5617 string_append_char(str, " DO UPDATE ");
5618 break;
5619
5620 case ONCONFLICT_NOTHING:
5621 string_append_char(str, " DO NOTHING ");
5622 break;
5623
5624 default:
5625 break;
5626 }
5627
5628 if (node->targetList)
5629 {
5630 _outSetClause(str, node->targetList);
5631 }
5632
5633 if (node->whereClause)
5634 {
5635 string_append_char(str, " WHERE ");
5636 _outNode(str, node->whereClause);
5637 }
5638 }
5639
5640 static void
_outPartitionElem(String * str,PartitionElem * node)5641 _outPartitionElem(String * str, PartitionElem *node)
5642 {
5643 }
5644
5645 static void
_outPartitionSpec(String * str,PartitionSpec * node)5646 _outPartitionSpec(String * str, PartitionSpec *node)
5647 {
5648 }
5649
5650 static void
_outPartitionBoundSpec(String * str,PartitionBoundSpec * node)5651 _outPartitionBoundSpec(String * str, PartitionBoundSpec *node)
5652 {
5653 }
5654
5655 static void
_outPartitionRangeDatum(String * str,PartitionRangeDatum * node)5656 _outPartitionRangeDatum(String * str, PartitionRangeDatum *node)
5657 {
5658 }
5659
5660 /*
5661 * _outNode -
5662 * converts a Node into ascii string and append it to 'str'
5663 */
5664 void
_outNode(String * str,void * obj)5665 _outNode(String * str, void *obj)
5666 {
5667 /* Guard against stack overflow due to overly complex expressions */
5668 /*
5669 * check_stack_depth();
5670 */
5671
5672 if (obj == NULL)
5673 return;
5674 else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList))
5675 _outList(str, obj);
5676 else if (IsA(obj, Integer) ||
5677 IsA(obj, Float) ||
5678 IsA(obj, String) ||
5679 IsA(obj, BitString))
5680 {
5681 /* nodeRead does not want to see { } around these! */
5682 _outValue(str, obj);
5683 }
5684 else
5685 {
5686 switch (nodeTag(obj))
5687 {
5688 case T_Alias:
5689 _outAlias(str, obj);
5690 break;
5691 case T_RangeVar:
5692 _outRangeVar(str, obj);
5693 break;
5694
5695 /*
5696 * case T_IntoClause: _outIntoClause(str, obj); break;
5697 */
5698 case T_Var:
5699 _outVar(str, obj);
5700 break;
5701 case T_Const:
5702 _outConst(str, obj);
5703 break;
5704 case T_Param:
5705 _outParam(str, obj);
5706 break;
5707 case T_Aggref:
5708 _outAggref(str, obj);
5709 break;
5710 case T_GroupingFunc:
5711 _outGroupingFunc(str, obj);
5712 break;
5713
5714 /*
5715 * case T_WindowFunc: _outWindowFunc(str, obj); break;
5716 */
5717 case T_SubscriptingRef:
5718 _outSubscriptingRef(str, obj);
5719 break;
5720 case T_FuncExpr:
5721 _outFuncExpr(str, obj);
5722 break;
5723 case T_NamedArgExpr:
5724 _outNamedArgExpr(str, obj);
5725 break;
5726 case T_OpExpr:
5727 _outOpExpr(str, obj);
5728 break;
5729 case T_DistinctExpr:
5730 _outDistinctExpr(str, obj);
5731 break;
5732 case T_NullIfExpr:
5733 _outNullIfExpr(str, obj);
5734 break;
5735 case T_ScalarArrayOpExpr:
5736 _outScalarArrayOpExpr(str, obj);
5737 break;
5738 case T_BoolExpr:
5739 _outBoolExpr(str, obj);
5740 break;
5741 case T_SubLink:
5742 _outSubLink(str, obj);
5743 break;
5744 case T_SubPlan:
5745 _outSubPlan(str, obj);
5746 break;
5747
5748 /*
5749 * case T_AlternativeSubPlan: _outAlternativeSubPlan(str,
5750 * obj); break;
5751 */
5752 case T_FieldSelect:
5753 _outFieldSelect(str, obj);
5754 break;
5755 case T_FieldStore:
5756 _outFieldStore(str, obj);
5757 break;
5758 case T_RelabelType:
5759 _outRelabelType(str, obj);
5760 break;
5761
5762 /*
5763 * case T_CoerceViaIO: _outCoerceViaIO(str, obj); break; case
5764 * T_ArrayCoerceExpr: _outArrayCoerceExpr(str, obj); break;
5765 */
5766 case T_ConvertRowtypeExpr:
5767 _outConvertRowtypeExpr(str, obj);
5768 break;
5769
5770 /*
5771 * case T_CollateExpr: _outCollateExpr(str, obj); break;
5772 */
5773 case T_CaseExpr:
5774 _outCaseExpr(str, obj);
5775 break;
5776 case T_CaseWhen:
5777 _outCaseWhen(str, obj);
5778 break;
5779 case T_CaseTestExpr:
5780 _outCaseTestExpr(str, obj);
5781 break;
5782 case T_ArrayExpr:
5783 _outArrayExpr(str, obj);
5784 break;
5785 case T_RowExpr:
5786 _outRowExpr(str, obj);
5787 break;
5788
5789 /*
5790 * case T_RowCompareExpr: _outRowCompareExpr(str, obj); break;
5791 */
5792 case T_CoalesceExpr:
5793 _outCoalesceExpr(str, obj);
5794 break;
5795 case T_MinMaxExpr:
5796 _outMinMaxExpr(str, obj);
5797 break;
5798
5799 /*
5800 * case T_SQLValueFunction: _outSQLValueFunction(str, obj);
5801 */
5802 break;
5803 case T_XmlExpr:
5804 _outXmlExpr(str, obj);
5805 break;
5806 case T_NullTest:
5807 _outNullTest(str, obj);
5808 break;
5809 case T_BooleanTest:
5810 _outBooleanTest(str, obj);
5811 break;
5812 case T_CoerceToDomain:
5813 _outCoerceToDomain(str, obj);
5814 break;
5815 case T_CoerceToDomainValue:
5816 _outCoerceToDomainValue(str, obj);
5817 break;
5818 case T_SetToDefault:
5819 _outSetToDefault(str, obj);
5820 break;
5821 case T_CurrentOfExpr:
5822 _outCurrentOfExpr(str, obj);
5823 break;
5824
5825 /*
5826 * case T_NextValueExpr: _outNextValueExpr(str, obj); break;
5827 */
5828 case T_InferenceElem:
5829 _outInferenceElem(str, obj);
5830 break;
5831 case T_TargetEntry:
5832 _outTargetEntry(str, obj);
5833 break;
5834 case T_RangeTblRef:
5835 _outRangeTblRef(str, obj);
5836 break;
5837 case T_JoinExpr:
5838 _outJoinExpr(str, obj);
5839 break;
5840 case T_FromExpr:
5841 _outFromExpr(str, obj);
5842 break;
5843 case T_OnConflictExpr:
5844 _outOnConflictExpr(str, obj);
5845 break;
5846 #ifdef NOT_USED
5847 case T_ExtensibleNode:
5848 _outExtensibleNode(str, obj);
5849 break;
5850 #endif
5851 case T_CreateStmt:
5852 _outCreateStmt(str, obj);
5853 break;
5854 case T_CreateTableAsStmt:
5855 _outCreateTableAsStmt(str, obj);
5856 break;
5857 case T_CreateForeignTableStmt:
5858 _outCreateForeignTableStmt(str, obj);
5859 break;
5860 case T_ImportForeignSchemaStmt:
5861 _outImportForeignSchemaStmt(str, obj);
5862 break;
5863 case T_IndexStmt:
5864 _outIndexStmt(str, obj);
5865 break;
5866 case T_CreateStatsStmt:
5867 _outCreateStatsStmt(str, obj);
5868 break;
5869 case T_AlterStatsStmt:
5870 _outAlterStatsStmt(str, obj);
5871 break;
5872 case T_NotifyStmt:
5873 _outNotifyStmt(str, obj);
5874 break;
5875 case T_DeclareCursorStmt:
5876 _outDeclareCursorStmt(str, obj);
5877 break;
5878 case T_SelectStmt:
5879 _outSelectStmt(str, obj);
5880 break;
5881 case T_ReturnStmt:
5882 _outReturnStmt(str, obj);
5883 break;
5884 case T_PLAssignStmt:
5885 _outPLAssignStmt(str, obj);
5886 break;
5887 case T_ColumnDef:
5888 _outColumnDef(str, obj);
5889 break;
5890 case T_TypeName:
5891 _outTypeName(str, obj);
5892 break;
5893 case T_TypeCast:
5894 _outTypeCast(str, obj);
5895 break;
5896 case T_CollateClause:
5897 _outCollateClause(str, obj);
5898 break;
5899 case T_IndexElem:
5900 _outIndexElem(str, obj);
5901 break;
5902
5903 /*
5904 * case T_Query: _outQuery(str, obj); break; case
5905 * T_WithCheckOption: _outWithCheckOption(str, obj); break;
5906 * case T_SortGroupClause: _outSortGroupClause(str, obj);
5907 * break;
5908 */
5909 case T_GroupingSet:
5910 _outGroupingSet(str, obj);
5911 break;
5912
5913 /*
5914 * case T_WindowClause: _outWindowClause(str, obj); break;
5915 * case T_RowMarkClause: _outRowMarkClause(str, obj); break;
5916 */
5917 case T_WithClause:
5918 _outWithClause(str, obj);
5919 break;
5920 case T_CTESearchClause:
5921 _outCTESearchClause(str, obj);
5922 break;
5923 case T_CTECycleClause:
5924 _outCTECycleClause(str, obj);
5925 break;
5926 case T_CommonTableExpr:
5927 _outCommonTableExpr(str, obj);
5928 break;
5929 case T_SetOperationStmt:
5930 _outSetOperationStmt(str, obj);
5931 break;
5932
5933 /*
5934 * case T_RangeTblEntry: _outRangeTblEntry(str, obj); break;
5935 */
5936 case T_TableSampleClause:
5937 _outTableSampleClause(str, obj);
5938 break;
5939 case T_A_Expr:
5940 _outAExpr(str, obj);
5941 break;
5942 case T_ColumnRef:
5943 _outColumnRef(str, obj);
5944 break;
5945 case T_ParamRef:
5946 _outParamRef(str, obj);
5947 break;
5948 case T_RawStmt:
5949 _outRawStmt(str, obj);
5950 break;
5951 case T_A_Const:
5952 _outAConst(str, obj);
5953 break;
5954
5955 /*
5956 * case T_A_Star: _outA_Star(str, obj); break;
5957 */
5958 case T_A_Indices:
5959 _outA_Indices(str, obj);
5960 break;
5961 case T_A_Indirection:
5962 _outA_Indirection(str, obj);
5963 break;
5964 case T_A_ArrayExpr:
5965 _outA_ArrayExpr(str, obj);
5966 break;
5967 case T_ResTarget:
5968 _outResTarget(str, obj);
5969 break;
5970 case T_MultiAssignRef:
5971 _outMultiAssignRef(str, obj);
5972 break;
5973 case T_SortBy:
5974 _outSortBy(str, obj);
5975 break;
5976 case T_WindowDef:
5977 _outWindowDef(str, obj);
5978 break;
5979 case T_RangeSubselect:
5980 _outRangeSubselect(str, obj);
5981 break;
5982 case T_RangeFunction:
5983 _outRangeFunction(str, obj);
5984 break;
5985 case T_RangeTableSample:
5986 _outRangeTableSample(str, obj);
5987 break;
5988 case T_RangeTableFunc:
5989 _outRangeTableFunc(str, obj);
5990 break;
5991 case T_RangeTableFuncCol:
5992 _outRangeTableFuncCol(str, obj);
5993 break;
5994 case T_Constraint:
5995 _outConstraint(str, obj);
5996 break;
5997 case T_FuncCall:
5998 _outFuncCall(str, obj);
5999 break;
6000 case T_DefElem:
6001 _outDefElem(str, obj);
6002 break;
6003
6004 /*
6005 * case T_TableLikeClause: _outTableLikeClause(str, obj);
6006 * break;
6007 */
6008 case T_LockingClause:
6009 _outLockingClause(str, obj);
6010 break;
6011 case T_XmlSerialize:
6012 _outXmlSerialize(str, obj);
6013 break;
6014 case T_TriggerTransition:
6015 _outTriggerTransition(str, obj);
6016 break;
6017 case T_PartitionElem:
6018 _outPartitionElem(str, obj);
6019 break;
6020 case T_PartitionSpec:
6021 _outPartitionSpec(str, obj);
6022 break;
6023 case T_PartitionBoundSpec:
6024 _outPartitionBoundSpec(str, obj);
6025 break;
6026 case T_PartitionRangeDatum:
6027 _outPartitionRangeDatum(str, obj);
6028 break;
6029
6030 case T_InsertStmt:
6031 _outInsertStmt(str, obj);
6032 break;
6033
6034 case T_DeleteStmt:
6035 _outDeleteStmt(str, obj);
6036 break;
6037
6038 case T_UpdateStmt:
6039 _outUpdateStmt(str, obj);
6040 break;
6041
6042 case T_TransactionStmt:
6043 _outTransactionStmt(str, obj);
6044 break;
6045
6046 case T_TruncateStmt:
6047 _outTruncateStmt(str, obj);
6048 break;
6049
6050 case T_VacuumStmt:
6051 _outVacuumStmt(str, obj);
6052 break;
6053
6054 case T_ExplainStmt:
6055 _outExplainStmt(str, obj);
6056 break;
6057
6058 case T_ClusterStmt:
6059 _outClusterStmt(str, obj);
6060 break;
6061
6062 case T_CheckPointStmt:
6063 _outCheckPointStmt(str, obj);
6064 break;
6065
6066 case T_ClosePortalStmt:
6067 _outClosePortalStmt(str, obj);
6068 break;
6069
6070 case T_ListenStmt:
6071 _outListenStmt(str, obj);
6072 break;
6073
6074 case T_UnlistenStmt:
6075 _outUnlistenStmt(str, obj);
6076 break;
6077
6078 case T_LoadStmt:
6079 _outLoadStmt(str, obj);
6080 break;
6081
6082 case T_CopyStmt:
6083 _outCopyStmt(str, obj);
6084 break;
6085
6086 case T_DeallocateStmt:
6087 _outDeallocateStmt(str, obj);
6088 break;
6089
6090 case T_RenameStmt:
6091 _outRenameStmt(str, obj);
6092 break;
6093
6094 case T_CreateRoleStmt:
6095 _outCreateRoleStmt(str, obj);
6096 break;
6097
6098 case T_AlterRoleStmt:
6099 _outAlterRoleStmt(str, obj);
6100 break;
6101
6102 case T_AlterRoleSetStmt:
6103 _outAlterRoleSetStmt(str, obj);
6104 break;
6105
6106 case T_RoleSpec:
6107 _outRoleSpec(str, obj);
6108 break;
6109
6110 case T_DropRoleStmt:
6111 _outDropRoleStmt(str, obj);
6112 break;
6113
6114 case T_CreateSchemaStmt:
6115 _outCreateSchemaStmt(str, obj);
6116 break;
6117
6118 case T_VariableSetStmt:
6119 _outVariableSetStmt(str, obj);
6120 break;
6121
6122 case T_VariableShowStmt:
6123 _outVariableShowStmt(str, obj);
6124 break;
6125
6126 case T_ConstraintsSetStmt:
6127 _outConstraintsSetStmt(str, obj);
6128 break;
6129
6130 case T_AlterTableStmt:
6131 _outAlterTableStmt(str, obj);
6132 break;
6133
6134 case T_AlterTableCmd:
6135 _outAlterTableCmd(str, obj);
6136 break;
6137
6138 case T_CreateSeqStmt:
6139 _outCreateSeqStmt(str, obj);
6140 break;
6141
6142 case T_AlterSeqStmt:
6143 _outAlterSeqStmt(str, obj);
6144 break;
6145
6146 case T_CreatePLangStmt:
6147 _outCreatePLangStmt(str, obj);
6148 break;
6149
6150 case T_CreateTableSpaceStmt:
6151 _outCreateTableSpaceStmt(str, obj);
6152 break;
6153
6154 case T_DropTableSpaceStmt:
6155 _outDropTableSpaceStmt(str, obj);
6156 break;
6157
6158 case T_CreateTrigStmt:
6159 _outCreateTrigStmt(str, obj);
6160 break;
6161
6162 case T_DefineStmt:
6163 _outDefineStmt(str, obj);
6164 break;
6165
6166 case T_CreateOpClassStmt:
6167 _outCreateOpClassStmt(str, obj);
6168 break;
6169
6170 case T_CreateOpClassItem:
6171 _outCreateOpClassItem(str, obj);
6172 break;
6173
6174 case T_DropStmt:
6175 _outDropStmt(str, obj);
6176 break;
6177
6178 case T_FetchStmt:
6179 _outFetchStmt(str, obj);
6180 break;
6181
6182 case T_GrantStmt:
6183 _outGrantStmt(str, obj);
6184 break;
6185
6186 case T_ObjectWithArgs:
6187 _outObjectWithArgs(str, obj);
6188 break;
6189
6190 case T_FunctionParameter:
6191 _outFunctionParameter(str, obj);
6192 break;
6193
6194 case T_GrantRoleStmt:
6195 _outGrantRoleStmt(str, obj);
6196 break;
6197
6198 case T_CreateFunctionStmt:
6199 _outCreateFunctionStmt(str, obj);
6200 break;
6201
6202 case T_AlterFunctionStmt:
6203 _outAlterFunctionStmt(str, obj);
6204 break;
6205
6206 case T_CreateCastStmt:
6207 _outCreateCastStmt(str, obj);
6208 break;
6209
6210 case T_ReindexStmt:
6211 _outReindexStmt(str, obj);
6212 break;
6213
6214 case T_AlterObjectSchemaStmt:
6215 _outAlterObjectSchemaStmt(str, obj);
6216 break;
6217
6218 case T_AlterOwnerStmt:
6219 _outAlterOwnerStmt(str, obj);
6220 break;
6221
6222 case T_RuleStmt:
6223 _outRuleStmt(str, obj);
6224 break;
6225
6226 case T_ViewStmt:
6227 _outViewStmt(str, obj);
6228 break;
6229
6230 case T_CreatedbStmt:
6231 _outCreatedbStmt(str, obj);
6232 break;
6233
6234 case T_AlterDatabaseStmt:
6235 _outAlterDatabaseStmt(str, obj);
6236 break;
6237
6238 case T_AlterDatabaseSetStmt:
6239 _outAlterDatabaseSetStmt(str, obj);
6240 break;
6241
6242 case T_DropdbStmt:
6243 _outDropdbStmt(str, obj);
6244 break;
6245
6246 case T_CreateDomainStmt:
6247 _outCreateDomainStmt(str, obj);
6248 break;
6249
6250 case T_AlterDomainStmt:
6251 _outAlterDomainStmt(str, obj);
6252 break;
6253
6254 case T_CreateConversionStmt:
6255 _outCreateConversionStmt(str, obj);
6256 break;
6257
6258 case T_PrepareStmt:
6259 _outPrepareStmt(str, obj);
6260 break;
6261
6262 case T_ExecuteStmt:
6263 _outExecuteStmt(str, obj);
6264 break;
6265
6266 case T_LockStmt:
6267 _outLockStmt(str, obj);
6268 break;
6269
6270 case T_CommentStmt:
6271 _outCommentStmt(str, obj);
6272 break;
6273
6274 case T_DiscardStmt:
6275 _outDiscardStmt(str, obj);
6276 break;
6277
6278 case T_CreateOpFamilyStmt:
6279 _outCreateOpFamilyStmt(str, obj);
6280 break;
6281
6282 case T_AlterOpFamilyStmt:
6283 _outAlterOpFamilyStmt(str, obj);
6284 break;
6285
6286 case T_CreateEnumStmt:
6287 _outCreateEnumStmt(str, obj);
6288 break;
6289
6290 case T_DropOwnedStmt:
6291 _outDropOwnedStmt(str, obj);
6292 break;
6293
6294 case T_ReassignOwnedStmt:
6295 _outReassignOwnedStmt(str, obj);
6296 break;
6297
6298 case T_AlterTSDictionaryStmt:
6299 _outAlterTSDictionaryStmt(str, obj);
6300 break;
6301
6302 case T_AlterTSConfigurationStmt:
6303 _outAlterTSConfigurationStmt(str, obj);
6304 break;
6305
6306 case T_OnConflictClause:
6307 _outOnConflictClause(str, obj);
6308 break;
6309
6310 default:
6311 break;
6312 }
6313 }
6314 }
6315
6316 /*
6317 * nodeToString -
6318 * returns the ascii representation of the Node as a palloc'd string
6319 */
6320 char *
nodeToString(const void * obj)6321 nodeToString(const void *obj)
6322 {
6323 String *str;
6324 char *p;
6325
6326 str = init_string("");
6327 _outNode(str, (void *) obj);
6328 p = palloc(str->len + 1);
6329 memcpy(p, str->data, str->len);
6330 *(p + str->len) = '\0';
6331
6332 free_string(str);
6333
6334 return p;
6335 }
6336