@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+39 -26
+39 -26
src/applications/search/fulltextstorage/PhabricatorMySQLFulltextStorageEngine.php
··· 473 473 } 474 474 475 475 private function newEngineLimits(AphrontDatabaseConnection $conn) { 476 - $result = queryfx_one( 477 - $conn, 478 - 'SELECT 479 - @@innodb_ft_min_token_size innodb_max, 480 - @@ft_min_word_len myisam_max, 481 - @@ft_stopword_file myisam_stopwords'); 476 + // First, try InnoDB. Some database may not have both table engines, so 477 + // selecting variables from missing table engines can fail and throw. 478 + 479 + try { 480 + $result = queryfx_one( 481 + $conn, 482 + 'SELECT @@innodb_ft_min_token_size innodb_max'); 483 + } catch (AphrontQueryException $ex) { 484 + $result = null; 485 + } 482 486 483 - if ($result['innodb_max']) { 487 + if ($result) { 484 488 $min_len = $result['innodb_max']; 485 489 $stopwords = queryfx_all( 486 490 $conn, 487 491 'SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD'); 488 492 $stopwords = ipull($stopwords, 'value'); 489 493 $stopwords = array_fuse($stopwords); 490 - } else { 491 - $min_len = $result['myisam_max']; 494 + 495 + return array($min_len, $stopwords); 496 + } 492 497 493 - $file = $result['myisam_stopwords']; 494 - if (preg_match('(/resources/sql/stopwords\.txt\z)', $file)) { 495 - // If this is set to something that looks like the Phabricator 496 - // stopword file, read that. 497 - $file = 'stopwords.txt'; 498 - } else { 499 - // Otherwise, just use the default stopwords. This might be wrong 500 - // but we can't read the actual value dynamically and reading 501 - // whatever file the variable is set to could be a big headache 502 - // to get right from a security perspective. 503 - $file = 'stopwords_myisam.txt'; 504 - } 498 + // If InnoDB fails, try MyISAM. 499 + $result = queryfx_one( 500 + $conn, 501 + 'SELECT 502 + @@ft_min_word_len myisam_max, 503 + @@ft_stopword_file myisam_stopwords'); 504 + 505 + $min_len = $result['myisam_max']; 505 506 506 - $root = dirname(phutil_get_library_root('phabricator')); 507 - $data = Filesystem::readFile($root.'/resources/sql/'.$file); 508 - $stopwords = explode("\n", $data); 509 - $stopwords = array_filter($stopwords); 510 - $stopwords = array_fuse($stopwords); 507 + $file = $result['myisam_stopwords']; 508 + if (preg_match('(/resources/sql/stopwords\.txt\z)', $file)) { 509 + // If this is set to something that looks like the Phabricator 510 + // stopword file, read that. 511 + $file = 'stopwords.txt'; 512 + } else { 513 + // Otherwise, just use the default stopwords. This might be wrong 514 + // but we can't read the actual value dynamically and reading 515 + // whatever file the variable is set to could be a big headache 516 + // to get right from a security perspective. 517 + $file = 'stopwords_myisam.txt'; 511 518 } 519 + 520 + $root = dirname(phutil_get_library_root('phabricator')); 521 + $data = Filesystem::readFile($root.'/resources/sql/'.$file); 522 + $stopwords = explode("\n", $data); 523 + $stopwords = array_filter($stopwords); 524 + $stopwords = array_fuse($stopwords); 512 525 513 526 return array($min_len, $stopwords); 514 527 }