diff options
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 80d4ec049d8..dfce503e314 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2010, 2015, MariaDB + Copyright (c) 2010, 2016, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2231,7 +2231,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, const char *comment_start; uint32 comment_len; - built_query.set_charset(system_charset_info); + built_query.set_charset(thd->charset()); if (if_exists) built_query.append("DROP TABLE IF EXISTS "); else @@ -3447,8 +3447,31 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, else { /* Field redefined */ + + /* + If we are replacing a BIT field, revert the increment + of total_uneven_bit_length that was done above. + */ + if (sql_field->sql_type == MYSQL_TYPE_BIT && + file->ha_table_flags() & HA_CAN_BIT_FIELD) + total_uneven_bit_length-= sql_field->length & 7; + sql_field->def= dup_field->def; sql_field->sql_type= dup_field->sql_type; + + /* + If we are replacing a field with a BIT field, we need + to initialize pack_flag. Note that we do not need to + increment total_uneven_bit_length here as this dup_field + has already been processed. + */ + if (sql_field->sql_type == MYSQL_TYPE_BIT) + { + sql_field->pack_flag= FIELDFLAG_NUMBER; + if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD)) + sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR; + } + sql_field->charset= (dup_field->charset ? dup_field->charset : create_info->default_table_charset); @@ -6167,6 +6190,7 @@ static bool fill_alter_inplace_info(THD *thd, c) flags passed to storage engine contain more detailed information about nature of changes than those provided from parser. */ + bool maybe_alter_vcol= false; for (f_ptr= table->field; (field= *f_ptr); f_ptr++) { /* Clear marker for renamed or dropped field @@ -6190,7 +6214,8 @@ static bool fill_alter_inplace_info(THD *thd, /* Check if type of column has changed to some incompatible type. */ - switch (field->is_equal(new_field)) + uint is_equal= field->is_equal(new_field); + switch (is_equal) { case IS_EQUAL_NO: /* New column type is incompatible with old one. */ @@ -6243,15 +6268,17 @@ static bool fill_alter_inplace_info(THD *thd, } /* - Check if the altered column is computed and either + Check if the column is computed and either is stored or is used in the partitioning expression. - TODO: Mark such a column with an alter flag only if - the defining expression has changed. */ if (field->vcol_info && (field->stored_in_db || field->vcol_info->is_in_partitioning_expr())) { - ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; + if (is_equal == IS_EQUAL_NO || + !field->vcol_info->is_equal(new_field->vcol_info)) + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; + else + maybe_alter_vcol= true; } /* Check if field was renamed */ @@ -6317,6 +6344,21 @@ static bool fill_alter_inplace_info(THD *thd, } } + if (maybe_alter_vcol) + { + /* + No virtual column was altered, but perhaps one of the other columns was, + and that column was part of the vcol expression? + We don't detect this correctly (FIXME), so let's just say that a vcol + *might* be affected if any other column was altered. + */ + if (ha_alter_info->handler_flags & + ( Alter_inplace_info::ALTER_COLUMN_TYPE + | Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE + | Alter_inplace_info::ALTER_COLUMN_OPTION )) + ha_alter_info->handler_flags|= Alter_inplace_info::ALTER_COLUMN_VCOL; + } + new_field_it.init(alter_info->create_list); while ((new_field= new_field_it++)) { @@ -6920,7 +6962,7 @@ static bool mysql_inplace_alter_table(THD *thd, MDL_request *target_mdl_request, Alter_table_ctx *alter_ctx) { - Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); + Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN | MYSQL_OPEN_IGNORE_KILLED); handlerton *db_type= table->s->db_type(); MDL_ticket *mdl_ticket= table->mdl_ticket; HA_CREATE_INFO *create_info= ha_alter_info->create_info; @@ -9146,13 +9188,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error, but still worth reporting as it might indicate serious problem with server. */ - goto err_with_mdl; + goto err_with_mdl_after_alter; } end_inplace: if (thd->locked_tables_list.reopen_tables(thd)) - goto err_with_mdl; + goto err_with_mdl_after_alter; THD_STAGE_INFO(thd, stage_end); @@ -9233,6 +9275,10 @@ err_new_table_cleanup: DBUG_RETURN(true); +err_with_mdl_after_alter: + /* the table was altered. binlog the operation */ + write_bin_log(thd, true, thd->query(), thd->query_length()); + err_with_mdl: /* An error happened while we were holding exclusive name metadata lock |