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