summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc66
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