From: Brad Jorsch Date: Wed, 12 Apr 2017 15:38:20 +0000 (-0400) Subject: ApiQueryLinks: Avoid MySQL order-by bug X-Git-Tag: 1.31.0-rc.0~1789 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/operations/recherche.php?a=commitdiff_plain;h=8c36aa3373b02111b7031522273693c05d3e37e7;p=lhc%2Fweb%2Fwiklou.git ApiQueryLinks: Avoid MySQL order-by bug MySQL (and MariaDB) have a strange bug where it will often get confused and insist on filesorting if a field that is constant in the WHERE clause is also present in ORDER BY. We've worked around this in several places in the API, and in fact it was done in this very module in r34720 and r37250. But when r67450 added the pltitles and tltemplates parameters, it didn't adjust the logic for avoiding the DB bug. This does that now. Change-Id: I9f37f8812a94cdd088d3940da43d1046ebd455d6 --- diff --git a/includes/api/ApiQueryLinks.php b/includes/api/ApiQueryLinks.php index 2f75e76343..508bdf3f9d 100644 --- a/includes/api/ApiQueryLinks.php +++ b/includes/api/ApiQueryLinks.php @@ -87,25 +87,34 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { $this->addTables( $this->table ); $this->addWhereFld( $this->prefix . '_from', array_keys( $this->getPageSet()->getGoodTitles() ) ); - $this->addWhereFld( $this->prefix . '_namespace', $params['namespace'] ); + $multiNS = true; + $multiTitle = true; if ( $params[$this->titlesParam] ) { + // Filter the titles in PHP so our ORDER BY bug avoidance below works right. + $filterNS = $params['namespace'] ? array_flip( $params['namespace'] ) : false; + $lb = new LinkBatch; foreach ( $params[$this->titlesParam] as $t ) { $title = Title::newFromText( $t ); if ( !$title ) { $this->addWarning( [ 'apiwarn-invalidtitle', wfEscapeWikiText( $t ) ] ); - } else { + } elseif ( !$filterNS || isset( $filterNS[$title->getNamespace()] ) ) { $lb->addObj( $title ); } } $cond = $lb->constructSet( $this->prefix, $this->getDB() ); if ( $cond ) { $this->addWhere( $cond ); + $multiNS = count( $lb->data ) !== 1; + $multiTitle = count( call_user_func_array( 'array_merge', $lb->data ) ) !== 1; } else { // No titles so no results return; } + } elseif ( $params['namespace'] ) { + $this->addWhereFld( $this->prefix . '_namespace', $params['namespace'] ); + $multiNS = count( $params['namespace'] ) !== 1; } if ( !is_null( $params['continue'] ) ) { @@ -134,12 +143,15 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { if ( count( $this->getPageSet()->getGoodTitles() ) != 1 ) { $order[] = $this->prefix . '_from' . $sort; } - if ( count( $params['namespace'] ) != 1 ) { + if ( $multiNS ) { $order[] = $this->prefix . '_namespace' . $sort; } - - $order[] = $this->prefix . '_title' . $sort; - $this->addOption( 'ORDER BY', $order ); + if ( $multiTitle ) { + $order[] = $this->prefix . '_title' . $sort; + } + if ( $order ) { + $this->addOption( 'ORDER BY', $order ); + } $this->addOption( 'LIMIT', $params['limit'] + 1 ); $res = $this->select( __METHOD__ );