* Handles selecting tags, and filtering.
* Needs $tables to be set up properly, so we can figure out which join conditions to use.
*/
- static function modifyDisplayQuery( &$tables, &$fields, &$conds, &$join_conds, $filter_tag = false ) {
+ static function modifyDisplayQuery( &$tables, &$fields, &$conds,
+ &$join_conds, &$options, $filter_tag = false ) {
global $wgRequest, $wgUseTagFilter;
if ($filter_tag === false) {
// Somebody wants to filter on a tag.
// Add an INNER JOIN on change_tag
+ // FORCE INDEX -- change_tags will almost ALWAYS be the correct query plan.
+ $options['USE INDEX'] = array( 'change_tag' => 'change_tag_tag_id' );
+ unset( $options['FORCE INDEX'] );
$tables[] = 'change_tag';
$join_conds['change_tag'] = array( 'INNER JOIN', "ct_$join_cond=$join_cond" );
$conds['ct_tag'] = $filter_tag;
$wgMemc->set( $key, $emptyTags, 300 );
return $emptyTags;
}
-}
\ No newline at end of file
+}
);
ChangeTags::modifyDisplayQuery( $info['tables'], $info['fields'], $info['conds'],
- $info['join_conds'], $this->mTagFilter );
+ $info['join_conds'], $info['options'], $this->mTagFilter );
return $info;
}
'options' => array( 'USE INDEX' => array('revision' => 'page_timestamp') ),
'join_conds' => array( 'tag_summary' => array( 'LEFT JOIN', 'ts_rev_id=rev_id' ) ),
);
- ChangeTags::modifyDisplayQuery( $queryInfo['tables'], $queryInfo['fields'], $queryInfo['conds'], $queryInfo['join_conds'], $this->tagFilter );
+ ChangeTags::modifyDisplayQuery( $queryInfo['tables'],
+ $queryInfo['fields'],
+ $queryInfo['conds'],
+ $queryInfo['join_conds'],
+ $queryInfo['options'],
+ $this->tagFilter );
wfRunHooks( 'PageHistoryPager::getQueryInfo', array( &$this, &$queryInfo ) );
return $queryInfo;
}
'join_conds' => $join_cond
);
- ChangeTags::modifyDisplayQuery( $queryInfo['tables'], $queryInfo['fields'], $queryInfo['conds'],
- $queryInfo['join_conds'], $this->tagFilter );
+ ChangeTags::modifyDisplayQuery( $queryInfo['tables'],
+ $queryInfo['fields'],
+ $queryInfo['conds'],
+ $queryInfo['join_conds'],
+ $queryInfo['options'],
+ $this->tagFilter );
wfRunHooks( 'ContribsPager::getQueryInfo', array( &$this, &$queryInfo ) );
return $queryInfo;
$fields = array();
## Modify query for tags
- ChangeTags::modifyDisplayQuery( $info['tables'], $fields, $info['conds'], $info['join_conds'], $this->opts['tagfilter'] );
+ ChangeTags::modifyDisplayQuery( $info['tables'],
+ $fields,
+ $info['conds'],
+ $info['join_conds'],
+ $info['options'],
+ $this->opts['tagfilter'] );
return $info;
}
$tables = array( 'recentchanges' );
$join_conds = array();
+ $query_options = array( 'USE INDEX' => array('recentchanges' => 'rc_timestamp') );
$uid = $wgUser->getId();
$dbr = wfGetDB( DB_SLAVE );
$join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
}
// Tag stuff.
- $fields = array(); // Fields are * in this case, so let the function modify an empty array to keep it happy.
- ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $opts['tagfilter'] );
+ $fields = array();
+ // Fields are * in this case, so let the function modify an empty array to keep it happy.
+ ChangeTags::modifyDisplayQuery( $tables,
+ $fields,
+ $conds,
+ $join_conds,
+ $query_options,
+ $opts['tagfilter']
+ );
wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) );
// Is there either one namespace selected or excluded?
+ // Tag filtering also has a better index.
// Also, if this is "all" or main namespace, just use timestamp index.
- if( is_null($namespace) || $invert || $namespace == NS_MAIN ) {
+ if( is_null($namespace) || $invert || $namespace == NS_MAIN || $opts['tagfilter'] ) {
$res = $dbr->select( $tables, '*', $conds, __METHOD__,
- array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit,
- 'USE INDEX' => array('recentchanges' => 'rc_timestamp') ),
+ array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) +
+ $query_options,
$join_conds );
// We have a new_namespace_time index! UNION over new=(0,1) and sort result set!
} else {
$tables = array( 'recentchanges' );
$select = array( $dbr->tableName( 'recentchanges' ) . '.*' );
$join_conds = array();
+ $query_options = array();
// left join with watchlist table to highlight watched rows
if( $uid = $wgUser->getId() ) {
$join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" );
}
- ChangeTags::modifyDisplayQuery( $tables, $select, $conds, $join_conds, $opts['tagfilter'] );
+ ChangeTags::modifyDisplayQuery( $tables,
+ $select,
+ $conds,
+ $join_conds,
+ $query_options,
+ $opts['tagfilter'],
+ );
// XXX: parent class does this, should we too?
// wfRunHooks('SpecialRecentChangesQuery', array( &$conds, &$tables, &$join_conds, $opts ) );
$select,
$conds + $subconds,
__METHOD__,
- array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ),
+ array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + $query_options,
$join_conds + array( $link_table => array( 'INNER JOIN', $subjoin ) )
);
}
$fields[] = 'page_latest';
}
- ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, '' );
+ ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
wfRunHooks('SpecialWatchlistQuery', array(&$conds,&$tables,&$join_conds,&$fields) );
$res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds );