From 467fbef034601ed172cbc643a633c18e5f69a2b6 Mon Sep 17 00:00:00 2001 From: Stephane Bisson Date: Wed, 30 Aug 2017 11:31:41 -0400 Subject: [PATCH] WLFilters: fix server-side tag filtering Tag filtering was enabled in the UI but the backend was not properly wired for it. Change-Id: I1c50b67b0a4aaddb561e79fdacd9849ffe0ded8c --- .../specialpage/ChangesListSpecialPage.php | 1 + includes/specials/SpecialRecentchanges.php | 1 - includes/specials/SpecialWatchlist.php | 24 +++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/includes/specialpage/ChangesListSpecialPage.php b/includes/specialpage/ChangesListSpecialPage.php index 4d27d35dd4..acd5d14fe6 100644 --- a/includes/specialpage/ChangesListSpecialPage.php +++ b/includes/specialpage/ChangesListSpecialPage.php @@ -904,6 +904,7 @@ abstract class ChangesListSpecialPage extends SpecialPage { $opts->add( 'invert', false ); $opts->add( 'associated', false ); $opts->add( 'urlversion', 1 ); + $opts->add( 'tagfilter', '' ); return $opts; } diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index 6ee697ebc4..547a1b06c2 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -241,7 +241,6 @@ class SpecialRecentChanges extends ChangesListSpecialPage { $opts->add( 'categories', '' ); $opts->add( 'categories_any', false ); - $opts->add( 'tagfilter', '' ); return $opts; } diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index 0dd66b023d..07889b7a9d 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -382,10 +382,6 @@ class SpecialWatchlist extends ChangesListSpecialPage { $tables = array_merge( [ 'recentchanges', 'watchlist' ], $tables ); $fields = array_merge( RecentChange::selectFields(), $fields ); - $query_options = array_merge( [ - 'ORDER BY' => 'rc_timestamp DESC', - 'LIMIT' => $opts['limit'] - ], $query_options ); $join_conds = array_merge( [ 'watchlist' => [ @@ -422,13 +418,14 @@ class SpecialWatchlist extends ChangesListSpecialPage { ], LIST_OR ); } + $tagFilter = $opts['tagfilter'] ? explode( '|', $opts['tagfilter'] ) : []; ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $query_options, - '' + $tagFilter ); $this->runMainQueryHook( $tables, $fields, $conds, $query_options, $join_conds, $opts ); @@ -437,6 +434,23 @@ class SpecialWatchlist extends ChangesListSpecialPage { return false; } + $orderByAndLimit = [ + 'ORDER BY' => 'rc_timestamp DESC', + 'LIMIT' => $opts['limit'] + ]; + if ( in_array( 'DISTINCT', $query_options ) ) { + // ChangeTags::modifyDisplayQuery() adds DISTINCT when filtering on multiple tags. + // In order to prevent DISTINCT from causing query performance problems, + // we have to GROUP BY the primary key. This in turn requires us to add + // the primary key to the end of the ORDER BY, and the old ORDER BY to the + // start of the GROUP BY + $orderByAndLimit['ORDER BY'] = 'rc_timestamp DESC, rc_id DESC'; + $orderByAndLimit['GROUP BY'] = 'rc_timestamp, rc_id'; + } + // array_merge() is used intentionally here so that hooks can, should + // they so desire, override the ORDER BY / LIMIT condition(s) + $query_options = array_merge( $orderByAndLimit, $query_options ); + return $dbr->select( $tables, $fields, -- 2.20.1