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