(bug 40353) SpecialDoubleRedirect: Fix for interwiki redirects
authorTimo Tijhof <ttijhof@wikimedia.org>
Wed, 19 Sep 2012 12:20:32 +0000 (14:20 +0200)
committerTimo Tijhof <ttijhof@wikimedia.org>
Wed, 19 Sep 2012 13:22:52 +0000 (15:22 +0200)
Previously there were problems:
- Non-double redirects that point to interwiki of the same name
  were also included (because it ignored rd_interwiki, it looked
  up a local page by that name and found a redirect, again etc.)

  e.g.:
  "Foo (edit) →‎ Foo →‎ somewiki:Foo"

- Double redirects that end in an interwiki appeared to be
  linking to a local one

  "X (edit) →‎ Y →‎ Y" // the second Y is really somewiki:Y

- Double redirects where the end is an interwiki and of a
  different title, are not included in the results.

- Redundant third join to page (pc), the information needed from
  that table (title, namespace) are already available in the
  redirect table. Redundant joins are generally not a bug, but
  in this case the third join caused interwiki targets to be
  excluded in most cases since those external pages did not
  exist in the local table (except for coincidences).

Example wiki:
* Foo redirects to somewiki:Foo
* X redirects to Y
* Y redirects to somewiki:Y
* A redirects to B
* B redirects to somewiki:C

Before (http://sqlfiddle.com/#!2/1d656/9/0):

* Foo →‎ Foo →‎ Foo

* X →‎ Y →‎ Y

After (http://sqlfiddle.com/#!2/1d656/6/0):

* X →‎ Y →‎ somewiki:Y

* A →‎ B →‎ somewiki:C

Change-Id: I986f3a03d71dd6457842e6189653bd606f4fa97e

RELEASE-NOTES-1.20
includes/specials/SpecialDoubleRedirects.php

index b28cc70..7fbacfa 100644 (file)
@@ -246,6 +246,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 40214) Category pages no longer use deprecated "width" HTML attribute.
 * (bug 39941) Add missing stylesheets to the installer pages
 * In HTML5 mode, allow new input element types values (such as color, range..)
+* (bug 40353) SpecialDoubleRedirect should support for interwiki redirects.
 
 === API changes in 1.20 ===
 * (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API.
index 5864ca9..224c162 100644 (file)
@@ -44,22 +44,43 @@ class DoubleRedirectsPage extends QueryPage {
        function reallyGetQueryInfo( $namespace = null, $title = null ) {
                $limitToTitle = !( $namespace === null && $title === null );
                $retval = array (
-                       'tables' => array ( 'ra' => 'redirect',
-                                       'rb' => 'redirect', 'pa' => 'page',
-                                       'pb' => 'page', 'pc' => 'page' ),
-                       'fields' => array ( 'namespace' => 'pa.page_namespace',
-                                       'title' => 'pa.page_title',
-                                       'value' => 'pa.page_title',
-                                       'nsb' => 'pb.page_namespace',
-                                       'tb' => 'pb.page_title',
-                                       'nsc' => 'pc.page_namespace',
-                                       'tc' => 'pc.page_title' ),
-                       'conds' => array ( 'ra.rd_from = pa.page_id',
-                                       'pb.page_namespace = ra.rd_namespace',
-                                       'pb.page_title = ra.rd_title',
-                                       'rb.rd_from = pb.page_id',
-                                       'pc.page_namespace = rb.rd_namespace',
-                                       'pc.page_title = rb.rd_title' )
+                       'tables' => array (
+                               'ra' => 'redirect',
+                               'rb' => 'redirect',
+                               'pa' => 'page',
+                               'pb' => 'page'
+                       ),
+                       'fields' => array(
+                               'namespace' => 'pa.page_namespace',
+                               'title' => 'pa.page_title',
+                               'value' => 'pa.page_title',
+
+                               'nsb' => 'pb.page_namespace',
+                               'tb' => 'pb.page_title',
+
+                               // Select fields from redirect instead of page. Because there may
+                               // not actually be a page table row for this target (e.g. for interwiki redirects)
+                               'nsc' => 'rb.rd_namespace',
+                               'tc' => 'rb.rd_title',
+                               'iwc' => 'rb.rd_interwiki',
+                       ),
+                       'conds' => array(
+                               'ra.rd_from = pa.page_id',
+
+                               // Filter out redirects where the target goes interwiki (bug 40353).
+                               // This isn't an optimization, it is required for correct results,
+                               // otherwise a non-double redirect like Bar -> w:Foo will show up
+                               // like "Bar -> Foo -> w:Foo".
+
+                               // Need to check both NULL and "" for some reason,
+                               // apparently either can be stored for non-iw entries.
+                               '(ra.rd_interwiki IS NULL OR ra.rd_interwiki = "")',
+
+                               'pb.page_namespace = ra.rd_namespace',
+                               'pb.page_title = ra.rd_title',
+
+                               'rb.rd_from = pb.page_id',
+                       )
                );
                if ( $limitToTitle ) {
                        $retval['conds']['pa.page_namespace'] = $namespace;
@@ -79,6 +100,11 @@ class DoubleRedirectsPage extends QueryPage {
        function formatResult( $skin, $result ) {
                $titleA = Title::makeTitle( $result->namespace, $result->title );
 
+               // If only titleA is in the query, it means this came from
+               // querycache (which only saves 3 columns).
+               // That does save the bulk of the query cost, but now we need to
+               // get a little more detail about each individual entry quickly
+               // using the filter of reallyGetQueryInfo.
                if ( $result && !isset( $result->nsb ) ) {
                        $dbr = wfGetDB( DB_SLAVE );
                        $qi = $this->reallyGetQueryInfo( $result->namespace,
@@ -94,7 +120,7 @@ class DoubleRedirectsPage extends QueryPage {
                }
 
                $titleB = Title::makeTitle( $result->nsb, $result->tb );
-               $titleC = Title::makeTitle( $result->nsc, $result->tc );
+               $titleC = Title::makeTitle( $result->nsc, $result->tc, '',  $result->iwc );
 
                $linkA = Linker::linkKnown(
                        $titleA,