MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
Syntax modified to allow statements: ALTER TABLE ADD/DROP COLUMN ALTER TABLE ADD/DROP INDEX ALTER TABLE ADD/DROP FOREIGN KEY ALTER TABLE ADD/DROP PARTITION ALTER TABLE CHANGE COLUMN ALTER TABLE MODIFY COLUMN DROP INDEX to have IF (NOT) EXISTS options. Appropriate implementations added to mysql_alter_table(). per-file comments: mysql-test/r/alter_table.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). test result updated. mysql-test/r/fulltext.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/r/partition.result test result updated. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/alter_table.test tests added. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/fulltext.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. mysql-test/t/partition.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. sql/field.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/field.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/partition_info.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). has_unique_name made public. sql/sp_head.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sql/sql_class.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_class.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_lex.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_lex.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_parse.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_table.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). handle_if_exists_options() added. it's called in mysql_alter_table(). sql/sql_trigger.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_view.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_yacc.yy MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sintax modified.
This commit is contained in:
parent
1a600125ff
commit
d8dccde6df
@ -1340,3 +1340,43 @@ rename table t2 to t1;
|
||||
execute stmt1;
|
||||
deallocate prepare stmt1;
|
||||
drop table t2;
|
||||
CREATE TABLE t1 (
|
||||
id INT(11) NOT NULL,
|
||||
x_param INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT,
|
||||
ADD COLUMN IF NOT EXISTS lol INT AFTER id;
|
||||
Warnings:
|
||||
Note 1060 Duplicate column name 'id'
|
||||
ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id;
|
||||
Warnings:
|
||||
Note 1060 Duplicate column name 'lol'
|
||||
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
|
||||
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP 'lol'; check that column/key exists
|
||||
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
|
||||
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
|
||||
Warnings:
|
||||
Note 1061 Duplicate key name 'x_param'
|
||||
ALTER TABLE t1 MODIFY IF EXISTS lol INT;
|
||||
Warnings:
|
||||
Note 1054 Unknown column 'lol' in 't1'
|
||||
DROP INDEX IF EXISTS x_param ON t1;
|
||||
DROP INDEX IF EXISTS x_param ON t1;
|
||||
Warnings:
|
||||
Note 1091 Can't DROP 'x_param'; check that column/key exists
|
||||
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
|
||||
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
|
||||
Warnings:
|
||||
Note 1061 Duplicate key name 'x_param1'
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`id` int(11) NOT NULL,
|
||||
`x_param` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `x_param1` (`x_param`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
@ -699,3 +699,14 @@ EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
CREATE TABLE t1 (
|
||||
id int(11) auto_increment,
|
||||
title varchar(100) default '',
|
||||
PRIMARY KEY (id),
|
||||
KEY ind5 (title)
|
||||
) ENGINE=MyISAM;
|
||||
CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
|
||||
CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
|
||||
Warnings:
|
||||
Note 1061 Duplicate key name 'ft1'
|
||||
DROP TABLE t1;
|
||||
|
@ -2493,3 +2493,25 @@ i
|
||||
3
|
||||
4
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 ( d DATE NOT NULL)
|
||||
PARTITION BY RANGE( YEAR(d) ) (
|
||||
PARTITION p0 VALUES LESS THAN (1960),
|
||||
PARTITION p1 VALUES LESS THAN (1970),
|
||||
PARTITION p2 VALUES LESS THAN (1980),
|
||||
PARTITION p3 VALUES LESS THAN (1990)
|
||||
);
|
||||
ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
|
||||
PARTITION `p5` VALUES LESS THAN (2010)
|
||||
COMMENT 'APSTART \' APEND'
|
||||
);
|
||||
ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
|
||||
PARTITION `p5` VALUES LESS THAN (2010)
|
||||
COMMENT 'APSTART \' APEND'
|
||||
);
|
||||
Warnings:
|
||||
Note 1517 Duplicate partition name p5
|
||||
alter table t1 drop partition if exists p5;
|
||||
alter table t1 drop partition if exists p5;
|
||||
Warnings:
|
||||
Note 1507 Error in list of partitions to DROP
|
||||
DROP TABLE t1;
|
||||
|
@ -1231,3 +1231,30 @@ execute stmt1;
|
||||
deallocate prepare stmt1;
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# Test of ALTER TABLE IF [NOT] EXISTS
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT(11) NOT NULL,
|
||||
x_param INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT,
|
||||
ADD COLUMN IF NOT EXISTS lol INT AFTER id;
|
||||
ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id;
|
||||
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
|
||||
ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
|
||||
|
||||
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
|
||||
ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
|
||||
ALTER TABLE t1 MODIFY IF EXISTS lol INT;
|
||||
|
||||
DROP INDEX IF EXISTS x_param ON t1;
|
||||
DROP INDEX IF EXISTS x_param ON t1;
|
||||
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
|
||||
CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
@ -646,3 +646,14 @@ DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) auto_increment,
|
||||
title varchar(100) default '',
|
||||
PRIMARY KEY (id),
|
||||
KEY ind5 (title)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
|
||||
CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
|
||||
DROP TABLE t1;
|
||||
|
@ -2494,3 +2494,31 @@ INSERT INTO t1 VALUES (1),(2),(2),(3),(4);
|
||||
ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
|
||||
SELECT * from t1 order by i;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test ALTER TABLE ADD/DROP PARTITION IF EXISTS
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( d DATE NOT NULL)
|
||||
PARTITION BY RANGE( YEAR(d) ) (
|
||||
PARTITION p0 VALUES LESS THAN (1960),
|
||||
PARTITION p1 VALUES LESS THAN (1970),
|
||||
PARTITION p2 VALUES LESS THAN (1980),
|
||||
PARTITION p3 VALUES LESS THAN (1990)
|
||||
);
|
||||
|
||||
ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
|
||||
PARTITION `p5` VALUES LESS THAN (2010)
|
||||
COMMENT 'APSTART \' APEND'
|
||||
);
|
||||
|
||||
ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
|
||||
PARTITION `p5` VALUES LESS THAN (2010)
|
||||
COMMENT 'APSTART \' APEND'
|
||||
);
|
||||
|
||||
alter table t1 drop partition if exists p5;
|
||||
alter table t1 drop partition if exists p5;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
|
@ -8886,6 +8886,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
||||
FLAGSTR(pack_flag, FIELDFLAG_DECIMAL),
|
||||
f_packtype(pack_flag)));
|
||||
vcol_info= 0;
|
||||
create_if_not_exists= FALSE;
|
||||
stored_in_db= TRUE;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
@ -8923,7 +8924,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
||||
char *fld_change, List<String> *fld_interval_list,
|
||||
CHARSET_INFO *fld_charset, uint fld_geom_type,
|
||||
Virtual_column_info *fld_vcol_info,
|
||||
engine_option_value *create_opt)
|
||||
engine_option_value *create_opt, bool check_exists)
|
||||
{
|
||||
uint sign_len, allowed_type_modifier= 0;
|
||||
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
|
||||
@ -8977,6 +8978,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
|
||||
|
||||
comment= *fld_comment;
|
||||
vcol_info= fld_vcol_info;
|
||||
create_if_not_exists= check_exists;
|
||||
stored_in_db= TRUE;
|
||||
|
||||
/* Initialize data for a computed field */
|
||||
@ -9585,6 +9587,7 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
|
||||
comment= old_field->comment;
|
||||
decimals= old_field->decimals();
|
||||
vcol_info= old_field->vcol_info;
|
||||
create_if_not_exists= FALSE;
|
||||
stored_in_db= old_field->stored_in_db;
|
||||
option_list= old_field->option_list;
|
||||
option_struct= old_field->option_struct;
|
||||
|
@ -2385,8 +2385,9 @@ public:
|
||||
|
||||
uint8 interval_id; // For rea_create_table
|
||||
uint offset,pack_flag;
|
||||
bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS
|
||||
|
||||
/*
|
||||
/*
|
||||
This is additinal data provided for any computed(virtual) field.
|
||||
In particular it includes a pointer to the item by which this field
|
||||
can be computed from other fields.
|
||||
@ -2399,7 +2400,8 @@ public:
|
||||
*/
|
||||
bool stored_in_db;
|
||||
|
||||
Create_field() :after(0), option_list(NULL), option_struct(NULL)
|
||||
Create_field() :after(0), option_list(NULL), option_struct(NULL),
|
||||
create_if_not_exists(FALSE)
|
||||
{}
|
||||
Create_field(Field *field, Field *orig_field);
|
||||
/* Used to make a clone of this object for ALTER/CREATE TABLE */
|
||||
@ -2417,7 +2419,7 @@ public:
|
||||
Item *on_update_value, LEX_STRING *comment, char *change,
|
||||
List<String> *interval_list, CHARSET_INFO *cs,
|
||||
uint uint_geom_type, Virtual_column_info *vcol_info,
|
||||
engine_option_value *option_list);
|
||||
engine_option_value *option_list, bool check_exists);
|
||||
|
||||
bool field_flags_are_binary()
|
||||
{
|
||||
|
@ -306,6 +306,7 @@ private:
|
||||
char *create_default_partition_names(uint part_no, uint num_parts,
|
||||
uint start_no);
|
||||
char *create_subpartition_name(uint subpart_no, const char *part_name);
|
||||
public:
|
||||
bool has_unique_name(partition_element *element);
|
||||
};
|
||||
|
||||
|
@ -2434,7 +2434,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
|
||||
lex->charset ? lex->charset :
|
||||
thd->variables.collation_database,
|
||||
lex->uint_geom_type,
|
||||
lex->vcol_info, NULL))
|
||||
lex->vcol_info, NULL, FALSE))
|
||||
return TRUE;
|
||||
|
||||
if (field_def->interval_list.elements)
|
||||
|
@ -112,7 +112,8 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root)
|
||||
columns(rhs.columns, mem_root),
|
||||
name(rhs.name),
|
||||
option_list(rhs.option_list),
|
||||
generated(rhs.generated)
|
||||
generated(rhs.generated),
|
||||
create_if_not_exists(rhs.create_if_not_exists)
|
||||
{
|
||||
list_copy_and_replace_each_value(columns, mem_root);
|
||||
}
|
||||
|
@ -222,8 +222,9 @@ public:
|
||||
enum drop_type {KEY, COLUMN };
|
||||
const char *name;
|
||||
enum drop_type type;
|
||||
Alter_drop(enum drop_type par_type,const char *par_name)
|
||||
:name(par_name), type(par_type) {}
|
||||
bool drop_if_exists;
|
||||
Alter_drop(enum drop_type par_type,const char *par_name, bool par_exists)
|
||||
:name(par_name), type(par_type), drop_if_exists(par_exists) {}
|
||||
/**
|
||||
Used to make a clone of this object for ALTER/CREATE TABLE
|
||||
@sa comment for Key_part_spec::clone
|
||||
@ -257,20 +258,23 @@ public:
|
||||
LEX_STRING name;
|
||||
engine_option_value *option_list;
|
||||
bool generated;
|
||||
bool create_if_not_exists;
|
||||
|
||||
Key(enum Keytype type_par, const LEX_STRING &name_arg,
|
||||
KEY_CREATE_INFO *key_info_arg,
|
||||
bool generated_arg, List<Key_part_spec> &cols,
|
||||
engine_option_value *create_opt)
|
||||
engine_option_value *create_opt, bool if_not_exists_opt)
|
||||
:type(type_par), key_create_info(*key_info_arg), columns(cols),
|
||||
name(name_arg), option_list(create_opt), generated(generated_arg)
|
||||
name(name_arg), option_list(create_opt), generated(generated_arg),
|
||||
create_if_not_exists(if_not_exists_opt)
|
||||
{}
|
||||
Key(enum Keytype type_par, const char *name_arg, size_t name_len_arg,
|
||||
KEY_CREATE_INFO *key_info_arg, bool generated_arg,
|
||||
List<Key_part_spec> &cols,
|
||||
engine_option_value *create_opt)
|
||||
engine_option_value *create_opt, bool if_not_exists_opt)
|
||||
:type(type_par), key_create_info(*key_info_arg), columns(cols),
|
||||
option_list(create_opt), generated(generated_arg)
|
||||
option_list(create_opt), generated(generated_arg),
|
||||
create_if_not_exists(if_not_exists_opt)
|
||||
{
|
||||
name.str= (char *)name_arg;
|
||||
name.length= name_len_arg;
|
||||
@ -301,8 +305,10 @@ public:
|
||||
uint delete_opt, update_opt, match_opt;
|
||||
Foreign_key(const LEX_STRING &name_arg, List<Key_part_spec> &cols,
|
||||
Table_ident *table, List<Key_part_spec> &ref_cols,
|
||||
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
||||
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
|
||||
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg,
|
||||
bool if_not_exists_opt)
|
||||
:Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL,
|
||||
if_not_exists_opt),
|
||||
ref_table(table), ref_columns(ref_cols),
|
||||
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
|
||||
match_opt(match_opt_arg)
|
||||
|
@ -507,6 +507,7 @@ void lex_start(THD *thd)
|
||||
lex->expr_allows_subselect= TRUE;
|
||||
lex->use_only_table_context= FALSE;
|
||||
lex->parse_vcol_expr= FALSE;
|
||||
lex->check_exists= FALSE;
|
||||
lex->verbose= 0;
|
||||
|
||||
lex->name.str= 0;
|
||||
|
@ -2509,7 +2509,8 @@ struct LEX: public Query_tables_list
|
||||
uint16 create_view_algorithm;
|
||||
uint8 create_view_check;
|
||||
uint8 context_analysis_only;
|
||||
bool drop_if_exists, drop_temporary, local_file, one_shot_set;
|
||||
bool drop_temporary, local_file, one_shot_set;
|
||||
bool check_exists;
|
||||
bool autocommit;
|
||||
bool verbose, no_write_to_binlog;
|
||||
|
||||
|
@ -2084,7 +2084,7 @@ mysql_execute_command(THD *thd)
|
||||
if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
|
||||
!(lex->sql_command == SQLCOM_SET_OPTION) &&
|
||||
!(lex->sql_command == SQLCOM_DROP_TABLE &&
|
||||
lex->drop_temporary && lex->drop_if_exists) &&
|
||||
lex->drop_temporary && lex->check_exists) &&
|
||||
all_tables_not_ok(thd, all_tables))
|
||||
{
|
||||
/* we warn the slave SQL thread */
|
||||
@ -3285,7 +3285,7 @@ end_with_restore_list:
|
||||
thd->variables.option_bits|= OPTION_KEEP_LOG;
|
||||
}
|
||||
/* DDL and binlog write order are protected by metadata locks. */
|
||||
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
|
||||
res= mysql_rm_table(thd, first_table, lex->check_exists,
|
||||
lex->drop_temporary);
|
||||
}
|
||||
break;
|
||||
@ -3499,7 +3499,7 @@ end_with_restore_list:
|
||||
#endif
|
||||
if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
|
||||
break;
|
||||
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
|
||||
res= mysql_rm_db(thd, lex->name.str, lex->check_exists, 0);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_ALTER_DB_UPGRADE:
|
||||
@ -3627,7 +3627,7 @@ end_with_restore_list:
|
||||
case SQLCOM_DROP_EVENT:
|
||||
if (!(res= Events::drop_event(thd,
|
||||
lex->spname->m_db, lex->spname->m_name,
|
||||
lex->drop_if_exists)))
|
||||
lex->check_exists)))
|
||||
my_ok(thd);
|
||||
break;
|
||||
#else
|
||||
@ -4314,7 +4314,7 @@ create_sp_error:
|
||||
|
||||
if (lex->spname->m_db.str == NULL)
|
||||
{
|
||||
if (lex->drop_if_exists)
|
||||
if (lex->check_exists)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
|
||||
@ -4383,7 +4383,7 @@ create_sp_error:
|
||||
my_ok(thd);
|
||||
break;
|
||||
case SP_KEY_NOT_FOUND:
|
||||
if (lex->drop_if_exists)
|
||||
if (lex->check_exists)
|
||||
{
|
||||
res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
@ -4596,7 +4596,7 @@ create_sp_error:
|
||||
|
||||
if ((err_code= drop_server(thd, &lex->server_options)))
|
||||
{
|
||||
if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
|
||||
if (! lex->check_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
|
||||
{
|
||||
DBUG_PRINT("info", ("problem dropping server %s",
|
||||
lex->server_options.server_name));
|
||||
@ -6016,7 +6016,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
||||
lex->col_list.push_back(new Key_part_spec(*field_name, 0));
|
||||
key= new Key(Key::PRIMARY, null_lex_str,
|
||||
&default_key_create_info,
|
||||
0, lex->col_list, NULL);
|
||||
0, lex->col_list, NULL, lex->check_exists);
|
||||
lex->alter_info.key_list.push_back(key);
|
||||
lex->col_list.empty();
|
||||
}
|
||||
@ -6026,7 +6026,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
||||
lex->col_list.push_back(new Key_part_spec(*field_name, 0));
|
||||
key= new Key(Key::UNIQUE, null_lex_str,
|
||||
&default_key_create_info, 0,
|
||||
lex->col_list, NULL);
|
||||
lex->col_list, NULL, lex->check_exists);
|
||||
lex->alter_info.key_list.push_back(key);
|
||||
lex->col_list.empty();
|
||||
}
|
||||
@ -6078,7 +6078,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
|
||||
new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
|
||||
default_value, on_update_value, comment, change,
|
||||
interval_list, cs, uint_geom_type, vcol_info,
|
||||
create_options))
|
||||
create_options, lex->check_exists))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
lex->alter_info.create_list.push_back(new_field);
|
||||
|
253
sql/sql_table.cc
253
sql/sql_table.cc
@ -4953,6 +4953,246 @@ is_index_maintenance_unique (TABLE *table, Alter_info *alter_info)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Preparation for table creation
|
||||
|
||||
SYNOPSIS
|
||||
handle_if_exists_option()
|
||||
thd Thread object.
|
||||
table The altered table.
|
||||
alter_info List of columns and indexes to create
|
||||
|
||||
DESCRIPTION
|
||||
Looks for the IF [NOT] EXISTS options, checks the states and remove items
|
||||
from the list if existing found.
|
||||
|
||||
RETURN VALUES
|
||||
NONE
|
||||
*/
|
||||
|
||||
static void
|
||||
handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
|
||||
{
|
||||
Field **f_ptr;
|
||||
DBUG_ENTER("handle_if_exists_option");
|
||||
|
||||
/* Handle ADD COLUMN IF NOT EXISTS. */
|
||||
{
|
||||
List_iterator<Create_field> it(alter_info->create_list);
|
||||
Create_field *sql_field;
|
||||
|
||||
while ((sql_field=it++))
|
||||
{
|
||||
if (!sql_field->create_if_not_exists || sql_field->change)
|
||||
continue;
|
||||
/*
|
||||
If there is a field with the same name in the table already,
|
||||
remove the sql_field from the list.
|
||||
*/
|
||||
for (f_ptr=table->field; *f_ptr; f_ptr++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
sql_field->field_name, (*f_ptr)->field_name) == 0)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),
|
||||
sql_field->field_name);
|
||||
it.remove();
|
||||
if (alter_info->create_list.is_empty())
|
||||
{
|
||||
alter_info->flags&= ~ALTER_ADD_COLUMN;
|
||||
if (alter_info->key_list.is_empty())
|
||||
alter_info->flags&= ~ALTER_ADD_INDEX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle MODIFY COLUMN IF EXISTS. */
|
||||
{
|
||||
List_iterator<Create_field> it(alter_info->create_list);
|
||||
Create_field *sql_field;
|
||||
|
||||
while ((sql_field=it++))
|
||||
{
|
||||
if (!sql_field->create_if_not_exists || !sql_field->change)
|
||||
continue;
|
||||
/*
|
||||
If there is NO field with the same name in the table already,
|
||||
remove the sql_field from the list.
|
||||
*/
|
||||
for (f_ptr=table->field; *f_ptr; f_ptr++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
sql_field->field_name, (*f_ptr)->field_name) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*f_ptr == NULL)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR),
|
||||
sql_field->change, table->s->table_name.str);
|
||||
it.remove();
|
||||
if (alter_info->create_list.is_empty())
|
||||
{
|
||||
alter_info->flags&= ~(ALTER_ADD_COLUMN | ALTER_CHANGE_COLUMN);
|
||||
if (alter_info->key_list.is_empty())
|
||||
alter_info->flags&= ~ALTER_ADD_INDEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle DROP COLUMN/KEY IF EXISTS. */
|
||||
{
|
||||
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
|
||||
Alter_drop *drop;
|
||||
bool remove_drop;
|
||||
while ((drop= drop_it++))
|
||||
{
|
||||
if (!drop->drop_if_exists)
|
||||
continue;
|
||||
remove_drop= TRUE;
|
||||
if (drop->type == Alter_drop::COLUMN)
|
||||
{
|
||||
/*
|
||||
If there is NO field with that name in the table,
|
||||
remove the 'drop' from the list.
|
||||
*/
|
||||
for (f_ptr=table->field; *f_ptr; f_ptr++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
drop->name, (*f_ptr)->field_name) == 0)
|
||||
{
|
||||
remove_drop= FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* Alter_drop::KEY */
|
||||
{
|
||||
uint n_key;
|
||||
for (n_key=0; n_key < table->s->keys; n_key++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
drop->name, table->key_info[n_key].name) == 0)
|
||||
{
|
||||
remove_drop= FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remove_drop)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY),
|
||||
drop->name);
|
||||
drop_it.remove();
|
||||
if (alter_info->drop_list.is_empty())
|
||||
alter_info->flags&= ~(ALTER_DROP_COLUMN | ALTER_DROP_INDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ALTER TABLE ADD KEY IF NOT EXISTS */
|
||||
/* ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS */
|
||||
{
|
||||
Key *key;
|
||||
List_iterator<Key> key_it(alter_info->key_list);
|
||||
uint n_key;
|
||||
while ((key=key_it++))
|
||||
{
|
||||
if (!key->create_if_not_exists)
|
||||
continue;
|
||||
for (n_key=0; n_key < table->s->keys; n_key++)
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
key->name.str, table->key_info[n_key].name) == 0)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), key->name.str);
|
||||
key_it.remove();
|
||||
if (key->type == Key::FOREIGN_KEY)
|
||||
{
|
||||
/* ADD FOREIGN KEY appends two items. */
|
||||
key_it.remove();
|
||||
}
|
||||
if (alter_info->key_list.is_empty())
|
||||
alter_info->flags&= ~ALTER_ADD_INDEX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
partition_info *tab_part_info= table->part_info;
|
||||
if (tab_part_info && thd->lex->check_exists)
|
||||
{
|
||||
/* ALTER TABLE ADD PARTITION IF NOT EXISTS */
|
||||
if (alter_info->flags & ALTER_ADD_PARTITION)
|
||||
{
|
||||
partition_info *alt_part_info= thd->lex->part_info;
|
||||
if (alt_part_info)
|
||||
{
|
||||
List_iterator<partition_element> new_part_it(alt_part_info->partitions);
|
||||
partition_element *pe;
|
||||
while ((pe= new_part_it++))
|
||||
{
|
||||
if (!tab_part_info->has_unique_name(pe))
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_SAME_NAME_PARTITION, ER(ER_SAME_NAME_PARTITION),
|
||||
pe->partition_name);
|
||||
alter_info->flags&= ~ALTER_ADD_PARTITION;
|
||||
thd->lex->part_info= NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ALTER TABLE DROP PARTITION IF EXISTS */
|
||||
if (alter_info->flags & ALTER_DROP_PARTITION)
|
||||
{
|
||||
List_iterator<char> names_it(alter_info->partition_names);
|
||||
char *name;
|
||||
|
||||
while ((name= names_it++))
|
||||
{
|
||||
List_iterator<partition_element> part_it(tab_part_info->partitions);
|
||||
partition_element *part_elem;
|
||||
while ((part_elem= part_it++))
|
||||
{
|
||||
if (my_strcasecmp(system_charset_info,
|
||||
part_elem->partition_name, name) == 0)
|
||||
break;
|
||||
}
|
||||
if (!part_elem)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_DROP_PARTITION_NON_EXISTENT,
|
||||
ER(ER_DROP_PARTITION_NON_EXISTENT), "DROP");
|
||||
names_it.remove();
|
||||
}
|
||||
}
|
||||
if (alter_info->partition_names.elements == 0)
|
||||
alter_info->flags&= ~ALTER_DROP_PARTITION;
|
||||
}
|
||||
}
|
||||
#endif /*WITH_PARTITION_STORAGE_ENGINE*/
|
||||
|
||||
/* Clear the ALTER_FOREIGN_KEY flag if nothing other than that set. */
|
||||
if (alter_info->flags == ALTER_FOREIGN_KEY)
|
||||
alter_info->flags= 0;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
mysql_compare_tables()
|
||||
@ -5873,7 +6113,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
|
||||
key= new Key(key_type, key_name, strlen(key_name),
|
||||
&key_create_info,
|
||||
test(key_info->flags & HA_GENERATED_KEY),
|
||||
key_parts, key_info->option_list);
|
||||
key_parts, key_info->option_list, FALSE);
|
||||
new_key_list.push_back(key);
|
||||
}
|
||||
}
|
||||
@ -6386,6 +6626,17 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
handle_if_exists_options(thd, table, alter_info);
|
||||
|
||||
/* Look if we have to do anything at all. */
|
||||
/* Normally ALTER can become NOOP only after handling */
|
||||
/* the IF (NOT) EXISTS options. */
|
||||
if (alter_info->flags == 0)
|
||||
{
|
||||
copied= deleted= 0;
|
||||
goto end_temporary;
|
||||
}
|
||||
|
||||
/* We have to do full alter table. */
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
|
@ -443,7 +443,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
|
||||
if (!create)
|
||||
{
|
||||
bool if_exists= thd->lex->drop_if_exists;
|
||||
bool if_exists= thd->lex->check_exists;
|
||||
|
||||
/*
|
||||
Protect the query table list from the temporary and potentially
|
||||
|
@ -1672,7 +1672,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
|
||||
{
|
||||
char name[FN_REFLEN];
|
||||
my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
|
||||
if (thd->lex->drop_if_exists)
|
||||
if (thd->lex->check_exists)
|
||||
{
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
|
||||
|
150
sql/sql_yacc.yy
150
sql/sql_yacc.yy
@ -722,7 +722,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
|
||||
{
|
||||
Key *key;
|
||||
key= new Key(type, name, info ? info : &lex->key_create_info, generated,
|
||||
lex->col_list, lex->option_list);
|
||||
lex->col_list, lex->option_list, lex->check_exists);
|
||||
if (key == NULL)
|
||||
return TRUE;
|
||||
|
||||
@ -1454,7 +1454,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
|
||||
NCHAR_STRING opt_component key_cache_name
|
||||
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
|
||||
opt_constraint constraint opt_ident
|
||||
opt_constraint constraint opt_ident opt_if_not_exists_ident
|
||||
|
||||
%type <lex_str_ptr>
|
||||
opt_table_alias
|
||||
@ -1471,7 +1471,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
|
||||
%type <num>
|
||||
type type_with_opt_collate int_type real_type order_dir lock_option
|
||||
udf_type if_exists opt_local opt_table_options table_options
|
||||
udf_type opt_if_exists opt_local opt_table_options table_options
|
||||
table_option opt_if_not_exists opt_no_write_to_binlog
|
||||
opt_temporary all_or_any opt_distinct
|
||||
opt_ignore_leaves fulltext_options spatial_type union_option
|
||||
@ -2131,36 +2131,36 @@ create:
|
||||
}
|
||||
create_table_set_open_action_and_adjust_tables(lex);
|
||||
}
|
||||
| CREATE opt_unique INDEX_SYM ident key_alg ON table_ident
|
||||
| CREATE opt_unique INDEX_SYM opt_if_not_exists ident key_alg ON table_ident
|
||||
{
|
||||
if (add_create_index_prepare(Lex, $7))
|
||||
if (add_create_index_prepare(Lex, $8))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
'(' key_list ')' normal_key_options
|
||||
{
|
||||
if (add_create_index(Lex, $2, $4))
|
||||
if (add_create_index(Lex, $2, $5))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| CREATE fulltext INDEX_SYM ident init_key_options ON
|
||||
| CREATE fulltext INDEX_SYM opt_if_not_exists ident init_key_options ON
|
||||
table_ident
|
||||
{
|
||||
if (add_create_index_prepare(Lex, $7))
|
||||
if (add_create_index_prepare(Lex, $8))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
'(' key_list ')' fulltext_key_options
|
||||
{
|
||||
if (add_create_index(Lex, $2, $4))
|
||||
if (add_create_index(Lex, $2, $5))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| CREATE spatial INDEX_SYM ident init_key_options ON
|
||||
| CREATE spatial INDEX_SYM opt_if_not_exists ident init_key_options ON
|
||||
table_ident
|
||||
{
|
||||
if (add_create_index_prepare(Lex, $7))
|
||||
if (add_create_index_prepare(Lex, $8))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
'(' key_list ')' spatial_key_options
|
||||
{
|
||||
if (add_create_index(Lex, $2, $4))
|
||||
if (add_create_index(Lex, $2, $5))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| CREATE DATABASE opt_if_not_exists ident
|
||||
@ -5079,9 +5079,17 @@ table_option:
|
||||
;
|
||||
|
||||
opt_if_not_exists:
|
||||
/* empty */ { $$= 0; }
|
||||
| IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
|
||||
;
|
||||
/* empty */
|
||||
{
|
||||
Lex->check_exists= FALSE;
|
||||
$$= 0;
|
||||
}
|
||||
| IF not EXISTS
|
||||
{
|
||||
Lex->check_exists= TRUE;
|
||||
$$=HA_LEX_CREATE_IF_NOT_EXISTS;
|
||||
}
|
||||
;
|
||||
|
||||
opt_create_table_options:
|
||||
/* empty */
|
||||
@ -5399,14 +5407,14 @@ column_def:
|
||||
;
|
||||
|
||||
key_def:
|
||||
normal_key_type opt_ident key_alg '(' key_list ')'
|
||||
normal_key_type opt_if_not_exists_ident key_alg '(' key_list ')'
|
||||
{ Lex->option_list= NULL; }
|
||||
normal_key_options
|
||||
{
|
||||
if (add_create_index (Lex, $1, $2))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| fulltext opt_key_or_index opt_ident init_key_options
|
||||
| fulltext opt_key_or_index opt_if_not_exists_ident init_key_options
|
||||
'(' key_list ')'
|
||||
{ Lex->option_list= NULL; }
|
||||
fulltext_key_options
|
||||
@ -5414,7 +5422,7 @@ key_def:
|
||||
if (add_create_index (Lex, $1, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| spatial opt_key_or_index opt_ident init_key_options
|
||||
| spatial opt_key_or_index opt_if_not_exists_ident init_key_options
|
||||
'(' key_list ')'
|
||||
{ Lex->option_list= NULL; }
|
||||
spatial_key_options
|
||||
@ -5430,7 +5438,7 @@ key_def:
|
||||
if (add_create_index (Lex, $2, $3.str ? $3 : $1))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
||||
| opt_constraint FOREIGN KEY_SYM opt_if_not_exists_ident '(' key_list ')' references
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list,
|
||||
@ -5438,7 +5446,8 @@ key_def:
|
||||
lex->ref_list,
|
||||
lex->fk_delete_opt,
|
||||
lex->fk_update_opt,
|
||||
lex->fk_match_option);
|
||||
lex->fk_match_option,
|
||||
lex->check_exists);
|
||||
if (key == NULL)
|
||||
MYSQL_YYABORT;
|
||||
lex->alter_info.key_list.push_back(key);
|
||||
@ -6407,6 +6416,18 @@ opt_ident:
|
||||
| field_ident { $$= $1; }
|
||||
;
|
||||
|
||||
opt_if_not_exists_ident:
|
||||
opt_if_not_exists opt_ident
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
if (lex->check_exists && lex->sql_command != SQLCOM_ALTER_TABLE)
|
||||
{
|
||||
my_parse_error(ER(ER_SYNTAX_ERROR));
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
$$= $2;
|
||||
};
|
||||
|
||||
opt_component:
|
||||
/* empty */ { $$= null_lex_str; }
|
||||
| '.' ident { $$= $2; }
|
||||
@ -6663,7 +6684,7 @@ alter_commands:
|
||||
new table and so forth.
|
||||
*/
|
||||
| add_partition_rule
|
||||
| DROP PARTITION_SYM alt_part_name_list
|
||||
| DROP PARTITION_SYM opt_if_exists alt_part_name_list
|
||||
{
|
||||
Lex->alter_info.flags|= ALTER_DROP_PARTITION;
|
||||
}
|
||||
@ -6764,7 +6785,7 @@ all_or_alt_part_name_list:
|
||||
;
|
||||
|
||||
add_partition_rule:
|
||||
ADD PARTITION_SYM opt_no_write_to_binlog
|
||||
ADD PARTITION_SYM opt_if_not_exists opt_no_write_to_binlog
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->part_info= new partition_info();
|
||||
@ -6774,7 +6795,7 @@ add_partition_rule:
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
lex->alter_info.flags|= ALTER_ADD_PARTITION;
|
||||
lex->no_write_to_binlog= $3;
|
||||
lex->no_write_to_binlog= $4;
|
||||
}
|
||||
add_part_extra
|
||||
{}
|
||||
@ -6850,7 +6871,7 @@ alter_list:
|
||||
;
|
||||
|
||||
add_column:
|
||||
ADD opt_column
|
||||
ADD opt_column opt_if_not_exists
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->change=0;
|
||||
@ -6872,10 +6893,10 @@ alter_list_item:
|
||||
{
|
||||
Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX;
|
||||
}
|
||||
| CHANGE opt_column field_ident
|
||||
| CHANGE opt_column opt_if_exists field_ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->change= $3.str;
|
||||
lex->change= $4.str;
|
||||
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
||||
lex->option_list= NULL;
|
||||
}
|
||||
@ -6883,7 +6904,7 @@ alter_list_item:
|
||||
{
|
||||
Lex->create_last_non_select_table= Lex->last_table();
|
||||
}
|
||||
| MODIFY_SYM opt_column field_ident
|
||||
| MODIFY_SYM opt_column opt_if_exists field_ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->length=lex->dec=0; lex->type=0;
|
||||
@ -6897,12 +6918,12 @@ alter_list_item:
|
||||
field_def
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (add_field_to_list(lex->thd,&$3,
|
||||
(enum enum_field_types) $5,
|
||||
if (add_field_to_list(lex->thd,&$4,
|
||||
(enum enum_field_types) $6,
|
||||
lex->length,lex->dec,lex->type,
|
||||
lex->default_value, lex->on_update_value,
|
||||
&lex->comment,
|
||||
$3.str, &lex->interval_list, lex->charset,
|
||||
$4.str, &lex->interval_list, lex->charset,
|
||||
lex->uint_geom_type,
|
||||
lex->vcol_info, lex->option_list))
|
||||
MYSQL_YYABORT;
|
||||
@ -6911,32 +6932,33 @@ alter_list_item:
|
||||
{
|
||||
Lex->create_last_non_select_table= Lex->last_table();
|
||||
}
|
||||
| DROP opt_column field_ident opt_restrict
|
||||
| DROP opt_column opt_if_exists field_ident opt_restrict
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str);
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $4.str, $3);
|
||||
if (ad == NULL)
|
||||
MYSQL_YYABORT;
|
||||
lex->alter_info.drop_list.push_back(ad);
|
||||
lex->alter_info.flags|= ALTER_DROP_COLUMN;
|
||||
}
|
||||
| DROP FOREIGN KEY_SYM opt_ident
|
||||
| DROP FOREIGN KEY_SYM opt_if_exists opt_ident
|
||||
{
|
||||
Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY;
|
||||
}
|
||||
| DROP PRIMARY_SYM KEY_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name);
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name,
|
||||
FALSE);
|
||||
if (ad == NULL)
|
||||
MYSQL_YYABORT;
|
||||
lex->alter_info.drop_list.push_back(ad);
|
||||
lex->alter_info.flags|= ALTER_DROP_INDEX;
|
||||
}
|
||||
| DROP key_or_index field_ident
|
||||
| DROP key_or_index opt_if_exists field_ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3);
|
||||
if (ad == NULL)
|
||||
MYSQL_YYABORT;
|
||||
lex->alter_info.drop_list.push_back(ad);
|
||||
@ -10815,41 +10837,41 @@ do:
|
||||
*/
|
||||
|
||||
drop:
|
||||
DROP opt_temporary table_or_tables if_exists
|
||||
DROP opt_temporary table_or_tables opt_if_exists
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->sql_command = SQLCOM_DROP_TABLE;
|
||||
lex->drop_temporary= $2;
|
||||
lex->drop_if_exists= $4;
|
||||
lex->check_exists= $4;
|
||||
YYPS->m_lock_type= TL_UNLOCK;
|
||||
YYPS->m_mdl_type= MDL_EXCLUSIVE;
|
||||
}
|
||||
table_list opt_restrict
|
||||
{}
|
||||
| DROP INDEX_SYM ident ON table_ident {}
|
||||
| DROP INDEX_SYM opt_if_exists ident ON table_ident {}
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
|
||||
Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3);
|
||||
if (ad == NULL)
|
||||
MYSQL_YYABORT;
|
||||
lex->sql_command= SQLCOM_DROP_INDEX;
|
||||
lex->alter_info.reset();
|
||||
lex->alter_info.flags= ALTER_DROP_INDEX;
|
||||
lex->alter_info.drop_list.push_back(ad);
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $6, NULL,
|
||||
TL_OPTION_UPDATING,
|
||||
TL_READ_NO_INSERT,
|
||||
MDL_SHARED_NO_WRITE))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| DROP DATABASE if_exists ident
|
||||
| DROP DATABASE opt_if_exists ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->sql_command= SQLCOM_DROP_DB;
|
||||
lex->drop_if_exists=$3;
|
||||
lex->check_exists=$3;
|
||||
lex->name= $4;
|
||||
}
|
||||
| DROP FUNCTION_SYM if_exists ident '.' ident
|
||||
| DROP FUNCTION_SYM opt_if_exists ident '.' ident
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
@ -10865,14 +10887,14 @@ drop:
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
lex->sql_command = SQLCOM_DROP_FUNCTION;
|
||||
lex->drop_if_exists= $3;
|
||||
lex->check_exists= $3;
|
||||
spname= new sp_name($4, $6, true);
|
||||
if (spname == NULL)
|
||||
MYSQL_YYABORT;
|
||||
spname->init_qname(thd);
|
||||
lex->spname= spname;
|
||||
}
|
||||
| DROP FUNCTION_SYM if_exists ident
|
||||
| DROP FUNCTION_SYM opt_if_exists ident
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= thd->lex;
|
||||
@ -10886,14 +10908,14 @@ drop:
|
||||
if (thd->db && lex->copy_db_to(&db.str, &db.length))
|
||||
MYSQL_YYABORT;
|
||||
lex->sql_command = SQLCOM_DROP_FUNCTION;
|
||||
lex->drop_if_exists= $3;
|
||||
lex->check_exists= $3;
|
||||
spname= new sp_name(db, $4, false);
|
||||
if (spname == NULL)
|
||||
MYSQL_YYABORT;
|
||||
spname->init_qname(thd);
|
||||
lex->spname= spname;
|
||||
}
|
||||
| DROP PROCEDURE_SYM if_exists sp_name
|
||||
| DROP PROCEDURE_SYM opt_if_exists sp_name
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
if (lex->sphead)
|
||||
@ -10902,34 +10924,34 @@ drop:
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
lex->sql_command = SQLCOM_DROP_PROCEDURE;
|
||||
lex->drop_if_exists= $3;
|
||||
lex->check_exists= $3;
|
||||
lex->spname= $4;
|
||||
}
|
||||
| DROP USER clear_privileges user_list
|
||||
{
|
||||
Lex->sql_command = SQLCOM_DROP_USER;
|
||||
}
|
||||
| DROP VIEW_SYM if_exists
|
||||
| DROP VIEW_SYM opt_if_exists
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command= SQLCOM_DROP_VIEW;
|
||||
lex->drop_if_exists= $3;
|
||||
lex->check_exists= $3;
|
||||
YYPS->m_lock_type= TL_UNLOCK;
|
||||
YYPS->m_mdl_type= MDL_EXCLUSIVE;
|
||||
}
|
||||
table_list opt_restrict
|
||||
{}
|
||||
| DROP EVENT_SYM if_exists sp_name
|
||||
| DROP EVENT_SYM opt_if_exists sp_name
|
||||
{
|
||||
Lex->drop_if_exists= $3;
|
||||
Lex->check_exists= $3;
|
||||
Lex->spname= $4;
|
||||
Lex->sql_command = SQLCOM_DROP_EVENT;
|
||||
}
|
||||
| DROP TRIGGER_SYM if_exists sp_name
|
||||
| DROP TRIGGER_SYM opt_if_exists sp_name
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
lex->sql_command= SQLCOM_DROP_TRIGGER;
|
||||
lex->drop_if_exists= $3;
|
||||
lex->check_exists= $3;
|
||||
lex->spname= $4;
|
||||
}
|
||||
| DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait
|
||||
@ -10942,10 +10964,10 @@ drop:
|
||||
LEX *lex= Lex;
|
||||
lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
|
||||
}
|
||||
| DROP SERVER_SYM if_exists ident_or_text
|
||||
| DROP SERVER_SYM opt_if_exists ident_or_text
|
||||
{
|
||||
Lex->sql_command = SQLCOM_DROP_SERVER;
|
||||
Lex->drop_if_exists= $3;
|
||||
Lex->check_exists= $3;
|
||||
Lex->server_options.server_name= $4.str;
|
||||
Lex->server_options.server_name_length= $4.length;
|
||||
}
|
||||
@ -10983,9 +11005,17 @@ table_alias_ref:
|
||||
}
|
||||
;
|
||||
|
||||
if_exists:
|
||||
/* empty */ { $$= 0; }
|
||||
| IF EXISTS { $$= 1; }
|
||||
opt_if_exists:
|
||||
/* empty */
|
||||
{
|
||||
Lex->check_exists= FALSE;
|
||||
$$= 0;
|
||||
}
|
||||
| IF EXISTS
|
||||
{
|
||||
Lex->check_exists= TRUE;
|
||||
$$= 1;
|
||||
}
|
||||
;
|
||||
|
||||
opt_temporary:
|
||||
|
Loading…
x
Reference in New Issue
Block a user