summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-03-02 15:02:13 +0100
committerSergei Golubchik <sergii@pisem.net>2014-03-02 15:02:13 +0100
commiteb9f422c43406172422eeaaa29dddeff742b6d14 (patch)
treec269e08c4cf12f100be8210eb08ac087d2f4be7d
parent1b608b0b9c0eae7ddcd35d54a4e9112b3c1c4966 (diff)
downloadmariadb-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.result18
-rw-r--r--mysql-test/t/plugin.test2
-rw-r--r--sql/handler.cc1
-rw-r--r--sql/handler.h9
-rw-r--r--sql/sql_table.cc12
-rw-r--r--storage/example/ha_example.cc130
-rw-r--r--storage/example/ha_example.h5
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