Commit 127c721c authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine

Subquery executes twice, at top level JOIN::optimize and ::execute stages.
At first execution create_sort_index() function is called and
FT_SELECT object is created and destroyed. HANDLER::ft_handler is cleaned up
in the object destructor and at second execution FT_SELECT::get_next() method
returns error.
The fix is to reinit HANDLER::ft_handler field before re-execution of subquery.


mysql-test/r/fulltext.result:
  test case
mysql-test/t/fulltext.test:
  test case
sql/item_func.cc:
  reinit ft_handler before re-execution of subquery
sql/item_func.h:
  Fixed method name
sql/sql_select.cc:
  reinit ft_handler before re-execution of subquery
parent e4fab954
......@@ -644,4 +644,40 @@ Table Op Msg_type Msg_text
test.t1 repair status OK
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
#
# Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine
#
CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1));
INSERT INTO t1 VALUES ('test');
SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1)) xor f1;
1
1
PREPARE stmt FROM
'SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1)) xor f1';
EXECUTE stmt;
1
1
EXECUTE stmt;
1
1
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
'SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1))';
EXECUTE stmt;
1
1
EXECUTE stmt;
1
1
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests
......@@ -585,4 +585,40 @@ REPAIR TABLE t1;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
DROP TABLE t1;
--echo #
--echo # Bug#54484 explain + prepared statement: crash and Got error -1 from storage engine
--echo #
CREATE TABLE t1(f1 VARCHAR(6) NOT NULL, FULLTEXT KEY(f1), UNIQUE(f1));
INSERT INTO t1 VALUES ('test');
SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1)) xor f1;
PREPARE stmt FROM
'SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1)) xor f1';
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
'SELECT 1 FROM t1 WHERE 1 >
ALL((SELECT 1 FROM t1 JOIN t1 a
ON (MATCH(t1.f1) against (""))
WHERE t1.f1 GROUP BY t1.f1))';
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo End of 5.1 tests
......@@ -5297,7 +5297,17 @@ void Item_func_match::init_search(bool no_order)
/* Check if init_search() has been called before */
if (ft_handler)
{
/*
We should reset ft_handler as it is cleaned up
on destruction of FT_SELECT object
(necessary in case of re-execution of subquery).
TODO: FT_SELECT should not clean up ft_handler.
*/
if (join_key)
table->file->ft_handler= ft_handler;
DBUG_VOID_RETURN;
}
if (key == NO_SUCH_KEY)
{
......
......@@ -1531,7 +1531,7 @@ public:
join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { }
void cleanup()
{
DBUG_ENTER("Item_func_match");
DBUG_ENTER("Item_func_match::cleanup");
Item_real_func::cleanup();
if (!master && ft_handler)
ft_handler->please->close_search(ft_handler);
......
......@@ -1713,6 +1713,9 @@ JOIN::reinit()
func->clear();
}
if (!(select_options & SELECT_DESCRIBE))
init_ftfuncs(thd, select_lex, test(order));
DBUG_RETURN(0);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment