[MDEV-16426] Optimizer erroneously treats equal constants of different formats as same Created: 2018-06-07 Updated: 2018-06-08 Resolved: 2018-06-08 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Data types, Optimizer |
| Affects Version/s: | 10.0, 10.1, 10.2, 10.3, 10.4 |
| Fix Version/s: | 10.4.0 |
| Type: | Bug | Priority: | Major |
| Reporter: | Alexander Barkov | Assignee: | Alexander Barkov |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
This script demonstrates that although TIME'00:00:00.0' and TIME'00:00:00.00' are equal to each other for comparison, they are still not equal in other contexts:
Notice, the two expressions return a different result (as expected), although TIME literals are equivalent for each other for comparison. Now I put the same expressions into a WHERE condition with <=>:
It returns all rows. This is wrong. The condition is expected to be false, and the query should return empty set. EXPLAIN for the same query tells that the condition was erroneously simplified to true by the optimizer:
|
| Comments |
| Comment by Alexander Barkov [ 2018-06-08 ] | ||||||||||||||||||||||||
|
The same problem is repeatable with DECIMAL:
Looks wrong. The SELECT query should return empty set, and EXPLAIN should not tell that the condition was simplified to true. | ||||||||||||||||||||||||
| Comment by Alexander Barkov [ 2018-06-08 ] | ||||||||||||||||||||||||
|
The problem happens because Item_bool_func2::remove_eq_conds() correctly calls eq() for the arguments like this:
but further eq() can handle binary vs non-binary comparison only for string constants (and not for temporal or decimal). eq() should be fixed to take into account possible different formats when the binary_cmp parameter is true, for all affected data types (such as temporal and DECIMAL). | ||||||||||||||||||||||||
| Comment by Alexander Barkov [ 2018-06-08 ] | ||||||||||||||||||||||||
|
In this scenario it works fine (the constants 'a' and 0x61 are not detected as same):
because Item_hex_constant::type() and Item_string::type() returns different codes (STRING_ITEM vs VARBIN_ITEM). |