mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Don't automaticly generate a new key for a foreign key constraint if there is already a usable key.
Prefer not automatic keys before automatic keys. If there is two conf
This commit is contained in:
@@ -774,3 +774,8 @@ ndb/lib/libndbclient.so
|
|||||||
ndb/lib/libndbclient_extra.so
|
ndb/lib/libndbclient_extra.so
|
||||||
libmysqld/discover.cc
|
libmysqld/discover.cc
|
||||||
include/readline
|
include/readline
|
||||||
|
ndb/config/autom4te.cache/*
|
||||||
|
ndb/config/config.mk
|
||||||
|
ndb/src/common/mgmcommon/printConfig/*.d
|
||||||
|
ndb/src/mgmclient/test_cpcd/*.d
|
||||||
|
*.d
|
||||||
|
@@ -191,7 +191,7 @@ enum ha_base_keytype {
|
|||||||
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
|
#define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */
|
||||||
#define HA_SPATIAL 1024 /* For spatial search */
|
#define HA_SPATIAL 1024 /* For spatial search */
|
||||||
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
|
#define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */
|
||||||
|
#define HA_GENERATED_KEY 8192 /* Automaticly generated key */
|
||||||
|
|
||||||
/* Automatic bits in key-flag */
|
/* Automatic bits in key-flag */
|
||||||
|
|
||||||
|
@@ -22,6 +22,8 @@ show create table t1;
|
|||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) default NULL,
|
`a` int(11) default NULL,
|
||||||
UNIQUE KEY `constraint_1` (`a`)
|
UNIQUE KEY `constraint_1` (`a`),
|
||||||
|
UNIQUE KEY `key_1` (`a`),
|
||||||
|
UNIQUE KEY `key_2` (`a`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@@ -155,7 +155,37 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` int(11) NOT NULL default '0',
|
`a` int(11) NOT NULL default '0',
|
||||||
`b` int(11) default NULL,
|
`b` int(11) default NULL,
|
||||||
PRIMARY KEY (`a`),
|
PRIMARY KEY (`a`),
|
||||||
KEY `b` (`b`)
|
KEY `b` (`b`),
|
||||||
|
KEY `b_2` (`b`),
|
||||||
|
KEY `b_3` (`b`),
|
||||||
|
KEY `b_4` (`b`),
|
||||||
|
KEY `b_5` (`b`),
|
||||||
|
KEY `b_6` (`b`),
|
||||||
|
KEY `b_7` (`b`),
|
||||||
|
KEY `b_8` (`b`),
|
||||||
|
KEY `b_9` (`b`),
|
||||||
|
KEY `b_10` (`b`),
|
||||||
|
KEY `b_11` (`b`),
|
||||||
|
KEY `b_12` (`b`),
|
||||||
|
KEY `b_13` (`b`),
|
||||||
|
KEY `b_14` (`b`),
|
||||||
|
KEY `b_15` (`b`),
|
||||||
|
KEY `b_16` (`b`),
|
||||||
|
KEY `b_17` (`b`),
|
||||||
|
KEY `b_18` (`b`),
|
||||||
|
KEY `b_19` (`b`),
|
||||||
|
KEY `b_20` (`b`),
|
||||||
|
KEY `b_21` (`b`),
|
||||||
|
KEY `b_22` (`b`),
|
||||||
|
KEY `b_23` (`b`),
|
||||||
|
KEY `b_24` (`b`),
|
||||||
|
KEY `b_25` (`b`),
|
||||||
|
KEY `b_26` (`b`),
|
||||||
|
KEY `b_27` (`b`),
|
||||||
|
KEY `b_28` (`b`),
|
||||||
|
KEY `b_29` (`b`),
|
||||||
|
KEY `b_30` (`b`),
|
||||||
|
KEY `b_31` (`b`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 select if(1,'1','0'), month("2002-08-02");
|
create table t1 select if(1,'1','0'), month("2002-08-02");
|
||||||
|
@@ -371,6 +371,7 @@ t1 0 PRIMARY 2 b A # NULL NULL BTREE
|
|||||||
t1 0 c 1 c A # NULL NULL BTREE
|
t1 0 c 1 c A # NULL NULL BTREE
|
||||||
t1 0 b 1 b A # NULL NULL BTREE
|
t1 0 b 1 b A # NULL NULL BTREE
|
||||||
t1 1 a 1 a A # NULL NULL BTREE
|
t1 1 a 1 a A # NULL NULL BTREE
|
||||||
|
t1 1 a_2 1 a A # NULL NULL BTREE
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
|
create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
|
||||||
alter table t1 engine=innodb;
|
alter table t1 engine=innodb;
|
||||||
@@ -1442,3 +1443,101 @@ drop table t1;
|
|||||||
create table t1 (a int) engine=innodb;
|
create table t1 (a int) engine=innodb;
|
||||||
create table t2 like t1;
|
create table t2 like t1;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
create table t1 (id int(11) not null, id2 int(11) not null, unique (id,id2)) engine=innodb;
|
||||||
|
create table t2 (id int(11) not null, constraint t1_id_fk foreign key ( id ) references t1 (id)) engine = innodb;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
UNIQUE KEY `id` (`id`,`id2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
KEY `t1_id_fk` (`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
create index id on t2 (id);
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
KEY `id` (`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
create index id2 on t2 (id);
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
KEY `id` (`id`),
|
||||||
|
KEY `id2` (`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop index id2 on t2;
|
||||||
|
drop index id on t2;
|
||||||
|
Got one of the listed errors
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
KEY `id` (`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id,id2) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
KEY `t1_id_fk` (`id`,`id2`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
create unique index id on t2 (id,id2);
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
UNIQUE KEY `id` (`id`,`id2`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
UNIQUE KEY `id` (`id`,`id2`),
|
||||||
|
KEY `t1_id_fk` (`id2`,`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2), constraint t1_id_fk foreign key (id) references t1 (id)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
UNIQUE KEY `id` (`id`,`id2`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
Table Create Table
|
||||||
|
t2 CREATE TABLE `t2` (
|
||||||
|
`id` int(11) NOT NULL default '0',
|
||||||
|
`id2` int(11) NOT NULL default '0',
|
||||||
|
UNIQUE KEY `id` (`id`,`id2`),
|
||||||
|
KEY `t1_id_fk` (`id2`,`id`),
|
||||||
|
CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||||
|
drop table t2;
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
|
||||||
|
ERROR HY000: Can't create table './test/t2.frm' (errno: 150)
|
||||||
|
drop table t1;
|
||||||
|
@@ -1044,3 +1044,46 @@ drop table t1;
|
|||||||
create table t1 (a int) engine=innodb;
|
create table t1 (a int) engine=innodb;
|
||||||
create table t2 like t1;
|
create table t2 like t1;
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test of automaticly created foreign keys
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (id int(11) not null, id2 int(11) not null, unique (id,id2)) engine=innodb;
|
||||||
|
create table t2 (id int(11) not null, constraint t1_id_fk foreign key ( id ) references t1 (id)) engine = innodb;
|
||||||
|
show create table t1;
|
||||||
|
show create table t2;
|
||||||
|
create index id on t2 (id);
|
||||||
|
show create table t2;
|
||||||
|
create index id2 on t2 (id);
|
||||||
|
show create table t2;
|
||||||
|
drop index id2 on t2;
|
||||||
|
--error 1025,1025
|
||||||
|
drop index id on t2;
|
||||||
|
show create table t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id,id2) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
create unique index id on t2 (id,id2);
|
||||||
|
show create table t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
# Check foreign key columns created in different order than key columns
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2), constraint t1_id_fk foreign key (id) references t1 (id)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
|
||||||
|
show create table t2;
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
# Test error handling
|
||||||
|
--error 1005
|
||||||
|
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
@@ -71,7 +71,7 @@ show status like 'key_blocks_used';
|
|||||||
# Following results differs on 64 and 32 bit systems because of different
|
# Following results differs on 64 and 32 bit systems because of different
|
||||||
# pointer sizes, which takes up different amount of space in key cache
|
# pointer sizes, which takes up different amount of space in key cache
|
||||||
|
|
||||||
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED
|
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED
|
||||||
show status like 'key_blocks_unused';
|
show status like 'key_blocks_unused';
|
||||||
|
|
||||||
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
||||||
@@ -84,7 +84,7 @@ update t1 set p=2 where p=1;
|
|||||||
update t2 set i=2 where i=1;
|
update t2 set i=2 where i=1;
|
||||||
|
|
||||||
show status like 'key_blocks_used';
|
show status like 'key_blocks_used';
|
||||||
--replace_result 1808 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED
|
--replace_result 1808 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1814 KEY_BLOCKS_UNUSED
|
||||||
show status like 'key_blocks_unused';
|
show status like 'key_blocks_unused';
|
||||||
|
|
||||||
cache index t1 key (`primary`) in keycache1;
|
cache index t1 key (`primary`) in keycache1;
|
||||||
@@ -146,7 +146,7 @@ cache index t1,t2 in default;
|
|||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
show status like 'key_blocks_used';
|
show status like 'key_blocks_used';
|
||||||
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED
|
--replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED
|
||||||
show status like 'key_blocks_unused';
|
show status like 'key_blocks_unused';
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
|
@@ -1918,7 +1918,8 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
ulong privileges = xx->rights;
|
ulong privileges = xx->rights;
|
||||||
bool old_row_exists=0;
|
bool old_row_exists=0;
|
||||||
key_restore(table,key,0,key_length);
|
key_restore(table,key,0,key_length);
|
||||||
table->field[4]->store(xx->column.ptr(),xx->column.length(),&my_charset_latin1);
|
table->field[4]->store(xx->column.ptr(),xx->column.length(),
|
||||||
|
&my_charset_latin1);
|
||||||
|
|
||||||
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,
|
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,
|
||||||
0, HA_READ_KEY_EXACT))
|
0, HA_READ_KEY_EXACT))
|
||||||
@@ -1931,9 +1932,10 @@ static int replace_column_table(GRANT_TABLE *g_t,
|
|||||||
continue; /* purecov: inspected */
|
continue; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
old_row_exists = 0;
|
old_row_exists = 0;
|
||||||
restore_record(table,default_values); // Get empty record
|
restore_record(table,default_values); // Get empty record
|
||||||
key_restore(table,key,0,key_length);
|
key_restore(table,key,0,key_length);
|
||||||
table->field[4]->store(xx->column.ptr(),xx->column.length(), &my_charset_latin1);
|
table->field[4]->store(xx->column.ptr(),xx->column.length(),
|
||||||
|
&my_charset_latin1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -84,26 +84,71 @@ bool key_part_spec::operator==(const key_part_spec& other) const
|
|||||||
return length == other.length && !strcmp(field_name, other.field_name);
|
return length == other.length && !strcmp(field_name, other.field_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equality comparison of keys (ignoring name) */
|
|
||||||
bool Key::operator==(Key& other)
|
/*
|
||||||
|
Test if a foreign key is a prefix of the given key
|
||||||
|
(ignoring key name, key type and order of columns)
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
This is only used to test if an index for a FOREIGN KEY exists
|
||||||
|
|
||||||
|
IMPLEMENTATION
|
||||||
|
We only compare field names
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 Generated key is a prefix of other key
|
||||||
|
1 Not equal
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool foreign_key_prefix(Key *a, Key *b)
|
||||||
{
|
{
|
||||||
if (type == other.type &&
|
/* Ensure that 'a' is the generated key */
|
||||||
algorithm == other.algorithm &&
|
if (a->generated)
|
||||||
columns.elements == other.columns.elements)
|
|
||||||
{
|
{
|
||||||
List_iterator<key_part_spec> col_it1(columns);
|
if (b->generated && a->columns.elements > b->columns.elements)
|
||||||
List_iterator<key_part_spec> col_it2(other.columns);
|
swap(Key*, a, b); // Put shorter key in 'a'
|
||||||
const key_part_spec *col1, *col2;
|
|
||||||
while ((col1 = col_it1++))
|
|
||||||
{
|
|
||||||
col2 = col_it2++;
|
|
||||||
DBUG_ASSERT(col2 != NULL);
|
|
||||||
if (!(*col1 == *col2))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
|
{
|
||||||
|
if (!b->generated)
|
||||||
|
return TRUE; // No foreign key
|
||||||
|
swap(Key*, a, b); // Put generated key in 'a'
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test if 'a' is a prefix of 'b' */
|
||||||
|
if (a->columns.elements > b->columns.elements)
|
||||||
|
return TRUE; // Can't be prefix
|
||||||
|
|
||||||
|
List_iterator<key_part_spec> col_it1(a->columns);
|
||||||
|
List_iterator<key_part_spec> col_it2(b->columns);
|
||||||
|
const key_part_spec *col1, *col2;
|
||||||
|
|
||||||
|
#ifdef ENABLE_WHEN_INNODB_CAN_HANDLE_SWAPED_FOREIGN_KEY_COLUMNS
|
||||||
|
while ((col1= col_it1++))
|
||||||
|
{
|
||||||
|
bool found= 0;
|
||||||
|
col_it2.rewind();
|
||||||
|
while ((col2= col_it2++))
|
||||||
|
{
|
||||||
|
if (*col1 == *col2)
|
||||||
|
{
|
||||||
|
found= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return TRUE; // Error
|
||||||
|
}
|
||||||
|
return FALSE; // Is prefix
|
||||||
|
#else
|
||||||
|
while ((col1= col_it1++))
|
||||||
|
{
|
||||||
|
col2= col_it2++;
|
||||||
|
if (!(*col1 == *col2))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE; // Is prefix
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -240,14 +240,16 @@ public:
|
|||||||
enum ha_key_alg algorithm;
|
enum ha_key_alg algorithm;
|
||||||
List<key_part_spec> columns;
|
List<key_part_spec> columns;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
bool generated;
|
||||||
|
|
||||||
Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par,
|
Key(enum Keytype type_par, const char *name_arg, enum ha_key_alg alg_par,
|
||||||
List<key_part_spec> &cols)
|
bool generated_arg, List<key_part_spec> &cols)
|
||||||
:type(type_par), algorithm(alg_par), columns(cols), name(name_arg)
|
:type(type_par), algorithm(alg_par), columns(cols), name(name_arg),
|
||||||
|
generated(generated_arg)
|
||||||
{}
|
{}
|
||||||
~Key() {}
|
~Key() {}
|
||||||
/* Equality comparison of keys (ignoring name) */
|
/* Equality comparison of keys (ignoring name) */
|
||||||
bool operator==(Key& other);
|
friend bool foreign_key_prefix(Key *a, Key *b);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Table_ident;
|
class Table_ident;
|
||||||
@@ -265,7 +267,7 @@ public:
|
|||||||
foreign_key(const char *name_arg, List<key_part_spec> &cols,
|
foreign_key(const char *name_arg, List<key_part_spec> &cols,
|
||||||
Table_ident *table, List<key_part_spec> &ref_cols,
|
Table_ident *table, List<key_part_spec> &ref_cols,
|
||||||
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
|
||||||
:Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, cols),
|
:Key(FOREIGN_KEY, name_arg, HA_KEY_ALG_UNDEF, 0, cols),
|
||||||
ref_table(table), ref_columns(cols),
|
ref_table(table), ref_columns(cols),
|
||||||
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
|
delete_opt(delete_opt_arg), update_opt(update_opt_arg),
|
||||||
match_opt(match_opt_arg)
|
match_opt(match_opt_arg)
|
||||||
|
@@ -3958,13 +3958,13 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||||||
{
|
{
|
||||||
lex->col_list.push_back(new key_part_spec(field_name,0));
|
lex->col_list.push_back(new key_part_spec(field_name,0));
|
||||||
lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF,
|
lex->key_list.push_back(new Key(Key::PRIMARY, NullS, HA_KEY_ALG_UNDEF,
|
||||||
lex->col_list));
|
0, lex->col_list));
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
|
||||||
{
|
{
|
||||||
lex->col_list.push_back(new key_part_spec(field_name,0));
|
lex->col_list.push_back(new key_part_spec(field_name,0));
|
||||||
lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF,
|
lex->key_list.push_back(new Key(Key::UNIQUE, NullS, HA_KEY_ALG_UNDEF, 0,
|
||||||
lex->col_list));
|
lex->col_list));
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
|
@@ -679,14 +679,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
key_iterator2.rewind ();
|
key_iterator2.rewind ();
|
||||||
while ((key2 = key_iterator2++) != key)
|
if (key->type != Key::FOREIGN_KEY)
|
||||||
{
|
{
|
||||||
if (*key == *key2)
|
while ((key2 = key_iterator2++) != key)
|
||||||
{
|
{
|
||||||
/* TO DO: issue warning message */
|
if ((key2->type != Key::FOREIGN_KEY && !foreign_key_prefix(key, key2)))
|
||||||
/* mark that the key should be ignored */
|
{
|
||||||
key->name=ignore_key;
|
/* TO DO: issue warning message */
|
||||||
break;
|
/* mark that the generated key should be ignored */
|
||||||
|
if (!key2->generated ||
|
||||||
|
(key->generated && key->columns.elements <
|
||||||
|
key2->columns.elements))
|
||||||
|
key->name= ignore_key;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Remove the previous, generated key */
|
||||||
|
key2->name= ignore_key;
|
||||||
|
key_parts-= key2->columns.elements;
|
||||||
|
(*key_count)--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key->name != ignore_key)
|
if (key->name != ignore_key)
|
||||||
@@ -731,14 +744,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
|
|
||||||
switch(key->type){
|
switch(key->type){
|
||||||
case Key::MULTIPLE:
|
case Key::MULTIPLE:
|
||||||
key_info->flags = 0;
|
key_info->flags= 0;
|
||||||
break;
|
break;
|
||||||
case Key::FULLTEXT:
|
case Key::FULLTEXT:
|
||||||
key_info->flags = HA_FULLTEXT;
|
key_info->flags= HA_FULLTEXT;
|
||||||
break;
|
break;
|
||||||
case Key::SPATIAL:
|
case Key::SPATIAL:
|
||||||
#ifdef HAVE_SPATIAL
|
#ifdef HAVE_SPATIAL
|
||||||
key_info->flags = HA_SPATIAL;
|
key_info->flags= HA_SPATIAL;
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
|
my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
|
||||||
@@ -749,8 +762,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
key_number--; // Skip this key
|
key_number--; // Skip this key
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
key_info->flags = HA_NOSAME;
|
key_info->flags = HA_NOSAME;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (key->generated)
|
||||||
|
key_info->flags|= HA_GENERATED_KEY;
|
||||||
|
|
||||||
key_info->key_parts=(uint8) key->columns.elements;
|
key_info->key_parts=(uint8) key->columns.elements;
|
||||||
key_info->key_part=key_part_info;
|
key_info->key_part=key_part_info;
|
||||||
@@ -774,7 +790,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: Add proper checks if handler supports key_type and algorithm */
|
/* TODO: Add proper checks if handler supports key_type and algorithm */
|
||||||
if (key_info->flags == HA_SPATIAL)
|
if (key_info->flags & HA_SPATIAL)
|
||||||
{
|
{
|
||||||
if (key_info->key_parts != 1)
|
if (key_info->key_parts != 1)
|
||||||
{
|
{
|
||||||
@@ -2824,6 +2840,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
Key::FULLTEXT : Key::MULTIPLE)),
|
Key::FULLTEXT : Key::MULTIPLE)),
|
||||||
key_name,
|
key_name,
|
||||||
key_info->algorithm,
|
key_info->algorithm,
|
||||||
|
test(key_info->flags & HA_GENERATED_KEY),
|
||||||
key_parts));
|
key_parts));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@@ -955,7 +955,7 @@ create:
|
|||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
|
|
||||||
lex->key_list.push_back(new Key($2,$4.str, $5, lex->col_list));
|
lex->key_list.push_back(new Key($2,$4.str, $5, 0, lex->col_list));
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
}
|
}
|
||||||
| CREATE DATABASE opt_if_not_exists ident
|
| CREATE DATABASE opt_if_not_exists ident
|
||||||
@@ -1187,14 +1187,15 @@ key_def:
|
|||||||
key_type opt_ident key_alg '(' key_list ')'
|
key_type opt_ident key_alg '(' key_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->key_list.push_back(new Key($1,$2, $3, lex->col_list));
|
lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list));
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
|
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
const char *key_name= $3 ? $3:$1;
|
const char *key_name= $3 ? $3:$1;
|
||||||
lex->key_list.push_back(new Key($2, key_name, $4, lex->col_list));
|
lex->key_list.push_back(new Key($2, key_name, $4, 0,
|
||||||
|
lex->col_list));
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
|
||||||
@@ -1206,8 +1207,9 @@ key_def:
|
|||||||
lex->fk_delete_opt,
|
lex->fk_delete_opt,
|
||||||
lex->fk_update_opt,
|
lex->fk_update_opt,
|
||||||
lex->fk_match_option));
|
lex->fk_match_option));
|
||||||
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4:$1,
|
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1,
|
||||||
HA_KEY_ALG_UNDEF, lex->col_list));
|
HA_KEY_ALG_UNDEF, 1,
|
||||||
|
lex->col_list));
|
||||||
lex->col_list.empty(); /* Alloced by sql_alloc */
|
lex->col_list.empty(); /* Alloced by sql_alloc */
|
||||||
}
|
}
|
||||||
| constraint opt_check_constraint
|
| constraint opt_check_constraint
|
||||||
|
@@ -43,7 +43,9 @@ bmove_align:
|
|||||||
.ba_20: pop %esi
|
.ba_20: pop %esi
|
||||||
movl %edx,%edi
|
movl %edx,%edi
|
||||||
ret
|
ret
|
||||||
.size bmove_align,.end-bmove_align
|
|
||||||
|
.bmove_align_end:
|
||||||
|
.size bmove_align,.bmove_align_end-bmove_align
|
||||||
|
|
||||||
# Move a string from higher to lower
|
# Move a string from higher to lower
|
||||||
# Arg from_end+1,to_end+1,length
|
# Arg from_end+1,to_end+1,length
|
||||||
|
Reference in New Issue
Block a user