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