From 532330b91599785ea69d8682f9c4db2373c13dfa Mon Sep 17 00:00:00 2001 From: vfilippov Date: Tue, 24 Dec 2013 11:38:12 +0000 Subject: [PATCH] Bug 142119 - Support SphinxSE (needs MySQL support) git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@1893 6955db30-a419-402b-8a0d-67ecbb4d7f56 --- Bugzilla/DB.pm | 2 ++ Bugzilla/Install/DB.pm | 27 +++++++++++++++++++++++---- Bugzilla/Install/Localconfig.pm | 8 ++++++++ Bugzilla/Search.pm | 24 +++++++++++++++++------- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 28edb5c4d..e8b32927a 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -107,6 +107,7 @@ sub connect_sphinx my $host = $lc->{sphinx_host}; my $port = $lc->{sphinx_port}; my $sock = $lc->{sphinx_sock}; + $host = '' if $sock; my $dsn = "dbi:mysql:host=$host;database=none"; $dsn .= ";port=$port" if $port; @@ -116,6 +117,7 @@ sub connect_sphinx mysql_enable_utf8 => 1, # Needs to be explicitly specified for command-line processes. mysql_auto_reconnect => 1, + raise_error => 0, }); $sphinx->do("SET NAMES utf8"); diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index 327e89a73..93306d359 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -3287,21 +3287,40 @@ sub _populate_bugs_fulltext $bug_ids = undef if $bug_ids && !@$bug_ids; my $dbh = Bugzilla->dbh; # These vary between different fulltext search engines (MySQL, Sphinx) - my ($table, $limit1, $id_field, $quote, $sph) = ('bugs_fulltext', $dbh->sql_limit(1), 'bug_id', 'quote_fulltext', $dbh); + my ($table, $id_field, $quote, $sph) = ('bugs_fulltext', 'bug_id', 'quote_fulltext', $dbh); + my $nonempty; if (Bugzilla->localconfig->{sphinx_index}) { $sph = Bugzilla->dbh_sphinx; - $limit1 = 'LIMIT 1'; $table = Bugzilla->localconfig->{sphinx_index}; $id_field = 'id'; $quote = 'quote'; + # Sphinx can't do fullscan for index without attributes, + # so we check if the index is empty by trying to insert a MAX_INT id + $sph->{PrintError} = 0; + $nonempty = !$sph->do("INSERT INTO $table (id) VALUES (-1)"); + $sph->{PrintError} = 1; + if (my $conn = Bugzilla->localconfig->{sphinxse_port}) + { + $conn = "sphinx://".Bugzilla->localconfig->{sphinx_host}.':'.Bugzilla->localconfig->{sphinxse_port}.'/'.$table; + $dbh->do("DROP TABLE IF EXISTS bugs_fulltext_sphinx"); + $dbh->do("CREATE TABLE bugs_fulltext_sphinx (". + "id BIGINT NOT NULL, ". + "`weight` INT NOT NULL, ". + "`query` VARCHAR(3072) NOT NULL, ". + "INDEX(`query`)". + ") ENGINE=SPHINX CONNECTION='$conn'"); + } + } + else + { + $nonempty = $sph->selectrow_array("SELECT $id_field FROM $table ".$dbh->sql_limit(1)); } - my $fulltext = $sph->selectrow_array("SELECT $id_field FROM $table $limit1"); my ($datasize, $time) = (0, time); my ($lastdata, $lasttime) = ($datasize, $time); # We only populate the table if it's empty or if we've been given a # set of bug ids. - if ($bug_ids || !$fulltext) + if ($bug_ids || !$nonempty) { # ... and if there are bugs in the bugs table. $bug_ids ||= $dbh->selectcol_arrayref("SELECT bug_id FROM bugs"); diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm index 38d8b697c..7ad24d764 100644 --- a/Bugzilla/Install/Localconfig.pm +++ b/Bugzilla/Install/Localconfig.pm @@ -174,6 +174,14 @@ EOT default => '', desc => "# Sphinx UNIX socket (listening MySQL protocol)\n", }, + { + name => 'sphinxse_port', + default => 0, + desc => < 'db_check', default => 1, diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 1c19bc449..f8fbe41a6 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -2135,14 +2135,12 @@ sub _content_matches { my $self = shift; + my $dbh = Bugzilla->dbh; + my $table = "bugs_fulltext_".$self->{sequence}; my $text = $self->{value}; if (my $index = Bugzilla->localconfig->{sphinx_index}) { - # Using Sphinx - my $sph = Bugzilla->dbh_sphinx; - my $query = 'SELECT id, WEIGHT() `weight` FROM '.$index. - ' WHERE MATCH(?) LIMIT 1000 OPTION field_weights=(short_desc=5, comments=1, comments_private=1)'; # Escape search query my $pattern_part = '\[\]:\(\)!@~&\/^$'; $text = trim($text); @@ -2154,6 +2152,21 @@ sub _content_matches } $text =~ s/((?:^|[^\\])(?:\\\\)*)([$pattern_part])/$1\\$2/gs; $text = ($self->{user}->is_insider ? '@(short_desc,comments,comments_private) ' : '@(short_desc,comments) ') . $text; + if (Bugzilla->localconfig->{sphinxse_port}) + { + # Using SphinxSE + $text =~ s/;/\\\\;/gso; + $self->{term} = { + table => "bugs_fulltext_sphinx $table", + where => "$table.query=".$dbh->quote("$text;mode=extended;limit=1000;fieldweights=short_desc,5,comments,1,comments_private,1"), + bugid_field => "$table.id", + }; + return; + } + # Using SphinxQL + my $sph = Bugzilla->dbh_sphinx; + my $query = 'SELECT `id`, WEIGHT() `weight` FROM '.$index. + ' WHERE MATCH(?) LIMIT 1000 OPTION field_weights=(short_desc=5, comments=1, comments_private=1)'; my $ids = $sph->selectall_arrayref($query, undef, $text) || []; $self->{term} = { term => @$ids ? 'bugs.bug_id IN ('.join(', ', map { $_->[0] } @$ids).')' : '1=0', @@ -2167,9 +2180,6 @@ sub _content_matches return; } - my $dbh = Bugzilla->dbh; - my $table = "bugs_fulltext_".$self->{sequence}; - # Create search terms to add to the SELECT and WHERE clauses. # These are (search term, rank term, search term, rank term, ...) my @terms = (