Bug #18503 | Queries with "> ALL (subquery)" on InnoDB tables may return wrong result. | ||
---|---|---|---|
Submitted: | 25 Mar 2006 0:06 | Modified: | 24 Jul 2006 17:19 |
Reporter: | Maciej Babinski | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | Tested on 4.1.16, 5.0.18 | OS: | Linux (FedoraCore 4 (x86-64) and FC5) |
Assigned to: | Evgeny Potemkin | CPU Architecture: | Any |
[25 Mar 2006 0:06]
Maciej Babinski
[25 Mar 2006 0:08]
Maciej Babinski
Changed incorrect Version in bug report.
[25 Mar 2006 7:21]
Heikki Tuuri
Hi! InnoDB does correctly return HA_ERR_END_OF_FILE from bar. The probable reason for the bug is that MySQL first opens a cursor to foo, retrieves one row from foo, and then, WITHOUT CLOSING THE CURSOR on foo, continues to fetch from foo. Since there are no more rows in foo, InnoDB returns HA_ERR_END_OF_FILE, and the query returns from MySQL. Breakpoint 2, ha_innobase::rnd_init (this=0x8981540) at ha_innodb.cc:4298 4298 row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; Current language: auto; currently c++ (gdb) Continuing. Breakpoint 3, ha_innobase::rnd_next (this=0x8441da8, buf=0x89a87c4 "\220é\231\b@\025\230\bÄ\207\232\b°\225 \bÀ") at mysql_priv.h:473 473 { HERE MYSQL retrieves one row from foo: (gdb) bt #0 ha_innobase::rnd_next (this=0x8441da8, buf=0x89a87c4 "\220é\231\b@\025\230\bÄ\207\232\b°\225 \bÀ") at mysql_priv.h:473 #1 0x082095d5 in rr_sequential (info=0x89a87c4) at records.cc:295 #2 0x081b8ac9 in join_init_read_record (tab=0x89a8788) at sql_select.cc:10262 #3 0x081b7840 in sub_select (join=0x899b720, join_tab=0x89a8788, end_of_records=3) at sql_select.cc:9654 #4 0x081b7392 in do_select (join=0x899b720, fields=0x89803b0, table=0x0, procedure=0x0) at sql_select.cc:9418 #5 0x081abf08 in JOIN::exec (this=0x899b720) at sql_select.cc:1721 #6 0x081ac86a in mysql_select (thd=0x89800c0, rref_pointer_array=0x898044c, tables=0x899ab50, wild_num=1, fields=@0x8981660, conds=0x899b618, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2156153344, result=0x899b710, unit=0x898010c, select_lex=0x898032c) at sql_select.cc:1885 #7 0x081a89a2 in handle_select (thd=0x89800c0, lex=0x89800fc, result=0x899b710, setup_tables_done_option=0) at sql_select.cc:238 #8 0x08175d1c in mysql_execute_command (thd=0x89800c0) at sql_parse.cc:2494 #9 0x0817e610 in mysql_parse (thd=0x89800c0, inBuf=0x899aa18 "SELECT * FROM foo WHERE col1 > ALL (SELECT col2 FROM bar where col2 = 10)", length=144179452) at sql_parse.cc:5628 #10 0x08174483 in dispatch_command (command=144179392, thd=0x89800c0, packet=0x89929e9 "", packet_length=144288280) at sql_parse.cc:1713 #11 0x08173fcd in do_command (thd=0x89800c0) at sql_parse.cc:1514 #12 0x081733a2 in handle_one_connection (arg=0x89800c0) at sql_parse.cc:1158 #13 0x40042b63 in start_thread () from /lib/tls/libpthread.so.0 #14 0x4024c18a in clone () from /lib/tls/libc.so.6 (gdb) (gdb) Continuing. Breakpoint 1, row_search_for_mysql (buf=0x8981660 "ý\001", mode=1, prebuilt=0x42b4c868, match_mode=0, direction=0) at row0sel.c:3059 3059 dict_index_t* index = prebuilt->index; Current language: auto; currently c (gdb) Continuing. Breakpoint 2, ha_innobase::rnd_init (this=0x89a7490) at ha_innodb.cc:4298 4298 row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; Current language: auto; currently c++ (gdb) Continuing. MySQL TRIES TO RETRIEVE A ROW FROM bar, INNODB RETURNS HA_ERR_END_OF_FILE: Breakpoint 3, ha_innobase::rnd_next (this=0x8441da8, buf=0x89a8e3c "øn\232\b\220t\232\b<\216\232\b°\225 \bÀ") at mysql_priv.h:473 473 { (gdb) Continuing. Breakpoint 1, row_search_for_mysql (buf=0x89a75b0 "ÿ", mode=1, prebuilt=0x42b4d868, match_mode=0, direction=0) at row0sel.c:3059 3059 dict_index_t* index = prebuilt->index; Current language: auto; currently c (gdb) Continuing. THE BUG: MYSQL FOR SOME REASON CONTINUES TO RETRIEVE FROM foo, WITHOUT OPENING THE CURSOR ANEW: Breakpoint 3, ha_innobase::rnd_next (this=0x8441da8, buf=0x89a87c4 "\220é\231\b@\025\230\bÄ\207\232\b°\225 \bÀ") at mysql_priv.h:473 473 { Current language: auto; currently c++ (gdb) (gdb) bt #0 ha_innobase::rnd_next (this=0x8441da8, buf=0x89a87c4 "\220é\231\b@\025\230\bÄ\207\232\b°\225 \bÀ") at mysql_priv.h:473 #1 0x082095d5 in rr_sequential (info=0x89a87c4) at records.cc:295 #2 0x081b77a6 in sub_select (join=0x899b720, join_tab=0x89a8788, end_of_records=false) at sql_select.cc:9660 #3 0x081b7392 in do_select (join=0x899b720, fields=0x89803b0, table=0x0, procedure=0x0) at sql_select.cc:9418 #4 0x081abf08 in JOIN::exec (this=0x899b720) at sql_select.cc:1721 #5 0x081ac86a in mysql_select (thd=0x89800c0, rref_pointer_array=0x898044c, tables=0x899ab50, wild_num=1, fields=@0x8981660, conds=0x899b618, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2156153344, result=0x899b710, unit=0x898010c, select_lex=0x898032c) at sql_select.cc:1885 #6 0x081a89a2 in handle_select (thd=0x89800c0, lex=0x89800fc, result=0x899b710, setup_tables_done_option=0) at sql_select.cc:238 #7 0x08175d1c in mysql_execute_command (thd=0x89800c0) at sql_parse.cc:2494 #8 0x0817e610 in mysql_parse (thd=0x89800c0, inBuf=0x899aa18 "SELECT * FROM foo WHERE col1 > ALL (SELECT col2 FROM bar where col2 = 10)", length=144179452) at sql_parse.cc:5628 #9 0x08174483 in dispatch_command (command=144179392, thd=0x89800c0, packet=0x89929e9 "", packet_length=144288280) at sql_parse.cc:1713 #10 0x08173fcd in do_command (thd=0x89800c0) at sql_parse.cc:1514 #11 0x081733a2 in handle_one_connection (arg=0x89800c0) at sql_parse.cc:1158 #12 0x40042b63 in start_thread () from /lib/tls/libpthread.so.0 #13 0x4024c18a in clone () from /lib/tls/libc.so.6 (gdb) Continuing. Breakpoint 1, row_search_for_mysql (buf=0x8981660 "ý\001", mode=0, prebuilt=0x42b4c868, match_mode=0, direction=1) at row0sel.c:3059 3059 dict_index_t* index = prebuilt->index; Current language: auto; currently c (gdb) Continuing. Regards, Heikki
[25 Mar 2006 7:23]
Heikki Tuuri
Verified on 5.0.18 on Linux.
[8 Jul 2006 0:12]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/8948
[10 Jul 2006 21:44]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/9018
[14 Jul 2006 22:55]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/9190
[19 Jul 2006 0:09]
Evgeny Potemkin
An Item_sum_hybrid object has the was_values flag which indicates whether any values were added to the sum function. By default it is set to true and reset to false on any no_rows_in_result() call. This method is called only in return_zero_rows() function. An ALL/ANY subquery can be optimized by MIN/MAX optimization. The was_values flag is used to indicate whether the subquery has returned at least one row. This bug occurs because return_zero_rows() is called only when we know that the select will return zero rows before starting any scans but often such information is not known. In the reported case the return_zero_rows() function is not called and the was_values flag is not reset to false and yet the subquery return no rows Item_func_not_all and Item_func_nop_all functions return a wrong comparison result. Fixed in 4.1.22, 5.0.25
[24 Jul 2006 17:19]
Paul DuBois
Noted in 4.1.22, 5.0.25 changelogs. Using > ALL with subqueries that return no rows yields incorrect results under certain circumstances due to incorrect application of MIN()/MAX() optimization.