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