| Bug #37740 | Server crashes on execute statement with full text search and match against | ||
|---|---|---|---|
| Submitted: | 30 Jun 2008 13:25 | Modified: | 7 Aug 2009 0:22 |
| Reporter: | Wiktor Kolodziej | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Prepared statements | Severity: | S2 (Serious) |
| Version: | 5.0.45, 5.0.51, 4.1, 5.0, 5.1, 6.0 bzr | OS: | Linux (Debian) |
| Assigned to: | Anurag Shekhar | CPU Architecture: | Any |
| Tags: | against, crash, execute statement, fts, full text search, match | ||
[30 Jun 2008 14:45]
Sveta Smirnova
Thank you for the report. Verified as described.
[18 May 2009 8:36]
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/74345 2748 Anurag Shekhar 2009-05-18 Bug#37740 Server crashes on execute statement with full text search and match against. While executing a prepared statement server checks the Item_func_match if the table variable is initialized, If it is initialized it assumes that the item_fields too are initialized. And proceeds with execution of prepared statement. But in reality the fields are not initialized, which results in a crash latter when the fields are accessed. This bug is fixed (for 5.0 and 5.1) by setting "table" to 0 so that table and fields are reinitialized while executing the prepared statement. However this fixes only the symptom of the actual problem which is incorrect implementation of Item_func_match::eq(). The fix for 6.0 will be made separately to address the actual problem by fixing implementation in eq() method. @ mysql-test/r/fulltext.result Updated results with the outputs of new test case. @ mysql-test/t/fulltext.test Added new test case to test scenario decribed in the bug. @ sql/item_func.h setting table to 0 to ensure the table and fields are reinitialized while executing the prepared statement.
[21 May 2009 9:06]
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/74681 2750 Anurag Shekhar 2009-05-21 Bug#37740 Server crashes on execute statement with full text search and match against. Server crashes when executing prepared statement with duplicating MATCH() function calls in SELECT and ORDER BY expressions, e.g.: SELECT MATCH(a) AGAINST('test') FROM t1 ORDER BY MATCH(a) AGAINST('test') This query gets optimized by the server, so the value returned by MATCH() from the SELECT list is reused for ORDER BY purposes. To make this optimization server is comparing items from SELECT and ORDER BY lists. We were getting server crash because comparision function for MATCH() item is not intended to be called at this point of execution. In 5.0 and 5.1 this problem is workarounded by resetting MATCH() item to the state as it was during PREPARE. Which in fact means that described above optimization is never applied to MATCH(). In 6.0 correct comparision function will be implemented and duplicating MATCH() items from the ORDER BY list will be optimized. @ mysql-test/r/fulltext.result Updated with the test case for Bug#37740 @ mysql-test/t/fulltext.test A test case for Bug#37740. @ sql/item_func.h Reset 'table' to the state as if Item_func_match was just created. True initialization of 'table' happens in ::fix_fields(). As Item_func_match::eq() may be called before ::fix_fields(), it is expected that 'table' is initialized to 0 when it is reused. This is mostly affecting prepared statements, when the same item doesn't get destroyed, but rather cleaned up and reused.
[21 May 2009 9:31]
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/74682 2750 Anurag Shekhar 2009-05-21 Bug#37740 Server crashes on execute statement with full text search and match against. Server crashes when executing prepared statement with duplicating MATCH() function calls in SELECT and ORDER BY expressions, e.g.: SELECT MATCH(a) AGAINST('test') FROM t1 ORDER BY MATCH(a) AGAINST('test') This query gets optimized by the server, so the value returned by MATCH() from the SELECT list is reused for ORDER BY purposes. To make this optimization server is comparing items from SELECT and ORDER BY lists. We were getting server crash because comparision function for MATCH() item is not intended to be called at this point of execution. In 5.0 and 5.1 this problem is workarounded by resetting MATCH() item to the state as it was during PREPARE. Which in fact means that described above optimization is never applied to MATCH(). In 6.0 correct comparision function will be implemented and duplicating MATCH() items from the ORDER BY list will be optimized. @ mysql-test/r/fulltext.result Updated with the test case for Bug#37740 @ mysql-test/t/fulltext.test A test case for Bug#37740. @ sql/item_func.h Reset 'table' to the state as if Item_func_match was just created. True initialization of 'table' happens in ::fix_fields(). As Item_func_match::eq() may be called before ::fix_fields(), it is expected that 'table' is initialized to 0 when it is reused. This is mostly affecting prepared statements, when the same item doesn't get destroyed, but rather cleaned up and reused.
[15 Jul 2009 9:36]
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/78707 2781 Anurag Shekhar 2009-07-15 Bug#37740 Server crashes on execute statement with full text search and match against. Server crashes when executing prepared statement with duplicating MATCH() function calls in SELECT and ORDER BY expressions, e.g.: SELECT MATCH(a) AGAINST('test') FROM t1 ORDER BY MATCH(a) AGAINST('test') This query gets optimized by the server, so the value returned by MATCH() from the SELECT list is reused for ORDER BY purposes. To make this optimization server is comparing items from SELECT and ORDER BY lists. We were getting server crash because comparision function for MATCH() item is not intended to be called at this point of execution. In 5.0 and 5.1 this problem is workarounded by resetting MATCH() item to the state as it was during PREPARE. In 6.0 correct comparision function will be implemented and duplicating MATCH() items from the ORDER BY list will be optimized. @ mysql-test/r/fulltext.result Updated with the test case for Bug#37740 @ mysql-test/t/fulltext.test A test case for Bug#37740. @ sql/item_func.h True initialization of 'table' happens in ::fix_fields(). As Item_func_match::eq() may be called before ::fix_fields(), it is expected that 'table' is initialized to 0 when it is reused. This is mostly affecting prepared statements, when the same item doesn't get destroyed, but rather cleaned up and reused.
[20 Jul 2009 10:51]
Anurag Shekhar
fix for 5.0 and 5.1 is pushed i will be committing separate patch for 6.0.
[30 Jul 2009 9:32]
Anurag Shekhar
Fix for bug#45130 will fix this bug on 6.0 too.
[4 Aug 2009 13:58]
Bugs System
Pushed into 5.0.85 (revid:davi.arnaut@sun.com-20090804135315-6lfdnk4zjwk7kn7r) (version source revid:davi.arnaut@sun.com-20090804135315-6lfdnk4zjwk7kn7r) (merge vers: 5.0.85) (pib:11)
[4 Aug 2009 19:52]
Bugs System
Pushed into 5.4.4-alpha (revid:alik@sun.com-20090804194615-h40sa098mx4z49qg) (version source revid:ramil@mysql.com-20090715111112-72fdhvyicpo0o9vp) (merge vers: 5.4.4-alpha) (pib:11)
[4 Aug 2009 20:45]
Bugs System
Pushed into 5.1.38 (revid:davi.arnaut@sun.com-20090804204317-ggodqkik7de6nfpz) (version source revid:davi.arnaut@sun.com-20090804204317-ggodqkik7de6nfpz) (merge vers: 5.1.38) (pib:11)
[7 Aug 2009 0:22]
Paul DuBois
Noted in 5.0.85, 5.1.38, 5.4.4 changelogs.
The server crashed when executing a prepared statement containing a
duplicated MATCH() function call in the select list and ORDER BY
clause; for example, SELECT MATCH(a) AGAINST('test') FROM t1 ORDER BY
MATCH(a) AGAINST('test').
[12 Aug 2009 22:53]
Paul DuBois
Noted in 5.4.2 changelog because next 5.4 version will be 5.4.2 and not 5.4.4.
[15 Aug 2009 2:10]
Paul DuBois
Ignore previous comment about 5.4.2.
[1 Oct 2009 5:58]
Bugs System
Pushed into 5.1.39-ndb-6.3.28 (revid:jonas@mysql.com-20091001055605-ap2kiaarr7p40mmv) (version source revid:jonas@mysql.com-20091001055605-ap2kiaarr7p40mmv) (merge vers: 5.1.39-ndb-6.3.28) (pib:11)
[1 Oct 2009 7:25]
Bugs System
Pushed into 5.1.39-ndb-7.0.9 (revid:jonas@mysql.com-20091001072547-kv17uu06hfjhgjay) (version source revid:jonas@mysql.com-20091001071652-irejtnumzbpsbgk2) (merge vers: 5.1.39-ndb-7.0.9) (pib:11)
[1 Oct 2009 13:25]
Bugs System
Pushed into 5.1.39-ndb-7.1.0 (revid:jonas@mysql.com-20091001123013-g9ob2tsyctpw6zs0) (version source revid:jonas@mysql.com-20091001123013-g9ob2tsyctpw6zs0) (merge vers: 5.1.39-ndb-7.1.0) (pib:11)
[5 Oct 2009 10:50]
Bugs System
Pushed into 5.1.39-ndb-6.2.19 (revid:jonas@mysql.com-20091005103850-dwij2dojwpvf5hi6) (version source revid:jonas@mysql.com-20090930185117-bhud4ek1y0hsj1nv) (merge vers: 5.1.39-ndb-6.2.19) (pib:11)
[8 Oct 2009 20:13]
Paul DuBois
The 5.4 fix has been pushed to 5.4.2.

Description: Server crashes on execute statement with full text search, order by and match against clause. Further details provided in the sample SQL. GDB output: [New Thread 0xb4feeb90 (LWP 5112)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb4feeb90 (LWP 5112)] 0x0814eb11 in Item_func_match::fix_index (this=0x8b18de0) at item_func.cc:5002 5002 if (item->field->eq(ft_key->key_part[part].field)){ (gdb) bt #0 0x0814eb11 in Item_func_match::fix_index (this=0x8b18de0) at item_func.cc:5002 #1 0x08211872 in setup_ftfuncs (select_lex=0x8b2bff0) at sql_base.cc:6122 #2 0x0824860f in JOIN::prepare (this=0x8b2fb80, rref_pointer_array=0x8b2c114, tables_init=0x8b18af8, wild_num=0, conds_init=0x0, og_num=1, order_init=0x8b18ed8, group_init=0x0, having_init=0x0, proc_param_init=0x0, select_lex_arg=0x8b2bff0, unit_arg=0x8b2bdc0) at sql_select.cc:543 #3 0x08248d46 in mysql_select (thd=0x8af78b8, rref_pointer_array=0x8b2c114, tables=0x8b18af8, wild_num=0, fields=@0x8b2c084, conds=0x0, og_num=1, order=0x8b18ed8, group=0x0, having=0x0, proc_param=0x0, select_options=2424588800, result=0x8b18f08, unit=0x8b2bdc0, select_lex=0x8b2bff0) at sql_select.cc:2244 #4 0x0824d398 in handle_select (thd=0x8af78b8, lex=0x8b2bd68, result=0x8b18f08, setup_tables_done_option=0) at sql_select.cc:255 #5 0x081e5690 in mysql_execute_command (thd=0x8af78b8) at sql_parse.cc:2853 #6 0x08259d64 in Prepared_statement::execute (this=0x8b2bad8, expanded_query=0xb4fed2a8, open_cursor=false) at sql_prepare.cc:3004 #7 0x0825a058 in mysql_sql_stmt_execute (thd=0x8af78b8) at sql_prepare.cc:2368 #8 0x081e56f3 in mysql_execute_command (thd=0x8af78b8) at sql_parse.cc:2867 #9 0x081eda7a in mysql_parse (thd=0x8af78b8, inBuf=0x8b2fad0 "execute segv", length=12, found_semicolon=0xb4fee1d0) at sql_parse.cc:6295 #10 0x081ee6df in dispatch_command (command=COM_QUERY, thd=0x8af78b8, packet=0x8b27a71 "execute segv", packet_length=13) at sql_parse.cc:1988 #11 0x081efce3 in do_command (thd=0x8af78b8) at sql_parse.cc:1759 #12 0x081f02ce in handle_one_connection (arg=0x8af78b8) at sql_parse.cc:1367 #13 0xb7ee64fb in start_thread () from /lib/i686/cmov/libpthread.so.0 #14 0xb7cffd7e in clone () from /lib/i686/cmov/libc.so.6 -=-=-=-= Seems a bit simillar to: http://bugs.mysql.com/bug.php?id=36737 How to repeat: use test1; DROP TABLE IF EXISTS `ttest`; -- table might be empty CREATE TABLE `ttest` ( `col` text, -- type, size oand numbert of cols does not matter FULLTEXT KEY `full_text` (`col`) ); -- prepare DOES NOT crash: prepare segv FROM "SELECT MATCH (`col`) AGAINST('findme') FROM `ttest` ORDER BY MATCH (`col`) AGAINST('findme') "; -- plain select DOES NOT crash mysql: SELECT MATCH (`col`) AGAINST('findme') FROM `ttest` ORDER BY MATCH (`col`) AGAINST('findme'); -- execute statement DOES: execute segv; Suggested fix: A temporary solution would be to change line: if (item->field->eq(ft_key->key_part[part].field)){ to: if (item->field && item->field->eq(ft_key->key_part[part].field)){ however the problem is probably located deeper, in the constructor of Item_func, file item_func.h