summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Glukhov <Sergey.Glukhov@sun.com>2010-10-18 14:47:26 +0400
committerSergey Glukhov <Sergey.Glukhov@sun.com>2010-10-18 14:47:26 +0400
commit127c721cef2c1b248af79a386c174a5e7addd556 (patch)
tree2531ef5b40462491747a2d3283a13f594835277f
parente4fab954d1f33a7aff8661b016d308f8776ba4dd (diff)
downloadmariadb-git-127c721cef2c1b248af79a386c174a5e7addd556.tar.gz
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
-rw-r--r--mysql-test/r/fulltext.result36
-rw-r--r--mysql-test/t/fulltext.test36
-rw-r--r--sql/item_func.cc10
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/sql_select.cc3
5 files changed, 86 insertions, 1 deletions
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 806675edc5a..4f406f5032c 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -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
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index ec64728a8c9..6de8b87197c 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -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
diff --git a/sql/item_func.cc b/sql/item_func.cc
index eaf6a1b6d14..30d5d844f7c 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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)
{
diff --git a/sql/item_func.h b/sql/item_func.h
index 256348eee08..26a7e033692 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 08bd0c28738..a260b78f131 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1713,6 +1713,9 @@ JOIN::reinit()
func->clear();
}
+ if (!(select_options & SELECT_DESCRIBE))
+ init_ftfuncs(thd, select_lex, test(order));
+
DBUG_RETURN(0);
}