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