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 "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 42 : PG_MODULE_MAGIC; 20 : 21 42 : PG_FUNCTION_INFO_V1(get_command_type); 22 42 : PG_FUNCTION_INFO_V1(get_command_tag); 23 8 : 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 374 : get_command_type(PG_FUNCTION_ARGS) 31 : { 32 374 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0); 33 : const char *type; 34 : 35 374 : switch (cmd->type) 36 : { 37 280 : case SCT_Simple: 38 280 : type = "simple"; 39 280 : break; 40 62 : case SCT_AlterTable: 41 62 : type = "alter table"; 42 62 : break; 43 24 : case SCT_Grant: 44 24 : type = "grant"; 45 24 : break; 46 2 : case SCT_AlterOpFamily: 47 2 : type = "alter operator family"; 48 2 : break; 49 2 : case SCT_AlterDefaultPrivileges: 50 2 : type = "alter default privileges"; 51 2 : break; 52 2 : case SCT_CreateOpClass: 53 2 : type = "create operator class"; 54 2 : break; 55 2 : case SCT_AlterTSConfig: 56 2 : type = "alter text search configuration"; 57 2 : break; 58 0 : default: 59 0 : type = "unknown command type"; 60 0 : break; 61 : } 62 : 63 374 : 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 374 : get_command_tag(PG_FUNCTION_ARGS) 72 : { 73 374 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0); 74 : 75 374 : if (!cmd->parsetree) 76 24 : PG_RETURN_NULL(); 77 : 78 350 : 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 62 : get_altertable_subcmdinfo(PG_FUNCTION_ARGS) 87 : { 88 62 : CollectedCommand *cmd = (CollectedCommand *) PG_GETARG_POINTER(0); 89 : ListCell *cell; 90 62 : ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; 91 : 92 62 : if (cmd->type != SCT_AlterTable) 93 0 : elog(ERROR, "command is not ALTER TABLE"); 94 : 95 62 : InitMaterializedSRF(fcinfo, 0); 96 : 97 62 : if (cmd->d.alterTable.subcmds == NIL) 98 0 : elog(ERROR, "empty alter table subcommand list"); 99 : 100 152 : foreach(cell, cmd->d.alterTable.subcmds) 101 : { 102 90 : CollectedATSubcmd *sub = lfirst(cell); 103 90 : AlterTableCmd *subcmd = castNode(AlterTableCmd, sub->parsetree); 104 90 : const char *strtype = "unrecognized"; 105 : Datum values[2]; 106 : bool nulls[2]; 107 : 108 90 : memset(values, 0, sizeof(values)); 109 90 : memset(nulls, 0, sizeof(nulls)); 110 : 111 90 : switch (subcmd->subtype) 112 : { 113 2 : case AT_AddColumn: 114 2 : strtype = "ADD COLUMN"; 115 2 : break; 116 0 : case AT_AddColumnToView: 117 0 : strtype = "ADD COLUMN TO VIEW"; 118 0 : break; 119 6 : case AT_ColumnDefault: 120 6 : strtype = "ALTER COLUMN SET DEFAULT"; 121 6 : break; 122 2 : case AT_CookedColumnDefault: 123 2 : strtype = "ALTER COLUMN SET DEFAULT (precooked)"; 124 2 : break; 125 2 : case AT_DropNotNull: 126 2 : strtype = "DROP NOT NULL"; 127 2 : break; 128 4 : case AT_SetNotNull: 129 4 : strtype = "SET NOT NULL"; 130 4 : break; 131 0 : case AT_SetExpression: 132 0 : strtype = "SET EXPRESSION"; 133 0 : break; 134 2 : case AT_DropExpression: 135 2 : strtype = "DROP EXPRESSION"; 136 2 : break; 137 6 : case AT_SetStatistics: 138 6 : strtype = "SET STATS"; 139 6 : 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 6 : case AT_SetStorage: 147 6 : strtype = "SET STORAGE"; 148 6 : break; 149 2 : case AT_SetCompression: 150 2 : strtype = "SET COMPRESSION"; 151 2 : break; 152 0 : case AT_DropColumn: 153 0 : strtype = "DROP COLUMN"; 154 0 : break; 155 2 : case AT_AddIndex: 156 2 : strtype = "ADD INDEX"; 157 2 : break; 158 0 : case AT_ReAddIndex: 159 0 : strtype = "(re) ADD INDEX"; 160 0 : break; 161 12 : case AT_AddConstraint: 162 12 : strtype = "ADD CONSTRAINT"; 163 12 : break; 164 2 : case AT_ReAddConstraint: 165 2 : strtype = "(re) ADD CONSTRAINT"; 166 2 : break; 167 2 : case AT_ReAddDomainConstraint: 168 2 : strtype = "(re) ADD DOMAIN CONSTRAINT"; 169 2 : 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 8 : case AT_AlterColumnType: 186 8 : strtype = "ALTER COLUMN SET TYPE"; 187 8 : 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 2 : case AT_ClusterOn: 195 2 : strtype = "CLUSTER"; 196 2 : break; 197 0 : case AT_DropCluster: 198 0 : strtype = "DROP CLUSTER"; 199 0 : break; 200 2 : case AT_SetLogged: 201 2 : strtype = "SET LOGGED"; 202 2 : break; 203 2 : case AT_SetUnLogged: 204 2 : strtype = "SET UNLOGGED"; 205 2 : 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 2 : case AT_SetRelOptions: 216 2 : strtype = "SET RELOPTIONS"; 217 2 : break; 218 2 : case AT_ResetRelOptions: 219 2 : strtype = "RESET RELOPTIONS"; 220 2 : break; 221 2 : case AT_ReplaceRelOptions: 222 2 : strtype = "REPLACE RELOPTIONS"; 223 2 : 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 2 : case AT_EnableRowSecurity: 276 2 : strtype = "ENABLE ROW SECURITY"; 277 2 : break; 278 2 : case AT_DisableRowSecurity: 279 2 : strtype = "DISABLE ROW SECURITY"; 280 2 : break; 281 2 : case AT_ForceRowSecurity: 282 2 : strtype = "FORCE ROW SECURITY"; 283 2 : break; 284 2 : case AT_NoForceRowSecurity: 285 2 : strtype = "NO FORCE ROW SECURITY"; 286 2 : break; 287 0 : case AT_GenericOptions: 288 0 : strtype = "SET OPTIONS"; 289 0 : break; 290 2 : case AT_DetachPartition: 291 2 : strtype = "DETACH PARTITION"; 292 2 : break; 293 2 : case AT_AttachPartition: 294 2 : strtype = "ATTACH PARTITION"; 295 2 : break; 296 0 : case AT_DetachPartitionFinalize: 297 0 : strtype = "DETACH PARTITION ... FINALIZE"; 298 0 : break; 299 2 : case AT_AddIdentity: 300 2 : strtype = "ADD IDENTITY"; 301 2 : break; 302 2 : case AT_SetIdentity: 303 2 : strtype = "SET IDENTITY"; 304 2 : break; 305 2 : case AT_DropIdentity: 306 2 : strtype = "DROP IDENTITY"; 307 2 : break; 308 2 : case AT_ReAddStatistics: 309 2 : strtype = "(re) ADD STATS"; 310 2 : break; 311 : } 312 : 313 90 : if (subcmd->recurse) 314 24 : values[0] = CStringGetTextDatum(psprintf("%s (and recurse)", strtype)); 315 : else 316 66 : values[0] = CStringGetTextDatum(strtype); 317 90 : if (OidIsValid(sub->address.objectId)) 318 : { 319 : char *objdesc; 320 : 321 72 : objdesc = getObjectDescription((const ObjectAddress *) &sub->address, false); 322 72 : values[1] = CStringGetTextDatum(objdesc); 323 : } 324 : else 325 18 : nulls[1] = true; 326 : 327 90 : tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); 328 : } 329 : 330 62 : return (Datum) 0; 331 : }