MDEV-34880 Incorrect result for query with derived table having TEXT field

When a derived table which has distinct values and BLOB fields is
materialized, an index is created over all columns to ensure only
unique values are placed to the result.
This index is created in a special mode HA_UNIQUE_HASH to support BLOBs.
Later the optimizer may incorrectly choose this index to retrieve values
from the derived table, although such type of index cannot be used
for data retrieval.

This commit excludes HA_UNIQUE_HASH indexes from adding to
`JOIN::keyuse` array thus preventing their subsequent usage for
data retrieval
This commit is contained in:
Oleg Smirnov 2024-09-29 20:50:58 +07:00
parent ebefef658e
commit 6bd1cb0ea0
5 changed files with 63 additions and 15 deletions

View File

@ -1862,3 +1862,19 @@ pk a
deallocate prepare stmt;
drop table t1,t2,t3;
# End of MariaDB 11.1 tests
#
# MDEV-34880: Incorrect result for query with derived table having TEXT field
#
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, notes TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'test1'), (2, 'test2');
SELECT dt.* FROM (SELECT * FROM t1 UNION SELECT * FROM t1) dt WHERE id = 1;
id notes
1 test1
SELECT dt.* FROM (SELECT * FROM t1 UNION SELECT * FROM t1) dt WHERE id = 1 AND
notes = 'test1';
id notes
1 test1
DROP TABLE t1;
#
# End of 11.2 tests
#

View File

@ -1514,3 +1514,20 @@ deallocate prepare stmt;
drop table t1,t2,t3;
--echo # End of MariaDB 11.1 tests
--echo #
--echo # MDEV-34880: Incorrect result for query with derived table having TEXT field
--echo #
CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, notes TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'test1'), (2, 'test2');
SELECT dt.* FROM (SELECT * FROM t1 UNION SELECT * FROM t1) dt WHERE id = 1;
SELECT dt.* FROM (SELECT * FROM t1 UNION SELECT * FROM t1) dt WHERE id = 1 AND
notes = 'test1';
DROP TABLE t1;
--echo #
--echo # End of 11.2 tests
--echo #

View File

@ -3737,6 +3737,28 @@ int handler::ha_rnd_pos(uchar *buf, uchar *pos)
DBUG_RETURN(result);
}
int handler::ha_index_init(uint idx, bool sorted)
{
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
int result;
DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
{
inited= INDEX;
active_index= idx;
end_range= NULL;
}
/*
Do not allow reads from UNIQUE HASH indexes.
*/
DBUG_ASSERT(!(table->key_info[active_index].flags & HA_UNIQUE_HASH));
DBUG_RETURN(result);
}
int handler::ha_index_read_map(uchar *buf, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)

View File

@ -3449,20 +3449,7 @@ public:
int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
int ha_index_init(uint idx, bool sorted)
{
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
int result;
DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
{
inited= INDEX;
active_index= idx;
end_range= NULL;
}
DBUG_RETURN(result);
}
int ha_index_init(uint idx, bool sorted);
int ha_index_end()
{
DBUG_ENTER("ha_index_end");

View File

@ -7257,8 +7257,14 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
{
if (!(form->keys_in_use_for_query.is_set(key)))
continue;
if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
if (form->key_info[key].flags & (HA_FULLTEXT|HA_SPATIAL|HA_UNIQUE_HASH))
{
/*
HA_UNIQUE_HASH indexes are excluded since they cannot be used
for lookups. See Create_tmp_field::finalize() for details
*/
continue; // ToDo: ft-keys in non-ft queries. SerG
}
KEY *keyinfo= form->key_info+key;
uint key_parts= form->actual_n_key_parts(keyinfo);