summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.h14
-rw-r--r--sql/sql_lex.cc13
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_table.cc76
-rw-r--r--sql/sql_yacc.yy10
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)