Page MenuHomePhabricator

D20298.id.diff
No OneTemporary

D20298.id.diff

diff --git a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
--- a/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
+++ b/src/infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php
@@ -83,6 +83,13 @@
$this->applyExternalCursorConstraintsToQuery($query, $cursor);
+ // If we have a Ferret fulltext query, copy it to the subquery so that we
+ // generate ranking columns appropriately, and compute the correct object
+ // ranking score for the current query.
+ if ($this->ferretEngine) {
+ $query->withFerretConstraint($this->ferretEngine, $this->ferretTokens);
+ }
+
// We're executing the subquery normally to make sure the viewer can
// actually see the object, and that it's a completely valid object which
// passes all filtering and policy checks. You aren't allowed to use an
@@ -204,6 +211,19 @@
get_class($this)));
}
+ if ($this->supportsFerretEngine()) {
+ if ($this->getFerretTokens()) {
+ $map += array(
+ 'rank' =>
+ $cursor->getRawRowProperty(self::FULLTEXT_RANK),
+ 'fulltext-modified' =>
+ $cursor->getRawRowProperty(self::FULLTEXT_MODIFIED),
+ 'fulltext-created' =>
+ $cursor->getRawRowProperty(self::FULLTEXT_CREATED),
+ );
+ }
+ }
+
foreach ($keys as $key) {
if (!array_key_exists($key, $map)) {
throw new Exception(
@@ -295,6 +315,8 @@
}
protected function didLoadRawRows(array $rows) {
+ $this->rawCursorRow = last($rows);
+
if ($this->ferretEngine) {
foreach ($rows as $row) {
$phid = $row['phid'];
@@ -312,8 +334,6 @@
}
}
- $this->rawCursorRow = last($rows);
-
return $rows;
}
@@ -467,7 +487,7 @@
*/
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = array();
- $where[] = $this->buildPagingClause($conn);
+ $where[] = $this->buildPagingWhereClause($conn);
$where[] = $this->buildEdgeLogicWhereClause($conn);
$where[] = $this->buildSpacesWhereClause($conn);
$where[] = $this->buildNgramsWhereClause($conn);
@@ -482,6 +502,7 @@
*/
protected function buildHavingClause(AphrontDatabaseConnection $conn) {
$having = $this->buildHavingClauseParts($conn);
+ $having[] = $this->buildPagingHavingClause($conn);
return $this->formatHavingClause($conn, $having);
}
@@ -539,6 +560,45 @@
/* -( Paging )------------------------------------------------------------- */
+ private function buildPagingWhereClause(AphrontDatabaseConnection $conn) {
+ if ($this->shouldPageWithHavingClause()) {
+ return null;
+ }
+
+ return $this->buildPagingClause($conn);
+ }
+
+ private function buildPagingHavingClause(AphrontDatabaseConnection $conn) {
+ if (!$this->shouldPageWithHavingClause()) {
+ return null;
+ }
+
+ return $this->buildPagingClause($conn);
+ }
+
+ private function shouldPageWithHavingClause() {
+ // If any of the paging conditions reference dynamic columns, we need to
+ // put the paging conditions in a "HAVING" clause instead of a "WHERE"
+ // clause.
+
+ // For example, this happens when paging on the Ferret "rank" column,
+ // since the "rank" value is computed dynamically in the SELECT statement.
+
+ $orderable = $this->getOrderableColumns();
+ $vector = $this->getOrderVector();
+
+ foreach ($vector as $order) {
+ $key = $order->getOrderKey();
+ $column = $orderable[$key];
+
+ if (!empty($column['having'])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/**
* @task paging
*/
@@ -655,6 +715,8 @@
'reverse' => 'optional bool',
'unique' => 'optional bool',
'null' => 'optional string|null',
+ 'requires-ferret' => 'optional bool',
+ 'having' => 'optional bool',
));
}
@@ -1106,6 +1168,7 @@
'column' => self::FULLTEXT_RANK,
'type' => 'int',
'requires-ferret' => true,
+ 'having' => true,
);
$columns['fulltext-created'] = array(
'table' => null,

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 14, 2:49 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7642054
Default Alt Text
D20298.id.diff (4 KB)

Event Timeline