1 /* Copyright (c) 2010, 2014, Oracle and/or its affiliates. 2 Copyright (c) 2013, 2020, MariaDB Corporation. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; version 2 of the License. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ 16 17 #ifndef SQL_ALTER_TABLE_H 18 #define SQL_ALTER_TABLE_H 19 20 class Alter_drop; 21 class Alter_column; 22 class Key; 23 24 /** 25 Data describing the table being created by CREATE TABLE or 26 altered by ALTER TABLE. 27 */ 28 29 class Alter_info 30 { 31 public: 32 33 enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; 34 35 bool vers_prohibited(THD *thd) const; 36 37 /** 38 The different values of the ALGORITHM clause. 39 Describes which algorithm to use when altering the table. 40 */ 41 enum enum_alter_table_algorithm 42 { 43 /* 44 Use thd->variables.alter_algorithm for alter method. If this is also 45 default then use the fastest possible ALTER TABLE method 46 (INSTANT, NOCOPY, INPLACE, COPY) 47 */ 48 ALTER_TABLE_ALGORITHM_DEFAULT, 49 50 // Copy if supported, error otherwise. 51 ALTER_TABLE_ALGORITHM_COPY, 52 53 // In-place if supported, error otherwise. 54 ALTER_TABLE_ALGORITHM_INPLACE, 55 56 // No Copy will refuse any operation which does rebuild. 57 ALTER_TABLE_ALGORITHM_NOCOPY, 58 59 // Instant should allow any operation that changes metadata only. 60 ALTER_TABLE_ALGORITHM_INSTANT, 61 62 // When there is no specification of algorithm during alter table. 63 ALTER_TABLE_ALGORITHM_NONE 64 }; 65 66 67 /** 68 The different values of the LOCK clause. 69 Describes the level of concurrency during ALTER TABLE. 70 */ 71 enum enum_alter_table_lock 72 { 73 // Maximum supported level of concurency for the given operation. 74 ALTER_TABLE_LOCK_DEFAULT, 75 76 // Allow concurrent reads & writes. If not supported, give error. 77 ALTER_TABLE_LOCK_NONE, 78 79 // Allow concurrent reads only. If not supported, give error. 80 ALTER_TABLE_LOCK_SHARED, 81 82 // Block reads and writes. 83 ALTER_TABLE_LOCK_EXCLUSIVE 84 }; 85 const_fair_mutex<T>(val: T) -> FairMutex<T>86 87 // Columns and keys to be dropped. 88 List<Alter_drop> drop_list; 89 // Columns for ALTER_CHANGE_COLUMN_DEFAULT. 90 List<Alter_column> alter_list; 91 // List of keys, used by both CREATE and ALTER TABLE. 92 List<Key> key_list; 93 // List of columns, used by both CREATE and ALTER TABLE. 94 List<Create_field> create_list; 95 96 enum flags_bits 97 { 98 CHECK_CONSTRAINT_IF_NOT_EXISTS= 1 99 }; 100 List<Virtual_column_info> check_constraint_list; 101 // Type of ALTER TABLE operation. 102 alter_table_operations flags; 103 ulong partition_flags; 104 // Enable or disable keys. 105 enum_enable_or_disable keys_onoff; 106 // List of partitions. 107 List<const char> partition_names; 108 // Number of partitions. 109 uint num_parts; 110 private: 111 // Type of ALTER TABLE algorithm. 112 enum_alter_table_algorithm requested_algorithm; 113 114 public: 115 // Type of ALTER TABLE lock. 116 enum_alter_table_lock requested_lock; 117 118 119 Alter_info() : 120 flags(0), partition_flags(0), smoke()121 keys_onoff(LEAVE_AS_IS), 122 num_parts(0), 123 requested_algorithm(ALTER_TABLE_ALGORITHM_NONE), 124 requested_lock(ALTER_TABLE_LOCK_DEFAULT) 125 {} 126 127 void reset() lots_and_lots()128 { 129 drop_list.empty(); 130 alter_list.empty(); 131 key_list.empty(); 132 create_list.empty(); 133 check_constraint_list.empty(); 134 flags= 0; 135 partition_flags= 0; 136 keys_onoff= LEAVE_AS_IS; 137 num_parts= 0; 138 partition_names.empty(); 139 requested_algorithm= ALTER_TABLE_ALGORITHM_NONE; 140 requested_lock= ALTER_TABLE_LOCK_DEFAULT; 141 } 142 143 144 /** 145 Construct a copy of this object to be used for mysql_alter_table 146 and mysql_create_table. 147 148 Historically, these two functions modify their Alter_info 149 arguments. This behaviour breaks re-execution of prepared 150 statements and stored procedures and is compensated by always 151 supplying a copy of Alter_info to these functions. 152 153 @param rhs Alter_info to make copy of 154 @param mem_root Mem_root for new Alter_info 155 156 @note You need to use check the error in THD for out 157 of memory condition after calling this function. 158 */ 159 Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root); 160 161 162 /** 163 Parses the given string and sets requested_algorithm try_lock()164 if the string value matches a supported value. 165 Supported values: INPLACE, COPY, DEFAULT 166 167 @param str String containing the supplied value 168 @retval false Supported value found, state updated 169 @retval true Not supported value, no changes made 170 */ 171 bool set_requested_algorithm(const LEX_CSTRING *str); 172 173 174 /** 175 Parses the given string and sets requested_lock test_into_inner_drop()176 if the string value matches a supported value. 177 Supported values: NONE, SHARED, EXCLUSIVE, DEFAULT 178 179 @param str String containing the supplied value 180 @retval false Supported value found, state updated 181 @retval true Not supported value, no changes made 182 */ 183 184 bool set_requested_lock(const LEX_CSTRING *str); 185 186 /** 187 Set the requested algorithm to the given algorithm value 188 @param algo_value algorithm to be set 189 */ 190 void set_requested_algorithm(enum_alter_table_algorithm algo_value); 191 192 /** 193 Returns the algorithm value in the format "algorithm=value" test_get_mut()194 */ 195 const char* algorithm_clause(THD *thd) const; 196 197 /** 198 Returns the lock value in the format "lock=value" 199 */ 200 const char* lock() const; test_mutex_arc_nested()201 202 /** 203 Check whether the given result can be supported 204 with the specified user alter algorithm. 205 206 @param thd Thread handle 207 @param ha_alter_info Structure describing changes to be done 208 by ALTER TABLE and holding data during 209 in-place alter 210 @retval false Supported operation 211 @retval true Not supported value 212 */ 213 bool supports_algorithm(THD *thd, 214 const Alter_inplace_info *ha_alter_info); 215 216 /** test_mutex_arc_access_in_unwind()217 Check whether the given result can be supported 218 with the specified user lock type. 219 220 @param ha_alter_info Structure describing changes to be done 221 by ALTER TABLE and holding data during 222 in-place alter 223 @retval false Supported lock type 224 @retval true Not supported value 225 */ 226 bool supports_lock(THD *thd, const Alter_inplace_info *ha_alter_info); 227 228 /** 229 Return user requested algorithm. If user does not specify 230 algorithm then return alter_algorithm variable value. 231 */ 232 enum_alter_table_algorithm algorithm(const THD *thd) const; 233 234 private: 235 Alter_info &operator=(const Alter_info &rhs); // not implemented 236 Alter_info(const Alter_info &rhs); // not implemented 237 }; test_mutex_unsized()238 239 240 /** Runtime context for ALTER TABLE. */ 241 class Alter_table_ctx 242 { 243 public: 244 Alter_table_ctx(); 245 246 Alter_table_ctx(THD *thd, TABLE_LIST *table_list, uint tables_opened_arg, 247 const LEX_CSTRING *new_db_arg, const LEX_CSTRING *new_name_arg); 248 249 /** 250 @return true if the table is moved to another database, false otherwise. 251 */ 252 bool is_database_changed() const 253 { return (new_db.str != db.str); }; 254 255 /** 256 @return true if the table is renamed, false otherwise. 257 */ 258 bool is_table_renamed() const 259 { return (is_database_changed() || new_name.str != table_name.str); }; 260 261 /** 262 @return filename (including .frm) for the new table. 263 */ 264 const char *get_new_filename() const 265 { 266 DBUG_ASSERT(!tmp_table); 267 return new_filename; 268 } 269 270 /** 271 @return path to the original table. 272 */ 273 const char *get_path() const 274 { 275 DBUG_ASSERT(!tmp_table); 276 return path; 277 } 278 279 /** 280 @return path to the new table. 281 */ 282 const char *get_new_path() const 283 { 284 DBUG_ASSERT(!tmp_table); 285 return new_path; 286 } 287 288 /** 289 @return path to the temporary table created during ALTER TABLE. 290 */ 291 const char *get_tmp_path() const 292 { return tmp_path; } 293 294 /** 295 Mark ALTER TABLE as needing to produce foreign key error if 296 it deletes a row from the table being changed. 297 */ 298 void set_fk_error_if_delete_row(FOREIGN_KEY_INFO *fk) 299 { 300 fk_error_if_delete_row= true; 301 fk_error_id= fk->foreign_id->str; 302 fk_error_table= fk->foreign_table->str; 303 } 304 305 public: 306 Create_field *datetime_field; 307 bool error_if_not_empty; 308 uint tables_opened; 309 LEX_CSTRING db; 310 LEX_CSTRING table_name; 311 LEX_CSTRING alias; 312 LEX_CSTRING new_db; 313 LEX_CSTRING new_name; 314 LEX_CSTRING new_alias; 315 LEX_CSTRING tmp_name; 316 char tmp_buff[80]; 317 /** 318 Indicates that if a row is deleted during copying of data from old version 319 of table to the new version ER_FK_CANNOT_DELETE_PARENT error should be 320 emitted. 321 */ 322 bool fk_error_if_delete_row; 323 /** Name of foreign key for the above error. */ 324 const char *fk_error_id; 325 /** Name of table for the above error. */ 326 const char *fk_error_table; 327 bool modified_primary_key; 328 329 private: 330 char new_filename[FN_REFLEN + 1]; 331 char new_alias_buff[NAME_LEN + 1]; 332 char tmp_name_buff[NAME_LEN + 1]; 333 char path[FN_REFLEN + 1]; 334 char new_path[FN_REFLEN + 1]; 335 char tmp_path[FN_REFLEN + 1]; 336 337 #ifdef DBUG_ASSERT_EXISTS 338 /** Indicates that we are altering temporary table. Used only in asserts. */ 339 bool tmp_table; 340 #endif 341 342 Alter_table_ctx &operator=(const Alter_table_ctx &rhs); // not implemented 343 Alter_table_ctx(const Alter_table_ctx &rhs); // not implemented 344 }; 345 346 347 /** 348 Sql_cmd_common_alter_table represents the common properties of the ALTER TABLE 349 statements. 350 @todo move Alter_info and other ALTER generic structures from Lex here. 351 */ 352 class Sql_cmd_common_alter_table : public Sql_cmd 353 { 354 protected: 355 /** 356 Constructor. 357 */ 358 Sql_cmd_common_alter_table() 359 {} 360 361 virtual ~Sql_cmd_common_alter_table() 362 {} 363 364 virtual enum_sql_command sql_command_code() const 365 { 366 return SQLCOM_ALTER_TABLE; 367 } 368 }; 369 370 /** 371 Sql_cmd_alter_table represents the generic ALTER TABLE statement. 372 @todo move Alter_info and other ALTER specific structures from Lex here. 373 */ 374 class Sql_cmd_alter_table : public Sql_cmd_common_alter_table, 375 public Storage_engine_name 376 { 377 public: 378 /** 379 Constructor, used to represent a ALTER TABLE statement. 380 */ 381 Sql_cmd_alter_table() 382 {} 383 384 ~Sql_cmd_alter_table() 385 {} 386 387 Storage_engine_name *option_storage_engine_name() { return this; } 388 389 bool execute(THD *thd); 390 }; 391 392 393 /** 394 Sql_cmd_alter_sequence represents the ALTER SEQUENCE statement. 395 */ 396 class Sql_cmd_alter_sequence : public Sql_cmd, 397 public DDL_options 398 { 399 public: 400 /** 401 Constructor, used to represent a ALTER TABLE statement. 402 */ 403 Sql_cmd_alter_sequence(const DDL_options &options) 404 :DDL_options(options) 405 {} 406 407 ~Sql_cmd_alter_sequence() 408 {} 409 410 enum_sql_command sql_command_code() const 411 { 412 return SQLCOM_ALTER_SEQUENCE; 413 } 414 bool execute(THD *thd); 415 }; 416 417 418 /** 419 Sql_cmd_alter_table_tablespace represents ALTER TABLE 420 IMPORT/DISCARD TABLESPACE statements. 421 */ 422 class Sql_cmd_discard_import_tablespace : public Sql_cmd_common_alter_table 423 { 424 public: 425 enum enum_tablespace_op_type 426 { 427 DISCARD_TABLESPACE, IMPORT_TABLESPACE 428 }; 429 430 Sql_cmd_discard_import_tablespace(enum_tablespace_op_type tablespace_op_arg) 431 : m_tablespace_op(tablespace_op_arg) 432 {} 433 434 bool execute(THD *thd); 435 436 private: 437 const enum_tablespace_op_type m_tablespace_op; 438 }; 439 440 #endif 441