@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.

Add a missing "GROUP BY" to MailQuery when querying for multiple recipients

Summary:
See <https://discourse.phabricator-community.org/t/mail-details-view-broken/4315>. The change in D21400 detects a missing "GROUP BY" in some variations of this query.

Specifically, we may join multiple recipient rows (since mail may have multiple recipients) and then fail to group the results.

Fix this by adding the "GROUP BY". Additionally, remove the special-cased behavior when no authors or recipients are specified -- it's complicated and not entirely correct (e.g., may produce a "no object" instead of a policy error when querying by ID), and likely predates overheating.

Test Plan:
- Disabled `metamta.one-mail-per-recipient` in Config.
- Generated a message to 2+ recipients.
- Viewed the message detail; queried for the message by specifying 2+ recipients.
- Viewed the unfiltered list of messages, saw the query overheat.

Differential Revision: https://secure.phabricator.com/D21486

+25 -30
+24 -29
src/applications/metamta/query/PhabricatorMetaMTAMailQuery.php
··· 64 64 $this->actorPHIDs); 65 65 } 66 66 67 - if ($this->recipientPHIDs !== null) { 68 - $where[] = qsprintf( 69 - $conn, 70 - 'recipient.dst IN (%Ls)', 71 - $this->recipientPHIDs); 72 - } 73 - 74 - if ($this->actorPHIDs === null && $this->recipientPHIDs === null) { 75 - $viewer = $this->getViewer(); 76 - if (!$viewer->isOmnipotent()) { 77 - $where[] = qsprintf( 78 - $conn, 79 - 'edge.dst = %s OR actorPHID = %s', 80 - $viewer->getPHID(), 81 - $viewer->getPHID()); 82 - } 83 - } 84 - 85 67 if ($this->createdMin !== null) { 86 68 $where[] = qsprintf( 87 69 $conn, ··· 102 84 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 103 85 $joins = parent::buildJoinClauseParts($conn); 104 86 105 - if ($this->actorPHIDs === null && $this->recipientPHIDs === null) { 87 + if ($this->shouldJoinRecipients()) { 106 88 $joins[] = qsprintf( 107 89 $conn, 108 - 'LEFT JOIN %T edge ON mail.phid = edge.src AND edge.type = %d', 90 + 'JOIN %T recipient 91 + ON mail.phid = recipient.src 92 + AND recipient.type = %d 93 + AND recipient.dst IN (%Ls)', 109 94 PhabricatorEdgeConfig::TABLE_NAME_EDGE, 110 - PhabricatorMetaMTAMailHasRecipientEdgeType::EDGECONST); 95 + PhabricatorMetaMTAMailHasRecipientEdgeType::EDGECONST, 96 + $this->recipientPHIDs); 111 97 } 112 98 113 - if ($this->recipientPHIDs !== null) { 114 - $joins[] = qsprintf( 115 - $conn, 116 - 'LEFT JOIN %T recipient '. 117 - 'ON mail.phid = recipient.src AND recipient.type = %d', 118 - PhabricatorEdgeConfig::TABLE_NAME_EDGE, 119 - PhabricatorMetaMTAMailHasRecipientEdgeType::EDGECONST); 99 + return $joins; 100 + } 101 + 102 + private function shouldJoinRecipients() { 103 + if ($this->recipientPHIDs === null) { 104 + return false; 120 105 } 121 106 122 - return $joins; 107 + return true; 123 108 } 124 109 125 110 protected function getPrimaryTableAlias() { ··· 132 117 133 118 public function getQueryApplicationClass() { 134 119 return 'PhabricatorMetaMTAApplication'; 120 + } 121 + 122 + protected function shouldGroupQueryResultRows() { 123 + if ($this->shouldJoinRecipients()) { 124 + if (count($this->recipientPHIDs) > 1) { 125 + return true; 126 + } 127 + } 128 + 129 + return parent::shouldGroupQueryResultRows(); 135 130 } 136 131 137 132 }
+1 -1
src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
··· 234 234 // T11773 for some discussion. 235 235 $this->isOverheated = false; 236 236 237 - // See T13386. If we on an old offset-based paging workflow, we need 237 + // See T13386. If we are on an old offset-based paging workflow, we need 238 238 // to base the overheating limit on both the offset and limit. 239 239 $overheat_limit = $need * 10; 240 240 $total_seen = 0;