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] 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; }