diff options
author | Sergei Golubchik <sergii@pisem.net> | 2014-03-02 15:02:13 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2014-03-02 15:02:13 +0100 |
commit | eb9f422c43406172422eeaaa29dddeff742b6d14 (patch) | |
tree | c269e08c4cf12f100be8210eb08ac087d2f4be7d | |
parent | 1b608b0b9c0eae7ddcd35d54a4e9112b3c1c4966 (diff) | |
download | mariadb-git-eb9f422c43406172422eeaaa29dddeff742b6d14.tar.gz |
MDEV-5667 online alter and changed field/index options
use the Alter_inplace_info::ALTER_COLUMN_OPTION flag if
field/column flags were altered.
change ha_example to use check_if_supported_inplace_alter() instead
of obsolete check_if_incompatible_data()
-rw-r--r-- | mysql-test/r/plugin.result | 18 | ||||
-rw-r--r-- | mysql-test/t/plugin.test | 2 | ||||
-rw-r--r-- | sql/handler.cc | 1 | ||||
-rw-r--r-- | sql/handler.h | 9 | ||||
-rw-r--r-- | sql/sql_table.cc | 12 | ||||
-rw-r--r-- | storage/example/ha_example.cc | 130 | ||||
-rw-r--r-- | storage/example/ha_example.h | 5 |
7 files changed, 94 insertions, 83 deletions
diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index d304f094987..54693eaee56 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -127,7 +127,7 @@ drop table t1; SET @OLD_SQL_MODE=@@SQL_MODE; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; #illegal value fixed -CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; +CREATE TABLE t1 (a int, b int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; Warnings: Warning 1912 Incorrect value '10000000000000000000' for option 'ULL' Warning 1912 Incorrect value 'ttt' for option 'one_or_two' @@ -135,7 +135,8 @@ Warning 1912 Incorrect value 'SSS' for option 'YESNO' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' #alter table alter table t1 ULL=10000000; @@ -144,7 +145,8 @@ Note 1105 EXAMPLE DEBUG: ULL 4294967290 -> 10000000 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 alter table t1 change a a int complex='c,c,c'; Warnings: @@ -152,15 +154,15 @@ Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> 'c,c,c' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL `complex`='c,c,c' + `a` int(11) DEFAULT NULL `complex`='c,c,c', + `b` int(11) DEFAULT NULL ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 alter table t1 one_or_two=two; -Warnings: -Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX 'c,c,c' -> 'c,c,c' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL `complex`='c,c,c' + `a` int(11) DEFAULT NULL `complex`='c,c,c', + `b` int(11) DEFAULT NULL ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 `one_or_two`=two drop table t1; #illegal value error @@ -204,8 +206,6 @@ t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15 alter table t1 varopt=default; -Warnings: -Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> '(null)' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index eda70dafc30..fb608ee5bf8 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -121,7 +121,7 @@ SET @OLD_SQL_MODE=@@SQL_MODE; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; --echo #illegal value fixed -CREATE TABLE t1 (a int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; +CREATE TABLE t1 (a int, b int) ENGINE=example ULL=10000000000000000000 one_or_two='ttt' YESNO=SSS; show create table t1; --echo #alter table diff --git a/sql/handler.cc b/sql/handler.cc index 8aee24fbe03..50044cf3cab 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4123,6 +4123,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH | Alter_inplace_info::ALTER_COLUMN_NAME | Alter_inplace_info::ALTER_COLUMN_DEFAULT | + Alter_inplace_info::ALTER_COLUMN_OPTION | Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::ALTER_RENAME; diff --git a/sql/handler.h b/sql/handler.h index d255c0543a9..06bc1863bbe 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1740,8 +1740,11 @@ public: // Table is renamed static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18; - // Change the storage type of column - static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19; + // column's engine options changed, something in field->option_struct + static const HA_ALTER_FLAGS ALTER_COLUMN_OPTION = 1L << 19; + + // MySQL alias for the same thing: + static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19; // Change the column format of column static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1L << 20; @@ -1770,7 +1773,7 @@ public: // Partition operation with ALL keyword static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28; - // Partition operation with ALL keyword + // Virtual columns changed static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1L << 29; /** diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c43ea8c453c..fdb902ee199 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5894,9 +5894,6 @@ static bool fill_alter_inplace_info(THD *thd, if (new_field) { - ha_alter_info->create_info->fields_option_struct[f_ptr - table->field]= - new_field->option_struct; - /* Field is not dropped. Evaluate changes bitmap for it. */ /* @@ -6008,6 +6005,15 @@ static bool fill_alter_inplace_info(THD *thd, if (new_field->column_format() != field->column_format()) ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT; + + if (engine_options_differ(field->option_struct, new_field->option_struct, + table->file->ht->field_options)) + { + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_OPTION; + ha_alter_info->create_info->fields_option_struct[f_ptr - table->field]= + new_field->option_struct; + } + } else { diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index f31bffb361a..930c4f38633 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -906,84 +906,84 @@ int ha_example::create(const char *name, TABLE *table_arg, /** - check_if_incompatible_data() called if ALTER TABLE can't detect otherwise - if new and old definition are compatible - - @details If there are no other explicit signs like changed number of - fields this function will be called by compare_tables() - (sql/sql_tables.cc) to decide should we rewrite whole table or only .frm - file. - + check_if_supported_inplace_alter() is used to ask the engine whether + it can execute this ALTER TABLE statement in place or the server needs to + create a new table and copy th data over. + + The engine may answer that the inplace alter is not supported or, + if supported, whether the server should protect the table from concurrent + accesses. Return values are + + HA_ALTER_INPLACE_NOT_SUPPORTED + HA_ALTER_INPLACE_EXCLUSIVE_LOCK + HA_ALTER_INPLACE_SHARED_LOCK + etc */ -bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes) +enum_alter_inplace_result +ha_example::check_if_supported_inplace_alter(TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { - ha_table_option_struct *param_old, *param_new; - DBUG_ENTER("ha_example::check_if_incompatible_data"); - /* - This example shows how custom engine specific table and field - options can be accessed from this function to be compared. - */ - param_new= info->option_struct; - DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u " - "boolparam: %u", - (param_new->strparam ? param_new->strparam : "<NULL>"), - param_new->ullparam, param_new->enumparam, - param_new->boolparam)); - - param_old= table->s->option_struct; - DBUG_PRINT("info", ("old strparam: '%-.64s' ullparam: %llu enumparam: %u " - "boolparam: %u", - (param_old->strparam ? param_old->strparam : "<NULL>"), - param_old->ullparam, param_old->enumparam, - param_old->boolparam)); - - /* - check important parameters: - for this example engine, we'll assume that changing ullparam or - boolparam requires a table to be rebuilt, while changing strparam - or enumparam - does not. - - For debugging purposes we'll announce this to the user - (don't do it in production!) + HA_CREATE_INFO *info= ha_alter_info->create_info; + DBUG_ENTER("ha_example::check_if_supported_inplace_alter"); - */ - if (param_new->ullparam != param_old->ullparam) + if (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) { - push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, - ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu", - param_old->ullparam, param_new->ullparam); - DBUG_RETURN(COMPATIBLE_DATA_NO); - } + /* + This example shows how custom engine specific table and field + options can be accessed from this function to be compared. + */ + ha_table_option_struct *param_new= info->option_struct; + ha_table_option_struct *param_old= table->s->option_struct; + + /* + check important parameters: + for this example engine, we'll assume that changing ullparam or + boolparam requires a table to be rebuilt, while changing strparam + or enumparam - does not. + + For debugging purposes we'll announce this to the user + (don't do it in production!) + + */ + if (param_new->ullparam != param_old->ullparam) + { + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu", + param_old->ullparam, param_new->ullparam); + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); + } - if (param_new->boolparam != param_old->boolparam) - { - push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, - ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u", - param_old->boolparam, param_new->boolparam); - DBUG_RETURN(COMPATIBLE_DATA_NO); + if (param_new->boolparam != param_old->boolparam) + { + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u", + param_old->boolparam, param_new->boolparam); + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); + } } - for (uint i= 0; i < table->s->fields; i++) + if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_OPTION) { - ha_field_option_struct *f_old, *f_new; - f_old= table->s->field[i]->option_struct; - DBUG_ASSERT(f_old); - if (info->fields_option_struct[i]) + for (uint i= 0; i < table->s->fields; i++) { - f_new= info->fields_option_struct[i]; - push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, - ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'", - table->s->field[i]->field_name, - f_old->complex_param_to_parse_it_in_engine, - f_new->complex_param_to_parse_it_in_engine); + ha_field_option_struct *f_old= table->s->field[i]->option_struct; + ha_field_option_struct *f_new= info->fields_option_struct[i]; + DBUG_ASSERT(f_old); + if (f_new) + { + push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, + ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'", + table->s->field[i]->field_name, + f_old->complex_param_to_parse_it_in_engine, + f_new->complex_param_to_parse_it_in_engine); + } + else + DBUG_PRINT("info", ("old field %i did not changed", i)); } - else - DBUG_PRINT("info", ("old field %i did not changed", i)); } - DBUG_RETURN(COMPATIBLE_DATA_YES); + DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK); } diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h index d25541f7422..2d3d0c81ed9 100644 --- a/storage/example/ha_example.h +++ b/storage/example/ha_example.h @@ -247,8 +247,9 @@ public: int delete_table(const char *from); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); ///< required - bool check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes); + enum_alter_inplace_result + check_if_supported_inplace_alter(TABLE* altered_table, + Alter_inplace_info* ha_alter_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, enum thr_lock_type lock_type); ///< required |