Skip to content

Commit 7f613eb

Browse files
author
Alexander Barkov
committed
MDEV-7284 INDEX: CREATE OR REPLACE
1 parent 118fc5c commit 7f613eb

9 files changed

+178
-16
lines changed

mysql-test/r/create_drop_binlog.result

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,32 @@ Log_name Pos Event_type Server_id End_log_pos Info
304304
# # Gtid 1 # GTID #-#-#
305305
# # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */
306306
RESET MASTER;
307+
CREATE TABLE t1(a INT, b INT);
308+
CREATE TABLE IF NOT EXISTS t1(a INT, b INT);
309+
Warnings:
310+
Note 1050 Table 't1' already exists
311+
CREATE OR REPLACE INDEX i1 ON t1(a);
312+
CREATE OR REPLACE INDEX i1 ON t1(a);
313+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
314+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
315+
DROP TABLE t1;
316+
SHOW BINLOG EVENTS;
317+
Log_name Pos Event_type Server_id End_log_pos Info
318+
# # Format_desc 1 # VER
319+
# # Gtid_list 1 # []
320+
# # Binlog_checkpoint 1 # master-bin.000001
321+
# # Gtid 1 # GTID #-#-#
322+
# # Query 1 # use `test`; CREATE TABLE t1(a INT, b INT)
323+
# # Gtid 1 # GTID #-#-#
324+
# # Query 1 # use `test`; CREATE TABLE IF NOT EXISTS t1(a INT, b INT)
325+
# # Gtid 1 # GTID #-#-#
326+
# # Query 1 # use `test`; CREATE OR REPLACE INDEX i1 ON t1(a)
327+
# # Gtid 1 # GTID #-#-#
328+
# # Query 1 # use `test`; CREATE OR REPLACE INDEX i1 ON t1(a)
329+
# # Gtid 1 # GTID #-#-#
330+
# # Query 1 # use `test`; CREATE OR REPLACE INDEX i1 ON t1(a,b)
331+
# # Gtid 1 # GTID #-#-#
332+
# # Query 1 # use `test`; CREATE OR REPLACE INDEX i1 ON t1(a,b)
333+
# # Gtid 1 # GTID #-#-#
334+
# # Query 1 # use `test`; DROP TABLE `t1` /* generated by server */
335+
RESET MASTER;

mysql-test/r/create_drop_index.result

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
CREATE TABLE t1(a INT, b INT);
2+
CREATE INDEX IF NOT EXISTS i1 ON t1(a);
3+
SHOW CREATE TABLE t1;
4+
Table Create Table
5+
t1 CREATE TABLE `t1` (
6+
`a` int(11) DEFAULT NULL,
7+
`b` int(11) DEFAULT NULL,
8+
KEY `i1` (`a`)
9+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
10+
DROP INDEX IF EXISTS i1 ON t1;
11+
SHOW CREATE TABLE t1;
12+
Table Create Table
13+
t1 CREATE TABLE `t1` (
14+
`a` int(11) DEFAULT NULL,
15+
`b` int(11) DEFAULT NULL
16+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
17+
DROP INDEX IF EXISTS i1 ON t1;
18+
Warnings:
19+
Note 1091 Can't DROP 'i1'; check that column/key exists
20+
SHOW CREATE TABLE t1;
21+
Table Create Table
22+
t1 CREATE TABLE `t1` (
23+
`a` int(11) DEFAULT NULL,
24+
`b` int(11) DEFAULT NULL
25+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
26+
CREATE OR REPLACE INDEX i1 ON t1(a);
27+
SHOW CREATE TABLE t1;
28+
Table Create Table
29+
t1 CREATE TABLE `t1` (
30+
`a` int(11) DEFAULT NULL,
31+
`b` int(11) DEFAULT NULL,
32+
KEY `i1` (`a`)
33+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
34+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
35+
SHOW CREATE TABLE t1;
36+
Table Create Table
37+
t1 CREATE TABLE `t1` (
38+
`a` int(11) DEFAULT NULL,
39+
`b` int(11) DEFAULT NULL,
40+
KEY `i1` (`a`,`b`)
41+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
42+
DROP TABLE t1;
43+
CREATE OR REPLACE INDEX IF NOT EXISTS i1 ON t1(b,a);
44+
ERROR HY000: Incorrect usage of OR REPLACE and IF NOT EXISTS
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
include/master-slave.inc
2+
[connection master]
3+
CREATE TABLE t1 (a INT, b INT);
4+
CREATE INDEX i1 ON t1 (a);
5+
CREATE OR REPLACE INDEX i1 ON t1 (a, b);
6+
# On slave:
7+
SHOW CREATE TABLE t1;
8+
Table Create Table
9+
t1 CREATE TABLE `t1` (
10+
`a` int(11) DEFAULT NULL,
11+
`b` int(11) DEFAULT NULL,
12+
KEY `i1` (`a`,`b`)
13+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
14+
# On master:
15+
SHOW CREATE TABLE t1;
16+
Table Create Table
17+
t1 CREATE TABLE `t1` (
18+
`a` int(11) DEFAULT NULL,
19+
`b` int(11) DEFAULT NULL,
20+
KEY `i1` (`a`,`b`)
21+
) ENGINE=MyISAM DEFAULT CHARSET=latin1
22+
DROP TABLE t1;
23+
include/rpl_end.inc
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--source include/master-slave.inc
2+
3+
connection master;
4+
5+
CREATE TABLE t1 (a INT, b INT);
6+
CREATE INDEX i1 ON t1 (a);
7+
CREATE OR REPLACE INDEX i1 ON t1 (a, b);
8+
sync_slave_with_master;
9+
10+
--echo # On slave:
11+
SHOW CREATE TABLE t1;
12+
13+
connection master;
14+
--echo # On master:
15+
SHOW CREATE TABLE t1;
16+
DROP TABLE t1;
17+
sync_slave_with_master;
18+
19+
--source include/rpl_end.inc

mysql-test/t/create_drop_binlog.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,16 @@ DROP TABLE t1;
147147
--replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ /Server.ver.*/VER/
148148
SHOW BINLOG EVENTS;
149149
RESET MASTER;
150+
151+
152+
CREATE TABLE t1(a INT, b INT);
153+
CREATE TABLE IF NOT EXISTS t1(a INT, b INT);
154+
CREATE OR REPLACE INDEX i1 ON t1(a);
155+
CREATE OR REPLACE INDEX i1 ON t1(a);
156+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
157+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
158+
DROP TABLE t1;
159+
--replace_column 1 # 2 # 5 #
160+
--replace_regex /xid=[0-9]+/xid=XX/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ /Server.ver.*/VER/
161+
SHOW BINLOG EVENTS;
162+
RESET MASTER;

mysql-test/t/create_drop_index.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CREATE TABLE t1(a INT, b INT);
2+
CREATE INDEX IF NOT EXISTS i1 ON t1(a);
3+
SHOW CREATE TABLE t1;
4+
DROP INDEX IF EXISTS i1 ON t1;
5+
SHOW CREATE TABLE t1;
6+
DROP INDEX IF EXISTS i1 ON t1;
7+
SHOW CREATE TABLE t1;
8+
9+
CREATE OR REPLACE INDEX i1 ON t1(a);
10+
SHOW CREATE TABLE t1;
11+
CREATE OR REPLACE INDEX i1 ON t1(a,b);
12+
SHOW CREATE TABLE t1;
13+
DROP TABLE t1;
14+
15+
--error ER_WRONG_USAGE
16+
CREATE OR REPLACE INDEX IF NOT EXISTS i1 ON t1(b,a);

sql/sql_lex.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2866,7 +2866,8 @@ struct LEX: public Query_tables_list
28662866
bool add_create_index(Key::Keytype type, const LEX_STRING &name,
28672867
ha_key_alg algorithm, DDL_options_st ddl)
28682868
{
2869-
if (!(last_key= new Key(type, name, algorithm, false, ddl)))
2869+
if (check_create_options(ddl) ||
2870+
!(last_key= new Key(type, name, algorithm, false, ddl)))
28702871
return true;
28712872
alter_info.key_list.push_back(last_key);
28722873
return false;

sql/sql_table.cc

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5830,7 +5830,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
58305830
const char *keyname;
58315831
while ((key=key_it++))
58325832
{
5833-
if (!key->if_not_exists())
5833+
if (!key->if_not_exists() && !key->or_replace())
58345834
continue;
58355835
/* If the name of the key is not specified, */
58365836
/* let us check the name of the first key part. */
@@ -5891,17 +5891,32 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
58915891
continue;
58925892

58935893
remove_key:
5894-
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
5895-
ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), keyname);
5896-
key_it.remove();
5897-
if (key->type == Key::FOREIGN_KEY)
5894+
if (key->if_not_exists())
58985895
{
5899-
/* ADD FOREIGN KEY appends two items. */
5896+
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
5897+
ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), keyname);
59005898
key_it.remove();
5899+
if (key->type == Key::FOREIGN_KEY)
5900+
{
5901+
/* ADD FOREIGN KEY appends two items. */
5902+
key_it.remove();
5903+
}
5904+
if (alter_info->key_list.is_empty())
5905+
alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
5906+
Alter_info::ADD_FOREIGN_KEY);
5907+
}
5908+
else if (key->or_replace())
5909+
{
5910+
Alter_drop::drop_type type= (key->type == Key::FOREIGN_KEY) ?
5911+
Alter_drop::FOREIGN_KEY : Alter_drop::KEY;
5912+
Alter_drop *ad= new Alter_drop(type, key->name.str, FALSE);
5913+
if (ad != NULL)
5914+
{
5915+
// Adding the index into the drop list for replacing
5916+
alter_info->flags |= Alter_info::ALTER_DROP_INDEX;
5917+
alter_info->drop_list.push_back(ad);
5918+
}
59015919
}
5902-
if (alter_info->key_list.is_empty())
5903-
alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
5904-
Alter_info::ADD_FOREIGN_KEY);
59055920
}
59065921
}
59075922

sql/sql_yacc.yy

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2487,31 +2487,33 @@ create:
24872487
}
24882488
create_table_set_open_action_and_adjust_tables(lex);
24892489
}
2490-
| CREATE opt_unique INDEX_SYM opt_if_not_exists ident
2490+
| create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident
24912491
opt_key_algorithm_clause
24922492
ON table_ident
24932493
{
24942494
if (add_create_index_prepare(Lex, $8))
24952495
MYSQL_YYABORT;
2496-
if (Lex->add_create_index($2, $5, $6, $4))
2496+
if (Lex->add_create_index($2, $5, $6, $1 | $4))
24972497
MYSQL_YYABORT;
24982498
}
24992499
'(' key_list ')' normal_key_options
25002500
opt_index_lock_algorithm { }
2501-
| CREATE fulltext INDEX_SYM opt_if_not_exists ident ON table_ident
2501+
| create_or_replace fulltext INDEX_SYM opt_if_not_exists ident
2502+
ON table_ident
25022503
{
25032504
if (add_create_index_prepare(Lex, $7))
25042505
MYSQL_YYABORT;
2505-
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $4))
2506+
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4))
25062507
MYSQL_YYABORT;
25072508
}
25082509
'(' key_list ')' fulltext_key_options
25092510
opt_index_lock_algorithm { }
2510-
| CREATE spatial INDEX_SYM opt_if_not_exists ident ON table_ident
2511+
| create_or_replace spatial INDEX_SYM opt_if_not_exists ident
2512+
ON table_ident
25112513
{
25122514
if (add_create_index_prepare(Lex, $7))
25132515
MYSQL_YYABORT;
2514-
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $4))
2516+
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4))
25152517
MYSQL_YYABORT;
25162518
}
25172519
'(' key_list ')' spatial_key_options

0 commit comments

Comments
 (0)