1 /*----------------------------------------------------------------------
2  * test_ddl_deparse.c
3  *		Support functions for the test_ddl_deparse module
4  *
5  * Copyright (c) 2014-2018, PostgreSQL Global Development Group
6  *
7  * IDENTIFICATION
8  *	  src/test/modules/test_ddl_deparse/test_ddl_deparse.c
9  *----------------------------------------------------------------------
10  */
11 #include "postgres.h"
12 
13 #include "catalog/pg_type.h"
14 #include "tcop/deparse_utility.h"
15 #include "tcop/utility.h"
16 #include "utils/builtins.h"
17 
18 PG_MODULE_MAGIC;
19 
20 PG_FUNCTION_INFO_V1(get_command_type);
21 PG_FUNCTION_INFO_V1(get_command_tag);
22 PG_FUNCTION_INFO_V1(get_altertable_subcmdtypes);
23 
24 /*
25  * Return the textual representation of the struct type used to represent a
26  * command in struct CollectedCommand format.
27  */
28 Datum
get_command_type(PG_FUNCTION_ARGS)29 get_command_type(PG_FUNCTION_ARGS)
30 {
31 	CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
32 	const char *type;
33 
34 	switch (cmd->type)
35 	{
36 		case SCT_Simple:
37 			type = "simple";
38 			break;
39 		case SCT_AlterTable:
40 			type = "alter table";
41 			break;
42 		case SCT_Grant:
43 			type = "grant";
44 			break;
45 		case SCT_AlterOpFamily:
46 			type = "alter operator family";
47 			break;
48 		case SCT_AlterDefaultPrivileges:
49 			type = "alter default privileges";
50 			break;
51 		case SCT_CreateOpClass:
52 			type = "create operator class";
53 			break;
54 		case SCT_AlterTSConfig:
55 			type = "alter text search configuration";
56 			break;
57 		default:
58 			type = "unknown command type";
59 			break;
60 	}
61 
62 	PG_RETURN_TEXT_P(cstring_to_text(type));
63 }
64 
65 /*
66  * Return the command tag corresponding to a parse node contained in a
67  * CollectedCommand struct.
68  */
69 Datum
get_command_tag(PG_FUNCTION_ARGS)70 get_command_tag(PG_FUNCTION_ARGS)
71 {
72 	CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
73 
74 	if (!cmd->parsetree)
75 		PG_RETURN_NULL();
76 
77 	PG_RETURN_TEXT_P(cstring_to_text(CreateCommandTag(cmd->parsetree)));
78 }
79 
80 /*
81  * Return a text array representation of the subcommands of an ALTER TABLE
82  * command.
83  */
84 Datum
get_altertable_subcmdtypes(PG_FUNCTION_ARGS)85 get_altertable_subcmdtypes(PG_FUNCTION_ARGS)
86 {
87 	CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
88 	ArrayBuildState *astate = NULL;
89 	ListCell   *cell;
90 
91 	if (cmd->type != SCT_AlterTable)
92 		elog(ERROR, "command is not ALTER TABLE");
93 
94 	foreach(cell, cmd->d.alterTable.subcmds)
95 	{
96 		CollectedATSubcmd *sub = lfirst(cell);
97 		AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree);
98 		const char *strtype;
99 
100 		switch (subcmd->subtype)
101 		{
102 			case AT_AddColumn:
103 				strtype = "ADD COLUMN";
104 				break;
105 			case AT_AddColumnRecurse:
106 				strtype = "ADD COLUMN (and recurse)";
107 				break;
108 			case AT_AddColumnToView:
109 				strtype = "ADD COLUMN TO VIEW";
110 				break;
111 			case AT_ColumnDefault:
112 				strtype = "ALTER COLUMN SET DEFAULT";
113 				break;
114 			case AT_DropNotNull:
115 				strtype = "DROP NOT NULL";
116 				break;
117 			case AT_SetNotNull:
118 				strtype = "SET NOT NULL";
119 				break;
120 			case AT_SetStatistics:
121 				strtype = "SET STATS";
122 				break;
123 			case AT_SetOptions:
124 				strtype = "SET OPTIONS";
125 				break;
126 			case AT_ResetOptions:
127 				strtype = "RESET OPTIONS";
128 				break;
129 			case AT_SetStorage:
130 				strtype = "SET STORAGE";
131 				break;
132 			case AT_DropColumn:
133 				strtype = "DROP COLUMN";
134 				break;
135 			case AT_DropColumnRecurse:
136 				strtype = "DROP COLUMN (and recurse)";
137 				break;
138 			case AT_AddIndex:
139 				strtype = "ADD INDEX";
140 				break;
141 			case AT_ReAddIndex:
142 				strtype = "(re) ADD INDEX";
143 				break;
144 			case AT_AddConstraint:
145 				strtype = "ADD CONSTRAINT";
146 				break;
147 			case AT_AddConstraintRecurse:
148 				strtype = "ADD CONSTRAINT (and recurse)";
149 				break;
150 			case AT_ReAddConstraint:
151 				strtype = "(re) ADD CONSTRAINT";
152 				break;
153 			case AT_AlterConstraint:
154 				strtype = "ALTER CONSTRAINT";
155 				break;
156 			case AT_ValidateConstraint:
157 				strtype = "VALIDATE CONSTRAINT";
158 				break;
159 			case AT_ValidateConstraintRecurse:
160 				strtype = "VALIDATE CONSTRAINT (and recurse)";
161 				break;
162 			case AT_ProcessedConstraint:
163 				strtype = "ADD (processed) CONSTRAINT";
164 				break;
165 			case AT_AddIndexConstraint:
166 				strtype = "ADD CONSTRAINT (using index)";
167 				break;
168 			case AT_DropConstraint:
169 				strtype = "DROP CONSTRAINT";
170 				break;
171 			case AT_DropConstraintRecurse:
172 				strtype = "DROP CONSTRAINT (and recurse)";
173 				break;
174 			case AT_ReAddComment:
175 				strtype = "(re) ADD COMMENT";
176 				break;
177 			case AT_AlterColumnType:
178 				strtype = "ALTER COLUMN SET TYPE";
179 				break;
180 			case AT_AlterColumnGenericOptions:
181 				strtype = "ALTER COLUMN SET OPTIONS";
182 				break;
183 			case AT_ChangeOwner:
184 				strtype = "CHANGE OWNER";
185 				break;
186 			case AT_ClusterOn:
187 				strtype = "CLUSTER";
188 				break;
189 			case AT_DropCluster:
190 				strtype = "DROP CLUSTER";
191 				break;
192 			case AT_SetLogged:
193 				strtype = "SET LOGGED";
194 				break;
195 			case AT_SetUnLogged:
196 				strtype = "SET UNLOGGED";
197 				break;
198 			case AT_AddOids:
199 				strtype = "ADD OIDS";
200 				break;
201 			case AT_AddOidsRecurse:
202 				strtype = "ADD OIDS (and recurse)";
203 				break;
204 			case AT_DropOids:
205 				strtype = "DROP OIDS";
206 				break;
207 			case AT_SetTableSpace:
208 				strtype = "SET TABLESPACE";
209 				break;
210 			case AT_SetRelOptions:
211 				strtype = "SET RELOPTIONS";
212 				break;
213 			case AT_ResetRelOptions:
214 				strtype = "RESET RELOPTIONS";
215 				break;
216 			case AT_ReplaceRelOptions:
217 				strtype = "REPLACE RELOPTIONS";
218 				break;
219 			case AT_EnableTrig:
220 				strtype = "ENABLE TRIGGER";
221 				break;
222 			case AT_EnableAlwaysTrig:
223 				strtype = "ENABLE TRIGGER (always)";
224 				break;
225 			case AT_EnableReplicaTrig:
226 				strtype = "ENABLE TRIGGER (replica)";
227 				break;
228 			case AT_DisableTrig:
229 				strtype = "DISABLE TRIGGER";
230 				break;
231 			case AT_EnableTrigAll:
232 				strtype = "ENABLE TRIGGER (all)";
233 				break;
234 			case AT_DisableTrigAll:
235 				strtype = "DISABLE TRIGGER (all)";
236 				break;
237 			case AT_EnableTrigUser:
238 				strtype = "ENABLE TRIGGER (user)";
239 				break;
240 			case AT_DisableTrigUser:
241 				strtype = "DISABLE TRIGGER (user)";
242 				break;
243 			case AT_EnableRule:
244 				strtype = "ENABLE RULE";
245 				break;
246 			case AT_EnableAlwaysRule:
247 				strtype = "ENABLE RULE (always)";
248 				break;
249 			case AT_EnableReplicaRule:
250 				strtype = "ENABLE RULE (replica)";
251 				break;
252 			case AT_DisableRule:
253 				strtype = "DISABLE RULE";
254 				break;
255 			case AT_AddInherit:
256 				strtype = "ADD INHERIT";
257 				break;
258 			case AT_DropInherit:
259 				strtype = "DROP INHERIT";
260 				break;
261 			case AT_AddOf:
262 				strtype = "OF";
263 				break;
264 			case AT_DropOf:
265 				strtype = "NOT OF";
266 				break;
267 			case AT_ReplicaIdentity:
268 				strtype = "REPLICA IDENTITY";
269 				break;
270 			case AT_EnableRowSecurity:
271 				strtype = "ENABLE ROW SECURITY";
272 				break;
273 			case AT_DisableRowSecurity:
274 				strtype = "DISABLE ROW SECURITY";
275 				break;
276 			case AT_ForceRowSecurity:
277 				strtype = "FORCE ROW SECURITY";
278 				break;
279 			case AT_NoForceRowSecurity:
280 				strtype = "NO FORCE ROW SECURITY";
281 				break;
282 			case AT_GenericOptions:
283 				strtype = "SET OPTIONS";
284 				break;
285 			default:
286 				strtype = "unrecognized";
287 				break;
288 		}
289 
290 		astate =
291 			accumArrayResult(astate, CStringGetTextDatum(strtype),
292 							 false, TEXTOID, CurrentMemoryContext);
293 	}
294 
295 	if (astate == NULL)
296 		elog(ERROR, "empty alter table subcommand list");
297 
298 	PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
299 }
300