Skip to content

Commit 95a0325

Browse files
committed
MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering upon reaching in_predicate_conversion_threshold
When converting an IN-list to a subquery, a temporary table stores the IN-list values and participates in join optimization. The problem is the bitmap of usable keys for the temporary table is initialized after the optimization phase, during execution. It happens when the table is opened via `ha_heap::open()`, after the subroutine `set_keys_for_scanning()` is called. Trying to access the bitmap earlier, during optimization, leads to MSAN/Valgrind errors. This fix removes the dependency on `set_keys_for_scanning()`. The key bitmap is now dynamically composed on demand in `keys_to_use_for_scanning()`, ensuring correctness without imposing strict call-order constraints. Reviewer: Oleksandr Byelkin <sanja@mariadb.com>
1 parent 3a6af45 commit 95a0325

File tree

4 files changed

+42
-19
lines changed

4 files changed

+42
-19
lines changed

mysql-test/main/opt_tvc.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,3 +780,15 @@ deallocate prepare stmt;
780780
drop table t1;
781781
set in_predicate_conversion_threshold=default;
782782
# End of 10.3 tests
783+
#
784+
# MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering
785+
# upon reaching in_predicate_conversion_threshold
786+
#
787+
create table t1 (a int, b int, c int, primary key (a, b));
788+
insert into t1 (a, b) values (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8);
789+
set in_predicate_conversion_threshold = 2;
790+
select * from t1 where a in (1, 2) and b = 2 order by a, b;
791+
a b c
792+
1 2 NULL
793+
drop table t1;
794+
# End of 11.4 tests

mysql-test/main/opt_tvc.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,3 +474,18 @@ drop table t1;
474474
set in_predicate_conversion_threshold=default;
475475

476476
--echo # End of 10.3 tests
477+
478+
--echo #
479+
--echo # MDEV-32575 MSAN / Valgrind errors in test_if_cheaper_ordering
480+
--echo # upon reaching in_predicate_conversion_threshold
481+
--echo #
482+
483+
create table t1 (a int, b int, c int, primary key (a, b));
484+
insert into t1 (a, b) values (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8);
485+
486+
set in_predicate_conversion_threshold = 2;
487+
select * from t1 where a in (1, 2) and b = 2 order by a, b;
488+
489+
drop table t1;
490+
491+
--echo # End of 11.4 tests

storage/heap/ha_heap.cc

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
144144
}
145145

146146
ref_length= sizeof(HEAP_PTR);
147-
/* Initialize variables for the opened table */
148-
set_keys_for_scanning();
149147
/*
150148
We cannot run update_key_stats() here because we do not have a
151149
lock on the table. The 'records' count might just be changed
@@ -186,32 +184,34 @@ handler *ha_heap::clone(const char *name, MEM_ROOT *mem_root)
186184

187185

188186
/*
189-
Compute which keys to use for scanning
187+
Return set of keys usable for scanning
190188
191189
SYNOPSIS
192-
set_keys_for_scanning()
193-
no parameter
190+
keys_to_use_for_scanning()
191+
(no parameters)
194192
195193
DESCRIPTION
196-
Set the bitmap btree_keys, which is used when the upper layers ask
197-
which keys to use for scanning. For each btree index the
198-
corresponding bit is set.
194+
This function populates the bitmap `btree_keys`, where each bit represents
195+
a key that can be used for scanning the table. The bitmap is dynamically
196+
updated on every call, ensuring it reflects the current state of the
197+
table's keys. Caching is avoided because the set of usable keys for
198+
MEMORY tables may change during optimization or execution.
199199
200200
RETURN
201-
void
201+
Pointer to the updated bitmap of keys (`btree_keys`)
202202
*/
203203

204-
void ha_heap::set_keys_for_scanning(void)
204+
const key_map *ha_heap::keys_to_use_for_scanning()
205205
{
206206
btree_keys.clear_all();
207207
for (uint i= 0 ; i < table->s->keys ; i++)
208208
{
209209
if (table->key_info[i].algorithm == HA_KEY_ALG_BTREE)
210210
btree_keys.set_bit(i);
211211
}
212+
return &btree_keys;
212213
}
213214

214-
215215
int ha_heap::can_continue_handler_scan()
216216
{
217217
int error= 0;
@@ -515,8 +515,7 @@ int ha_heap::disable_indexes(key_map map, bool persist)
515515
if (!persist)
516516
{
517517
DBUG_ASSERT(map.is_clear_all());
518-
if (!(error= heap_disable_indexes(file)))
519-
set_keys_for_scanning();
518+
error= heap_disable_indexes(file);
520519
}
521520
else
522521
{
@@ -534,8 +533,7 @@ int ha_heap::disable_indexes(key_map map, bool persist)
534533
enable_indexes()
535534
536535
DESCRIPTION
537-
Enable indexes and set keys to use for scanning.
538-
The indexes might have been disabled by disable_index() before.
536+
Enable indexes taht might have been disabled by disable_index() before.
539537
The function works only if both data and indexes are empty,
540538
since the heap storage engine cannot repair the indexes.
541539
To be sure, call handler::delete_all_rows() before.
@@ -555,8 +553,7 @@ int ha_heap::enable_indexes(key_map map, bool persist)
555553
if (!persist)
556554
{
557555
DBUG_ASSERT(map.is_prefix(table->s->keys));
558-
if (!(error= heap_enable_indexes(file)))
559-
set_keys_for_scanning();
556+
error= heap_enable_indexes(file);
560557
}
561558
else
562559
{

storage/heap/ha_heap.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class ha_heap final : public handler
5959
HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE :
6060
HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR);
6161
}
62-
const key_map *keys_to_use_for_scanning() override { return &btree_keys; }
62+
const key_map *keys_to_use_for_scanning() override;
6363
uint max_supported_keys() const override { return MAX_KEY; }
6464
uint max_supported_key_part_length() const override { return MAX_KEY_LENGTH; }
6565
IO_AND_CPU_COST scan_time() override;
@@ -121,5 +121,4 @@ class ha_heap final : public handler
121121
int find_unique_row(uchar *record, uint unique_idx) override;
122122
private:
123123
void update_key_stats();
124-
void set_keys_for_scanning(void);
125124
};

0 commit comments

Comments
 (0)