1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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()
This commit is contained in:
Sergei Golubchik
2014-03-02 15:02:13 +01:00
parent 1b608b0b9c
commit eb9f422c43
7 changed files with 93 additions and 82 deletions

View File

@ -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'
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
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'
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` (
`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` (

View File

@ -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

View File

@ -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;

View File

@ -1740,7 +1740,10 @@ public:
// 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 @@ public:
// 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;
/** /**

View File

@ -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,
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
{ {

View File

@ -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 The engine may answer that the inplace alter is not supported or,
fields this function will be called by compare_tables() if supported, whether the server should protect the table from concurrent
(sql/sql_tables.cc) to decide should we rewrite whole table or only .frm accesses. Return values are
file.
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,
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,
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,
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);
} }

View File

@ -247,8 +247,9 @@ public:
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