Changeset View
Changeset View
Standalone View
Standalone View
src/applications/maniphest/query/ManiphestTaskQuery.php
Show First 20 Lines • Show All 397 Lines • ▼ Show 20 Lines | protected function loadPage() { | ||||
if ($this->subpriorityMax) { | if ($this->subpriorityMax) { | ||||
$where[] = qsprintf( | $where[] = qsprintf( | ||||
$conn, | $conn, | ||||
'task.subpriority <= %f', | 'task.subpriority <= %f', | ||||
$this->subpriorityMax); | $this->subpriorityMax); | ||||
} | } | ||||
$where[] = $this->buildPagingClause($conn); | $where[] = $this->buildWhereClauseParts($conn); | ||||
$where = $this->formatWhereClause($where); | $where = $this->formatWhereClause($where); | ||||
$having = ''; | |||||
$count = ''; | $count = ''; | ||||
if (count($this->projectPHIDs) > 1) { | if (count($this->projectPHIDs) > 1) { | ||||
// We want to treat the query as an intersection query, not a union | |||||
// query. We sum the project count and require it be the same as the | |||||
// number of projects we're searching for. | |||||
$count = ', COUNT(project.dst) projectCount'; | $count = ', COUNT(project.dst) projectCount'; | ||||
$having = qsprintf( | |||||
$conn, | |||||
'HAVING projectCount = %d', | |||||
count($this->projectPHIDs)); | |||||
} | } | ||||
$group_column = ''; | $group_column = ''; | ||||
switch ($this->groupBy) { | switch ($this->groupBy) { | ||||
case self::GROUP_PROJECT: | case self::GROUP_PROJECT: | ||||
$group_column = qsprintf( | $group_column = qsprintf( | ||||
$conn, | $conn, | ||||
', projectGroupName.indexedObjectPHID projectGroupPHID'); | ', projectGroupName.indexedObjectPHID projectGroupPHID'); | ||||
break; | break; | ||||
} | } | ||||
$rows = queryfx_all( | $rows = queryfx_all( | ||||
$conn, | $conn, | ||||
'SELECT task.* %Q %Q FROM %T task %Q %Q %Q %Q %Q %Q', | '%Q %Q %Q FROM %T task %Q %Q %Q %Q %Q %Q', | ||||
$this->buildSelectClause($conn), | |||||
$count, | $count, | ||||
$group_column, | $group_column, | ||||
$task_dao->getTableName(), | $task_dao->getTableName(), | ||||
$this->buildJoinsClause($conn), | $this->buildJoinClause($conn), | ||||
$where, | $where, | ||||
$this->buildGroupClause($conn), | $this->buildGroupClause($conn), | ||||
$having, | $this->buildHavingClause($conn), | ||||
$this->buildOrderClause($conn), | $this->buildOrderClause($conn), | ||||
$this->buildLimitClause($conn)); | $this->buildLimitClause($conn)); | ||||
switch ($this->groupBy) { | switch ($this->groupBy) { | ||||
case self::GROUP_PROJECT: | case self::GROUP_PROJECT: | ||||
$data = ipull($rows, null, 'id'); | $data = ipull($rows, null, 'id'); | ||||
break; | break; | ||||
default: | default: | ||||
▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | if (!$this->xprojectPHIDs) { | ||||
return null; | return null; | ||||
} | } | ||||
return qsprintf( | return qsprintf( | ||||
$conn, | $conn, | ||||
'xproject.dst IS NULL'); | 'xproject.dst IS NULL'); | ||||
} | } | ||||
private function buildJoinsClause(AphrontDatabaseConnection $conn_r) { | protected function buildJoinClauseParts(AphrontDatabaseConnection $conn_r) { | ||||
$edge_table = PhabricatorEdgeConfig::TABLE_NAME_EDGE; | $edge_table = PhabricatorEdgeConfig::TABLE_NAME_EDGE; | ||||
$joins = array(); | $joins = array(); | ||||
if ($this->projectPHIDs || $this->includeNoProject) { | if ($this->projectPHIDs || $this->includeNoProject) { | ||||
$joins[] = qsprintf( | $joins[] = qsprintf( | ||||
$conn_r, | $conn_r, | ||||
'%Q JOIN %T project ON project.src = task.phid | '%Q JOIN %T project ON project.src = task.phid | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | switch ($this->groupBy) { | ||||
$joins[] = qsprintf( | $joins[] = qsprintf( | ||||
$conn_r, | $conn_r, | ||||
'LEFT JOIN %T projectGroupName | 'LEFT JOIN %T projectGroupName | ||||
ON projectGroup.dst = projectGroupName.indexedObjectPHID', | ON projectGroup.dst = projectGroupName.indexedObjectPHID', | ||||
id(new ManiphestNameIndex())->getTableName()); | id(new ManiphestNameIndex())->getTableName()); | ||||
break; | break; | ||||
} | } | ||||
$joins[] = $this->buildApplicationSearchJoinClause($conn_r); | $joins[] = parent::buildJoinClauseParts($conn_r); | ||||
return implode(' ', $joins); | return $joins; | ||||
} | } | ||||
protected function buildGroupClause(AphrontDatabaseConnection $conn_r) { | protected function buildGroupClause(AphrontDatabaseConnection $conn_r) { | ||||
$joined_multiple_rows = (count($this->projectPHIDs) > 1) || | $joined_multiple_rows = (count($this->projectPHIDs) > 1) || | ||||
(count($this->anyProjectPHIDs) > 1) || | (count($this->anyProjectPHIDs) > 1) || | ||||
$this->shouldJoinBlockingTasks() || | $this->shouldJoinBlockingTasks() || | ||||
$this->shouldJoinBlockedTasks() || | $this->shouldJoinBlockedTasks() || | ||||
($this->getApplicationSearchMayJoinMultipleRows()); | ($this->shouldGroupQueryResultRows()); | ||||
$joined_project_name = ($this->groupBy == self::GROUP_PROJECT); | $joined_project_name = ($this->groupBy == self::GROUP_PROJECT); | ||||
// If we're joining multiple rows, we need to group the results by the | // If we're joining multiple rows, we need to group the results by the | ||||
// task IDs. | // task IDs. | ||||
if ($joined_multiple_rows) { | if ($joined_multiple_rows) { | ||||
if ($joined_project_name) { | if ($joined_project_name) { | ||||
return 'GROUP BY task.phid, projectGroup.dst'; | return 'GROUP BY task.phid, projectGroup.dst'; | ||||
Show All 37 Lines | private function getIgnoreGroupedProjectPHIDs() { | ||||
// Maybe we should also exclude the "excludeProjectPHIDs"? It won't | // Maybe we should also exclude the "excludeProjectPHIDs"? It won't | ||||
// impact the results, but we might end up with a better query plan. | // impact the results, but we might end up with a better query plan. | ||||
// Investigate this on real data? This is likely very rare. | // Investigate this on real data? This is likely very rare. | ||||
return array_mergev($phids); | return array_mergev($phids); | ||||
} | } | ||||
// TODO: Remove this when moving fully to edge logic. | |||||
protected function buildHavingClauseParts(AphrontDatabaseConnection $conn) { | |||||
$having = parent::buildHavingClauseParts($conn); | |||||
if (count($this->projectPHIDs) > 1) { | |||||
$having[] = qsprintf( | |||||
$conn, | |||||
'projectCount = %d', | |||||
count($this->projectPHIDs)); | |||||
} | |||||
return $having; | |||||
} | |||||
protected function getResultCursor($result) { | protected function getResultCursor($result) { | ||||
$id = $result->getID(); | $id = $result->getID(); | ||||
if ($this->groupBy == self::GROUP_PROJECT) { | if ($this->groupBy == self::GROUP_PROJECT) { | ||||
return rtrim($id.'.'.$result->getGroupByProjectPHID(), '.');; | return rtrim($id.'.'.$result->getGroupByProjectPHID(), '.');; | ||||
} | } | ||||
return $id; | return $id; | ||||
▲ Show 20 Lines • Show All 102 Lines • Show Last 20 Lines |