From 556de62f8da2c1cf6c1656efd2f903f01250e01d Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Fri, 30 Mar 2007 13:00:21 +0500 Subject: [PATCH 1/2] BUG#26138 - REPAIR TABLE with option USE_FRM erases all records in ARCHIVE table ARCHIVE table was truncated by REPAIR TABLE ... USE_FRM statement. The table handler returned its file name extensions in a wrong order. REPAIR TABLE believed it has to use the meta file to create a new table from it. With the fixed order, REPAIR TABLE does now use the data file to create a new table. So REPAIR TABLE ... USE_FRM works well with ARCHIVE engine now. This issue affects 5.0 only, since in 5.1 ARCHIVE engine stores meta information and data in the same file. --- mysql-test/r/archive.result | 9 +++++++++ mysql-test/t/archive.test | 10 ++++++++++ sql/examples/ha_example.cc | 6 ++++++ sql/ha_archive.cc | 2 +- sql/handler.h | 11 +++++++++++ sql/sql_table.cc | 4 +++- 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index f73a80dde65..d89cecedcdd 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12355,3 +12355,12 @@ auto fld1 companynr fld3 fld4 fld5 4 011403 37 intercepted audiology tinily 4 011403 37 intercepted audiology tinily drop table t1, t2, t4; +create table t1 (i int) engine=archive; +insert into t1 values (1); +repair table t1 use_frm; +Table Op Msg_type Msg_text +test.t1 repair status OK +select * from t1; +i +1 +drop table t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 80533f21311..0ffbfab3d4f 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1364,3 +1364,13 @@ SELECT * from t2; drop table t1, t2, t4; + +# +# BUG#26138 - REPAIR TABLE with option USE_FRM erases all records in ARCHIVE +# table +# +create table t1 (i int) engine=archive; +insert into t1 values (1); +repair table t1 use_frm; +select * from t1; +drop table t1; diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index 19c686ee495..d59ada3b445 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -211,6 +211,12 @@ ha_example::ha_example(TABLE *table_arg) If frm_error() is called then we will use this to to find out what file extentions exist for the storage engine. This is also used by the default rename_table and delete_table method in handler.cc. + + For engines that have two file name extentions (separate meta/index file + and data file), the order of elements is relevant. First element of engine + file name extentions array should be meta/index file extention. Second + element - data file extention. This order is assumed by + prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. */ static const char *ha_example_exts[] = { NullS diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index 2ee514f29c9..e2a2211259f 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -503,8 +503,8 @@ int ha_archive::init_archive_writer() We just implement one additional file extension. */ static const char *ha_archive_exts[] = { - ARZ, ARM, + ARZ, NullS }; diff --git a/sql/handler.h b/sql/handler.h index 9e381ca4482..9863d541b5f 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -780,6 +780,17 @@ public: virtual void free_foreign_key_create_info(char* str) {} /* The following can be called without an open handler */ virtual const char *table_type() const =0; + /* + If frm_error() is called then we will use this to find out what file + extentions exist for the storage engine. This is also used by the default + rename_table and delete_table method in handler.cc. + + For engines that have two file name extentions (separate meta/index file + and data file), the order of elements is relevant. First element of engine + file name extentions array should be meta/index file extention. Second + element - data file extention. This order is assumed by + prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. + */ virtual const char **bas_ext() const =0; virtual ulong table_flags(void) const =0; virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c75aff7fab6..fb377971630 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2068,7 +2068,9 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, /* Check if this is a table type that stores index and data separately, - like ISAM or MyISAM + like ISAM or MyISAM. We assume fixed order of engine file name + extentions array. First element of engine file name extentions array + is meta/index file extention. Second element - data file extention. */ if (!ext[0] || !ext[1]) goto end; // No data file From 27d9265c26888c063c91382d5096ccfc12156262 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Mon, 2 Apr 2007 17:26:39 +0500 Subject: [PATCH 2/2] BUG#25729 - boolean full text search is confused by NULLs produced by LEFT JOIN Fixed that in certain situations MATCH ... AGAINST returns false hits for NULLs produced by LEFT JOIN when there is no fulltext index available. --- mysql-test/r/fulltext_left_join.result | 7 +++++++ mysql-test/t/fulltext_left_join.test | 11 +++++++++++ sql/item_func.cc | 8 ++++---- sql/item_func.h | 8 ++++---- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result index fdf11c14cc4..ea4cacf2fab 100644 --- a/mysql-test/r/fulltext_left_join.result +++ b/mysql-test/r/fulltext_left_join.result @@ -90,3 +90,10 @@ id link name relevance 1 1 string 0 2 0 string 0 DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c TEXT, KEY(b)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle'); +SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE); +a b c +DROP TABLE t1, t2; diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test index 5942ce119ee..8c13ae5cad9 100644 --- a/mysql-test/t/fulltext_left_join.test +++ b/mysql-test/t/fulltext_left_join.test @@ -87,3 +87,14 @@ SELECT t1.*, MATCH(t1.name) AGAINST('string') AS relevance DROP TABLE t1,t2; # End of 4.1 tests + +# +# BUG#25729 - boolean full text search is confused by NULLs produced by LEFT +# JOIN +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c TEXT, KEY(b)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle'); +SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE); +DROP TABLE t1, t2; diff --git a/sql/item_func.cc b/sql/item_func.cc index 32cc90b96d6..34122631fe3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4597,14 +4597,14 @@ void Item_func_match::init_search(bool no_order) fields.push_back(new Item_string(" ",1, cmp_collation.collation)); for (uint i=1; i < arg_count; i++) fields.push_back(args[i]); - concat=new Item_func_concat_ws(fields); + concat_ws=new Item_func_concat_ws(fields); /* Above function used only to get value and do not need fix_fields for it: Item_string - basic constant fields - fix_fields() was already called for this arguments Item_func_concat_ws - do not need fix_fields() to produce value */ - concat->quick_fix_field(); + concat_ws->quick_fix_field(); } if (master) @@ -4819,8 +4819,8 @@ double Item_func_match::val_real() if (key == NO_SUCH_KEY) { - String *a= concat->val_str(&value); - if ((null_value= (a == 0))) + String *a= concat_ws->val_str(&value); + if ((null_value= (a == 0)) || !a->length()) DBUG_RETURN(0); DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, (byte *)a->ptr(), a->length())); diff --git a/sql/item_func.h b/sql/item_func.h index 68591f9c6f5..3f87d210431 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1308,12 +1308,12 @@ public: FT_INFO *ft_handler; TABLE *table; Item_func_match *master; // for master-slave optimization - Item *concat; // Item_func_concat_ws - String value; // value of concat + Item *concat_ws; // Item_func_concat_ws + String value; // value of concat_ws String search_value; // key_item()'s value converted to cmp_collation Item_func_match(List &a, uint b): Item_real_func(a), key(0), flags(b), - join_key(0), ft_handler(0), table(0), master(0), concat(0) { } + join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { } void cleanup() { DBUG_ENTER("Item_func_match"); @@ -1321,7 +1321,7 @@ public: if (!master && ft_handler) ft_handler->please->close_search(ft_handler); ft_handler= 0; - concat= 0; + concat_ws= 0; DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; }