[MDEV-4839] MySQL Bug# 69638 Created: 2013-08-02 Updated: 2013-10-10 Resolved: 2013-10-10 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | Sergei Petrunia | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Description |
|
This is to track MySQL Bug# 69638. The bug is reproducible in MySQL 5.6.13. MariaDB 5.5 is not affected. The query plan in mysql-5.6 is:
In MariaDB 5.5, it is:
The bug is not related to "Using index for group-by" optimization, however. If I disable it (in gdb), MySQL 5.6 produces the same EXPLAIN as MariaDB 5.5 does, but the bug is still there. |
| Comments |
| Comment by Sergei Petrunia [ 2013-08-02 ] |
|
If I trace execution in MariaDB, I see that
Code-wise, it is Item_func_lt::val_int(), which has an argument of Item_ref, which points to Item_field, which is a field in the temporary table. |
| Comment by Sergei Petrunia [ 2013-08-02 ] |
|
If I trace execution in MySQL 5.6, I see that "r < 20" is checked before writing to the temporary table. It seems, the problem is that rand() is evaluated two times for each group: In other words, the following happens: S2. The second call to rand() call returns value that does satisfy HAVING. We write tem. table row buffer into the temp. table |
| Comment by Sergei Petrunia [ 2013-08-02 ] |
|
Possible solutions: == Evaluate the "late" form of HAVING clause == if we used "late" form, we would have avoided re-calculation of rand(). == Change rand() to have next_value() method == Make rand() return the same value until somebody calls next_value() or something like that. This is a rather big change, because we will need to define when it's time to use the "next value" for all possible cases. == Don't use early-HAVING-evaluation for rand() == end_write_group() has the code that checks HAVING clause (join->having) in MariaDB 5.5 However, when tracing the query from the bug, I see that join->having==NULL.
Perhaps, we should make MySQL 5.6 not to use early HAVING evaluation for conditions with RAND_TABLE_BIT? |
| Comment by Sergei Petrunia [ 2013-08-02 ] |
|
The optimizer switches between "early" and "late" form of WHERE by changing "ref array". Here is how the changes are made: curr_join->set_items_ref_array(items1); == mysql 5.6 == Hardware watchpoint 16: **$a In JOIN::make_tmp_tables_info(): // Need to set them now for correct group_fields setup, reset at the end. Hardware watchpoint 16: **$a // Reset before execution JOIN::exec() ... ^^^^^^^^ this is where the problem happens .... in QEP_tmp_table::end_send (): // Update ref array Hardware watchpoint 16: **$a in JOIN::cleanup (this=0x7fffc4007f30, full=true): /* Restore ref array to original state */ |
| Comment by Sergei Petrunia [ 2013-10-10 ] |
|
The fix is in the last comment. |