1 /* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #ifndef SQL_ALTER_TABLE_H
24 #define SQL_ALTER_TABLE_H
25
26 #include <assert.h>
27 #include <stddef.h>
28 #include <sys/types.h>
29 #include <functional> // std::function
30
31 #include "lex_string.h"
32 #include "my_dbug.h"
33 #include "my_io.h"
34 #include "my_sqlcommand.h"
35 #include "mysql/psi/psi_base.h"
36 #include "nullable.h"
37 #include "sql/dd/types/column.h"
38 #include "sql/gis/srid.h"
39 #include "sql/mdl.h" // MDL_request
40 #include "sql/mem_root_array.h" // Mem_root_array
41 #include "sql/sql_check_constraint.h" // Sql_check_constraint_spec_list
42 #include "sql/sql_cmd.h" // Sql_cmd
43 #include "sql/sql_cmd_ddl_table.h" // Sql_cmd_ddl_table
44 #include "sql/sql_list.h" // List
45 #include "sql/thr_malloc.h"
46
47 class Alter_info;
48 class Create_field;
49 class FOREIGN_KEY;
50 class Value_generator;
51 class Item;
52 class Key_spec;
53 class String;
54 class THD;
55 struct TABLE_LIST;
56
57 enum enum_field_types : int;
58
59 using Mysql::Nullable;
60
61 /**
62 Class representing DROP COLUMN, DROP KEY, DROP FOREIGN KEY, DROP CHECK
63 CONSTRAINT and DROP CONSTRAINT clauses in ALTER TABLE statement.
64 */
65
66 class Alter_drop {
67 public:
68 enum drop_type { KEY, COLUMN, FOREIGN_KEY, CHECK_CONSTRAINT, ANY_CONSTRAINT };
69 const char *name;
70 drop_type type;
71
Alter_drop(drop_type par_type,const char * par_name)72 Alter_drop(drop_type par_type, const char *par_name)
73 : name(par_name), type(par_type) {
74 DBUG_ASSERT(par_name != nullptr);
75 }
76 };
77
78 /**
79 Class representing SET DEFAULT, DROP DEFAULT and RENAME
80 COLUMN clause in ALTER TABLE statement.
81 */
82
83 class Alter_column {
84 public:
85 /// The column name being altered.
86 const char *name;
87
88 /// The default value supplied.
89 Item *def;
90
91 /// The expression to be used to generated the default value.
92 Value_generator *m_default_val_expr;
93
94 /// The new colum name.
95 const char *m_new_name;
96
97 enum class Type { SET_DEFAULT, DROP_DEFAULT, RENAME_COLUMN };
98
99 public:
100 /// Type of change requested in ALTER TABLE.
change_type()101 inline Type change_type() const { return m_type; }
102
103 /// Constructor used when altering the field's default value with a literal
104 /// constant or when dropping a field's default value.
Alter_column(const char * par_name,Item * literal)105 Alter_column(const char *par_name, Item *literal)
106 : name(par_name),
107 def(literal),
108 m_default_val_expr(nullptr),
109 m_new_name(nullptr) {
110 if (def)
111 m_type = Type::SET_DEFAULT;
112 else
113 m_type = Type::DROP_DEFAULT;
114 }
115
116 /// Constructor used when setting a field's DEFAULT value to an expression.
Alter_column(const char * par_name,Value_generator * gen_def)117 Alter_column(const char *par_name, Value_generator *gen_def)
118 : name(par_name),
119 def(nullptr),
120 m_default_val_expr(gen_def),
121 m_new_name(nullptr),
122 m_type(Type::SET_DEFAULT) {}
123
124 /// Constructor used while renaming field name.
Alter_column(const char * old_name,const char * new_name)125 Alter_column(const char *old_name, const char *new_name)
126 : name(old_name),
127 def(nullptr),
128 m_new_name(new_name),
129 m_type(Type::RENAME_COLUMN) {}
130
131 private:
132 Type m_type;
133 };
134
135 /// An ALTER INDEX operation that changes the visibility of an index.
136 class Alter_index_visibility {
137 public:
Alter_index_visibility(const char * name,bool is_visible)138 Alter_index_visibility(const char *name, bool is_visible)
139 : m_name(name), m_is_visible(is_visible) {
140 assert(name != nullptr);
141 }
142
name()143 const char *name() const { return m_name; }
144
145 /// The visibility after the operation is performed.
is_visible()146 bool is_visible() const { return m_is_visible; }
147
148 private:
149 const char *m_name;
150 bool m_is_visible;
151 };
152
153 /**
154 Class which instances represent RENAME INDEX clauses in
155 ALTER TABLE statement.
156 */
157
158 class Alter_rename_key {
159 public:
160 const char *old_name;
161 const char *new_name;
162
Alter_rename_key(const char * old_name_arg,const char * new_name_arg)163 Alter_rename_key(const char *old_name_arg, const char *new_name_arg)
164 : old_name(old_name_arg), new_name(new_name_arg) {}
165 };
166
167 /**
168 Class representing ALTER CHECK and ALTER CONSTRAINT clauses in ALTER TABLE
169 statement.
170 */
171
172 class Alter_constraint_enforcement {
173 public:
174 enum class Type { CHECK_CONSTRAINT, ANY_CONSTRAINT };
175 const char *name;
176 Type type;
177 bool is_enforced;
178
Alter_constraint_enforcement(Type par_type,const char * par_name,bool par_is_enforced)179 Alter_constraint_enforcement(Type par_type, const char *par_name,
180 bool par_is_enforced)
181 : name(par_name), type(par_type), is_enforced(par_is_enforced) {
182 DBUG_ASSERT(par_name != nullptr);
183 }
184 };
185
186 using CreateFieldApplier = std::function<bool(Create_field *, Alter_info *)>;
187
188 /**
189 Data describing the table being created by CREATE TABLE or
190 altered by ALTER TABLE.
191 */
192
193 class Alter_info {
194 public:
195 /*
196 These flags are set by the parser and describes the type of
197 operation(s) specified by the ALTER TABLE statement.
198
199 They do *not* describe the type operation(s) to be executed
200 by the storage engine. For example, we don't yet know the
201 type of index to be added/dropped.
202 */
203
204 enum Alter_info_flag : ulonglong {
205 /// Set for ADD [COLUMN]
206 ALTER_ADD_COLUMN = 1ULL << 0,
207
208 /// Set for DROP [COLUMN]
209 ALTER_DROP_COLUMN = 1ULL << 1,
210
211 /// Set for CHANGE [COLUMN] | MODIFY [CHANGE]
212 /// Set by mysql_recreate_table()
213 ALTER_CHANGE_COLUMN = 1ULL << 2,
214
215 /// Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
216 /// ADD UNIQUE INDEX | ALTER ADD [COLUMN]
217 ALTER_ADD_INDEX = 1ULL << 3,
218
219 /// Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX
220 ALTER_DROP_INDEX = 1ULL << 4,
221
222 /// Set for RENAME [TO]
223 ALTER_RENAME = 1ULL << 5,
224
225 /// Set for ORDER BY
226 ALTER_ORDER = 1ULL << 6,
227
228 /// Set for table_options
229 ALTER_OPTIONS = 1ULL << 7,
230
231 /// Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
232 ALTER_CHANGE_COLUMN_DEFAULT = 1ULL << 8,
233
234 /// Set for DISABLE KEYS | ENABLE KEYS
235 ALTER_KEYS_ONOFF = 1ULL << 9,
236
237 /// Set for FORCE
238 /// Set for ENGINE(same engine)
239 /// Set by mysql_recreate_table()
240 ALTER_RECREATE = 1ULL << 10,
241
242 /// Set for ADD PARTITION
243 ALTER_ADD_PARTITION = 1ULL << 11,
244
245 /// Set for DROP PARTITION
246 ALTER_DROP_PARTITION = 1ULL << 12,
247
248 /// Set for COALESCE PARTITION
249 ALTER_COALESCE_PARTITION = 1ULL << 13,
250
251 /// Set for REORGANIZE PARTITION ... INTO
252 ALTER_REORGANIZE_PARTITION = 1ULL << 14,
253
254 /// Set for partition_options
255 ALTER_PARTITION = 1ULL << 15,
256
257 /// Set for LOAD INDEX INTO CACHE ... PARTITION
258 /// Set for CACHE INDEX ... PARTITION
259 ALTER_ADMIN_PARTITION = 1ULL << 16,
260
261 /// Set for REORGANIZE PARTITION
262 ALTER_TABLE_REORG = 1ULL << 17,
263
264 /// Set for REBUILD PARTITION
265 ALTER_REBUILD_PARTITION = 1ULL << 18,
266
267 /// Set for partitioning operations specifying ALL keyword
268 ALTER_ALL_PARTITION = 1ULL << 19,
269
270 /// Set for REMOVE PARTITIONING
271 ALTER_REMOVE_PARTITIONING = 1ULL << 20,
272
273 /// Set for ADD FOREIGN KEY
274 ADD_FOREIGN_KEY = 1ULL << 21,
275
276 /// Set for DROP FOREIGN KEY
277 DROP_FOREIGN_KEY = 1ULL << 22,
278
279 /// Set for EXCHANGE PARITION
280 ALTER_EXCHANGE_PARTITION = 1ULL << 23,
281
282 /// Set by Sql_cmd_alter_table_truncate_partition::execute()
283 ALTER_TRUNCATE_PARTITION = 1ULL << 24,
284
285 /// Set for ADD [COLUMN] FIRST | AFTER
286 ALTER_COLUMN_ORDER = 1ULL << 25,
287
288 /// Set for RENAME INDEX
289 ALTER_RENAME_INDEX = 1ULL << 26,
290
291 /// Set for discarding the tablespace
292 ALTER_DISCARD_TABLESPACE = 1ULL << 27,
293
294 /// Set for importing the tablespace
295 ALTER_IMPORT_TABLESPACE = 1ULL << 28,
296
297 /// Means that the visibility of an index is changed.
298 ALTER_INDEX_VISIBILITY = 1ULL << 29,
299
300 /// Set for SECONDARY LOAD
301 ALTER_SECONDARY_LOAD = 1ULL << 30,
302
303 /// Set for SECONDARY UNLOAD
304 ALTER_SECONDARY_UNLOAD = 1ULL << 31,
305
306 /// Set for add check constraint.
307 ADD_CHECK_CONSTRAINT = 1ULL << 32,
308
309 /// Set for drop check constraint.
310 DROP_CHECK_CONSTRAINT = 1ULL << 33,
311
312 /// Set for check constraint enforce.
313 ENFORCE_CHECK_CONSTRAINT = 1ULL << 34,
314
315 /// Set for check constraint suspend.
316 SUSPEND_CHECK_CONSTRAINT = 1ULL << 35,
317
318 /// Set for DROP CONSTRAINT.
319 DROP_ANY_CONSTRAINT = 1ULL << 36,
320
321 /// Set for ALTER CONSTRAINT symbol ENFORCED.
322 ENFORCE_ANY_CONSTRAINT = 1ULL << 37,
323
324 /// Set for ALTER CONSTRAINT symbol NOT ENFORCED.
325 SUSPEND_ANY_CONSTRAINT = 1ULL << 38,
326
327 /// Set if ANY engine attribute is used (also in CREATE) Note that
328 /// this is NOT to be set for SECONDARY_ENGINE_ATTRIBUTE as this flag
329 /// controls if execution should check if SE supports engine
330 /// attributes.
331 ANY_ENGINE_ATTRIBUTE = 1ULL << 39
332 };
333
334 enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
335
336 /**
337 The different values of the ALGORITHM clause.
338 Describes which algorithm to use when altering the table.
339 */
340 enum enum_alter_table_algorithm {
341 // In-place if supported, copy otherwise.
342 ALTER_TABLE_ALGORITHM_DEFAULT,
343
344 // In-place if supported, error otherwise.
345 ALTER_TABLE_ALGORITHM_INPLACE,
346
347 // Instant if supported, error otherwise.
348 ALTER_TABLE_ALGORITHM_INSTANT,
349
350 // Copy if supported, error otherwise.
351 ALTER_TABLE_ALGORITHM_COPY
352 };
353
354 /**
355 The different values of the LOCK clause.
356 Describes the level of concurrency during ALTER TABLE.
357 */
358 enum enum_alter_table_lock {
359 // Maximum supported level of concurency for the given operation.
360 ALTER_TABLE_LOCK_DEFAULT,
361
362 // Allow concurrent reads & writes. If not supported, give erorr.
363 ALTER_TABLE_LOCK_NONE,
364
365 // Allow concurrent reads only. If not supported, give error.
366 ALTER_TABLE_LOCK_SHARED,
367
368 // Block reads and writes.
369 ALTER_TABLE_LOCK_EXCLUSIVE
370 };
371
372 /**
373 Status of validation clause in ALTER TABLE statement. Used during
374 partitions and GC alterations.
375 */
376 enum enum_with_validation {
377 /**
378 Default value, used when it's not specified in the statement.
379 Means WITH VALIDATION for partitions alterations and WITHOUT VALIDATION
380 for altering virtual GC.
381 */
382 ALTER_VALIDATION_DEFAULT,
383 ALTER_WITH_VALIDATION,
384 ALTER_WITHOUT_VALIDATION
385 };
386
387 /**
388 Columns, keys and constraints to be dropped.
389 */
390 Mem_root_array<const Alter_drop *> drop_list;
391 // Columns for ALTER_COLUMN_CHANGE_DEFAULT.
392 Mem_root_array<const Alter_column *> alter_list;
393 // List of keys, used by both CREATE and ALTER TABLE.
394
395 Mem_root_array<Key_spec *> key_list;
396 // Keys to be renamed.
397 Mem_root_array<const Alter_rename_key *> alter_rename_key_list;
398
399 /// Indexes whose visibilities are to be changed.
400 Mem_root_array<const Alter_index_visibility *> alter_index_visibility_list;
401
402 /// List of check constraints whose enforcement state is changed.
403 Mem_root_array<const Alter_constraint_enforcement *>
404 alter_constraint_enforcement_list;
405
406 /// Check constraints specification for CREATE and ALTER TABLE operations.
407 Sql_check_constraint_spec_list check_constraint_spec_list;
408
409 // List of columns, used by both CREATE and ALTER TABLE.
410 List<Create_field> create_list;
411 std::vector<CreateFieldApplier> cf_appliers;
412
413 // Type of ALTER TABLE operation.
414 ulonglong flags;
415 // Enable or disable keys.
416 enum_enable_or_disable keys_onoff;
417 // List of partitions.
418 List<String> partition_names;
419 // Number of partitions.
420 uint num_parts;
421 // Type of ALTER TABLE algorithm.
422 enum_alter_table_algorithm requested_algorithm;
423 // Type of ALTER TABLE lock.
424 enum_alter_table_lock requested_lock;
425 /*
426 Whether VALIDATION is asked for an operation. Used during virtual GC and
427 partitions alterations.
428 */
429 enum_with_validation with_validation;
430
431 /// "new_db" (if any) or "db" (if any) or default database from
432 /// ALTER TABLE [db.]table [ RENAME [TO|AS|=] [new_db.]new_table ]
433 LEX_CSTRING new_db_name;
434
435 /// New table name in the
436 /// \code
437 /// RENAME [TO] <table_name>
438 /// \endcode
439 /// clause or NULL_STR
440 LEX_CSTRING new_table_name;
441
Alter_info(MEM_ROOT * mem_root)442 explicit Alter_info(MEM_ROOT *mem_root)
443 : drop_list(mem_root),
444 alter_list(mem_root),
445 key_list(mem_root),
446 alter_rename_key_list(mem_root),
447 alter_index_visibility_list(mem_root),
448 alter_constraint_enforcement_list(mem_root),
449 check_constraint_spec_list(mem_root),
450 flags(0),
451 keys_onoff(LEAVE_AS_IS),
452 num_parts(0),
453 requested_algorithm(ALTER_TABLE_ALGORITHM_DEFAULT),
454 requested_lock(ALTER_TABLE_LOCK_DEFAULT),
455 with_validation(ALTER_VALIDATION_DEFAULT),
456 new_db_name(LEX_CSTRING{nullptr, 0}),
457 new_table_name(LEX_CSTRING{nullptr, 0}) {}
458
459 /**
460 Construct a copy of this object to be used for mysql_alter_table
461 and mysql_create_table.
462
463 Historically, these two functions modify their Alter_info
464 arguments. This behaviour breaks re-execution of prepared
465 statements and stored procedures and is compensated by always
466 supplying a copy of Alter_info to these functions.
467
468 @param rhs Alter_info to make copy of
469 @param mem_root Mem_root for new Alter_info
470
471 @note You need to use check the error in THD for out
472 of memory condition after calling this function.
473 */
474 Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root);
475
476 bool add_field(THD *thd, const LEX_STRING *field_name,
477 enum enum_field_types type, const char *length,
478 const char *decimal, uint type_modifier, Item *default_value,
479 Item *on_update_value, LEX_CSTRING *comment,
480 const char *change, List<String> *interval_list,
481 const CHARSET_INFO *cs, bool has_explicit_collation,
482 uint uint_geom_type, Value_generator *gcol_info,
483 Value_generator *default_val_expr, const char *opt_after,
484 Nullable<gis::srid_t> srid,
485 Sql_check_constraint_spec_list *check_cons_list,
486 dd::Column::enum_hidden_type hidden, bool is_array = false);
487
488 private:
489 Alter_info &operator=(const Alter_info &rhs); // not implemented
490 Alter_info(const Alter_info &rhs); // not implemented
491 };
492
493 /** Runtime context for ALTER TABLE. */
494 class Alter_table_ctx {
495 public:
496 Alter_table_ctx();
497
498 Alter_table_ctx(THD *thd, TABLE_LIST *table_list, uint tables_opened_arg,
499 const char *new_db_arg, const char *new_name_arg);
500
501 ~Alter_table_ctx();
502
503 /**
504 @return true if the table is moved to another database, false otherwise.
505 */
is_database_changed()506 bool is_database_changed() const { return (new_db != db); }
507
508 /**
509 @return true if the table name is changed, false otherwise.
510 */
is_table_name_changed()511 bool is_table_name_changed() const { return (new_name != table_name); }
512
513 /**
514 @return true if the table is renamed (i.e. its name or database changed),
515 false otherwise.
516 */
is_table_renamed()517 bool is_table_renamed() const {
518 return is_database_changed() || is_table_name_changed();
519 }
520
521 /**
522 @return path to the original table.
523 */
get_path()524 const char *get_path() const {
525 DBUG_ASSERT(!tmp_table);
526 return path;
527 }
528
529 /**
530 @return path to the temporary table created during ALTER TABLE.
531 */
get_tmp_path()532 const char *get_tmp_path() const { return tmp_path; }
533
534 public:
535 typedef uint error_if_not_empty_mask;
536 static const error_if_not_empty_mask DATETIME_WITHOUT_DEFAULT = 1 << 0;
537 static const error_if_not_empty_mask GEOMETRY_WITHOUT_DEFAULT = 1 << 1;
538
539 Create_field *datetime_field;
540 error_if_not_empty_mask error_if_not_empty;
541 uint tables_opened;
542 const char *db;
543 const char *table_name;
544 const char *alias;
545 const char *new_db;
546 const char *new_name;
547 const char *new_alias;
548 char tmp_name[80];
549
550 /* Used to remember which foreign keys already existed in the table. */
551 FOREIGN_KEY *fk_info;
552 uint fk_count;
553 /**
554 Maximum number component used by generated foreign key names in the
555 old version of table.
556 */
557 uint fk_max_generated_name_number;
558
559 /**
560 Metadata lock request on table's new name when this name or database
561 are changed.
562 */
563 MDL_request target_mdl_request;
564 /** Metadata lock request on table's new database if it is changed. */
565 MDL_request target_db_mdl_request;
566
567 private:
568 char new_filename[FN_REFLEN + 1];
569 char new_alias_buff[FN_REFLEN + 1];
570 char path[FN_REFLEN + 1];
571 char new_path[FN_REFLEN + 1];
572 char tmp_path[FN_REFLEN + 1];
573
574 #ifndef DBUG_OFF
575 /** Indicates that we are altering temporary table. Used only in asserts. */
576 bool tmp_table;
577 #endif
578
579 Alter_table_ctx &operator=(const Alter_table_ctx &rhs); // not implemented
580 Alter_table_ctx(const Alter_table_ctx &rhs); // not implemented
581 };
582
583 /**
584 Represents the common properties of the ALTER TABLE statements.
585 @todo move Alter_info and other ALTER generic structures from Lex here.
586 */
587 class Sql_cmd_common_alter_table : public Sql_cmd_ddl_table {
588 public:
589 using Sql_cmd_ddl_table::Sql_cmd_ddl_table;
590
591 ~Sql_cmd_common_alter_table() override = 0; // force abstract class
592
sql_command_code()593 enum_sql_command sql_command_code() const override final {
594 return SQLCOM_ALTER_TABLE;
595 }
596 };
597
~Sql_cmd_common_alter_table()598 inline Sql_cmd_common_alter_table::~Sql_cmd_common_alter_table() {}
599
600 /**
601 Represents the generic ALTER TABLE statement.
602 @todo move Alter_info and other ALTER specific structures from Lex here.
603 */
604 class Sql_cmd_alter_table : public Sql_cmd_common_alter_table {
605 public:
606 using Sql_cmd_common_alter_table::Sql_cmd_common_alter_table;
607
608 bool execute(THD *thd) override;
609 };
610
611 /**
612 Represents ALTER TABLE IMPORT/DISCARD TABLESPACE statements.
613 */
614 class Sql_cmd_discard_import_tablespace : public Sql_cmd_common_alter_table {
615 public:
616 using Sql_cmd_common_alter_table::Sql_cmd_common_alter_table;
617
618 bool execute(THD *thd) override;
619
620 private:
621 bool mysql_discard_or_import_tablespace(THD *thd, TABLE_LIST *table_list);
622 };
623
624 /**
625 Represents ALTER TABLE SECONDARY_LOAD/SECONDARY_UNLOAD statements.
626 */
627 class Sql_cmd_secondary_load_unload final : public Sql_cmd_common_alter_table {
628 public:
629 // Inherit the constructors from the parent class.
630 using Sql_cmd_common_alter_table::Sql_cmd_common_alter_table;
631
632 bool execute(THD *thd) override;
633
634 private:
635 bool mysql_secondary_load_or_unload(THD *thd, TABLE_LIST *table_list);
636 };
637
638 #endif
639