Commit 926adcfe authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-14694 ALTER COLUMN IF EXISTS .. causes syntax error.

        Implementing the 'IF EXISTS' option for statements
        ALTER TABLE ALTER COLUMN SET/DROP DEFAULT.
parent 5478547c
......@@ -2275,6 +2275,19 @@ t1 CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (i int);
alter table t1 alter column if exists a set default 1;
Warnings:
Note 1054 Unknown column 'a' in 't1'
alter table t1 alter column if exists a drop default;
Warnings:
Note 1054 Unknown column 'a' in 't1'
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`i` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
#
# End of 10.2 tests
#
......@@ -1882,6 +1882,16 @@ alter table t1 drop column a, drop index a;
show create table t1;
drop table t1;
#
# MDEV-14694 ALTER COLUMN IF EXISTS .. causes syntax error
#
create table t1 (i int);
alter table t1 alter column if exists a set default 1;
alter table t1 alter column if exists a drop default;
show create table t1;
drop table t1;
--echo #
--echo # End of 10.2 tests
--echo #
......@@ -284,8 +284,9 @@ class Alter_column :public Sql_alloc {
public:
const char *name;
Virtual_column_info *default_value;
Alter_column(const char *par_name, Virtual_column_info *expr)
:name(par_name), default_value(expr) {}
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) {}
/**
Used to make a clone of this object for ALTER/CREATE TABLE
@sa comment for Key_part_spec::clone
......
......@@ -3645,6 +3645,8 @@ struct LEX: public Query_tables_list
alter_info.check_constraint_list.push_back(constr);
return false;
}
bool add_alter_list(const char *par_name, Virtual_column_info *expr,
bool par_exists);
void set_command(enum_sql_command command,
DDL_options_st options)
{
......
......@@ -6114,6 +6114,40 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
}
}
/* Handle ALTER COLUMN IF EXISTS SET/DROP DEFAULT. */
{
List_iterator<Alter_column> it(alter_info->alter_list);
Alter_column *acol;
while ((acol=it++))
{
if (!acol->alter_if_exists)
continue;
/*
If there is NO field with the same name in the table already,
remove the acol from the list.
*/
for (f_ptr=table->field; *f_ptr; f_ptr++)
{
if (my_strcasecmp(system_charset_info,
acol->name, (*f_ptr)->field_name.str) == 0)
break;
}
if (*f_ptr == NULL)
{
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);
it.remove();
if (alter_info->alter_list.is_empty())
{
alter_info->flags&= ~(Alter_info::ALTER_CHANGE_COLUMN_DEFAULT);
}
}
}
}
/* Handle DROP COLUMN/KEY IF EXISTS. */
{
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
......@@ -6142,7 +6176,9 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
}
else if (drop->type == Alter_drop::CHECK_CONSTRAINT)
{
for (uint i=table->s->field_check_constraints; i < table->s->table_check_constraints; i++)
for (uint i=table->s->field_check_constraints;
i < table->s->table_check_constraints;
i++)
{
if (my_strcasecmp(system_charset_info, drop->name,
table->check_constraints[i]->name.str) == 0)
......
......@@ -699,6 +699,18 @@ void LEX::add_key_to_list(LEX_CSTRING *field_name,
alter_info.key_list.push_back(key, mem_root);
}
bool LEX::add_alter_list(const char *name, Virtual_column_info *expr,
bool exists)
{
MEM_ROOT *mem_root= thd->mem_root;
Alter_column *ac= new (mem_root) Alter_column(name, expr, exists);
if (ac == NULL)
return true;
alter_info.alter_list.push_back(ac, mem_root);
alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
return false;
}
void LEX::init_last_field(Column_definition *field,
const LEX_CSTRING *field_name,
const CHARSET_INFO *cs)
......@@ -8174,24 +8186,15 @@ alter_list_item:
lex->alter_info.keys_onoff= Alter_info::ENABLE;
lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
}
| ALTER opt_column field_ident SET DEFAULT column_default_expr
| ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
{
LEX *lex=Lex;
Alter_column *ac= new (thd->mem_root) Alter_column($3.str,$6);
if (ac == NULL)
if (Lex->add_alter_list($4.str, $7, $3))
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac, thd->mem_root);
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| ALTER opt_column field_ident DROP DEFAULT
| ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT
{
LEX *lex=Lex;
Alter_column *ac= (new (thd->mem_root)
Alter_column($3.str, (Virtual_column_info*) 0));
if (ac == NULL)
if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3))
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac, thd->mem_root);
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| RENAME opt_to table_ident
{
......
......@@ -7735,24 +7735,15 @@ alter_list_item:
lex->alter_info.keys_onoff= Alter_info::ENABLE;
lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
}
| ALTER opt_column field_ident SET DEFAULT column_default_expr
| ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
{
LEX *lex=Lex;
Alter_column *ac= new (thd->mem_root) Alter_column($3.str,$6);
if (ac == NULL)
if (Lex->add_alter_list($4.str, $7, $3))
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac, thd->mem_root);
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| ALTER opt_column field_ident DROP DEFAULT
| ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT
{
LEX *lex=Lex;
Alter_column *ac= (new (thd->mem_root)
Alter_column($3.str, (Virtual_column_info*) 0));
if (ac == NULL)
if (Lex->add_alter_list($4.str, (Virtual_column_info*) 0, $3))
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac, thd->mem_root);
lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
}
| RENAME opt_to table_ident
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment