Line data Source code
1 : /*---------------------------------------------------------------------- 2 : * test_ddl_deparse.c 3 : * Support functions for the test_ddl_deparse module 4 : * 5 : * Copyright (c) 2014-2023, 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 2 : case AT_DropExpression: 136 2 : strtype = "DROP EXPRESSION"; 137 2 : break; 138 6 : case AT_SetStatistics: 139 6 : strtype = "SET STATS"; 140 6 : 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 6 : case AT_SetStorage: 148 6 : strtype = "SET STORAGE"; 149 6 : break; 150 2 : case AT_SetCompression: 151 2 : strtype = "SET COMPRESSION"; 152 2 : break; 153 0 : case AT_DropColumn: 154 0 : strtype = "DROP COLUMN"; 155 0 : break; 156 2 : case AT_AddIndex: 157 2 : strtype = "ADD INDEX"; 158 2 : break; 159 0 : case AT_ReAddIndex: 160 0 : strtype = "(re) ADD INDEX"; 161 0 : break; 162 26 : case AT_AddConstraint: 163 26 : strtype = "ADD CONSTRAINT"; 164 26 : break; 165 2 : case AT_ReAddConstraint: 166 2 : strtype = "(re) ADD CONSTRAINT"; 167 2 : break; 168 2 : case AT_ReAddDomainConstraint: 169 2 : strtype = "(re) ADD DOMAIN CONSTRAINT"; 170 2 : 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 8 : case AT_AlterColumnType: 187 8 : strtype = "ALTER COLUMN SET TYPE"; 188 8 : 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 2 : case AT_ClusterOn: 196 2 : strtype = "CLUSTER"; 197 2 : break; 198 0 : case AT_DropCluster: 199 0 : strtype = "DROP CLUSTER"; 200 0 : break; 201 2 : case AT_SetLogged: 202 2 : strtype = "SET LOGGED"; 203 2 : break; 204 2 : case AT_SetUnLogged: 205 2 : strtype = "SET UNLOGGED"; 206 2 : 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 2 : case AT_SetRelOptions: 217 2 : strtype = "SET RELOPTIONS"; 218 2 : break; 219 2 : case AT_ResetRelOptions: 220 2 : strtype = "RESET RELOPTIONS"; 221 2 : 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 2 : case AT_EnableRowSecurity: 277 2 : strtype = "ENABLE ROW SECURITY"; 278 2 : break; 279 2 : case AT_DisableRowSecurity: 280 2 : strtype = "DISABLE ROW SECURITY"; 281 2 : break; 282 2 : case AT_ForceRowSecurity: 283 2 : strtype = "FORCE ROW SECURITY"; 284 2 : break; 285 2 : case AT_NoForceRowSecurity: 286 2 : strtype = "NO FORCE ROW SECURITY"; 287 2 : break; 288 0 : case AT_GenericOptions: 289 0 : strtype = "SET OPTIONS"; 290 0 : break; 291 2 : case AT_DetachPartition: 292 2 : strtype = "DETACH PARTITION"; 293 2 : break; 294 2 : case AT_AttachPartition: 295 2 : strtype = "ATTACH PARTITION"; 296 2 : break; 297 0 : case AT_DetachPartitionFinalize: 298 0 : strtype = "DETACH PARTITION ... FINALIZE"; 299 0 : break; 300 2 : case AT_AddIdentity: 301 2 : strtype = "ADD IDENTITY"; 302 2 : break; 303 2 : case AT_SetIdentity: 304 2 : strtype = "SET IDENTITY"; 305 2 : break; 306 2 : case AT_DropIdentity: 307 2 : strtype = "DROP IDENTITY"; 308 2 : break; 309 2 : case AT_ReAddStatistics: 310 2 : strtype = "(re) ADD STATS"; 311 2 : break; 312 : } 313 : 314 126 : if (subcmd->recurse) 315 32 : values[0] = CStringGetTextDatum(psprintf("%s (and recurse)", strtype)); 316 : else 317 94 : values[0] = CStringGetTextDatum(strtype); 318 126 : if (OidIsValid(sub->address.objectId)) 319 : { 320 : char *objdesc; 321 : 322 94 : objdesc = getObjectDescription((const ObjectAddress *) &sub->address, false); 323 94 : values[1] = CStringGetTextDatum(objdesc); 324 : } 325 : else 326 32 : nulls[1] = true; 327 : 328 126 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); 329 : } 330 : 331 80 : return (Datum) 0; 332 : }