1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 16:52:41 +01:00

Select Ferret fulltext columns in results so fulltext queries work under UNION

Summary:
Ref T13091. In Differential, if you provide a query and "Sort by: Relevance", we build a query like this:

```
((SELECT revision.* FROM ... ORDER BY rank) UNION ALL (SELECT revision.* FROM ... ORDER BY rank)) ORDER BY rank
```

The internal "ORDER BY rank" is technically redundant (probably?), but doesn't hurt anything, and makes construction easier.

The problem is that the outer "ORDER BY rank" at the end, which attempts to order the results of the two parts of the UNION, can't actually order them, since `rank` wasn't selected.

(The column isn't actually "rank", which //is// selected -- it's the document modified/created subcolumns, which are not.)

To fix this, actually select the fulltext columns into the result set.

Test Plan:
  - Ran a non-empty fulltext query in Differential with "Bucket: Required Action" selected so the UNION construction fired.
  - Ran normal queries in Maniphest and global search.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13091

Differential Revision: https://secure.phabricator.com/D20297
This commit is contained in:
epriestley 2019-03-18 16:03:28 -07:00
parent a8ba8217d8
commit b90e02bec2

View file

@ -37,6 +37,10 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
private $ferretQuery;
private $ferretMetadata = array();
const FULLTEXT_RANK = '_ft_rank';
const FULLTEXT_MODIFIED = '_ft_epochModified';
const FULLTEXT_CREATED = '_ft_epochCreated';
/* -( Cursors )------------------------------------------------------------ */
protected function newExternalCursorStringForResult($object) {
@ -298,11 +302,13 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$metadata = id(new PhabricatorFerretMetadata())
->setPHID($phid)
->setEngine($this->ferretEngine)
->setRelevance(idx($row, '_ft_rank'));
->setRelevance(idx($row, self::FULLTEXT_RANK));
$this->ferretMetadata[$phid] = $metadata;
unset($row['_ft_rank']);
unset($row[self::FULLTEXT_RANK]);
unset($row[self::FULLTEXT_MODIFIED]);
unset($row[self::FULLTEXT_CREATED]);
}
}
@ -1097,19 +1103,19 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
if ($this->supportsFerretEngine()) {
$columns['rank'] = array(
'table' => null,
'column' => '_ft_rank',
'column' => self::FULLTEXT_RANK,
'type' => 'int',
'requires-ferret' => true,
);
$columns['fulltext-created'] = array(
'table' => 'ft_doc',
'column' => 'epochCreated',
'table' => null,
'column' => self::FULLTEXT_CREATED,
'type' => 'int',
'requires-ferret' => true,
);
$columns['fulltext-modified'] = array(
'table' => 'ft_doc',
'column' => 'epochModified',
'table' => null,
'column' => self::FULLTEXT_MODIFIED,
'type' => 'int',
'requires-ferret' => true,
);
@ -1779,7 +1785,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
}
if (!$this->ferretEngine) {
$select[] = qsprintf($conn, '0 _ft_rank');
$select[] = qsprintf($conn, '0 AS %T', self::FULLTEXT_RANK);
return $select;
}
@ -1858,8 +1864,27 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$select[] = qsprintf(
$conn,
'%Q _ft_rank',
$sum);
'%Q AS %T',
$sum,
self::FULLTEXT_RANK);
// See D20297. We select these as real columns in the result set so that
// constructions like this will work:
//
// ((SELECT ...) UNION (SELECT ...)) ORDER BY ...
//
// If the columns aren't part of the result set, the final "ORDER BY" can
// not act on them.
$select[] = qsprintf(
$conn,
'ft_doc.epochCreated AS %T',
self::FULLTEXT_CREATED);
$select[] = qsprintf(
$conn,
'ft_doc.epochModified AS %T',
self::FULLTEXT_MODIFIED);
return $select;
}