#At file:///home/svoj/devel/bzr-mysql/mysql-5.1-bugteam-bug39746/
2739 Sergey Vojtovich 2008-12-17
BUG#39746 - Debug flag breaks struct definition
(server crash)
Altering a table with fulltext index[es] which use
pluggable fulltext parser may cause server crash
in debug builds.
The problem was that ALTER TABLE code wrongly assigned
fulltext parser name.
Also fixed that altering a table with fulltext index[es]
leave stale fulltext parser locks, which prevent
fulltext parsers from being uninstalled after
ALTER TABLE.
added:
mysql-test/include/have_simple_parser.inc
mysql-test/r/fulltext_plugin.result
mysql-test/r/have_simple_parser.require
mysql-test/t/fulltext_plugin-master.opt
mysql-test/t/fulltext_plugin.test
modified:
mysql-test/mysql-test-run.pl
sql/sql_table.cc
sql/table.cc
per-file messages:
mysql-test/include/have_simple_parser.inc
Added support for testing simple fulltext parser.
mysql-test/mysql-test-run.pl
Added support for testing simple fulltext parser.
mysql-test/r/fulltext_plugin.result
A test case for BUG#39746.
mysql-test/r/have_simple_parser.require
Added support for testing simple fulltext parser.
mysql-test/t/fulltext_plugin-master.opt
A test case for BUG#39746.
mysql-test/t/fulltext_plugin.test
A test case for BUG#39746.
sql/sql_table.cc
Fixed that alter table wrongly assigns fulltext parser
name. parser_name member is only available during
table creation. When we open existing table we must
get parser_name from plugin_ref, which is handled
by plugin_name() macro.
sql/table.cc
Moved code that releases fulltext parsers into
free_table_share(). This fixes stale fulltext parser
locks set by ALTER TABLE, which are preventing fulltext
parsers from being uninstalled.
=== added file 'mysql-test/include/have_simple_parser.inc'
--- a/mysql-test/include/have_simple_parser.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/have_simple_parser.inc 2008-12-17 13:24:34 +0000
@@ -0,0 +1,16 @@
+#
+# Check if server has support for loading udf's
+# i.e it will support dlopen
+#
+--require r/have_dynamic_loading.require
+disable_query_log;
+show variables like 'have_dynamic_loading';
+enable_query_log;
+
+#
+# Check if the variable SIMPLE_PARSER is set
+#
+--require r/have_simple_parser.require
+disable_query_log;
+eval select LENGTH('$SIMPLE_PARSER') > 0 as 'have_simple_parser';
+enable_query_log;
=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl 2008-12-15 03:20:05 +0000
+++ b/mysql-test/mysql-test-run.pl 2008-12-17 13:24:34 +0000
@@ -163,6 +163,7 @@ our $exe_my_print_defaults;
our $exe_perror;
our $lib_udf_example;
our $lib_example_plugin;
+our $lib_simple_parser;
our $exe_libtool;
our $opt_bench= 0;
@@ -1717,6 +1718,10 @@ sub executable_setup () {
mtr_file_exists(vs_config_dirs('storage/example', 'ha_example.dll'),
"$glob_basedir/storage/example/.libs/ha_example.so",);
+ # Look for the simple_parser library
+ $lib_simple_parser=
+ mtr_file_exists(vs_config_dirs('plugin/fulltext', 'mypluglib.dll'),
+ "$glob_basedir/plugin/fulltext/.libs/mypluglib.so",);
}
# Look for mysqltest executable
@@ -2200,6 +2205,14 @@ sub environment_setup () {
($lib_example_plugin ? "--plugin_dir=" . dirname($lib_example_plugin) : "");
# ----------------------------------------------------
+ # Add the path where mysqld will find mypluglib.so
+ # ----------------------------------------------------
+ $ENV{'SIMPLE_PARSER'}=
+ ($lib_simple_parser ? basename($lib_simple_parser) : "");
+ $ENV{'SIMPLE_PARSER_OPT'}=
+ ($lib_simple_parser ? "--plugin_dir=" . dirname($lib_simple_parser) : "");
+
+ # ----------------------------------------------------
# Setup env so childs can execute myisampack and myisamchk
# ----------------------------------------------------
$ENV{'MYISAMCHK'}= mtr_native_path(mtr_exe_exists(
=== added file 'mysql-test/r/fulltext_plugin.result'
--- a/mysql-test/r/fulltext_plugin.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/fulltext_plugin.result 2008-12-17 13:24:34 +0000
@@ -0,0 +1,5 @@
+INSTALL PLUGIN simple_parser SONAME 'mypluglib.so';
+CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a) WITH PARSER simple_parser);
+ALTER TABLE t1 ADD FULLTEXT(b) WITH PARSER simple_parser;
+DROP TABLE t1;
+UNINSTALL PLUGIN simple_parser;
=== added file 'mysql-test/r/have_simple_parser.require'
--- a/mysql-test/r/have_simple_parser.require 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/have_simple_parser.require 2008-12-17 13:24:34 +0000
@@ -0,0 +1,2 @@
+have_simple_parser
+1
=== added file 'mysql-test/t/fulltext_plugin-master.opt'
--- a/mysql-test/t/fulltext_plugin-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/fulltext_plugin-master.opt 2008-12-17 13:24:34 +0000
@@ -0,0 +1 @@
+$SIMPLE_PARSER_OPT
=== added file 'mysql-test/t/fulltext_plugin.test'
--- a/mysql-test/t/fulltext_plugin.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/fulltext_plugin.test 2008-12-17 13:24:34 +0000
@@ -0,0 +1,10 @@
+--source include/have_simple_parser.inc
+
+#
+# BUG#39746 - Debug flag breaks struct definition (server crash)
+#
+INSTALL PLUGIN simple_parser SONAME 'mypluglib.so';
+CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a) WITH PARSER simple_parser);
+ALTER TABLE t1 ADD FULLTEXT(b) WITH PARSER simple_parser;
+DROP TABLE t1;
+UNINSTALL PLUGIN simple_parser;
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-12-09 13:31:22 +0000
+++ b/sql/sql_table.cc 2008-12-17 13:24:34 +0000
@@ -5870,7 +5870,7 @@ mysql_prepare_alter_table(THD *thd, TABL
if (key_info->flags & HA_USES_BLOCK_SIZE)
key_create_info.block_size= key_info->block_size;
if (key_info->flags & HA_USES_PARSER)
- key_create_info.parser_name= *key_info->parser_name;
+ key_create_info.parser_name= *plugin_name(key_info->parser);
if (key_info->flags & HA_SPATIAL)
key_type= Key::SPATIAL;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2008-11-29 13:36:17 +0000
+++ b/sql/table.cc 2008-12-17 13:24:34 +0000
@@ -400,6 +400,8 @@ void init_tmp_table_share(THD *thd, TABL
void free_table_share(TABLE_SHARE *share)
{
MEM_ROOT mem_root;
+ uint idx;
+ KEY *key_info;
DBUG_ENTER("free_table_share");
DBUG_PRINT("enter", ("table: %s.%s", share->db.str, share->table_name.str));
DBUG_ASSERT(share->ref_count == 0);
@@ -426,6 +428,16 @@ void free_table_share(TABLE_SHARE *share
plugin_unlock(NULL, share->db_plugin);
share->db_plugin= NULL;
+ /* Release fulltext parsers */
+ key_info= share->key_info;
+ for (idx= share->keys; idx; idx--, key_info++)
+ {
+ if (key_info->flags & HA_USES_PARSER)
+ {
+ plugin_unlock(NULL, key_info->parser);
+ key_info->flags= 0;
+ }
+ }
/* We must copy mem_root from share because share is allocated through it */
memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root));
free_root(&mem_root, MYF(0)); // Free's share
@@ -1943,22 +1955,11 @@ partititon_err:
int closefrm(register TABLE *table, bool free_share)
{
int error=0;
- uint idx;
- KEY *key_info;
DBUG_ENTER("closefrm");
DBUG_PRINT("enter", ("table: 0x%lx", (long) table));
if (table->db_stat)
error=table->file->close();
- key_info= table->key_info;
- for (idx= table->s->keys; idx; idx--, key_info++)
- {
- if (key_info->flags & HA_USES_PARSER)
- {
- plugin_unlock(NULL, key_info->parser);
- key_info->flags= 0;
- }
- }
my_free((char*) table->alias, MYF(MY_ALLOW_ZERO_PTR));
table->alias= 0;
if (table->field)