RCFilters: Filter duplicates when filtering for multiple tags
authorRoan Kattouw <roan.kattouw@gmail.com>
Mon, 10 Jul 2017 17:14:57 +0000 (10:14 -0700)
committerRoan Kattouw <roan.kattouw@gmail.com>
Mon, 24 Jul 2017 17:34:20 +0000 (10:34 -0700)
commit2a04f2dbf9dce34fed578d996f9a780c5633bc0d
tree00d02a942314335c44c54be2f8dc3ad0762e6254
parent024a0a9d847297214ce0a9e70d10d211dac34631
RCFilters: Filter duplicates when filtering for multiple tags

When filtering for multiple tags, add DISTINCT to the query.
To make this not result in terrible query performance, we also
have to add the rc_id to the end of the ORDER BY, and add
a GROUP BY equal to the ORDER BY.

Make ChangeTags::modifyDisplayQuery() take an array of tags
instead of a pipe-separated string. This allows each caller
to explicitly opt into supporting multi-tag filters and the
conditional GROUP BY mess that that entails.

Only support multi-tag filters in SpecialRecentChanges and
SpecialRecentchangesLinked. This means we don't have to adapt
the queries in HistoryAction, ContribsPager, LogPager and
NewPagesPager to deal with a possible DISTINCT modifier.

Example query with no tag filters:
SELECT rc_id, ... FROM recentchanges ... ORDER BY rc_timestamp DESC

Example query with one tag filter:
SELECT rc_id, ... FROM recentchanges JOIN change_tag ON ...
WHERE ... AND ct_tag='foo' ORDER BY rc_timestamp DESC

Example query with two tag filters:
SELECT DISTINCT rc_id, ... FROM recentchanges JOIN change_tag ON ...
WHERE ... AND ct_tag IN ('foo', 'bar') GROUP BY rc_timestamp, rc_id
ORDER BY rc_timestamp DESC, rc_id DESC

Bug: T168501
Change-Id: I54a270a563d99b143b55ce83c7d6f70ac4861c64
includes/changetags/ChangeTags.php
includes/specials/SpecialRecentchanges.php
includes/specials/SpecialRecentchangeslinked.php