Skip to content

Commit 5bde239

Browse files
committed
MDEV-35159 Assertion `tab->join->select_limit < (~ (ha_rows) 0)' fails upon forcing vector key
init_from_binary_frm_image() wrongly assumed that * if a table has primary key * and it has the HA_PRIMARY_KEY_IN_READ_INDEX flag * than ORDER BY any index automatically implies ORDER BY pk at the end, that is for an index (a,b,c) ORDER BY a,b,c means ORDER BY a,b,c,pk which is wrong, it holds not for _any index_ but only for indexes that can be used for ORDER BY. So, don't do `field->part_of_sortkey= share->keys_in_use` but introduce `sort_keys_in_use` and use that.
1 parent a83afd8 commit 5bde239

File tree

3 files changed

+41
-21
lines changed

3 files changed

+41
-21
lines changed

mysql-test/main/vector_innodb.result

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,10 @@ DROP TABLE t;
167167
create table t (f varchar(1024) not null, v vector(2) not null, unique(f)) engine=innodb charset=utf8mb3;
168168
alter table t add vector (v);
169169
drop table t;
170+
#
171+
# MDEV-35159 Assertion `tab->join->select_limit < (~ (ha_rows) 0)' fails upon forcing vector key
172+
#
173+
create table t (v vector(1) not null, vector vec(v), unique vu(v)) engine=innodb;
174+
select * from t force index(vec) order by v;
175+
v
176+
drop table t;

mysql-test/main/vector_innodb.test

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,10 @@ DROP TABLE t;
162162
create table t (f varchar(1024) not null, v vector(2) not null, unique(f)) engine=innodb charset=utf8mb3;
163163
alter table t add vector (v);
164164
drop table t;
165+
166+
--echo #
167+
--echo # MDEV-35159 Assertion `tab->join->select_limit < (~ (ha_rows) 0)' fails upon forcing vector key
168+
--echo #
169+
create table t (v vector(1) not null, vector vec(v), unique vu(v)) engine=innodb;
170+
select * from t force index(vec) order by v;
171+
drop table t;

sql/table.cc

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
18521852
bool *interval_unescaped= NULL;
18531853
extra2_fields extra2;
18541854
bool extra_index_flags_present= FALSE;
1855+
key_map sort_keys_in_use(0);
18551856
DBUG_ENTER("TABLE_SHARE::init_from_binary_frm_image");
18561857

18571858
keyinfo= &first_keyinfo;
@@ -3207,7 +3208,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
32073208
field->part_of_key.set_bit(key);
32083209
}
32093210
if (handler_file->index_flags(key, i, 1) & HA_READ_ORDER)
3211+
{
32103212
field->part_of_sortkey.set_bit(key);
3213+
sort_keys_in_use.set_bit(key);
3214+
}
32113215

32123216
if (i < keyinfo->user_defined_key_parts)
32133217
field->part_of_key_not_clustered.set_bit(key);
@@ -3216,22 +3220,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
32163220
usable_parts == i)
32173221
usable_parts++; // For FILESORT
32183222
field->flags|= PART_KEY_FLAG;
3219-
if (key == primary_key)
3220-
{
3221-
field->flags|= PRI_KEY_FLAG;
3222-
/*
3223-
If this field is part of the primary key and all keys contains
3224-
the primary key, then we can use any key to find this column
3225-
*/
3226-
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
3227-
{
3228-
if (field->key_length() == key_part->length &&
3229-
!(field->flags & BLOB_FLAG))
3230-
field->part_of_key= share->keys_in_use;
3231-
if (field->part_of_sortkey.is_set(key))
3232-
field->part_of_sortkey= share->keys_in_use;
3233-
}
3234-
}
32353223
if (field->key_length() != key_part->length)
32363224
{
32373225
#ifndef TO_BE_DELETED_ON_PRODUCTION
@@ -3294,21 +3282,39 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
32943282
if (primary_key < MAX_KEY &&
32953283
(share->keys_in_use.is_set(primary_key)))
32963284
{
3297-
DBUG_ASSERT(share->primary_key == primary_key);
3285+
keyinfo= share->key_info + primary_key;
32983286
/*
32993287
If we are using an integer as the primary key then allow the user to
33003288
refer to it as '_rowid'
33013289
*/
3302-
if (share->key_info[primary_key].user_defined_key_parts == 1)
3290+
if (keyinfo->user_defined_key_parts == 1)
33033291
{
3304-
Field *field= share->key_info[primary_key].key_part[0].field;
3292+
Field *field= keyinfo->key_part[0].field;
33053293
if (field && field->result_type() == INT_RESULT)
33063294
{
33073295
/* note that fieldnr here (and rowid_field_offset) starts from 1 */
3308-
share->rowid_field_offset= (share->key_info[primary_key].key_part[0].
3309-
fieldnr);
3296+
share->rowid_field_offset= keyinfo->key_part[0].fieldnr;
33103297
}
33113298
}
3299+
for (i=0; i < keyinfo->user_defined_key_parts; key_part++, i++)
3300+
{
3301+
Field *field= keyinfo->key_part[i].field;
3302+
field->flags|= PRI_KEY_FLAG;
3303+
/*
3304+
If this field is part of the primary key and all keys contains
3305+
the primary key, then we can use any key to find this column
3306+
*/
3307+
if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX)
3308+
{
3309+
if (field->key_length() == keyinfo->key_part[i].length &&
3310+
!(field->flags & BLOB_FLAG))
3311+
{
3312+
field->part_of_key= share->keys_in_use;
3313+
field->part_of_sortkey= sort_keys_in_use;
3314+
}
3315+
}
3316+
}
3317+
DBUG_ASSERT(share->primary_key == primary_key);
33123318
}
33133319
else
33143320
{

0 commit comments

Comments
 (0)