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:
None 
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
Tags: against, crash, execute statement, fts, full text search, match
Triage: Triaged: D1 (Critical) / R2 (Low) / E3 (Medium)

[30 Jun 2008 13:25] Wiktor Kolodziej
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
[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.