summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/DB.pm25
-rw-r--r--Bugzilla/DB/Mysql.pm13
-rw-r--r--Bugzilla/Search.pm6
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<sql_>. All other methods have prefix C<bz_>.
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<sql_istrcmp>
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";