Line data Source code
1 : /*----------------------------------------------------------------------
2 : * test_ddl_deparse.c
3 : * Support functions for the test_ddl_deparse module
4 : *
5 : * Copyright (c) 2014-2026, 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 "funcapi.h"
14 : #include "nodes/execnodes.h"
15 : #include "tcop/deparse_utility.h"
16 : #include "tcop/utility.h"
17 : #include "utils/builtins.h"
18 :
19 0 : PG_MODULE_MAGIC;
20 :
21 0 : PG_FUNCTION_INFO_V1(get_command_type);
22 0 : PG_FUNCTION_INFO_V1(get_command_tag);
23 0 : PG_FUNCTION_INFO_V1(get_altertable_subcmdinfo);
24 :
25 : /*
26 : * Return the textual representation of the struct type used to represent a
27 : * command in struct CollectedCommand format.
28 : */
29 : Datum
30 0 : get_command_type(PG_FUNCTION_ARGS)
31 : {
32 0 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
33 0 : const char *type;
34 :
35 0 : switch (cmd->type)
36 : {
37 : case SCT_Simple:
38 0 : type = "simple";
39 0 : break;
40 : case SCT_AlterTable:
41 0 : type = "alter table";
42 0 : break;
43 : case SCT_Grant:
44 0 : type = "grant";
45 0 : break;
46 : case SCT_AlterOpFamily:
47 0 : type = "alter operator family";
48 0 : break;
49 : case SCT_AlterDefaultPrivileges:
50 0 : type = "alter default privileges";
51 0 : break;
52 : case SCT_CreateOpClass:
53 0 : type = "create operator class";
54 0 : break;
55 : case SCT_AlterTSConfig:
56 0 : type = "alter text search configuration";
57 0 : break;
58 : default:
59 0 : type = "unknown command type";
60 0 : break;
61 : }
62 :
63 0 : PG_RETURN_TEXT_P(cstring_to_text(type));
64 0 : }
65 :
66 : /*
67 : * Return the command tag corresponding to a parse node contained in a
68 : * CollectedCommand struct.
69 : */
70 : Datum
71 0 : get_command_tag(PG_FUNCTION_ARGS)
72 : {
73 0 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
74 :
75 0 : if (!cmd->parsetree)
76 0 : PG_RETURN_NULL();
77 :
78 0 : PG_RETURN_TEXT_P(cstring_to_text(CreateCommandName(cmd->parsetree)));
79 0 : }
80 :
81 : /*
82 : * Return a text array representation of the subcommands of an ALTER TABLE
83 : * command.
84 : */
85 : Datum
86 0 : get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
87 : {
88 0 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0);
89 0 : ListCell *cell;
90 0 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
91 :
92 0 : if (cmd->type != SCT_AlterTable)
93 0 : elog(ERROR, "command is not ALTER TABLE");
94 :
95 0 : InitMaterializedSRF(fcinfo, 0);
96 :
97 0 : if (cmd->d.alterTable.subcmds == NIL)
98 0 : elog(ERROR, "empty alter table subcommand list");
99 :
100 0 : foreach(cell, cmd->d.alterTable.subcmds)
101 : {
102 0 : CollectedATSubcmd *sub = lfirst(cell);
103 0 : AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree);
104 0 : const char *strtype = "unrecognized";
105 0 : Datum values[2];
106 0 : bool nulls[2];
107 :
108 0 : memset(values, 0, sizeof(values));
109 0 : memset(nulls, 0, sizeof(nulls));
110 :
111 0 : switch (subcmd->subtype)
112 : {
113 : case AT_AddColumn:
114 0 : strtype = "ADD COLUMN";
115 0 : break;
116 : case AT_AddColumnToView:
117 0 : strtype = "ADD COLUMN TO VIEW";
118 0 : break;
119 : case AT_ColumnDefault:
120 0 : strtype = "ALTER COLUMN SET DEFAULT";
121 0 : break;
122 : case AT_CookedColumnDefault:
123 0 : strtype = "ALTER COLUMN SET DEFAULT (precooked)";
124 0 : break;
125 : case AT_DropNotNull:
126 0 : strtype = "DROP NOT NULL";
127 0 : break;
128 : case AT_SetNotNull:
129 0 : strtype = "SET NOT NULL";
130 0 : break;
131 : case AT_SetExpression:
132 0 : strtype = "SET EXPRESSION";
133 0 : break;
134 : case AT_DropExpression:
135 0 : strtype = "DROP EXPRESSION";
136 0 : break;
137 : case AT_SetStatistics:
138 0 : strtype = "SET STATS";
139 0 : break;
140 : case AT_SetOptions:
141 0 : strtype = "SET OPTIONS";
142 0 : break;
143 : case AT_ResetOptions:
144 0 : strtype = "RESET OPTIONS";
145 0 : break;
146 : case AT_SetStorage:
147 0 : strtype = "SET STORAGE";
148 0 : break;
149 : case AT_SetCompression:
150 0 : strtype = "SET COMPRESSION";
151 0 : break;
152 : case AT_DropColumn:
153 0 : strtype = "DROP COLUMN";
154 0 : break;
155 : case AT_AddIndex:
156 0 : strtype = "ADD INDEX";
157 0 : break;
158 : case AT_ReAddIndex:
159 0 : strtype = "(re) ADD INDEX";
160 0 : break;
161 : case AT_AddConstraint:
162 0 : strtype = "ADD CONSTRAINT";
163 0 : break;
164 : case AT_ReAddConstraint:
165 0 : strtype = "(re) ADD CONSTRAINT";
166 0 : break;
167 : case AT_ReAddDomainConstraint:
168 0 : strtype = "(re) ADD DOMAIN CONSTRAINT";
169 0 : break;
170 : case AT_AlterConstraint:
171 0 : strtype = "ALTER CONSTRAINT";
172 0 : break;
173 : case AT_ValidateConstraint:
174 0 : strtype = "VALIDATE CONSTRAINT";
175 0 : break;
176 : case AT_AddIndexConstraint:
177 0 : strtype = "ADD CONSTRAINT (using index)";
178 0 : break;
179 : case AT_DropConstraint:
180 0 : strtype = "DROP CONSTRAINT";
181 0 : break;
182 : case AT_ReAddComment:
183 0 : strtype = "(re) ADD COMMENT";
184 0 : break;
185 : case AT_AlterColumnType:
186 0 : strtype = "ALTER COLUMN SET TYPE";
187 0 : break;
188 : case AT_AlterColumnGenericOptions:
189 0 : strtype = "ALTER COLUMN SET OPTIONS";
190 0 : break;
191 : case AT_ChangeOwner:
192 0 : strtype = "CHANGE OWNER";
193 0 : break;
194 : case AT_ClusterOn:
195 0 : strtype = "CLUSTER";
196 0 : break;
197 : case AT_DropCluster:
198 0 : strtype = "DROP CLUSTER";
199 0 : break;
200 : case AT_SetLogged:
201 0 : strtype = "SET LOGGED";
202 0 : break;
203 : case AT_SetUnLogged:
204 0 : strtype = "SET UNLOGGED";
205 0 : break;
206 : case AT_DropOids:
207 0 : strtype = "DROP OIDS";
208 0 : break;
209 : case AT_SetAccessMethod:
210 0 : strtype = "SET ACCESS METHOD";
211 0 : break;
212 : case AT_SetTableSpace:
213 0 : strtype = "SET TABLESPACE";
214 0 : break;
215 : case AT_SetRelOptions:
216 0 : strtype = "SET RELOPTIONS";
217 0 : break;
218 : case AT_ResetRelOptions:
219 0 : strtype = "RESET RELOPTIONS";
220 0 : break;
221 : case AT_ReplaceRelOptions:
222 0 : strtype = "REPLACE RELOPTIONS";
223 0 : break;
224 : case AT_EnableTrig:
225 0 : strtype = "ENABLE TRIGGER";
226 0 : break;
227 : case AT_EnableAlwaysTrig:
228 0 : strtype = "ENABLE TRIGGER (always)";
229 0 : break;
230 : case AT_EnableReplicaTrig:
231 0 : strtype = "ENABLE TRIGGER (replica)";
232 0 : break;
233 : case AT_DisableTrig:
234 0 : strtype = "DISABLE TRIGGER";
235 0 : break;
236 : case AT_EnableTrigAll:
237 0 : strtype = "ENABLE TRIGGER (all)";
238 0 : break;
239 : case AT_DisableTrigAll:
240 0 : strtype = "DISABLE TRIGGER (all)";
241 0 : break;
242 : case AT_EnableTrigUser:
243 0 : strtype = "ENABLE TRIGGER (user)";
244 0 : break;
245 : case AT_DisableTrigUser:
246 0 : strtype = "DISABLE TRIGGER (user)";
247 0 : break;
248 : case AT_EnableRule:
249 0 : strtype = "ENABLE RULE";
250 0 : break;
251 : case AT_EnableAlwaysRule:
252 0 : strtype = "ENABLE RULE (always)";
253 0 : break;
254 : case AT_EnableReplicaRule:
255 0 : strtype = "ENABLE RULE (replica)";
256 0 : break;
257 : case AT_DisableRule:
258 0 : strtype = "DISABLE RULE";
259 0 : break;
260 : case AT_AddInherit:
261 0 : strtype = "ADD INHERIT";
262 0 : break;
263 : case AT_DropInherit:
264 0 : strtype = "DROP INHERIT";
265 0 : break;
266 : case AT_AddOf:
267 0 : strtype = "OF";
268 0 : break;
269 : case AT_DropOf:
270 0 : strtype = "NOT OF";
271 0 : break;
272 : case AT_ReplicaIdentity:
273 0 : strtype = "REPLICA IDENTITY";
274 0 : break;
275 : case AT_EnableRowSecurity:
276 0 : strtype = "ENABLE ROW SECURITY";
277 0 : break;
278 : case AT_DisableRowSecurity:
279 0 : strtype = "DISABLE ROW SECURITY";
280 0 : break;
281 : case AT_ForceRowSecurity:
282 0 : strtype = "FORCE ROW SECURITY";
283 0 : break;
284 : case AT_NoForceRowSecurity:
285 0 : strtype = "NO FORCE ROW SECURITY";
286 0 : break;
287 : case AT_GenericOptions:
288 0 : strtype = "SET OPTIONS";
289 0 : break;
290 : case AT_DetachPartition:
291 0 : strtype = "DETACH PARTITION";
292 0 : break;
293 : case AT_AttachPartition:
294 0 : strtype = "ATTACH PARTITION";
295 0 : break;
296 : case AT_DetachPartitionFinalize:
297 0 : strtype = "DETACH PARTITION ... FINALIZE";
298 0 : break;
299 : case AT_SplitPartition:
300 0 : strtype = "SPLIT PARTITION";
301 0 : break;
302 : case AT_MergePartitions:
303 0 : strtype = "MERGE PARTITIONS";
304 0 : break;
305 : case AT_AddIdentity:
306 0 : strtype = "ADD IDENTITY";
307 0 : break;
308 : case AT_SetIdentity:
309 0 : strtype = "SET IDENTITY";
310 0 : break;
311 : case AT_DropIdentity:
312 0 : strtype = "DROP IDENTITY";
313 0 : break;
314 : case AT_ReAddStatistics:
315 0 : strtype = "(re) ADD STATS";
316 0 : break;
317 : }
318 :
319 0 : if (subcmd->recurse)
320 0 : values[0] = CStringGetTextDatum(psprintf("%s (and recurse)", strtype));
321 : else
322 0 : values[0] = CStringGetTextDatum(strtype);
323 0 : if (OidIsValid(sub->address.objectId))
324 : {
325 0 : char *objdesc;
326 :
327 0 : objdesc = getObjectDescription((const ObjectAddress *) &sub->address, false);
328 0 : values[1] = CStringGetTextDatum(objdesc);
329 0 : }
330 : else
331 0 : nulls[1] = true;
332 :
333 0 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
334 0 : }
335 :
336 0 : return (Datum) 0;
337 0 : }
|