[MDEV-18304] sql_safe_updates does not work with OR clauses Created: 2019-01-18 Updated: 2022-03-14 Resolved: 2022-03-14 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.3.11 |
| Fix Version/s: | 10.3.35, 10.4.25, 10.5.16, 10.6.8, 10.7.4, 10.8.3 |
| Type: | Bug | Priority: | Major |
| Reporter: | Vincent Milum Jr | Assignee: | Sergei Golubchik |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||
| Description |
|
The error message says that a KEY was not used in the delete statement. Both sides of the OR are keys, however the OR apparently is preventing the optimizer from realizing this. These types of statements are comment when creating a one-to-many or many-to-many linking tables, and attempting to either UPDATE or DELETE these links. Current work-around is to use an arbitrarily large LIMIT on the query, as this bypasses the WHERE safety check. It also appears that the optimizer assumes that a LIMIT of 0xFFFFFFFFFFFFFFFF or (2^64)-1 is the same as having no limit at all.
|
| Comments |
| Comment by Elena Stepanova [ 2019-01-19 ] | |||||||||||||||||||||||||||||||||||||||||||
|
Thanks for the report. There is definitely room for improvement here. First of all, documentation in regard to sql_safe_updates is insufficient, there is definitely more to it than the description says. MySQL manual is somewhat better in this regard, as it at least has a separate section for safe updates, but it's also incomplete, as this report shows. The feature is vague, it needs to be described as precisely as possible. Further, for the particular example from the bug description, one can argue that the keys aren't actually used here, as the table is empty. It can be seen if we switch off sql_slave_updates and run EXPLAIN, e.g. on 10.3:
Even so, the error message is bad:
It's all wrong, the UPDATE has a WHERE clause which uses key columns; optimizer chooses not to use keys, but that's another story. But further, even if we insert some data into the table and make DELETE use the keys, it still doesn't work:
So, obviously there the condition is stricter than just using a key. Maybe the problem is that it uses index_merge, more than one key. I'm not sure if it's intentional or not, but it does need to be either fixed or documented. Finally, on a somewhat separate but related note, it's inconvenient that EXPLAIN doesn't work either:
This part was actually fixed recently in upstream 5.7+, in the scope of bug #91080. So, to summarize,
|