Commit eb9f422c authored by Sergei Golubchik's avatar Sergei Golubchik

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()
parent 1b608b0b
...@@ -127,7 +127,7 @@ drop table t1; ...@@ -127,7 +127,7 @@ drop table t1;
SET @OLD_SQL_MODE=@@SQL_MODE; SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
#illegal value fixed #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: Warnings:
Warning 1912 Incorrect value '10000000000000000000' for option 'ULL' Warning 1912 Incorrect value '10000000000000000000' for option 'ULL'
Warning 1912 Incorrect value 'ttt' for option 'one_or_two' Warning 1912 Incorrect value 'ttt' for option 'one_or_two'
...@@ -135,7 +135,8 @@ Warning 1912 Incorrect value 'SSS' for option 'YESNO' ...@@ -135,7 +135,8 @@ Warning 1912 Incorrect value 'SSS' for option 'YESNO'
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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' ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5'
#alter table #alter table
alter table t1 ULL=10000000; alter table t1 ULL=10000000;
...@@ -144,7 +145,8 @@ Note 1105 EXAMPLE DEBUG: ULL 4294967290 -> 10000000 ...@@ -144,7 +145,8 @@ Note 1105 EXAMPLE DEBUG: ULL 4294967290 -> 10000000
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) 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'; alter table t1 change a a int complex='c,c,c';
Warnings: Warnings:
...@@ -152,15 +154,15 @@ Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> 'c,c,c' ...@@ -152,15 +154,15 @@ Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> 'c,c,c'
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000
alter table t1 one_or_two=two; 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; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 `one_or_two`=two
drop table t1; drop table t1;
#illegal value error #illegal value error
...@@ -204,8 +206,6 @@ t1 CREATE TABLE `t1` ( ...@@ -204,8 +206,6 @@ t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL `a` int(11) DEFAULT NULL
) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15 ) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15
alter table t1 varopt=default; alter table t1 varopt=default;
Warnings:
Note 1105 EXAMPLE DEBUG: Field `a` COMPLEX '(null)' -> '(null)'
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
......
...@@ -121,7 +121,7 @@ SET @OLD_SQL_MODE=@@SQL_MODE; ...@@ -121,7 +121,7 @@ SET @OLD_SQL_MODE=@@SQL_MODE;
SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS';
--echo #illegal value fixed --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; show create table t1;
--echo #alter table --echo #alter table
......
...@@ -4123,6 +4123,7 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, ...@@ -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_EQUAL_PACK_LENGTH |
Alter_inplace_info::ALTER_COLUMN_NAME | Alter_inplace_info::ALTER_COLUMN_NAME |
Alter_inplace_info::ALTER_COLUMN_DEFAULT | Alter_inplace_info::ALTER_COLUMN_DEFAULT |
Alter_inplace_info::ALTER_COLUMN_OPTION |
Alter_inplace_info::CHANGE_CREATE_OPTION | Alter_inplace_info::CHANGE_CREATE_OPTION |
Alter_inplace_info::ALTER_RENAME; Alter_inplace_info::ALTER_RENAME;
......
...@@ -1740,7 +1740,10 @@ class Alter_inplace_info ...@@ -1740,7 +1740,10 @@ class Alter_inplace_info
// Table is renamed // Table is renamed
static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18; static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18;
// Change the storage type of column // 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; static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19;
// Change the column format of column // Change the column format of column
...@@ -1770,7 +1773,7 @@ class Alter_inplace_info ...@@ -1770,7 +1773,7 @@ class Alter_inplace_info
// Partition operation with ALL keyword // Partition operation with ALL keyword
static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28; 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; static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1L << 29;
/** /**
......
...@@ -5894,9 +5894,6 @@ static bool fill_alter_inplace_info(THD *thd, ...@@ -5894,9 +5894,6 @@ static bool fill_alter_inplace_info(THD *thd,
if (new_field) 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. */ /* Field is not dropped. Evaluate changes bitmap for it. */
/* /*
...@@ -6008,6 +6005,15 @@ static bool fill_alter_inplace_info(THD *thd, ...@@ -6008,6 +6005,15 @@ static bool fill_alter_inplace_info(THD *thd,
if (new_field->column_format() != field->column_format()) if (new_field->column_format() != field->column_format())
ha_alter_info->handler_flags|= ha_alter_info->handler_flags|=
Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT; 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 else
{ {
......
...@@ -906,38 +906,35 @@ int ha_example::create(const char *name, TABLE *table_arg, ...@@ -906,38 +906,35 @@ int ha_example::create(const char *name, TABLE *table_arg,
/** /**
check_if_incompatible_data() called if ALTER TABLE can't detect otherwise check_if_supported_inplace_alter() is used to ask the engine whether
if new and old definition are compatible it can execute this ALTER TABLE statement in place or the server needs to
create a new table and copy th data over.
@details If there are no other explicit signs like changed number of
fields this function will be called by compare_tables() The engine may answer that the inplace alter is not supported or,
(sql/sql_tables.cc) to decide should we rewrite whole table or only .frm if supported, whether the server should protect the table from concurrent
file. 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, enum_alter_inplace_result
uint table_changes) ha_example::check_if_supported_inplace_alter(TABLE* altered_table,
Alter_inplace_info* ha_alter_info)
{ {
ha_table_option_struct *param_old, *param_new; HA_CREATE_INFO *info= ha_alter_info->create_info;
DBUG_ENTER("ha_example::check_if_incompatible_data"); DBUG_ENTER("ha_example::check_if_supported_inplace_alter");
if (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION)
{
/* /*
This example shows how custom engine specific table and field This example shows how custom engine specific table and field
options can be accessed from this function to be compared. options can be accessed from this function to be compared.
*/ */
param_new= info->option_struct; ha_table_option_struct *param_new= info->option_struct;
DBUG_PRINT("info", ("new strparam: '%-.64s' ullparam: %llu enumparam: %u " ha_table_option_struct *param_old= table->s->option_struct;
"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: check important parameters:
...@@ -954,7 +951,7 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, ...@@ -954,7 +951,7 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu", ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: ULL %llu -> %llu",
param_old->ullparam, param_new->ullparam); param_old->ullparam, param_new->ullparam);
DBUG_RETURN(COMPATIBLE_DATA_NO); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
} }
if (param_new->boolparam != param_old->boolparam) if (param_new->boolparam != param_old->boolparam)
...@@ -962,17 +959,19 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, ...@@ -962,17 +959,19 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u", ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: YESNO %u -> %u",
param_old->boolparam, param_new->boolparam); param_old->boolparam, param_new->boolparam);
DBUG_RETURN(COMPATIBLE_DATA_NO); DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
} }
if (ha_alter_info->handler_flags & Alter_inplace_info::ALTER_COLUMN_OPTION)
{
for (uint i= 0; i < table->s->fields; i++) for (uint i= 0; i < table->s->fields; i++)
{ {
ha_field_option_struct *f_old, *f_new; ha_field_option_struct *f_old= table->s->field[i]->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); DBUG_ASSERT(f_old);
if (info->fields_option_struct[i]) if (f_new)
{ {
f_new= info->fields_option_struct[i];
push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE, push_warning_printf(ha_thd(), Sql_condition::WARN_LEVEL_NOTE,
ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'", ER_UNKNOWN_ERROR, "EXAMPLE DEBUG: Field %`s COMPLEX '%s' -> '%s'",
table->s->field[i]->field_name, table->s->field[i]->field_name,
...@@ -982,8 +981,9 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info, ...@@ -982,8 +981,9 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
else else
DBUG_PRINT("info", ("old field %i did not changed", i)); DBUG_PRINT("info", ("old field %i did not changed", i));
} }
}
DBUG_RETURN(COMPATIBLE_DATA_YES); DBUG_RETURN(HA_ALTER_INPLACE_EXCLUSIVE_LOCK);
} }
......
...@@ -247,8 +247,9 @@ class ha_example: public handler ...@@ -247,8 +247,9 @@ class ha_example: public handler
int delete_table(const char *from); int delete_table(const char *from);
int create(const char *name, TABLE *form, int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required HA_CREATE_INFO *create_info); ///< required
bool check_if_incompatible_data(HA_CREATE_INFO *info, enum_alter_inplace_result
uint table_changes); 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, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); ///< required enum thr_lock_type lock_type); ///< required
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment