mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX
NDB cluster is not fully supported. This will be added with WL 1892 (NDB Handler: Add support for CREATE/DROP INDEX). Some preparatory code for this is already present though. A change for the "duplicate key" error message is planned for another changeset. include/my_base.h: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX Defined a mask of flags which must be the same for two indexes if they should compare as compatible. Added an error number for a new drop index error message. mysql-test/r/key.result: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX The test result. mysql-test/t/key.test: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX The test case. sql/handler.cc: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX Prepared for a later change in an error message: Replace index number by index name for "duplicate key" error. Added handling for the new drop index error message. sql/handler.h: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX Added new flags and methods. Removed old flags and methods (from the last attempt). sql/share/errmsg.txt: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX Added a new error message for drop index. sql/sql_table.cc: WL#1563 - Modify MySQL to support fast CREATE/DROP INDEX Moved definitions to the top of the file. In mysql_prepare_table() allow an index to have the name "PRIMARY" if it has the key type "Key::PRIMARY". Added a parenthesis for readability. Removed old code from the last attempt. Some changes to compare_tables(): - Input parameter "List<Key> *key_list" is replaced by "KEY *key_info_buffer, uint key_count". - Output parameters added: "index_drop_buffer/index_drop_count" and "index_add_buffer/index_add_count". - Key comparison must now find matching keys in changed old and new key lists. - Key comparison of a key is easier now because both old and new keys are of type 'KEY'. Call mysql_prepare_table() before compare_tables(). The translated KEY structs are needed at some places now. Inserted a code segment for checking alter_table_flags(). Removed mysql_prepare_table() from the 'partition' branches (it is done above now). Removed a pair of unnecessary braces. Inserted a code segment for executing fast add/drop index. Made close of table dependent on whether it was opened. Prepared for NDB cluster support. Fixed commit to be called outside of LOCK_open.
This commit is contained in:
@ -206,6 +206,11 @@ enum ha_base_keytype {
|
||||
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
|
||||
#define HA_GENERATED_KEY 8192 /* Automaticly generated key */
|
||||
|
||||
/* The combination of the above can be used for key type comparison. */
|
||||
#define HA_KEYFLAG_MASK (HA_NOSAME | HA_PACK_KEY | HA_AUTO_KEY | \
|
||||
HA_BINARY_PACK_KEY | HA_FULLTEXT | HA_UNIQUE_CHECK | \
|
||||
HA_SPATIAL | HA_NULL_ARE_EQUAL | HA_GENERATED_KEY)
|
||||
|
||||
/* Automatic bits in key-flag */
|
||||
|
||||
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
|
||||
@ -349,8 +354,9 @@ enum ha_base_keytype {
|
||||
#define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for
|
||||
given value */
|
||||
#define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */
|
||||
#define HA_ERR_DROP_INDEX_FK 162 /* Index needed in foreign key constr. */
|
||||
|
||||
#define HA_ERR_LAST 161 /* Copy last error no */
|
||||
#define HA_ERR_LAST 162 /* Copy last error no */
|
||||
|
||||
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
|
||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||
|
@ -396,3 +396,71 @@ a int(11) NO PRI
|
||||
b varchar(20) NO MUL
|
||||
c varchar(20) NO
|
||||
drop table t1;
|
||||
create table t1 (
|
||||
c1 int,
|
||||
c2 char(12),
|
||||
c3 varchar(123),
|
||||
c4 timestamp,
|
||||
index (c1),
|
||||
index i1 (c1),
|
||||
index i2 (c2),
|
||||
index i3 (c3),
|
||||
unique i4 (c4),
|
||||
index i5 (c1, c2, c3, c4),
|
||||
primary key (c2, c3),
|
||||
index (c2, c4));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) default NULL,
|
||||
`c2` char(12) NOT NULL default '',
|
||||
`c3` varchar(123) NOT NULL default '',
|
||||
`c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`c2`,`c3`),
|
||||
UNIQUE KEY `i4` (`c4`),
|
||||
KEY `c1` (`c1`),
|
||||
KEY `i1` (`c1`),
|
||||
KEY `i2` (`c2`),
|
||||
KEY `i3` (`c3`),
|
||||
KEY `i5` (`c1`,`c2`,`c3`,`c4`),
|
||||
KEY `c2` (`c2`,`c4`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
alter table t1 drop index c1;
|
||||
alter table t1 add index (c1);
|
||||
alter table t1 add index (c1);
|
||||
alter table t1 drop index i3;
|
||||
alter table t1 add index i3 (c3);
|
||||
alter table t1 drop index i2, drop index i4;
|
||||
alter table t1 add index i2 (c2), add index i4 (c4);
|
||||
alter table t1 drop index i2, drop index i4, add index i6 (c2, c4);
|
||||
alter table t1 add index i2 (c2), add index i4 (c4), drop index i6;
|
||||
alter table t1 drop index i2, drop index i4, add unique i4 (c4);
|
||||
alter table t1 add index i2 (c2), drop index i4, add index i4 (c4);
|
||||
alter table t1 drop index c2, add index (c2(4),c3(7));
|
||||
alter table t1 drop index c2, add index (c2(4),c3(7));
|
||||
alter table t1 add primary key (c1, c2), drop primary key;
|
||||
alter table t1 drop primary key;
|
||||
alter table t1 add primary key (c1, c2), drop primary key;
|
||||
ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL default '0',
|
||||
`c2` char(12) NOT NULL default '',
|
||||
`c3` varchar(123) NOT NULL default '',
|
||||
`c4` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||
KEY `i1` (`c1`),
|
||||
KEY `i5` (`c1`,`c2`,`c3`,`c4`),
|
||||
KEY `c1` (`c1`),
|
||||
KEY `c1_2` (`c1`),
|
||||
KEY `i3` (`c3`),
|
||||
KEY `i2` (`c2`),
|
||||
KEY `i4` (`c4`),
|
||||
KEY `c2` (`c2`(4),`c3`(7))
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
insert into t1 values(1, 'a', 'a', NULL);
|
||||
insert into t1 values(1, 'b', 'b', NULL);
|
||||
alter table t1 drop index i3, drop index i2, drop index i1;
|
||||
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
drop table t1;
|
||||
|
@ -372,3 +372,61 @@ desc t1;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# WL#1563 - Modify MySQL to support on-line CREATE/DROP INDEX
|
||||
# To test if this really works, you need to run with --debug
|
||||
# and check the trace file.
|
||||
#
|
||||
# Create a table with named and unnamed indexes.
|
||||
create table t1 (
|
||||
c1 int,
|
||||
c2 char(12),
|
||||
c3 varchar(123),
|
||||
c4 timestamp,
|
||||
index (c1),
|
||||
index i1 (c1),
|
||||
index i2 (c2),
|
||||
index i3 (c3),
|
||||
unique i4 (c4),
|
||||
index i5 (c1, c2, c3, c4),
|
||||
primary key (c2, c3),
|
||||
index (c2, c4));
|
||||
show create table t1;
|
||||
# Some simple tests.
|
||||
alter table t1 drop index c1;
|
||||
alter table t1 add index (c1);
|
||||
# This creates index 'c1_2'.
|
||||
alter table t1 add index (c1);
|
||||
alter table t1 drop index i3;
|
||||
alter table t1 add index i3 (c3);
|
||||
# Two indexes at the same time.
|
||||
alter table t1 drop index i2, drop index i4;
|
||||
alter table t1 add index i2 (c2), add index i4 (c4);
|
||||
# Three indexes, one of them reversely.
|
||||
alter table t1 drop index i2, drop index i4, add index i6 (c2, c4);
|
||||
alter table t1 add index i2 (c2), add index i4 (c4), drop index i6;
|
||||
# include an unique index.
|
||||
alter table t1 drop index i2, drop index i4, add unique i4 (c4);
|
||||
alter table t1 add index i2 (c2), drop index i4, add index i4 (c4);
|
||||
# Modify an index by changing its definition.
|
||||
alter table t1 drop index c2, add index (c2(4),c3(7));
|
||||
# Change nothing. The new key definition is the same as the old one.
|
||||
alter table t1 drop index c2, add index (c2(4),c3(7));
|
||||
# Test primary key handling.
|
||||
alter table t1 add primary key (c1, c2), drop primary key;
|
||||
alter table t1 drop primary key;
|
||||
# Drop is checked first. Primary key must exist.
|
||||
--error 1091
|
||||
alter table t1 add primary key (c1, c2), drop primary key;
|
||||
show create table t1;
|
||||
# Insert non-unique values.
|
||||
insert into t1 values(1, 'a', 'a', NULL);
|
||||
insert into t1 values(1, 'b', 'b', NULL);
|
||||
# Drop some indexes for new adds.
|
||||
alter table t1 drop index i3, drop index i2, drop index i1;
|
||||
# Add indexes, one is unique on non-unique values.
|
||||
--error 1062
|
||||
alter table t1 add index i3 (c3), add index i2 (c2), add unique index i1 (c1);
|
||||
drop table t1;
|
||||
|
||||
|
@ -1851,7 +1851,12 @@ void handler::print_error(int error, myf errflag)
|
||||
str.length(max_length-4);
|
||||
str.append(STRING_WITH_LEN("..."));
|
||||
}
|
||||
#ifdef XXX_TO_BE_DONE_BY_A_FOLLOWUP_OF_WL1563
|
||||
my_printf_error(ER_DUP_ENTRY, "Duplicate entry '%s' for key '%s'",
|
||||
MYF(0), str.c_ptr(), table->key_info[key_nr].name);
|
||||
#else
|
||||
my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1);
|
||||
#endif
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
textno=ER_DUP_KEY;
|
||||
@ -1936,6 +1941,15 @@ void handler::print_error(int error, myf errflag)
|
||||
case HA_ERR_RBR_LOGGING_FAILED:
|
||||
textno= ER_BINLOG_ROW_LOGGING_FAILED;
|
||||
break;
|
||||
case HA_ERR_DROP_INDEX_FK:
|
||||
{
|
||||
const char *ptr= "???";
|
||||
uint key_nr= get_dup_key(error);
|
||||
if ((int) key_nr >= 0)
|
||||
ptr= table->key_info[key_nr].name;
|
||||
my_error(ER_DROP_INDEX_FK, MYF(0), ptr);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* The error was "unknown" to this function.
|
||||
@ -1984,7 +1998,7 @@ uint handler::get_dup_key(int error)
|
||||
DBUG_ENTER("handler::get_dup_key");
|
||||
table->file->errkey = (uint) -1;
|
||||
if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE ||
|
||||
error == HA_ERR_NULL_IN_SPATIAL)
|
||||
error == HA_ERR_NULL_IN_SPATIAL || error == HA_ERR_DROP_INDEX_FK)
|
||||
info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
|
||||
DBUG_RETURN(table->file->errkey);
|
||||
}
|
||||
|
@ -110,8 +110,29 @@
|
||||
#define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
|
||||
|
||||
/* bits in alter_table_flags */
|
||||
#define HA_ONLINE_ADD_EMPTY_PARTITION 1
|
||||
#define HA_ONLINE_DROP_PARTITION 2
|
||||
#define HA_ONLINE_ADD_EMPTY_PARTITION 0x00000001
|
||||
#define HA_ONLINE_DROP_PARTITION 0x00000002
|
||||
/*
|
||||
These bits are set if different kinds of indexes can be created
|
||||
off-line without re-create of the table (but with a table lock).
|
||||
*/
|
||||
#define HA_ONLINE_ADD_INDEX_NO_WRITES 0x00000004 /*add index w/lock*/
|
||||
#define HA_ONLINE_DROP_INDEX_NO_WRITES 0x00000008 /*drop index w/lock*/
|
||||
#define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES 0x00000010 /*add unique w/lock*/
|
||||
#define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES 0x00000020 /*drop uniq. w/lock*/
|
||||
#define HA_ONLINE_ADD_PK_INDEX_NO_WRITES 0x00000040 /*add prim. w/lock*/
|
||||
#define HA_ONLINE_DROP_PK_INDEX_NO_WRITES 0x00000080 /*drop prim. w/lock*/
|
||||
/*
|
||||
These are set if different kinds of indexes can be created on-line
|
||||
(without a table lock). If a handler is capable of one or more of
|
||||
these, it should also set the corresponding *_NO_WRITES bit(s).
|
||||
*/
|
||||
#define HA_ONLINE_ADD_INDEX 0x00000100 /*add index online*/
|
||||
#define HA_ONLINE_DROP_INDEX 0x00000200 /*drop index online*/
|
||||
#define HA_ONLINE_ADD_UNIQUE_INDEX 0x00000400 /*add unique online*/
|
||||
#define HA_ONLINE_DROP_UNIQUE_INDEX 0x00000800 /*drop uniq. online*/
|
||||
#define HA_ONLINE_ADD_PK_INDEX 0x00001000 /*add prim. online*/
|
||||
#define HA_ONLINE_DROP_PK_INDEX 0x00002000 /*drop prim. online*/
|
||||
|
||||
/*
|
||||
Index scan will not return records in rowid order. Not guaranteed to be
|
||||
@ -134,16 +155,6 @@
|
||||
*/
|
||||
#define MAX_HA 15
|
||||
|
||||
/*
|
||||
Bits in index_ddl_flags(KEY *wanted_index)
|
||||
for what ddl you can do with index
|
||||
If none is set, the wanted type of index is not supported
|
||||
by the handler at all. See WorkLog 1563.
|
||||
*/
|
||||
#define HA_DDL_SUPPORT 1 /* Supported by handler */
|
||||
#define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */
|
||||
#define HA_DDL_ONLINE 4 /* Can create/drop without lock */
|
||||
|
||||
/*
|
||||
Parameters for open() (in register form->filestat)
|
||||
HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
|
||||
@ -1442,11 +1453,13 @@ public:
|
||||
virtual void set_part_info(partition_info *part_info) { return; }
|
||||
#endif
|
||||
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
|
||||
virtual ulong index_ddl_flags(KEY *wanted_index) const
|
||||
{ return (HA_DDL_SUPPORT); }
|
||||
|
||||
virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
virtual int drop_index(TABLE *table_arg, uint *key_num, uint num_of_keys)
|
||||
virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
|
||||
uint num_of_keys)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
virtual int final_drop_index(TABLE *table_arg)
|
||||
{ return (HA_ERR_WRONG_COMMAND); }
|
||||
|
||||
uint max_record_length() const
|
||||
|
@ -5779,3 +5779,6 @@ ER_EVENT_SAME_NAME
|
||||
eng "Same old and new event name"
|
||||
ER_EVENT_DATA_TOO_LONG
|
||||
eng "Data for column '%s' too long"
|
||||
ER_DROP_INDEX_FK
|
||||
eng "Cannot drop index '%-.64s': needed in a foreign key constraint"
|
||||
ger "Kann Index '%-.64s' nicht l<>schen: wird f<>r einen einen Fremdschl<68>ssel ben<65>tigt"
|
||||
|
831
sql/sql_table.cc
831
sql/sql_table.cc
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user