Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions mysql-test/main/partition_explicit_prune.result
Original file line number Diff line number Diff line change
Expand Up @@ -2008,3 +2008,12 @@ drop table t1;
#
# End of 10.4 tests
#
#
# MDEV-35555 UBSAN runtime error: applying non-zero offset 32 to null pointer in sel_trees_must_be_ored
#
CREATE TABLE t (a INT,b CHAR,PRIMARY KEY(a,b)) PARTITION BY LINEAR KEY() PARTITIONS 2;
EXPLAIN SELECT * FROM t WHERE a=1 OR a=2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
DROP TABLE t;
# End of 10.11 tests
9 changes: 9 additions & 0 deletions mysql-test/main/partition_explicit_prune.test
Original file line number Diff line number Diff line change
Expand Up @@ -942,3 +942,12 @@ drop table t1;
--echo # End of 10.4 tests
--echo #

--echo #
--echo # MDEV-35555 UBSAN runtime error: applying non-zero offset 32 to null pointer in sel_trees_must_be_ored
--echo #

CREATE TABLE t (a INT,b CHAR,PRIMARY KEY(a,b)) PARTITION BY LINEAR KEY() PARTITIONS 2;
EXPLAIN SELECT * FROM t WHERE a=1 OR a=2;
DROP TABLE t;

--echo # End of 10.11 tests
5 changes: 4 additions & 1 deletion sql/opt_range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9753,7 +9753,8 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,

int idx1, idx2;
key_map::Iterator it1(oredable_keys);
while ((idx1= it1++) != key_map::Iterator::BITMAP_END)
while ((idx1= it1++) != key_map::Iterator::BITMAP_END
&& param->key[idx1] && tree1->keys[idx1])
{
Comment on lines +9756 to 9758

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

By putting the null checks directly in the while loop condition, the loop will terminate prematurely on the first key that has a null pointer. This prevents any subsequent valid keys in oredable_keys from being processed. Instead, you should perform the null checks inside the loop body and use continue to skip the current key.

  while ((idx1= it1++) != key_map::Iterator::BITMAP_END)
  {
    if (!param->key[idx1] || !tree1->keys[idx1])
      continue;

KEY_PART *key1_init= param->key[idx1]+tree1->keys[idx1]->part;
KEY_PART *key1_end= param->key[idx1]+tree1->keys[idx1]->max_part_no;
Expand All @@ -9763,6 +9764,8 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,
if (idx2 <= idx1)
continue;

if (!param->key[idx2] || !tree2->keys[idx2])
break;
Comment on lines +9767 to +9768

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using break here will terminate the entire inner loop, which prevents checking any subsequent keys in oredable_keys that might be valid. Using continue instead will correctly skip only the current invalid key and allow the loop to proceed with the remaining keys.

      if (!param->key[idx2] || !tree2->keys[idx2])
        continue;

KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part;
KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no;
if (!is_key_infix(key1_init, key1_end, key2_init, key2_end) &&
Expand Down