1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-23 07:12:41 +01:00

Use PhutilQueryCompiler in Phabricator fulltext search

Summary:
Ref T11741. Fixes T10642. Parse and compile user queries with a consistent ruleset, then submit queries to the backend using whatever ruleset MySQL is configured with.

This means that `ft_boolean_syntax` no longer needs to be configured (we'll just do the right thing in all cases).

This should improve behavior with RDS immediately (T10642), and allow us to improve behavior with InnoDB in the future (T11741).

Test Plan:
  - Ran various queries in the UI, saw the expected results.
  - Ran bad queries, got useful errors.
  - Searched threads in Conpherence.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10642, T11741

Differential Revision: https://secure.phabricator.com/D16939
This commit is contained in:
epriestley 2016-11-24 08:13:38 -08:00
parent eac49e421a
commit a956047989
5 changed files with 33 additions and 40 deletions

View file

@ -248,44 +248,6 @@ final class PhabricatorMySQLSetupCheck extends PhabricatorSetupCheck {
} }
} }
$bool_syntax = $ref->loadRawMySQLConfigValue('ft_boolean_syntax');
if ($bool_syntax != ' |-><()~*:""&^') {
if ($this->shouldUseMySQLSearchEngine()) {
$summary = pht(
'MySQL (on host "%s") is configured to search on fulltext indexes '.
'using "OR" by default. Using "AND" is usually the desired '.
'behaviour.',
$host_name);
$message = pht(
"Database host \"%s\" is configured to use the default Boolean ".
"search syntax when using fulltext indexes. This means searching ".
"for 'search words' will yield the query 'search OR words' ".
"instead of the desired 'search AND words'.\n\n".
"This might produce unexpected search results. \n\n".
"You can change this setting to a more sensible default. ".
"Alternatively, you can ignore this warning if ".
"using 'OR' is the desired behaviour. If you later plan ".
"to configure ElasticSearch, you can also ignore this warning: ".
"only MySQL fulltext search is affected.\n\n".
"To change this setting, add this to your %s file ".
"(in the %s section) and then restart %s:\n\n".
"%s\n",
$host_name,
phutil_tag('tt', array(), 'my.cnf'),
phutil_tag('tt', array(), '[mysqld]'),
phutil_tag('tt', array(), 'mysqld'),
phutil_tag('pre', array(), 'ft_boolean_syntax=\' |-><()~*:""&^\''));
$this->newIssue('mysql.ft_boolean_syntax')
->setName(pht('MySQL is Using the Default Boolean Syntax'))
->setSummary($summary)
->setMessage($message)
->setDatabaseRef($ref)
->addMySQLConfig('ft_boolean_syntax');
}
}
$innodb_pool = $ref->loadRawMySQLConfigValue('innodb_buffer_pool_size'); $innodb_pool = $ref->loadRawMySQLConfigValue('innodb_buffer_pool_size');
$innodb_bytes = phutil_parse_bytes($innodb_pool); $innodb_bytes = phutil_parse_bytes($innodb_pool);
$innodb_readable = phutil_format_bytes($innodb_bytes); $innodb_readable = phutil_format_bytes($innodb_bytes);

View file

@ -56,10 +56,14 @@ final class ConpherenceFulltextQuery
} }
if (strlen($this->fulltext)) { if (strlen($this->fulltext)) {
$compiled_query = PhabricatorSearchDocument::newQueryCompiler()
->setQuery($this->fulltext)
->compileQuery();
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn_r,
'MATCH(i.corpus) AGAINST (%s IN BOOLEAN MODE)', 'MATCH(i.corpus) AGAINST (%s IN BOOLEAN MODE)',
$this->fulltext); $compiled_query);
} }
return $this->formatWhereClause($where); return $this->formatWhereClause($where);

View file

@ -317,6 +317,8 @@ final class PhabricatorApplicationSearchController
$exec_errors[] = pht( $exec_errors[] = pht(
'This query specifies an invalid parameter. Review the '. 'This query specifies an invalid parameter. Review the '.
'query parameters and correct errors.'); 'query parameters and correct errors.');
} catch (PhutilSearchQueryCompilerSyntaxException $ex) {
$exec_errors[] = $ex->getMessage();
} }
// The engine may have encountered additional errors during rendering; // The engine may have encountered additional errors during rendering;

View file

@ -165,7 +165,8 @@ final class PhabricatorMySQLFulltextStorageEngine
$conn_r = $dao_doc->establishConnection('r'); $conn_r = $dao_doc->establishConnection('r');
$q = $query->getParameter('query'); $raw_query = $query->getParameter('query');
$q = $this->compileQuery($raw_query);
if (strlen($q)) { if (strlen($q)) {
$join[] = qsprintf( $join[] = qsprintf(
@ -351,6 +352,14 @@ final class PhabricatorMySQLFulltextStorageEngine
return $sql; return $sql;
} }
private function compileQuery($raw_query) {
$compiler = PhabricatorSearchDocument::newQueryCompiler();
return $compiler
->setQuery($raw_query)
->compileQuery();
}
public function indexExists() { public function indexExists() {
return true; return true;
} }

View file

@ -37,4 +37,20 @@ final class PhabricatorSearchDocument extends PhabricatorSearchDAO {
return 'phid'; return 'phid';
} }
public static function newQueryCompiler() {
$table = new self();
$conn = $table->establishConnection('r');
$compiler = new PhutilSearchQueryCompiler();
$operators = queryfx_one(
$conn,
'SELECT @@ft_boolean_syntax AS syntax');
if ($operators) {
$compiler->setOperators($operators['syntax']);
}
return $compiler;
}
} }