mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
MDEV-10360: Extended keys: index properties depend on index order
TABLE_SHARE::init_from_binary_frm_image has a rule: if an index has a partially-covered column (like in "KEY(col(N))" ), then dont provide "Extended Keys" feature for this index. The problem was that due to coding error Extended Keys feature was disabled for *ALL* subsequent indexes. Fixed the error.
This commit is contained in:
parent
0bb5d95542
commit
8a8ba1949b
3 changed files with 103 additions and 3 deletions
|
@ -1064,5 +1064,50 @@ explain select * from t1 where col1='1234567890-a';
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 ALL idx1 NULL NULL NULL # Using where
|
1 SIMPLE t1 ALL idx1 NULL NULL NULL # Using where
|
||||||
drop table t0,t1;
|
drop table t0,t1;
|
||||||
|
#
|
||||||
|
# MDEV-10360: Extended keys: index properties depend on index order
|
||||||
|
#
|
||||||
|
create table t0 (a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
create table t1 (
|
||||||
|
index_id bigint(20) unsigned NOT NULL,
|
||||||
|
index_class varchar(265) COLLATE latin1_general_ci DEFAULT NULL ,
|
||||||
|
index_object_id int(10) unsigned NOT NULL DEFAULT '0' ,
|
||||||
|
index_date_updated int(10) unsigned DEFAULT NULL ,
|
||||||
|
PRIMARY KEY (index_id),
|
||||||
|
KEY object (index_class(181),index_object_id),
|
||||||
|
KEY index_date_updated (index_date_updated)
|
||||||
|
) engine=innodb;
|
||||||
|
create table t2 (
|
||||||
|
index_id bigint(20) unsigned NOT NULL,
|
||||||
|
index_class varchar(265) COLLATE latin1_general_ci DEFAULT NULL ,
|
||||||
|
index_object_id int(10) unsigned NOT NULL DEFAULT '0' ,
|
||||||
|
index_date_updated int(10) unsigned DEFAULT NULL ,
|
||||||
|
PRIMARY KEY (index_id),
|
||||||
|
KEY index_date_updated (index_date_updated),
|
||||||
|
KEY object (index_class(181),index_object_id)
|
||||||
|
) engine=innodb;
|
||||||
|
insert into t1 select
|
||||||
|
@a:=A.a + 10*B.a + 100*C.a,
|
||||||
|
concat('val-', @a),
|
||||||
|
123456,
|
||||||
|
A.a + 10*B.a
|
||||||
|
from
|
||||||
|
t0 A, t0 B, t0 C;
|
||||||
|
insert into t2 select * from t1;
|
||||||
|
# This must have the same query plan as the query below it:
|
||||||
|
# type=range, key=index_date_updated, key_len=13
|
||||||
|
explain
|
||||||
|
select * from t1 force index(index_date_updated)
|
||||||
|
where index_date_updated= 10 and index_id < 800;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 range index_date_updated index_date_updated 13 NULL # Using index condition
|
||||||
|
# This used to work from the start:
|
||||||
|
explain
|
||||||
|
select * from t2 force index(index_date_updated)
|
||||||
|
where index_date_updated= 10 and index_id < 800;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition
|
||||||
|
drop table t0,t1,t2;
|
||||||
set optimizer_switch=@save_ext_key_optimizer_switch;
|
set optimizer_switch=@save_ext_key_optimizer_switch;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
|
|
@ -721,5 +721,58 @@ explain select * from t1 where col1='1234567890-a';
|
||||||
|
|
||||||
drop table t0,t1;
|
drop table t0,t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10360: Extended keys: index properties depend on index order
|
||||||
|
--echo #
|
||||||
|
create table t0 (a int);
|
||||||
|
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||||
|
|
||||||
|
create table t1 (
|
||||||
|
index_id bigint(20) unsigned NOT NULL,
|
||||||
|
index_class varchar(265) COLLATE latin1_general_ci DEFAULT NULL ,
|
||||||
|
index_object_id int(10) unsigned NOT NULL DEFAULT '0' ,
|
||||||
|
index_date_updated int(10) unsigned DEFAULT NULL ,
|
||||||
|
|
||||||
|
PRIMARY KEY (index_id),
|
||||||
|
KEY object (index_class(181),index_object_id),
|
||||||
|
KEY index_date_updated (index_date_updated)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
create table t2 (
|
||||||
|
index_id bigint(20) unsigned NOT NULL,
|
||||||
|
index_class varchar(265) COLLATE latin1_general_ci DEFAULT NULL ,
|
||||||
|
index_object_id int(10) unsigned NOT NULL DEFAULT '0' ,
|
||||||
|
index_date_updated int(10) unsigned DEFAULT NULL ,
|
||||||
|
|
||||||
|
PRIMARY KEY (index_id),
|
||||||
|
KEY index_date_updated (index_date_updated),
|
||||||
|
KEY object (index_class(181),index_object_id)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
insert into t1 select
|
||||||
|
@a:=A.a + 10*B.a + 100*C.a,
|
||||||
|
concat('val-', @a),
|
||||||
|
123456,
|
||||||
|
A.a + 10*B.a
|
||||||
|
from
|
||||||
|
t0 A, t0 B, t0 C;
|
||||||
|
|
||||||
|
insert into t2 select * from t1;
|
||||||
|
|
||||||
|
--echo # This must have the same query plan as the query below it:
|
||||||
|
--echo # type=range, key=index_date_updated, key_len=13
|
||||||
|
--replace_column 9 #
|
||||||
|
explain
|
||||||
|
select * from t1 force index(index_date_updated)
|
||||||
|
where index_date_updated= 10 and index_id < 800;
|
||||||
|
|
||||||
|
--echo # This used to work from the start:
|
||||||
|
--replace_column 9 #
|
||||||
|
explain
|
||||||
|
select * from t2 force index(index_date_updated)
|
||||||
|
where index_date_updated= 10 and index_id < 800;
|
||||||
|
|
||||||
|
drop table t0,t1,t2;
|
||||||
|
|
||||||
set optimizer_switch=@save_ext_key_optimizer_switch;
|
set optimizer_switch=@save_ext_key_optimizer_switch;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
|
|
@ -1804,6 +1804,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||||
{
|
{
|
||||||
KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
|
KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
|
||||||
(keyinfo-1)->ext_key_parts;
|
(keyinfo-1)->ext_key_parts;
|
||||||
|
uint add_keyparts_for_this_key= add_first_key_parts;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do not extend the key that contains a component
|
Do not extend the key that contains a component
|
||||||
|
@ -1815,19 +1816,20 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
|
||||||
if (share->field[fieldnr-1]->key_length() !=
|
if (share->field[fieldnr-1]->key_length() !=
|
||||||
keyinfo->key_part[i].length)
|
keyinfo->key_part[i].length)
|
||||||
{
|
{
|
||||||
add_first_key_parts= 0;
|
add_keyparts_for_this_key= 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_first_key_parts < keyinfo->ext_key_parts-keyinfo->user_defined_key_parts)
|
if (add_keyparts_for_this_key < (keyinfo->ext_key_parts -
|
||||||
|
keyinfo->user_defined_key_parts))
|
||||||
{
|
{
|
||||||
share->ext_key_parts-= keyinfo->ext_key_parts;
|
share->ext_key_parts-= keyinfo->ext_key_parts;
|
||||||
key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
|
key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
|
||||||
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
|
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
|
||||||
keyinfo->ext_key_flags= keyinfo->flags;
|
keyinfo->ext_key_flags= keyinfo->flags;
|
||||||
keyinfo->ext_key_part_map= 0;
|
keyinfo->ext_key_part_map= 0;
|
||||||
for (i= 0; i < add_first_key_parts; i++)
|
for (i= 0; i < add_keyparts_for_this_key; i++)
|
||||||
{
|
{
|
||||||
if (ext_key_part_map & 1<<i)
|
if (ext_key_part_map & 1<<i)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue