diff options
author | unknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru> | 2007-10-26 15:37:38 +0500 |
---|---|---|
committer | unknown <ramil/ram@mysql.com/ramil.myoffice.izhnet.ru> | 2007-10-26 15:37:38 +0500 |
commit | d7d93cf548064aef95f18ac45a9d8c03220abfad (patch) | |
tree | bee3dd52db241dee91e3a66776658a52e07176bd | |
parent | c63f2e3fb6bf3a5eb6da2995c47965843e9b212d (diff) | |
download | mariadb-git-d7d93cf548064aef95f18ac45a9d8c03220abfad.tar.gz |
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
Problem: if a partial unique key followed by a non-partial one we declare
the second one as a primary key.
Fix: sort non-partial unique keys before partial ones.
include/my_base.h:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- sort unique keys that don't contain partial segments before other keys:
set HA_KEY_HAS_PART_KEY_SEG flag for such keys in the mysql_prepare_table(),
use it in the sort_keys();
mysql-test/r/innodb_mysql.result:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- test result.
mysql-test/r/key.result:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- test result.
mysql-test/t/innodb_mysql.test:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- test case.
mysql-test/t/key.test:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- test case.
sql/sql_table.cc:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- sort unique keys that don't contain partial segments before other keys:
set HA_KEY_HAS_PART_KEY_SEG flag for such keys in the mysql_prepare_table(),
use it in the sort_keys();
sql/structs.h:
Fix for bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0,
file .\ha_innodb.
- sort unique keys that don't contain partial segments before other keys:
set HA_KEY_HAS_PART_KEY_SEG flag for such keys in the mysql_prepare_table(),
use it in the sort_keys();
-rw-r--r-- | include/my_base.h | 2 | ||||
-rw-r--r-- | mysql-test/r/innodb_mysql.result | 15 | ||||
-rw-r--r-- | mysql-test/r/key.result | 44 | ||||
-rw-r--r-- | mysql-test/t/innodb_mysql.test | 9 | ||||
-rw-r--r-- | mysql-test/t/key.test | 18 | ||||
-rw-r--r-- | sql/sql_table.cc | 26 | ||||
-rw-r--r-- | sql/structs.h | 2 |
7 files changed, 106 insertions, 10 deletions
diff --git a/include/my_base.h b/include/my_base.h index ef5ac364fed..9240b01a9f1 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -224,7 +224,7 @@ enum ha_base_keytype { #define HA_SPATIAL 1024 /* For spatial search */ #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ #define HA_GENERATED_KEY 8192 /* Automaticly generated key */ - +#define HA_KEY_HAS_PART_KEY_SEG 65536 /* Key contains partial segments */ /* Automatic bits in key-flag */ #define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */ diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index d5f014b6840..5a85df76347 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1211,4 +1211,19 @@ a b 3 2 1 1 DROP TABLE t1; +create table t1(a char(10) not null, unique key aa(a(1)), +b char(4) not null, unique key bb(b(4))) engine=innodb; +desc t1; +Field Type Null Key Default Extra +a char(10) NO UNI NULL +b char(4) NO PRI NULL +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) NOT NULL, + `b` char(4) NOT NULL, + UNIQUE KEY `bb` (`b`), + UNIQUE KEY `aa` (`a`(1)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 2fc751c63bf..0f1ea46bd61 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -462,4 +462,48 @@ EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 system NULL NULL NULL NULL 1 DROP TABLE t1; +create table t1(a int not null, key aa(a), +b char(10) not null, unique key bb(b(1)), +c char(4) not null, unique key cc(c)); +desc t1; +Field Type Null Key Default Extra +a int(11) NO MUL NULL +b char(10) NO UNI NULL +c char(4) NO PRI NULL +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` char(10) NOT NULL, + `c` char(4) NOT NULL, + UNIQUE KEY `cc` (`c`), + UNIQUE KEY `bb` (`b`(1)), + KEY `aa` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1(a int not null, key aa(a), +b char(10) not null, unique key bb(b(1)), +c char(4) not null); +desc t1; +Field Type Null Key Default Extra +a int(11) NO MUL NULL +b char(10) NO UNI NULL +c char(4) NO NULL +alter table t1 add unique key cc(c); +desc t1; +Field Type Null Key Default Extra +a int(11) NO MUL NULL +b char(10) NO UNI NULL +c char(4) NO PRI NULL +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` char(10) NOT NULL, + `c` char(4) NOT NULL, + UNIQUE KEY `cc` (`c`), + UNIQUE KEY `bb` (`b`(1)), + KEY `aa` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; End of 5.0 tests. diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index f64efd600c5..13aa6afd701 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -960,4 +960,13 @@ SELECT * FROM t1 ORDER BY b DESC, a ASC; DROP TABLE t1; +# +# Bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0 +# +create table t1(a char(10) not null, unique key aa(a(1)), + b char(4) not null, unique key bb(b(4))) engine=innodb; +desc t1; +show create table t1; +drop table t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index 3d0e68dc0f3..f63336a9864 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -443,4 +443,22 @@ ALTER TABLE t1 DISABLE KEYS; EXPLAIN SELECT MAX(a) FROM t1 FORCE INDEX(a); DROP TABLE t1; +# +# Bug #31137: Assertion failed: primary_key_no == -1 || primary_key_no == 0 +# +create table t1(a int not null, key aa(a), + b char(10) not null, unique key bb(b(1)), + c char(4) not null, unique key cc(c)); +desc t1; +show create table t1; +drop table t1; +create table t1(a int not null, key aa(a), + b char(10) not null, unique key bb(b(1)), + c char(4) not null); +desc t1; +alter table t1 add unique key cc(c); +desc t1; +show create table t1; +drop table t1; + --echo End of 5.0 tests. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b6e41788ef0..9d6f66aff53 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -361,7 +361,8 @@ int quick_rm_table(enum db_type base,const char *db, /* Sort keys in the following order: - PRIMARY KEY - - UNIQUE keyws where all column are NOT NULL + - UNIQUE keys where all column are NOT NULL + - UNIQUE keys that don't contain partial segments - Other UNIQUE keys - Normal keys - Fulltext keys @@ -372,26 +373,31 @@ int quick_rm_table(enum db_type base,const char *db, static int sort_keys(KEY *a, KEY *b) { - if (a->flags & HA_NOSAME) + ulong a_flags= a->flags, b_flags= b->flags; + + if (a_flags & HA_NOSAME) { - if (!(b->flags & HA_NOSAME)) + if (!(b_flags & HA_NOSAME)) return -1; - if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) + if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) { /* Sort NOT NULL keys before other keys */ - return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1; + return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1; } if (a->name == primary_key_name) return -1; if (b->name == primary_key_name) return 1; + /* Sort keys don't containing partial segments before others */ + if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG) + return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1; } - else if (b->flags & HA_NOSAME) + else if (b_flags & HA_NOSAME) return 1; // Prefer b - if ((a->flags ^ b->flags) & HA_FULLTEXT) + if ((a_flags ^ b_flags) & HA_FULLTEXT) { - return (a->flags & HA_FULLTEXT) ? 1 : -1; + return (a_flags & HA_FULLTEXT) ? 1 : -1; } /* Prefer original key order. usable_key_parts contains here @@ -1421,6 +1427,10 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else key_info->flags|= HA_PACK_KEY; } + /* Check if the key segment is partial, set the key flag accordingly */ + if (length != sql_field->key_length) + key_info->flags|= HA_KEY_HAS_PART_KEY_SEG; + key_length+=length; key_part_info++; diff --git a/sql/structs.h b/sql/structs.h index 28bdd8c1519..bc373fe4b52 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -87,7 +87,7 @@ typedef struct st_key_part_info { /* Info about a key part */ typedef struct st_key { uint key_length; /* Tot length of key */ - uint flags; /* dupp key and pack flags */ + ulong flags; /* dupp key and pack flags */ uint key_parts; /* How many key_parts */ uint extra_length; uint usable_key_parts; /* Should normally be = key_parts */ |