diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_class.h | 14 | ||||
-rw-r--r-- | sql/sql_lex.cc | 13 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 76 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 |
5 files changed, 82 insertions, 34 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 13b2659789d..6a7c0cd4d94 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -333,17 +333,25 @@ public: class Alter_column :public Sql_alloc { public: - const char *name; + LEX_CSTRING name; + LEX_CSTRING new_name; Virtual_column_info *default_value; bool alter_if_exists; - Alter_column(const char *par_name, Virtual_column_info *expr, bool par_exists) - :name(par_name), default_value(expr), alter_if_exists(par_exists) {} + Alter_column(LEX_CSTRING par_name, Virtual_column_info *expr, bool par_exists) + :name(par_name), new_name{NULL, 0}, default_value(expr), alter_if_exists(par_exists) {} + Alter_column(LEX_CSTRING par_name, LEX_CSTRING _new_name) + :name(par_name), new_name(_new_name), default_value(NULL), alter_if_exists(false) {} /** Used to make a clone of this object for ALTER/CREATE TABLE @sa comment for Key_part_spec::clone */ Alter_column *clone(MEM_ROOT *mem_root) const { return new (mem_root) Alter_column(*this); } + bool is_rename() + { + DBUG_ASSERT(!new_name.str || !default_value); + return new_name.str; + } }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ea60d0cebd0..3ab1a46f95d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -511,7 +511,7 @@ void LEX::add_key_to_list(LEX_CSTRING *field_name, } -bool LEX::add_alter_list(const char *name, Virtual_column_info *expr, +bool LEX::add_alter_list(LEX_CSTRING name, Virtual_column_info *expr, bool exists) { MEM_ROOT *mem_root= thd->mem_root; @@ -524,6 +524,17 @@ bool LEX::add_alter_list(const char *name, Virtual_column_info *expr, } +bool LEX::add_alter_list(LEX_CSTRING name, LEX_CSTRING new_name) +{ + Alter_column *ac= new (thd->mem_root) Alter_column(name, new_name); + if (unlikely(ac == NULL)) + return true; + alter_info.alter_list.push_back(ac, thd->mem_root); + alter_info.flags|= ALTER_RENAME_COLUMN; + return false; +} + + void LEX::init_last_field(Column_definition *field, const LEX_CSTRING *field_name, const CHARSET_INFO *cs) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2d08aa6c79b..c75833ae282 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4320,8 +4320,9 @@ public: alter_info.check_constraint_list.push_back(constr); return false; } - bool add_alter_list(const char *par_name, Virtual_column_info *expr, + bool add_alter_list(LEX_CSTRING par_name, Virtual_column_info *expr, bool par_exists); + bool add_alter_list(LEX_CSTRING name, LEX_CSTRING new_name); void set_command(enum_sql_command command, DDL_options_st options) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 240f001f7de..b5cc07b1411 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6167,7 +6167,7 @@ drop_create_field: for (f_ptr=table->field; *f_ptr; f_ptr++) { if (my_strcasecmp(system_charset_info, - acol->name, (*f_ptr)->field_name.str) == 0) + acol->name.str, (*f_ptr)->field_name.str) == 0) break; } if (unlikely(*f_ptr == NULL)) @@ -6175,7 +6175,7 @@ drop_create_field: push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_BAD_FIELD_ERROR, ER_THD(thd, ER_BAD_FIELD_ERROR), - acol->name, table->s->table_name.str); + acol->name.str, table->s->table_name.str); it.remove(); if (alter_info->alter_list.is_empty()) { @@ -8138,24 +8138,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, continue; } - /* - If we are doing a rename of a column, update all references in virtual - column expressions, constraints and defaults to use the new column name - */ - if (alter_info->flags & ALTER_RENAME_COLUMN) - { - if (field->vcol_info) - field->vcol_info->expr->walk(&Item::rename_fields_processor, 1, - &column_rename_param); - if (field->check_constraint) - field->check_constraint->expr->walk(&Item::rename_fields_processor, 1, - &column_rename_param); - if (field->default_value) - field->default_value->expr->walk(&Item::rename_fields_processor, 1, - &column_rename_param); - table->m_needs_reopen= 1; // because new column name is on thd->mem_root - } - /* Check if field is changed */ def_it.rewind(); while ((def=def_it++)) @@ -8229,19 +8211,61 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((alter=alter_it++)) { if (!my_strcasecmp(system_charset_info,field->field_name.str, - alter->name)) + alter->name.str)) break; } if (alter) { - if ((def->default_value= alter->default_value)) - def->flags&= ~NO_DEFAULT_VALUE_FLAG; + if (alter->is_rename()) + { + def->change= alter->name; + def->field_name= alter->new_name; + column_rename_param.fields.push_back(def); + } else - def->flags|= NO_DEFAULT_VALUE_FLAG; + { + if ((def->default_value= alter->default_value)) + def->flags&= ~NO_DEFAULT_VALUE_FLAG; + else + def->flags|= NO_DEFAULT_VALUE_FLAG; + } alter_it.remove(); } } } + + /* + If we are doing a rename of a column, update all references in virtual + column expressions, constraints and defaults to use the new column name + */ + if (alter_info->flags & ALTER_RENAME_COLUMN) + { + alter_it.rewind(); + Alter_column *alter; + while ((alter=alter_it++)) + { + if (alter->is_rename()) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), alter->name.str, + table->s->table_name.str); + goto err; + } + } + for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) + { + if (field->vcol_info) + field->vcol_info->expr->walk(&Item::rename_fields_processor, 1, + &column_rename_param); + if (field->check_constraint) + field->check_constraint->expr->walk(&Item::rename_fields_processor, 1, + &column_rename_param); + if (field->default_value) + field->default_value->expr->walk(&Item::rename_fields_processor, 1, + &column_rename_param); + } + table->m_needs_reopen= 1; // because new column name is on thd->mem_root + } + dropped_sys_vers_fields &= VERS_SYSTEM_FIELD; if ((dropped_sys_vers_fields || alter_info->flags & ALTER_DROP_PERIOD) && @@ -8357,7 +8381,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, while ((alter=alter_it++)) { if (!my_strcasecmp(system_charset_info,def->field_name.str, - alter->name)) + alter->name.str)) break; } if (alter) @@ -8372,7 +8396,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (unlikely(alter_info->alter_list.elements)) { my_error(ER_BAD_FIELD_ERROR, MYF(0), - alter_info->alter_list.head()->name, table->s->table_name.str); + alter_info->alter_list.head()->name.str, table->s->table_name.str); goto err; } if (unlikely(!new_create_list.elements)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f24da3ed412..1d4a8a7e228 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7705,13 +7705,12 @@ alter_list_item: } | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr { - if (unlikely(Lex->add_alter_list($4.str, $7, $3))) + if (unlikely(Lex->add_alter_list($4, $7, $3))) MYSQL_YYABORT; } | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT { - if (unlikely(Lex->add_alter_list($4.str, (Virtual_column_info*) 0, - $3))) + if (unlikely(Lex->add_alter_list($4, (Virtual_column_info*) 0, $3))) MYSQL_YYABORT; } | RENAME opt_to table_ident @@ -7728,6 +7727,11 @@ alter_list_item: lex->name= $3->table; lex->alter_info.flags|= ALTER_RENAME; } + | RENAME COLUMN_SYM ident TO_SYM ident + { + if (unlikely(Lex->add_alter_list($3, $5))) + MYSQL_YYABORT; + } | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate { if (!$4) |