mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Fix a fulltext search issue where finding token length and stopwords could fail
Summary: Ref T12137. If a database is missing the InnoDB or MyISAM table engines, the big combined query to get both will fail. Instead, try InnoDB first and then MyISAM. (I have both engines locally so this worked until I deployed it.) Test Plan: Faked an InnoDB error like `secure`, got a MyISAM result. Reviewers: chad Reviewed By: chad Maniphest Tasks: T12137 Differential Revision: https://secure.phabricator.com/D17673
This commit is contained in:
parent
3245e74f16
commit
ada9046e31
1 changed files with 40 additions and 27 deletions
|
@ -473,43 +473,56 @@ final class PhabricatorMySQLFulltextStorageEngine
|
|||
}
|
||||
|
||||
private function newEngineLimits(AphrontDatabaseConnection $conn) {
|
||||
$result = queryfx_one(
|
||||
$conn,
|
||||
'SELECT
|
||||
@@innodb_ft_min_token_size innodb_max,
|
||||
@@ft_min_word_len myisam_max,
|
||||
@@ft_stopword_file myisam_stopwords');
|
||||
// First, try InnoDB. Some database may not have both table engines, so
|
||||
// selecting variables from missing table engines can fail and throw.
|
||||
|
||||
if ($result['innodb_max']) {
|
||||
try {
|
||||
$result = queryfx_one(
|
||||
$conn,
|
||||
'SELECT @@innodb_ft_min_token_size innodb_max');
|
||||
} catch (AphrontQueryException $ex) {
|
||||
$result = null;
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
$min_len = $result['innodb_max'];
|
||||
$stopwords = queryfx_all(
|
||||
$conn,
|
||||
'SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD');
|
||||
$stopwords = ipull($stopwords, 'value');
|
||||
$stopwords = array_fuse($stopwords);
|
||||
} else {
|
||||
$min_len = $result['myisam_max'];
|
||||
|
||||
$file = $result['myisam_stopwords'];
|
||||
if (preg_match('(/resources/sql/stopwords\.txt\z)', $file)) {
|
||||
// If this is set to something that looks like the Phabricator
|
||||
// stopword file, read that.
|
||||
$file = 'stopwords.txt';
|
||||
} else {
|
||||
// Otherwise, just use the default stopwords. This might be wrong
|
||||
// but we can't read the actual value dynamically and reading
|
||||
// whatever file the variable is set to could be a big headache
|
||||
// to get right from a security perspective.
|
||||
$file = 'stopwords_myisam.txt';
|
||||
}
|
||||
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
$data = Filesystem::readFile($root.'/resources/sql/'.$file);
|
||||
$stopwords = explode("\n", $data);
|
||||
$stopwords = array_filter($stopwords);
|
||||
$stopwords = array_fuse($stopwords);
|
||||
return array($min_len, $stopwords);
|
||||
}
|
||||
|
||||
// If InnoDB fails, try MyISAM.
|
||||
$result = queryfx_one(
|
||||
$conn,
|
||||
'SELECT
|
||||
@@ft_min_word_len myisam_max,
|
||||
@@ft_stopword_file myisam_stopwords');
|
||||
|
||||
$min_len = $result['myisam_max'];
|
||||
|
||||
$file = $result['myisam_stopwords'];
|
||||
if (preg_match('(/resources/sql/stopwords\.txt\z)', $file)) {
|
||||
// If this is set to something that looks like the Phabricator
|
||||
// stopword file, read that.
|
||||
$file = 'stopwords.txt';
|
||||
} else {
|
||||
// Otherwise, just use the default stopwords. This might be wrong
|
||||
// but we can't read the actual value dynamically and reading
|
||||
// whatever file the variable is set to could be a big headache
|
||||
// to get right from a security perspective.
|
||||
$file = 'stopwords_myisam.txt';
|
||||
}
|
||||
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
$data = Filesystem::readFile($root.'/resources/sql/'.$file);
|
||||
$stopwords = explode("\n", $data);
|
||||
$stopwords = array_filter($stopwords);
|
||||
$stopwords = array_fuse($stopwords);
|
||||
|
||||
return array($min_len, $stopwords);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue