From 5a7981bbfcf51569e5f59fd75d89ea838f681e75 Mon Sep 17 00:00:00 2001 From: "myk%mozilla.org" <> Date: Fri, 15 Jul 2005 09:05:08 +0000 Subject: Fix for bug 232612: enables boolean mode fulltext searches for better searching capabilities in the "Find a Specific Bug" page; r=lpsolit --- Bugzilla/DB.pm | 25 +++++++++++++------------ Bugzilla/DB/Mysql.pm | 13 ++++++++++++- Bugzilla/Search.pm | 6 ++---- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 76e090d6c..f3b9e4ed9 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -257,22 +257,23 @@ sub sql_fulltext_search { # This is as close as we can get to doing full text search using # standard ANSI SQL, without real full text search support. DB specific - # modules shoud override this, as this will be always much slower. - - # the text is already sql-quoted, so we need to remove the quotes first - my $quote = substr($self->quote(''), 0, 1); - $text = $1 if ($text =~ /^$quote(.*)$quote$/); + # modules should override this, as this will be always much slower. # make the string lowercase to do case insensitive search my $lower_text = lc($text); - # split the text we search for to separate words + # split the text we search for into separate words my @words = split(/\s+/, $lower_text); - # search for occurence of all specified words in the column - return "CASE WHEN (LOWER($column) LIKE ${quote}%" . - join("%${quote} AND LOWER($column) LIKE ${quote}%", @words) . - "%${quote}) THEN 1 ELSE 0 END"; + # surround the words with wildcards and SQL quotes so we can use them + # in LIKE search clauses + @words = map($self->quote("%$_%"), @words); + + # turn the words into a set of LIKE search clauses + @words = map("LOWER($column) LIKE $_", @words); + + # search for occurrences of all specified words in the column + return "CASE WHEN (" . join(" AND ", @words) . ") THEN 1 ELSE 0 END"; } ##################################################################### @@ -1159,12 +1160,12 @@ formatted SQL command have prefix C. All other methods have prefix C. specified text on a given column. There is a ANSI SQL version of this method implemented using LIKE operator, but it's not a real full text search. DB specific - modules shoud override this, as this generic implementation will + modules should override this, as this generic implementation will be always much slower. This generic implementation returns 'relevance' as 0 for no match, or 1 for a match. Params: $column = name of column to search (scalar) $text = text to search for (scalar) - Returns: formatted SQL for for full text search + Returns: formatted SQL for full text search =item C diff --git a/Bugzilla/DB/Mysql.pm b/Bugzilla/DB/Mysql.pm index 77127630c..25c3d5f3d 100644 --- a/Bugzilla/DB/Mysql.pm +++ b/Bugzilla/DB/Mysql.pm @@ -42,6 +42,7 @@ package Bugzilla::DB::Mysql; use strict; +use Bugzilla::Util; use Bugzilla::Error; # This module extends the DB interface via inheritance @@ -108,7 +109,17 @@ sub sql_string_concat { sub sql_fulltext_search { my ($self, $column, $text) = @_; - return "MATCH($column) AGAINST($text)"; + # Add the boolean mode modifier if the search string contains + # boolean operators. + my $mode = ($text =~ /[+-<>()~*"]/ ? "IN BOOLEAN MODE" : ""); + + # quote the text for use in the MATCH AGAINST expression + $text = $self->quote($text); + + # untaint the text, since it's safe to use now that we've quoted it + trick_taint($text); + + return "MATCH($column) AGAINST($text $mode)"; } sub sql_istring { diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 710334049..96f38fc06 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -582,10 +582,8 @@ sub init { # $term1 searches comments. # $term2 searches summaries, which contributes to the relevance # ranking in SELECT but doesn't limit which bugs get retrieved. - my $term1 = $dbh->sql_fulltext_search("${table}.thetext", - ::SqlQuote($v)); - my $term2 = $dbh->sql_fulltext_search("bugs.short_desc", - ::SqlQuote($v)); + my $term1 = $dbh->sql_fulltext_search("${table}.thetext", $v); + my $term2 = $dbh->sql_fulltext_search("bugs.short_desc", $v); # The term to use in the WHERE clause. $term = "$term1 > 0"; -- cgit v1.2.3-24-g4f1b