r97022 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r97021‎ | r97022 | r97023 >
Date:23:24, 13 September 2011
Author:aaron
Status:ok (Comments)
Tags:post1.18deploy 
Comment:
Possible fix for issue reported in r83762. I had a hard time confirming the problem/fix with profiling. Committing this now to get more attention.
Modified paths:
  • /trunk/extensions/FlaggedRevs/presentation/specialpages/reports/ProblemChanges_body.php (modified) (history)
  • /trunk/phase3/includes/Pager.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Pager.php
@@ -67,10 +67,15 @@
6868 public $mPastTheEndRow;
6969
7070 /**
71 - * The index to actually be used for ordering. This is a single string
72 - * even if multiple orderings are supported.
 71+ * The index to actually be used for ordering. This is a single column,
 72+ * for one ordering, even if multiple orderings are supported.
7373 */
7474 protected $mIndexField;
 75+ /**
 76+ * An array of secondary columns to order by. These fields are not part of the offset.
 77+ * This is a column list for one ordering, even if multiple orderings are supported.
 78+ */
 79+ protected $mExtraSortFields;
7580 /** For pages that support multiple types of ordering, which one to use.
7681 */
7782 protected $mOrderType;
@@ -115,18 +120,22 @@
116121 $this->mDb = wfGetDB( DB_SLAVE );
117122
118123 $index = $this->getIndexField();
 124+ $extraSort = $this->getExtraSortFields();
119125 $order = $this->mRequest->getVal( 'order' );
120126 if( is_array( $index ) && isset( $index[$order] ) ) {
121127 $this->mOrderType = $order;
122128 $this->mIndexField = $index[$order];
 129+ $this->mExtraSortFields = (array)$extraSort[$order];
123130 } elseif( is_array( $index ) ) {
124131 # First element is the default
125132 reset( $index );
126133 list( $this->mOrderType, $this->mIndexField ) = each( $index );
 134+ $this->mExtraSortFields = (array)$extraSort[$this->mOrderType];
127135 } else {
128136 # $index is not an array
129137 $this->mOrderType = null;
130138 $this->mIndexField = $index;
 139+ $this->mExtraSortFields = (array)$extraSort;
131140 }
132141
133142 if( !isset( $this->mDefaultDirection ) ) {
@@ -269,11 +278,16 @@
270279 $conds = isset( $info['conds'] ) ? $info['conds'] : array();
271280 $options = isset( $info['options'] ) ? $info['options'] : array();
272281 $join_conds = isset( $info['join_conds'] ) ? $info['join_conds'] : array();
 282+ $sortColumns = array_merge( array( $this->mIndexField ), $this->mExtraSortFields );
273283 if ( $descending ) {
274 - $options['ORDER BY'] = $this->mIndexField;
 284+ $options['ORDER BY'] = implode( ',', $sortColumns );
275285 $operator = '>';
276286 } else {
277 - $options['ORDER BY'] = $this->mIndexField . ' DESC';
 287+ $orderBy = array();
 288+ foreach ( $sortColumns as $col ) {
 289+ $orderBy[] = $col . ' DESC';
 290+ }
 291+ $options['ORDER BY'] = implode( ',', $orderBy );
278292 $operator = '<';
279293 }
280294 if ( $offset != '' ) {
@@ -574,10 +588,30 @@
575589 *
576590 * Needless to say, it's really not a good idea to use a non-unique index
577591 * for this! That won't page right.
 592+ *
 593+ * @return string|Array
578594 */
579595 abstract function getIndexField();
580596
581597 /**
 598+ * This function should be overridden to return the names of secondary columns
 599+ * to order by in addition to the column in getIndexField(). These fields will
 600+ * not be used in the pager offset or in any links for users.
 601+ *
 602+ * If getIndexField() returns an array of 'querykey' => 'indexfield' pairs then
 603+ * this must return a corresponding array of 'querykey' => array( fields...) pairs,
 604+ * so that a request with &count=querykey will use array( fields...) to sort.
 605+ *
 606+ * This is useful for pagers that GROUP BY a unique column (say page_id)
 607+ * and ORDER BY another (say page_len). Using GROUP BY and ORDER BY both on
 608+ * page_len,page_id avoids temp tables (given a page_len index). This would
 609+ * also work if page_id was non-unique but we had a page_len,page_id index.
 610+ *
 611+ * @return Array
 612+ */
 613+ protected function getExtraSortFields() { return array(); }
 614+
 615+ /**
582616 * Return the default sorting direction: false for ascending, true for de-
583617 * scending. You can also have an associative array of ordertype => dir,
584618 * if multiple order types are supported. In this case getIndexField()
Index: trunk/extensions/FlaggedRevs/presentation/specialpages/reports/ProblemChanges_body.php
@@ -346,6 +346,7 @@
347347 }
348348 array_unshift( $tables, 'flaggedpages' ); // order matters
349349 $this->mIndexField = 'fp_pending_since';
 350+ $this->mExtraSortFields = array( 'fp_page_id' );
350351 $groupBy = 'fp_pending_since,fp_page_id';
351352 # Show outdated pages for a specific review level
352353 } else {
@@ -372,6 +373,7 @@
373374 }
374375 array_unshift( $tables, 'flaggedpage_pending' ); // order matters
375376 $this->mIndexField = 'fpp_pending_since';
 377+ $this->mExtraSortFields = array( 'fpp_page_id' );
376378 $groupBy = 'fpp_pending_since,fpp_page_id';
377379 }
378380 $fields[] = $this->mIndexField; // Pager needs this

Follow-up revisions

RevisionCommit summaryAuthorDate
r97077FU r97022: Fallback to empty array for getExtraSortFields() result in __const...aaron17:42, 14 September 2011
r97082Merged revisions 97057,97060,97071,97073-97074,97077-97080 via svnmerge from...dantman18:11, 14 September 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r83762different GROUP BY and ORDER BY will result in a temptable of a full resultse...midom15:16, 12 March 2011

Comments

#Comment by Aaron Schulz (talk | contribs)   23:26, 13 September 2011

This basically just matches the ORDER BY and GROUP BY.

#Comment by Aaron Schulz (talk | contribs)   23:50, 13 September 2011

The branch this came from also added fp_page_id to the fp_pending_since index.

#Comment by Nikerabbit (talk | contribs)   10:49, 14 September 2011

PHP Notice: Undefined offset: 0 in /www/w/includes/Pager.php on line 133

#Comment by Aaron Schulz (talk | contribs)   17:10, 14 September 2011

Which special page?

#Comment by Aaron Schulz (talk | contribs)   23:31, 15 September 2011

Here is the query now on my testwiki:

SELECT  /*! STRAIGHT_JOIN */ page_namespace,page_title,page_latest,fp_stable AS stable,fp_quality AS quality,fp_pending_since AS pending_since,fp_pending_since  FROM `mw_flaggedpages` FORCE INDEX (fp_pending_since),`mw_revision`,`mw_change_tag` FORCE INDEX (change_tag_rev_tag),`mw_page`   WHERE (fp_pending_since IS NOT NULL) AND (rev_page = fp_page_id) AND (rev_id > fp_stable) AND (ct_rev_id = rev_id) AND (page_id = fp_page_id) AND page_namespace IN ('0','6','10')   GROUP BY fp_pending_since,fp_page_id ORDER BY fp_pending_since,fp_page_id LIMIT 51

This could also be tried with the fp_pending_since index changed to fp_pending_since,fp_page_id.

#Comment by Aaron Schulz (talk | contribs)   00:32, 16 September 2011

Query could also be like:

SELECT  /*! STRAIGHT_JOIN */ page_namespace,page_title,page_latest,fpp_rev_id AS stable,fpp_quality AS quality,fpp_pending_since AS pending_since,fpp_pending_since  FROM `mw_flaggedpage_pending` FORCE INDEX (fpp_quality_pending),`mw_revision`,`mw_change_tag` FORCE INDEX (change_tag_rev_tag),`mw_page`   WHERE (fpp_pending_since IS NOT NULL) AND (page_id = fpp_page_id) AND (rev_page = page_id) AND (rev_id > fpp_rev_id) AND (rev_id = ct_rev_id) AND ct_tag = '' AND fpp_quality = '0' AND page_namespace IN ('0','6','10')   GROUP BY fpp_pending_since,fpp_page_id ORDER BY fpp_pending_since,fpp_page_id LIMIT 51

If the dropdown is used with any option other than 'stable'.

#Comment by Midom (talk | contribs)   07:21, 19 September 2011

looks ok'ish, except that force index references unknown indexes

#Comment by Aaron Schulz (talk | contribs)   09:12, 19 September 2011

You mean the change tag one? It uses one name or another depending on a global var (indicating whether the new or old index is used).

Status & tagging log