summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormkanat%bugzilla.org <>2008-08-07 06:43:54 +0200
committermkanat%bugzilla.org <>2008-08-07 06:43:54 +0200
commit18d0e31a946e8e3d29eac2acda177d6c0af8a433 (patch)
tree5951fd37d0c131b965befb0313c288ee9c1ac9a7
parent70540fb131c58cf4fb012854759eef2d73528a30 (diff)
downloadbugzilla-18d0e31a946e8e3d29eac2acda177d6c0af8a433.tar.gz
bugzilla-18d0e31a946e8e3d29eac2acda177d6c0af8a433.tar.xz
Bug 446645: Properly escape and understand hyphenated words in fulltext searches when using MySQL
Patch By Jesse Clark <jjclark1982@gmail.com> r=mkanat, a=mkanat
-rw-r--r--Bugzilla/DB/Mysql.pm18
1 files changed, 16 insertions, 2 deletions
diff --git a/Bugzilla/DB/Mysql.pm b/Bugzilla/DB/Mysql.pm
index fdb475078..43646d8de 100644
--- a/Bugzilla/DB/Mysql.pm
+++ b/Bugzilla/DB/Mysql.pm
@@ -49,6 +49,7 @@ use Bugzilla::Error;
use Bugzilla::DB::Schema::Mysql;
use List::Util qw(max);
+use Text::ParseWords;
# This module extends the DB interface via inheritance
use base qw(Bugzilla::DB);
@@ -141,8 +142,21 @@ sub sql_fulltext_search {
my ($self, $column, $text) = @_;
# Add the boolean mode modifier if the search string contains
- # boolean operators.
- my $mode = ($text =~ /[+-<>()~*"]/ ? "IN BOOLEAN MODE" : "");
+ # boolean operators at the start or end of a word.
+ my $mode = '';
+ if ($text =~ /(?:^|\W)[+\-<>~"()]/ || $text =~ /[()"*](?:$|\W)/) {
+ $mode = 'IN BOOLEAN MODE';
+
+ # quote un-quoted compound words
+ my @words = quotewords('[\s()]+', 'delimiter', $text);
+ foreach my $word (@words) {
+ # match words that have word chars, non-word chars, and no quotes
+ if ($word =~ /\w/ && $word =~ m/\W/ && $word !~ m/"/) {
+ $word = '"' . $word . '"';
+ }
+ }
+ $text = join('', @words);
+ }
# quote the text for use in the MATCH AGAINST expression
$text = $self->quote($text);