[MDEV-26553] NOT IN subquery construct crashing 10.1 and up Created: 2021-09-06 Updated: 2022-04-04 Resolved: 2022-03-22 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.1.48, 10.2.40, 10.3.31, 10.4.21, 10.5.12, 10.6.4, 10.2, 10.3, 10.4, 10.5, 10.6 |
| Fix Version/s: | 10.2.43, 10.3.34, 10.4.24, 10.5.15, 10.6.7, 10.7.3 |
| Type: | Bug | Priority: | Critical |
| Reporter: | Hartmut Holzgraefe | Assignee: | Igor Babaev |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
The following works on MySQL 5.6 and MariaDB 10.0, but crashes later MariaDB releases:
As the crash already happens in the optimizer stage it also crashes the server when trying to run "EXPLAIN SELECT" This seems to be independent from any optimizer_switch settings as even with all individual switch settings set to "off" it still crashes. MariaDB 10.6.4 gdb backtrace:
|
| Comments |
| Comment by Alice Sherepa [ 2021-09-07 ] | |||||||||||||||||||||||||||||||||||||
|
Setting optimizer_switch to 'in_to_exists=off' prevents the crash. The initial test case crashed with InnoDB engine, but not Myisam,
| |||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-24 ] | |||||||||||||||||||||||||||||||||||||
|
A more natural variant using Standard SQL that uses the predicate (i2 IS NULL) works fine:
The fact is that the predicate (i2 = NULL) is always evaluated to NULL/FALSE and it does not make sense to use it as a disjunct at the top level of any WHERE condition. | |||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-24 ] | |||||||||||||||||||||||||||||||||||||
|
The following query also works fine:
Here we also have a disjunct that is always FALSE that is removed from the top level disjunction. It is done by this code in the function optimize_cond()
We see that JOIN::cond_equal is updated here. At the same time we see that for the query
the disjunct i2 is NULL is not removed when optimize_cond() is called for WHERE.
The above code should have updated join->item_equal as well. As it was not done we have a crash later in substitute_for_best_equal_field (). | |||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-25 ] | |||||||||||||||||||||||||||||||||||||
|
The disjunct (i2 = NULL) could have been removed by the call of remove_eq_conds(). Here is an example with the disjunct that cannot be removed the call of remove_eq_conds(), but is removed by the mentioned call of get_quick_record_count():
This query causes the same kind of crash as the query from the reported test case. | |||||||||||||||||||||||||||||||||||||
| Comment by Oleksandr Byelkin [ 2021-11-26 ] | |||||||||||||||||||||||||||||||||||||
|
OK to push | |||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-29 ] | |||||||||||||||||||||||||||||||||||||
|
The variant of the fix that should be applied to 10.3 and up
| |||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2022-03-22 ] | |||||||||||||||||||||||||||||||||||||
|
A fix for this bug was pushed into 10.2 |