From c668e7142113f297355cef791332c89ab9d05d48 Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Sat, 17 Oct 2009 12:23:23 +0000 Subject: [PATCH] (bug 20256) Fixed SQL errors on Special:Recentchanges and Special:Recentchangeslinked on SQLite backend --- RELEASE-NOTES | 2 ++ includes/db/Database.php | 9 +++++++++ includes/db/DatabaseSqlite.php | 9 +++++++++ includes/specials/SpecialRecentchanges.php | 6 +++++- .../specials/SpecialRecentchangeslinked.php | 17 ++++++++++++++--- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 9b0713c988..6fefee4442 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -562,6 +562,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * (bug 21116) MediaWiki:Templatesused, MediaWiki:Templatesusedpreview and MediaWiki:Templatesusedsection now support plural * (bug 21079) There is no more line wrapping between label and field in Special:Log +* (bug 20256) Fixed SQL errors on Special:Recentchanges and Special:Recentchangeslinked + on SQLite backend == API changes in 1.16 == diff --git a/includes/db/Database.php b/includes/db/Database.php index 34e33dbb61..c8deb337e9 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -1695,6 +1695,15 @@ abstract class DatabaseBase { return $this->limitResult( $sql, $num, 0 ); } + /** + * Returns true if current database backend supports ORDER BY or LIMIT for separate subqueries + * within the UNION construct. + * @return Boolean + */ + function unionSupportsOrderAndLimit() { + return true; // True for almost every DB supported + } + /** * Construct a UNION query * This is used for providing overload point for other DB abstractions diff --git a/includes/db/DatabaseSqlite.php b/includes/db/DatabaseSqlite.php index 1eb49108cd..e9fe549e4d 100644 --- a/includes/db/DatabaseSqlite.php +++ b/includes/db/DatabaseSqlite.php @@ -299,6 +299,15 @@ class DatabaseSqlite extends DatabaseBase { return - 1; } + function unionSupportsOrderAndLimit() { + return false; + } + + function unionQueries( $sqls, $all ) { + $glue = $all ? ' UNION ALL ' : ' UNION '; + return implode( $glue, $sqls ); + } + function wasDeadlock() { return $this->lastErrno() == SQLITE_BUSY; } diff --git a/includes/specials/SpecialRecentchanges.php b/includes/specials/SpecialRecentchanges.php index 85ace3cb86..1d38e57d2b 100644 --- a/includes/specials/SpecialRecentchanges.php +++ b/includes/specials/SpecialRecentchanges.php @@ -306,7 +306,11 @@ class SpecialRecentChanges extends SpecialPage { // 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 || $opts['tagfilter'] ) { + if( is_null($namespace) + || $invert + || $opts['tagfilter'] + || !$dbr->unionSupportsOrderAndLimit() ) + { $res = $dbr->select( $tables, '*', $conds, __METHOD__, array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + $query_options, diff --git a/includes/specials/SpecialRecentchangeslinked.php b/includes/specials/SpecialRecentchangeslinked.php index a5bd098f78..d84ffa32b4 100644 --- a/includes/specials/SpecialRecentchangeslinked.php +++ b/includes/specials/SpecialRecentchangeslinked.php @@ -144,19 +144,30 @@ class SpecialRecentchangeslinked extends SpecialRecentchanges { } } - $subsql[] = $dbr->selectSQLText( + if( $dbr->unionSupportsOrderAndLimit()) + $order = array( 'ORDER BY' => 'rc_timestamp DESC' ); + else + $order = array(); + + + $query = $dbr->selectSQLText( array_merge( $tables, array( $link_table ) ), $select, $conds + $subconds, __METHOD__, - array( 'ORDER BY' => 'rc_timestamp DESC', 'LIMIT' => $limit ) + $query_options, + $order + $query_options, $join_conds + array( $link_table => array( 'INNER JOIN', $subjoin ) ) ); + + if( $dbr->unionSupportsOrderAndLimit()) + $query = $dbr->limitResult( $query, $limit ); + + $subsql[] = $query; } if( count($subsql) == 0 ) return false; // should never happen - if( count($subsql) == 1 ) + if( count($subsql) == 1 && $dbr->unionSupportsOrderAndLimit() ) $sql = $subsql[0]; else { // need to resort and relimit after union -- 2.20.1