From 7055d6416d6c3c19e3a02e5be0e3f29cf1da48ff Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Wed, 21 Oct 2009 12:21:09 +0000 Subject: [PATCH] (bug 20268) Fixed Database::estimateRowCount on SQLite backend. This involved moving the previous implementation to where it belongs - DatabaseMysql, and replacing it with slightly tweaked DB2 implementation. --- RELEASE-NOTES | 1 + includes/db/Database.php | 32 ++++++++++++++++---------------- includes/db/DatabaseIbm_db2.php | 24 +----------------------- includes/db/DatabaseMssql.php | 16 ---------------- includes/db/DatabaseMysql.php | 24 ++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 55 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index f89cc3ce60..8e81535ac3 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -580,6 +580,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * (bug 20847) Deprecated deprecated akeytt() removed in wikibits.js leaving dummy * (bug 21161) Changing $wgCaCacheEpoch now always invalidates file cache +* (bug 20268) Fixed row count estimation on SQLite backend == API changes in 1.16 == diff --git a/includes/db/Database.php b/includes/db/Database.php index c8deb337e9..e9e87535da 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -961,26 +961,26 @@ abstract class DatabaseBase { /** * Estimate rows in dataset - * Returns estimated count, based on EXPLAIN output + * Returns estimated count - not necessarily an accurate estimate across different databases, + * so use sparingly * Takes same arguments as Database::select() + * + * @param string $table table name + * @param array $vars unused + * @param array $conds filters on the table + * @param string $fname function name for profiling + * @param array $options options for select + * @return int row count */ public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'Database::estimateRowCount', $options = array() ) { - $options['EXPLAIN'] = true; - $res = $this->select( $table, $vars, $conds, $fname, $options ); - if ( $res === false ) - return false; - if ( !$this->numRows( $res ) ) { - $this->freeResult($res); - return 0; + $rows = 0; + $res = $this->select ( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options ); + if ( $res ) { + $row = $this->fetchRow( $res ); + $rows = ( isset( $row['rowcount'] ) ) ? $row['rowcount'] : 0; } - - $rows = 1; - while( $plan = $this->fetchObject( $res ) ) { - $rows *= $plan->rows > 0 ? $plan->rows : 1; // avoid resetting to zero - } - - $this->freeResult($res); - return $rows; + $this->freeResult( $res ); + return $rows; } /** diff --git a/includes/db/DatabaseIbm_db2.php b/includes/db/DatabaseIbm_db2.php index ed493e299a..b6866c5b22 100644 --- a/includes/db/DatabaseIbm_db2.php +++ b/includes/db/DatabaseIbm_db2.php @@ -1662,29 +1662,7 @@ SQL; $this->query( $sql, $fname ); } - - /** - * Estimate rows in dataset - * Returns estimated count, based on COUNT(*) output - * Takes same arguments as Database::select() - * @param string $table table name - * @param array $vars unused - * @param array $conds filters on the table - * @param string $fname function name for profiling - * @param array $options options for select - * @return int row count - */ - public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'Database::estimateRowCount', $options = array() ) { - $rows = 0; - $res = $this->select ($table, 'COUNT(*) as mwrowcount', $conds, $fname, $options ); - if ($res) { - $row = $this->fetchRow($res); - $rows = (isset($row['mwrowcount'])) ? $row['mwrowcount'] : 0; - } - $this->freeResult($res); - return $rows; - } - + /** * Description is left as an exercise for the reader * @param mixed $b data to be encoded diff --git a/includes/db/DatabaseMssql.php b/includes/db/DatabaseMssql.php index 533d0cd7a0..923ffe4981 100644 --- a/includes/db/DatabaseMssql.php +++ b/includes/db/DatabaseMssql.php @@ -445,22 +445,6 @@ class DatabaseMssql extends DatabaseBase { return $this->query( $sql, $fname ); } - /** - * Estimate rows in dataset - * Returns estimated count, based on EXPLAIN output - * Takes same arguments as Database::select() - */ - function estimateRowCount( $table, $vars='*', $conds='', $fname = 'Database::estimateRowCount', $options = array() ) { - $rows = 0; - $res = $this->select ($table, 'COUNT(*)', $conds, $fname, $options ); - if ($res) { - $row = $this->fetchObject($res); - $rows = $row[0]; - } - $this->freeResult($res); - return $rows; - } - /** * Determines whether a field exists in a table * Usually aborts on failure diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index 9727eaf1b3..40425466d7 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -229,6 +229,30 @@ class DatabaseMysql extends DatabaseBase { } function affectedRows() { return mysql_affected_rows( $this->mConn ); } + + /** + * Estimate rows in dataset + * Returns estimated count, based on EXPLAIN output + * Takes same arguments as Database::select() + */ + public function estimateRowCount( $table, $vars='*', $conds='', $fname = 'Database::estimateRowCount', $options = array() ) { + $options['EXPLAIN'] = true; + $res = $this->select( $table, $vars, $conds, $fname, $options ); + if ( $res === false ) + return false; + if ( !$this->numRows( $res ) ) { + $this->freeResult($res); + return 0; + } + + $rows = 1; + while( $plan = $this->fetchObject( $res ) ) { + $rows *= $plan->rows > 0 ? $plan->rows : 1; // avoid resetting to zero + } + + $this->freeResult($res); + return $rows; + } function fieldInfo( $table, $field ) { $table = $this->tableName( $table ); -- 2.20.1