From aff21af9aea38ea2939604877e5d39a2c66e1f7a Mon Sep 17 00:00:00 2001 From: umherirrender Date: Wed, 15 Aug 2012 15:16:09 +0200 Subject: [PATCH] Allow aliased field names with separated syntax This introduce the syntax from aliased table names for aliased field names into the abstract database layer: array( 'alias' => 'field' ) gives 'field AS alias' This patch also includes changes to query pages, api and some more places to show, how the new syntax looks in "production". This allow us to remove the "AS" for Non-PostgreSQL databases, if we want that. Change-Id: I5f0de1c2f29092c173aec3de93ffdef436799e8d --- includes/Category.php | 6 +- includes/QueryPage.php | 6 +- includes/Revision.php | 2 +- includes/WikiPage.php | 6 +- includes/api/ApiQueryAllCategories.php | 2 +- includes/api/ApiQueryAllUsers.php | 2 +- includes/api/ApiQueryCategoryInfo.php | 2 +- includes/api/ApiQueryLinks.php | 6 +- includes/api/ApiQueryTags.php | 2 +- includes/db/Database.php | 45 +++++++++-- includes/db/ORMTable.php | 2 +- includes/job/Job.php | 4 +- includes/specials/SpecialActiveusers.php | 6 +- includes/specials/SpecialAncientpages.php | 6 +- includes/specials/SpecialBlockList.php | 2 +- includes/specials/SpecialBrokenRedirects.php | 6 +- includes/specials/SpecialDeadendpages.php | 6 +- includes/specials/SpecialDisambiguations.php | 6 +- includes/specials/SpecialDoubleRedirects.php | 14 ++-- includes/specials/SpecialExport.php | 6 +- includes/specials/SpecialFewestrevisions.php | 8 +- .../specials/SpecialFileDuplicateSearch.php | 4 +- includes/specials/SpecialLinkSearch.php | 6 +- includes/specials/SpecialListredirects.php | 8 +- includes/specials/SpecialLonelypages.php | 6 +- includes/specials/SpecialMIMEsearch.php | 6 +- includes/specials/SpecialMostcategories.php | 6 +- includes/specials/SpecialMostimages.php | 6 +- includes/specials/SpecialMostlinked.php | 6 +- .../specials/SpecialMostlinkedcategories.php | 6 +- .../specials/SpecialMostlinkedtemplates.php | 6 +- includes/specials/SpecialNewpages.php | 2 +- includes/specials/SpecialPopularpages.php | 6 +- includes/specials/SpecialShortpages.php | 6 +- includes/specials/SpecialTags.php | 2 +- .../specials/SpecialUncategorizedimages.php | 6 +- .../specials/SpecialUncategorizedpages.php | 6 +- includes/specials/SpecialUndelete.php | 2 +- includes/specials/SpecialUnusedcategories.php | 6 +- includes/specials/SpecialUnusedimages.php | 6 +- includes/specials/SpecialUnusedtemplates.php | 6 +- includes/specials/SpecialUnwatchedpages.php | 6 +- includes/specials/SpecialWantedcategories.php | 6 +- includes/specials/SpecialWantedfiles.php | 6 +- includes/specials/SpecialWantedpages.php | 6 +- includes/specials/SpecialWantedtemplates.php | 6 +- includes/specials/SpecialWatchlist.php | 2 +- includes/specials/SpecialWithoutinterwiki.php | 6 +- tests/phpunit/includes/db/DatabaseSQLTest.php | 75 +++++++++++++++++++ 49 files changed, 238 insertions(+), 128 deletions(-) create mode 100644 tests/phpunit/includes/db/DatabaseSQLTest.php diff --git a/includes/Category.php b/includes/Category.php index 79870692df..d9ca234ef8 100644 --- a/includes/Category.php +++ b/includes/Category.php @@ -301,9 +301,9 @@ class Category { $cond2 = $dbw->conditional( 'page_namespace=' . NS_FILE, 1, 'NULL' ); $result = $dbw->selectRow( array( 'categorylinks', 'page' ), - array( 'COUNT(*) AS pages', - "COUNT($cond1) AS subcats", - "COUNT($cond2) AS files" + array( 'pages' => 'COUNT(*)', + 'subcats' => "COUNT($cond1)", + 'files' => "COUNT($cond2)" ), array( 'cl_to' => $this->mName, 'page_id = cl_from' ), __METHOD__, diff --git a/includes/QueryPage.php b/includes/QueryPage.php index 501fd2fe32..076b1b5a6c 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -432,9 +432,9 @@ abstract class QueryPage extends SpecialPage { $options['ORDER BY'] = 'qc_value ASC'; } $res = $dbr->select( 'querycache', array( 'qc_type', - 'qc_namespace AS namespace', - 'qc_title AS title', - 'qc_value AS value' ), + 'namespace' => 'qc_namespace', + 'title' => 'qc_title', + 'value' => 'qc_value' ), array( 'qc_type' => $this->getName() ), __METHOD__, $options ); diff --git a/includes/Revision.php b/includes/Revision.php index 731a5f2b09..e7ddf3c08a 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -1268,7 +1268,7 @@ class Revision implements IDBAccessObject { * @return Integer */ static function countByPageId( $db, $id ) { - $row = $db->selectRow( 'revision', 'COUNT(*) AS revCount', + $row = $db->selectRow( 'revision', array( 'revCount' => 'COUNT(*)' ), array( 'rev_page' => $id ), __METHOD__ ); if( $row ) { return $row->revCount; diff --git a/includes/WikiPage.php b/includes/WikiPage.php index f4ed70d672..5ec58191d1 100644 --- a/includes/WikiPage.php +++ b/includes/WikiPage.php @@ -891,10 +891,10 @@ class WikiPage extends Page implements IDBAccessObject { $tables = array( 'revision', 'user' ); $fields = array( - 'rev_user as user_id', - 'rev_user_text AS user_name', + 'user_id' => 'rev_user', + 'user_name' => 'rev_user_text', $realNameField, - 'MAX(rev_timestamp) AS timestamp', + 'timestamp' => 'MAX(rev_timestamp)', ); $conds = array( 'rev_page' => $this->getId() ); diff --git a/includes/api/ApiQueryAllCategories.php b/includes/api/ApiQueryAllCategories.php index 09f6edbd3b..4f4c77f0e7 100644 --- a/includes/api/ApiQueryAllCategories.php +++ b/includes/api/ApiQueryAllCategories.php @@ -103,7 +103,7 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase { 'pp_page=page_id', 'pp_propname' => 'hiddencat' ) ), ) ); - $this->addFields( 'pp_propname AS cat_hidden' ); + $this->addFields( array( 'cat_hidden' => 'pp_propname' ) ); } $res = $this->select( __METHOD__ ); diff --git a/includes/api/ApiQueryAllUsers.php b/includes/api/ApiQueryAllUsers.php index 1e29a64832..13256624a6 100644 --- a/includes/api/ApiQueryAllUsers.php +++ b/includes/api/ApiQueryAllUsers.php @@ -152,7 +152,7 @@ class ApiQueryAllUsers extends ApiQueryBase { 'INNER JOIN', 'rc_user_text=user_name' ) ) ); - $this->addFields( 'COUNT(*) AS recentedits' ); + $this->addFields( array( 'recentedits' => 'COUNT(*)' ) ); $this->addWhere( 'rc_log_type IS NULL OR rc_log_type != ' . $db->addQuotes( 'newusers' ) ); $timestamp = $db->timestamp( wfTimestamp( TS_UNIX ) - $wgActiveUserDays*24*3600 ); diff --git a/includes/api/ApiQueryCategoryInfo.php b/includes/api/ApiQueryCategoryInfo.php index 76246a2831..31517fabaf 100644 --- a/includes/api/ApiQueryCategoryInfo.php +++ b/includes/api/ApiQueryCategoryInfo.php @@ -62,7 +62,7 @@ class ApiQueryCategoryInfo extends ApiQueryBase { 'pp_propname' => 'hiddencat' ) ), ) ); - $this->addFields( array( 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'pp_propname AS cat_hidden' ) ); + $this->addFields( array( 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files', 'cat_hidden' => 'pp_propname' ) ); $this->addWhere( array( 'cat_title' => $cattitles ) ); if ( !is_null( $params['continue'] ) ) { diff --git a/includes/api/ApiQueryLinks.php b/includes/api/ApiQueryLinks.php index e54e2e8676..9e4b7ebb36 100644 --- a/includes/api/ApiQueryLinks.php +++ b/includes/api/ApiQueryLinks.php @@ -85,9 +85,9 @@ class ApiQueryLinks extends ApiQueryGeneratorBase { $params = $this->extractRequestParams(); $this->addFields( array( - $this->prefix . '_from AS pl_from', - $this->prefix . '_namespace AS pl_namespace', - $this->prefix . '_title AS pl_title' + 'pl_from' => $this->prefix . '_from', + 'pl_namespace' => $this->prefix . '_namespace', + 'pl_title' => $this->prefix . '_title' ) ); $this->addTables( $this->table ); diff --git a/includes/api/ApiQueryTags.php b/includes/api/ApiQueryTags.php index edd1553c0b..eb679e0395 100644 --- a/includes/api/ApiQueryTags.php +++ b/includes/api/ApiQueryTags.php @@ -59,7 +59,7 @@ class ApiQueryTags extends ApiQueryBase { $this->addTables( 'change_tag' ); $this->addFields( 'ct_tag' ); - $this->addFieldsIf( 'count(*) AS hitcount', $this->fld_hitcount ); + $this->addFieldsIf( array( 'hitcount' => 'COUNT(*)' ), $this->fld_hitcount ); $this->addOption( 'LIMIT', $this->limit + 1 ); $this->addOption( 'GROUP BY', 'ct_tag' ); diff --git a/includes/db/Database.php b/includes/db/Database.php index 3bf058829d..61061b2012 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -1202,10 +1202,12 @@ abstract class DatabaseBase implements DatabaseType { * @param $vars string|array * * May be either a field name or an array of field names. The field names - * here are complete fragments of SQL, for direct inclusion into the SELECT - * query. Expressions and aliases may be specified as in SQL, for example: + * can be complete fragments of SQL, for direct inclusion into the SELECT + * query. If an array is given, field aliases can be specified, for example: * - * array( 'MAX(rev_id) AS maxrev' ) + * array( 'maxrev' => 'MAX(rev_id)' ) + * + * This includes an expression with the alias "maxrev" in the query. * * If an expression is given, care must be taken to ensure that it is * DBMS-independent. @@ -1335,7 +1337,7 @@ abstract class DatabaseBase implements DatabaseType { $options = array(), $join_conds = array() ) { if ( is_array( $vars ) ) { - $vars = implode( ',', $vars ); + $vars = implode( ',', $this->fieldNamesWithAlias( $vars ) ); } $options = (array)$options; @@ -1442,7 +1444,7 @@ abstract class DatabaseBase implements DatabaseType { $fname = 'DatabaseBase::estimateRowCount', $options = array() ) { $rows = 0; - $res = $this->select( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options ); + $res = $this->select( $table, array( 'rowcount' => 'COUNT(*)' ), $conds, $fname, $options ); if ( $res ) { $row = $this->fetchRow( $res ); @@ -2044,6 +2046,39 @@ abstract class DatabaseBase implements DatabaseType { return $retval; } + /** + * Get an aliased field name + * e.g. fieldName AS newFieldName + * + * @param $name string Field name + * @param $alias string|bool Alias (optional) + * @return string SQL name for aliased field. Will not alias a field to its own name + */ + public function fieldNameWithAlias( $name, $alias = false ) { + if ( !$alias || (string)$alias === (string)$name ) { + return $name; + } else { + return $name . ' AS ' . $alias; //PostgreSQL needs AS + } + } + + /** + * Gets an array of aliased field names + * + * @param $fields array( [alias] => field ) + * @return array of strings, see fieldNameWithAlias() + */ + public function fieldNamesWithAlias( $fields ) { + $retval = array(); + foreach ( $fields as $alias => $field ) { + if ( is_numeric( $alias ) ) { + $alias = $field; + } + $retval[] = $this->fieldNameWithAlias( $field, $alias ); + } + return $retval; + } + /** * Get the aliased table name clause for a FROM clause * which might have a JOIN and/or USE INDEX clause diff --git a/includes/db/ORMTable.php b/includes/db/ORMTable.php index bd6bf0b817..a77074ffca 100644 --- a/includes/db/ORMTable.php +++ b/includes/db/ORMTable.php @@ -308,7 +308,7 @@ abstract class ORMTable implements IORMTable { */ public function count( array $conditions = array(), array $options = array() ) { $res = $this->rawSelectRow( - array( 'COUNT(*) AS rowcount' ), + array( 'rowcount' => 'COUNT(*)' ), $this->getPrefixedValues( $conditions ), $options ); diff --git a/includes/job/Job.php b/includes/job/Job.php index fcf5ca8555..d7c95632fe 100644 --- a/includes/job/Job.php +++ b/includes/job/Job.php @@ -158,8 +158,8 @@ abstract class Job { if ( !$affected ) { // Failed, someone else beat us to it // Try getting a random row - $row = $dbw->selectRow( 'job', array( 'MIN(job_id) as minjob', - 'MAX(job_id) as maxjob' ), '1=1', __METHOD__ ); + $row = $dbw->selectRow( 'job', array( 'minjob' => 'MIN(job_id)', + 'maxjob' => 'MAX(job_id)' ), '1=1', __METHOD__ ); if ( $row === false || is_null( $row->minjob ) || is_null( $row->maxjob ) ) { // No jobs to get wfProfileOut( __METHOD__ ); diff --git a/includes/specials/SpecialActiveusers.php b/includes/specials/SpecialActiveusers.php index 156b5f2d5b..aefa6cca4e 100644 --- a/includes/specials/SpecialActiveusers.php +++ b/includes/specials/SpecialActiveusers.php @@ -103,11 +103,11 @@ class ActiveUsersPager extends UsersPager { $query = array( 'tables' => array( 'recentchanges', 'user', 'ipblocks' ), - 'fields' => array( 'rc_user_text AS user_name', // inheritance + 'fields' => array( 'user_name' => 'rc_user_text', // inheritance 'rc_user_text', // for Pager 'user_id', - 'COUNT(*) AS recentedits', - 'MAX(ipb_user) AS blocked' + 'recentedits' => 'COUNT(*)', + 'blocked' => 'MAX(ipb_user)' ), 'options' => array( 'GROUP BY' => array( 'rc_user_text', 'user_id' ), diff --git a/includes/specials/SpecialAncientpages.php b/includes/specials/SpecialAncientpages.php index 1203e1fd9c..6e3d49bdce 100644 --- a/includes/specials/SpecialAncientpages.php +++ b/includes/specials/SpecialAncientpages.php @@ -41,9 +41,9 @@ class AncientPagesPage extends QueryPage { function getQueryInfo() { return array( 'tables' => array( 'page', 'revision' ), - 'fields' => array( 'page_namespace AS namespace', - 'page_title AS title', - 'rev_timestamp AS value' ), + 'fields' => array( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'rev_timestamp' ), 'conds' => array( 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0, 'page_latest=rev_id' ) diff --git a/includes/specials/SpecialBlockList.php b/includes/specials/SpecialBlockList.php index 0a3a28fe19..7143d5bc42 100644 --- a/includes/specials/SpecialBlockList.php +++ b/includes/specials/SpecialBlockList.php @@ -372,7 +372,7 @@ class BlockListPager extends TablePager { 'ipb_user', 'ipb_by', 'ipb_by_text', - 'user_name AS by_user_name', + 'by_user_name' => 'user_name', 'ipb_reason', 'ipb_timestamp', 'ipb_auto', diff --git a/includes/specials/SpecialBrokenRedirects.php b/includes/specials/SpecialBrokenRedirects.php index d6244300dc..8119e6d1e8 100644 --- a/includes/specials/SpecialBrokenRedirects.php +++ b/includes/specials/SpecialBrokenRedirects.php @@ -45,9 +45,9 @@ class BrokenRedirectsPage extends QueryPage { return array( 'tables' => array( 'redirect', 'p1' => 'page', 'p2' => 'page' ), - 'fields' => array( 'p1.page_namespace AS namespace', - 'p1.page_title AS title', - 'p1.page_title AS value', + 'fields' => array( 'namespace' => 'p1.page_namespace', + 'title' => 'p1.page_title', + 'value' => 'p1.page_title', 'rd_namespace', 'rd_title' ), diff --git a/includes/specials/SpecialDeadendpages.php b/includes/specials/SpecialDeadendpages.php index 75818c9128..f4904a50ce 100644 --- a/includes/specials/SpecialDeadendpages.php +++ b/includes/specials/SpecialDeadendpages.php @@ -59,9 +59,9 @@ class DeadendPagesPage extends PageQueryPage { function getQueryInfo() { return array( 'tables' => array( 'page', 'pagelinks' ), - 'fields' => array( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' + 'fields' => array( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array( 'pl_from IS NULL', 'page_namespace' => MWNamespace::getContentNamespaces(), diff --git a/includes/specials/SpecialDisambiguations.php b/includes/specials/SpecialDisambiguations.php index e7606c6edc..48180a7723 100644 --- a/includes/specials/SpecialDisambiguations.php +++ b/includes/specials/SpecialDisambiguations.php @@ -99,9 +99,9 @@ class DisambiguationsPage extends QueryPage { 'p2' => 'page' ), 'fields' => array( - 'p1.page_namespace AS namespace', - 'p1.page_title AS title', - 'pl_from AS value' + 'namespace' => 'p1.page_namespace', + 'title' => 'p1.page_title', + 'value' => 'pl_from' ), 'conds' => array( $this->getQueryFromLinkBatch(), diff --git a/includes/specials/SpecialDoubleRedirects.php b/includes/specials/SpecialDoubleRedirects.php index 51cb08af6e..5864ca9fd5 100644 --- a/includes/specials/SpecialDoubleRedirects.php +++ b/includes/specials/SpecialDoubleRedirects.php @@ -47,13 +47,13 @@ class DoubleRedirectsPage extends QueryPage { 'tables' => array ( 'ra' => 'redirect', 'rb' => 'redirect', 'pa' => 'page', 'pb' => 'page', 'pc' => 'page' ), - 'fields' => array ( 'pa.page_namespace AS namespace', - 'pa.page_title AS title', - 'pa.page_title AS value', - 'pb.page_namespace AS nsb', - 'pb.page_title AS tb', - 'pc.page_namespace AS nsc', - 'pc.page_title AS tc' ), + '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', diff --git a/includes/specials/SpecialExport.php b/includes/specials/SpecialExport.php index b00eec8245..b4294b3288 100644 --- a/includes/specials/SpecialExport.php +++ b/includes/specials/SpecialExport.php @@ -455,7 +455,7 @@ class SpecialExport extends SpecialPage { private function getTemplates( $inputPages, $pageSet ) { return $this->getLinks( $inputPages, $pageSet, 'templatelinks', - array( 'tl_namespace AS namespace', 'tl_title AS title' ), + array( 'namespace' => 'tl_namespace', 'title' => 'tl_title' ), array( 'page_id=tl_from' ) ); } @@ -497,7 +497,7 @@ class SpecialExport extends SpecialPage { for( ; $depth > 0; --$depth ) { $pageSet = $this->getLinks( $inputPages, $pageSet, 'pagelinks', - array( 'pl_namespace AS namespace', 'pl_title AS title' ), + array( 'namespace' => 'pl_namespace', 'title' => 'pl_title' ), array( 'page_id=pl_from' ) ); $inputPages = array_keys( $pageSet ); @@ -519,7 +519,7 @@ class SpecialExport extends SpecialPage { $inputPages, $pageSet, 'imagelinks', - array( NS_FILE . ' AS namespace', 'il_to AS title' ), + array( 'namespace' => NS_FILE, 'title' => 'il_to' ), array( 'page_id=il_from' ) ); } diff --git a/includes/specials/SpecialFewestrevisions.php b/includes/specials/SpecialFewestrevisions.php index 5610cc2bc8..7e4bc9cee3 100644 --- a/includes/specials/SpecialFewestrevisions.php +++ b/includes/specials/SpecialFewestrevisions.php @@ -44,10 +44,10 @@ class FewestrevisionsPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'revision', 'page' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'COUNT(*) AS value', - 'page_is_redirect AS redirect' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'COUNT(*)', + 'redirect' => 'page_is_redirect' ), 'conds' => array ( 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_id = rev_page' ), 'options' => array ( 'HAVING' => 'COUNT(*) > 1', diff --git a/includes/specials/SpecialFileDuplicateSearch.php b/includes/specials/SpecialFileDuplicateSearch.php index f8e40e0f40..ccf8ba1716 100644 --- a/includes/specials/SpecialFileDuplicateSearch.php +++ b/includes/specials/SpecialFileDuplicateSearch.php @@ -78,8 +78,8 @@ class FileDuplicateSearchPage extends QueryPage { return array( 'tables' => array( 'image' ), 'fields' => array( - 'img_name AS title', - 'img_sha1 AS value', + 'title' => 'img_name', + 'value' => 'img_sha1', 'img_user_text', 'img_timestamp' ), diff --git a/includes/specials/SpecialLinkSearch.php b/includes/specials/SpecialLinkSearch.php index 06282693f2..0810ee777a 100644 --- a/includes/specials/SpecialLinkSearch.php +++ b/includes/specials/SpecialLinkSearch.php @@ -171,9 +171,9 @@ class LinkSearchPage extends QueryPage { $like = $dbr->buildLike( $stripped ); $retval = array ( 'tables' => array ( 'page', 'externallinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'el_index AS value', 'el_to AS url' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'el_index', 'url' => 'el_to' ), 'conds' => array ( 'page_id = el_from', "$clause $like" ), 'options' => array( 'USE INDEX' => $clause ) diff --git a/includes/specials/SpecialListredirects.php b/includes/specials/SpecialListredirects.php index f9cf3e6e50..fe338a08a5 100644 --- a/includes/specials/SpecialListredirects.php +++ b/includes/specials/SpecialListredirects.php @@ -41,14 +41,14 @@ class ListredirectsPage extends QueryPage { function getQueryInfo() { return array( 'tables' => array( 'p1' => 'page', 'redirect', 'p2' => 'page' ), - 'fields' => array( 'p1.page_namespace AS namespace', - 'p1.page_title AS title', - 'p1.page_title AS value', + 'fields' => array( 'namespace' => 'p1.page_namespace', + 'title' => 'p1.page_title', + 'value' => 'p1.page_title', 'rd_namespace', 'rd_title', 'rd_fragment', 'rd_interwiki', - 'p2.page_id AS redirid' ), + 'redirid' => 'p2.page_id' ), 'conds' => array( 'p1.page_is_redirect' => 1 ), 'join_conds' => array( 'redirect' => array( 'LEFT JOIN', 'rd_from=p1.page_id' ), diff --git a/includes/specials/SpecialLonelypages.php b/includes/specials/SpecialLonelypages.php index 0c86163709..763bbdb1d8 100644 --- a/includes/specials/SpecialLonelypages.php +++ b/includes/specials/SpecialLonelypages.php @@ -50,9 +50,9 @@ class LonelyPagesPage extends PageQueryPage { return array ( 'tables' => array ( 'page', 'pagelinks', 'templatelinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array ( 'pl_namespace IS NULL', 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0, diff --git a/includes/specials/SpecialMIMEsearch.php b/includes/specials/SpecialMIMEsearch.php index 46a35c4ce1..104c653f7b 100644 --- a/includes/specials/SpecialMIMEsearch.php +++ b/includes/specials/SpecialMIMEsearch.php @@ -45,9 +45,9 @@ class MIMEsearchPage extends QueryPage { public function getQueryInfo() { return array( 'tables' => array( 'image' ), - 'fields' => array( "'" . NS_FILE . "' AS namespace", - 'img_name AS title', - 'img_major_mime AS value', + 'fields' => array( 'namespace' => NS_FILE, + 'title' => 'img_name', + 'value' => 'img_major_mime', 'img_size', 'img_width', 'img_height', diff --git a/includes/specials/SpecialMostcategories.php b/includes/specials/SpecialMostcategories.php index 6de484086b..3f0bafa312 100644 --- a/includes/specials/SpecialMostcategories.php +++ b/includes/specials/SpecialMostcategories.php @@ -41,9 +41,9 @@ class MostcategoriesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'categorylinks', 'page' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'COUNT(*)' ), 'conds' => array ( 'page_namespace' => MWNamespace::getContentNamespaces() ), 'options' => array ( 'HAVING' => 'COUNT(*) > 1', 'GROUP BY' => array( 'page_namespace', 'page_title' ) ), diff --git a/includes/specials/SpecialMostimages.php b/includes/specials/SpecialMostimages.php index 7805e53e73..3d797908e4 100644 --- a/includes/specials/SpecialMostimages.php +++ b/includes/specials/SpecialMostimages.php @@ -41,9 +41,9 @@ class MostimagesPage extends ImageQueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'imagelinks' ), - 'fields' => array ( "'" . NS_FILE . "' AS namespace", - 'il_to AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => NS_FILE, + 'title' => 'il_to', + 'value' => 'COUNT(*)' ), 'options' => array ( 'GROUP BY' => 'il_to', 'HAVING' => 'COUNT(*) > 1' ) ); diff --git a/includes/specials/SpecialMostlinked.php b/includes/specials/SpecialMostlinked.php index 3c3ab36c55..89c4350911 100644 --- a/includes/specials/SpecialMostlinked.php +++ b/includes/specials/SpecialMostlinked.php @@ -42,9 +42,9 @@ class MostlinkedPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'pagelinks', 'page' ), - 'fields' => array ( 'pl_namespace AS namespace', - 'pl_title AS title', - 'COUNT(*) AS value', + 'fields' => array ( 'namespace' => 'pl_namespace', + 'title' => 'pl_title', + 'value' => 'COUNT(*)', 'page_namespace' ), 'options' => array ( 'HAVING' => 'COUNT(*) > 1', 'GROUP BY' => array( 'pl_namespace', 'pl_title', diff --git a/includes/specials/SpecialMostlinkedcategories.php b/includes/specials/SpecialMostlinkedcategories.php index 408d79170a..dadef8bf9c 100644 --- a/includes/specials/SpecialMostlinkedcategories.php +++ b/includes/specials/SpecialMostlinkedcategories.php @@ -40,9 +40,9 @@ class MostlinkedCategoriesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'category' ), - 'fields' => array ( 'cat_title AS title', - NS_CATEGORY . ' AS namespace', - 'cat_pages AS value' ), + 'fields' => array ( 'title' => 'cat_title', + 'namespace' => NS_CATEGORY, + 'value' => 'cat_pages' ), ); } diff --git a/includes/specials/SpecialMostlinkedtemplates.php b/includes/specials/SpecialMostlinkedtemplates.php index 0b587dcf9f..22932e5cc9 100644 --- a/includes/specials/SpecialMostlinkedtemplates.php +++ b/includes/specials/SpecialMostlinkedtemplates.php @@ -64,9 +64,9 @@ class MostlinkedTemplatesPage extends QueryPage { public function getQueryInfo() { return array ( 'tables' => array ( 'templatelinks' ), - 'fields' => array ( 'tl_namespace AS namespace', - 'tl_title AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => 'tl_namespace', + 'title' => 'tl_title', + 'value' => 'COUNT(*)' ), 'conds' => array ( 'tl_namespace' => NS_TEMPLATE ), 'options' => array( 'GROUP BY' => array( 'tl_namespace', 'tl_title' ) ) ); diff --git a/includes/specials/SpecialNewpages.php b/includes/specials/SpecialNewpages.php index 1798e8f07a..19ea1719c0 100644 --- a/includes/specials/SpecialNewpages.php +++ b/includes/specials/SpecialNewpages.php @@ -530,7 +530,7 @@ class NewPagesPager extends ReverseChronologicalPager { $fields = array( 'rc_namespace', 'rc_title', 'rc_cur_id', 'rc_user', 'rc_user_text', 'rc_comment', 'rc_timestamp', 'rc_patrolled','rc_id', 'rc_deleted', - 'page_len AS length', 'page_latest AS rev_id', 'ts_tags', 'rc_this_oldid', + 'length' => 'page_len', 'rev_id' => 'page_latest', 'ts_tags', 'rc_this_oldid', 'page_namespace', 'page_title' ); $join_conds = array( 'page' => array( 'INNER JOIN', 'page_id=rc_cur_id' ) ); diff --git a/includes/specials/SpecialPopularpages.php b/includes/specials/SpecialPopularpages.php index 9f84804a05..448d179984 100644 --- a/includes/specials/SpecialPopularpages.php +++ b/includes/specials/SpecialPopularpages.php @@ -42,9 +42,9 @@ class PopularPagesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array( 'page' ), - 'fields' => array( 'page_namespace AS namespace', - 'page_title AS title', - 'page_counter AS value'), + 'fields' => array( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_counter'), 'conds' => array( 'page_is_redirect' => 0, 'page_namespace' => MWNamespace::getContentNamespaces() ) ); } diff --git a/includes/specials/SpecialShortpages.php b/includes/specials/SpecialShortpages.php index ee045744a8..5a4e8f0383 100644 --- a/includes/specials/SpecialShortpages.php +++ b/includes/specials/SpecialShortpages.php @@ -40,9 +40,9 @@ class ShortPagesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'page' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_len AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_len' ), 'conds' => array ( 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0 ), diff --git a/includes/specials/SpecialTags.php b/includes/specials/SpecialTags.php index df720a125c..c895daec74 100644 --- a/includes/specials/SpecialTags.php +++ b/includes/specials/SpecialTags.php @@ -47,7 +47,7 @@ class SpecialTags extends SpecialPage { Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() ) ); $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'change_tag', array( 'ct_tag', 'count(*) AS hitcount' ), + $res = $dbr->select( 'change_tag', array( 'ct_tag', 'hitcount' => 'count(*)' ), array(), __METHOD__, array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) ); foreach ( $res as $row ) { diff --git a/includes/specials/SpecialUncategorizedimages.php b/includes/specials/SpecialUncategorizedimages.php index 3efed74705..5865bf62af 100644 --- a/includes/specials/SpecialUncategorizedimages.php +++ b/includes/specials/SpecialUncategorizedimages.php @@ -49,9 +49,9 @@ class UncategorizedImagesPage extends ImageQueryPage { function getQueryInfo() { return array ( 'tables' => array( 'page', 'categorylinks' ), - 'fields' => array( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array( 'cl_from IS NULL', 'page_namespace' => NS_FILE, 'page_is_redirect' => 0 ), diff --git a/includes/specials/SpecialUncategorizedpages.php b/includes/specials/SpecialUncategorizedpages.php index 08a694486c..1226a6ca35 100644 --- a/includes/specials/SpecialUncategorizedpages.php +++ b/includes/specials/SpecialUncategorizedpages.php @@ -46,9 +46,9 @@ class UncategorizedPagesPage extends PageQueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'page', 'categorylinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), // default for page_namespace is all content namespaces (if requestedNamespace is false) // otherwise, page_namespace is requestedNamespace 'conds' => array ( 'cl_from IS NULL', diff --git a/includes/specials/SpecialUndelete.php b/includes/specials/SpecialUndelete.php index 611b3b9212..dfdd08e2a2 100644 --- a/includes/specials/SpecialUndelete.php +++ b/includes/specials/SpecialUndelete.php @@ -92,7 +92,7 @@ class PageArchive { array( 'ar_namespace', 'ar_title', - 'COUNT(*) AS count' + 'count' => 'COUNT(*)' ), $condition, __METHOD__, diff --git a/includes/specials/SpecialUnusedcategories.php b/includes/specials/SpecialUnusedcategories.php index 611a33c3bf..1bd38e176e 100644 --- a/includes/specials/SpecialUnusedcategories.php +++ b/includes/specials/SpecialUnusedcategories.php @@ -39,9 +39,9 @@ class UnusedCategoriesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'page', 'categorylinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array ( 'cl_from IS NULL', 'page_namespace' => NS_CATEGORY, 'page_is_redirect' => 0 ), diff --git a/includes/specials/SpecialUnusedimages.php b/includes/specials/SpecialUnusedimages.php index 9c8ccfa79c..cdab557ee3 100644 --- a/includes/specials/SpecialUnusedimages.php +++ b/includes/specials/SpecialUnusedimages.php @@ -47,9 +47,9 @@ class UnusedimagesPage extends ImageQueryPage { global $wgCountCategorizedImagesAsUsed; $retval = array ( 'tables' => array ( 'image', 'imagelinks' ), - 'fields' => array ( "'" . NS_FILE . "' AS namespace", - 'img_name AS title', - 'img_timestamp AS value', + 'fields' => array ( 'namespace' => NS_FILE, + 'title' => 'img_name', + 'value' => 'img_timestamp', 'img_user', 'img_user_text', 'img_description' ), 'conds' => array ( 'il_to IS NULL' ), diff --git a/includes/specials/SpecialUnusedtemplates.php b/includes/specials/SpecialUnusedtemplates.php index 0928e261bd..06077d1f18 100644 --- a/includes/specials/SpecialUnusedtemplates.php +++ b/includes/specials/SpecialUnusedtemplates.php @@ -42,9 +42,9 @@ class UnusedtemplatesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'page', 'templatelinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array ( 'page_namespace' => NS_TEMPLATE, 'tl_from IS NULL', 'page_is_redirect' => 0 ), diff --git a/includes/specials/SpecialUnwatchedpages.php b/includes/specials/SpecialUnwatchedpages.php index 4bd0232d09..e5a79413f7 100644 --- a/includes/specials/SpecialUnwatchedpages.php +++ b/includes/specials/SpecialUnwatchedpages.php @@ -41,9 +41,9 @@ class UnwatchedpagesPage extends QueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'page', 'watchlist' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_namespace AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_namespace' ), 'conds' => array ( 'wl_title IS NULL', 'page_is_redirect' => 0, "page_namespace != '" . NS_MEDIAWIKI . diff --git a/includes/specials/SpecialWantedcategories.php b/includes/specials/SpecialWantedcategories.php index f497e4e26b..0b1fb25107 100644 --- a/includes/specials/SpecialWantedcategories.php +++ b/includes/specials/SpecialWantedcategories.php @@ -37,9 +37,9 @@ class WantedCategoriesPage extends WantedQueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'categorylinks', 'page' ), - 'fields' => array ( "'" . NS_CATEGORY . "' AS namespace", - 'cl_to AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => NS_CATEGORY, + 'title' => 'cl_to', + 'value' => 'COUNT(*)' ), 'conds' => array ( 'page_title IS NULL' ), 'options' => array ( 'GROUP BY' => 'cl_to' ), 'join_conds' => array ( 'page' => array ( 'LEFT JOIN', diff --git a/includes/specials/SpecialWantedfiles.php b/includes/specials/SpecialWantedfiles.php index 2475189147..f52f7bb9bd 100644 --- a/includes/specials/SpecialWantedfiles.php +++ b/includes/specials/SpecialWantedfiles.php @@ -75,9 +75,9 @@ class WantedFilesPage extends WantedQueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'imagelinks', 'image' ), - 'fields' => array ( "'" . NS_FILE . "' AS namespace", - 'il_to AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => NS_FILE, + 'title' => 'il_to', + 'value' => 'COUNT(*)' ), 'conds' => array ( 'img_name IS NULL' ), 'options' => array ( 'GROUP BY' => 'il_to' ), 'join_conds' => array ( 'image' => diff --git a/includes/specials/SpecialWantedpages.php b/includes/specials/SpecialWantedpages.php index 9f5d52d5cb..7673305d02 100644 --- a/includes/specials/SpecialWantedpages.php +++ b/includes/specials/SpecialWantedpages.php @@ -60,9 +60,9 @@ class WantedPagesPage extends WantedQueryPage { 'pg2' => 'page' ), 'fields' => array( - 'pl_namespace AS namespace', - 'pl_title AS title', - 'COUNT(*) AS value' + 'namespace' => 'pl_namespace', + 'title' => 'pl_title', + 'value' => 'COUNT(*)' ), 'conds' => array( 'pg1.page_namespace IS NULL', diff --git a/includes/specials/SpecialWantedtemplates.php b/includes/specials/SpecialWantedtemplates.php index 2b4364bc46..f3e3369838 100644 --- a/includes/specials/SpecialWantedtemplates.php +++ b/includes/specials/SpecialWantedtemplates.php @@ -40,9 +40,9 @@ class WantedTemplatesPage extends WantedQueryPage { function getQueryInfo() { return array ( 'tables' => array ( 'templatelinks', 'page' ), - 'fields' => array ( 'tl_namespace AS namespace', - 'tl_title AS title', - 'COUNT(*) AS value' ), + 'fields' => array ( 'namespace' => 'tl_namespace', + 'title' => 'tl_title', + 'value' => 'COUNT(*)' ), 'conds' => array ( 'page_title IS NULL', 'tl_namespace' => NS_TEMPLATE ), 'options' => array ( diff --git a/includes/specials/SpecialWatchlist.php b/includes/specials/SpecialWatchlist.php index a81eb5bf6f..5dfc1133ef 100644 --- a/includes/specials/SpecialWatchlist.php +++ b/includes/specials/SpecialWatchlist.php @@ -500,7 +500,7 @@ class SpecialWatchlist extends SpecialPage { $dbr = wfGetDB( DB_SLAVE, 'watchlist' ); # Fetch the raw count - $res = $dbr->select( 'watchlist', 'COUNT(*) AS count', + $res = $dbr->select( 'watchlist', array( 'count' => 'COUNT(*)' ), array( 'wl_user' => $this->getUser()->getId() ), __METHOD__ ); $row = $dbr->fetchObject( $res ); $count = $row->count; diff --git a/includes/specials/SpecialWithoutinterwiki.php b/includes/specials/SpecialWithoutinterwiki.php index 74eedc37ee..2988b04f4c 100644 --- a/includes/specials/SpecialWithoutinterwiki.php +++ b/includes/specials/SpecialWithoutinterwiki.php @@ -80,9 +80,9 @@ class WithoutInterwikiPage extends PageQueryPage { function getQueryInfo() { $query = array ( 'tables' => array ( 'page', 'langlinks' ), - 'fields' => array ( 'page_namespace AS namespace', - 'page_title AS title', - 'page_title AS value' ), + 'fields' => array ( 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title' ), 'conds' => array ( 'll_title IS NULL', 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0 ), diff --git a/tests/phpunit/includes/db/DatabaseSQLTest.php b/tests/phpunit/includes/db/DatabaseSQLTest.php new file mode 100644 index 0000000000..d56e632c30 --- /dev/null +++ b/tests/phpunit/includes/db/DatabaseSQLTest.php @@ -0,0 +1,75 @@ +db->getType() !== 'mysql' ) { + $this->markTestSkipped( 'No mysql database' ); + } + } + + /** + * @dataProvider dataSQL + */ + function testSQL( $sql, $sqlText ) { + $this->assertEquals( trim( $this->db->selectSQLText( + isset( $sql['tables'] ) ? $sql['tables'] : array(), + isset( $sql['fields'] ) ? $sql['fields'] : array(), + isset( $sql['conds'] ) ? $sql['conds'] : array(), + __METHOD__, + isset( $sql['options'] ) ? $sql['options'] : array(), + isset( $sql['join_conds'] ) ? $sql['join_conds'] : array() + ) ), $sqlText ); + } + + function dataSQL() { + return array( + array( + array( + 'tables' => 'table', + 'fields' => array( 'field', 'alias' => 'field2' ), + 'conds' => array( 'alias' => 'text' ), + ), + "SELECT field,field2 AS alias " . + "FROM `unittest_table` " . + "WHERE alias = 'text'" + ), + array( + array( + 'tables' => 'table', + 'fields' => array( 'field', 'alias' => 'field2' ), + 'conds' => array( 'alias' => 'text' ), + 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), + ), + "SELECT field,field2 AS alias " . + "FROM `unittest_table` " . + "WHERE alias = 'text' " . + "ORDER BY field " . + "LIMIT 1" + ), + array( + array( + 'tables' => array( 'table', 't2' => 'table2' ), + 'fields' => array( 'tid', 'field', 'alias' => 'field2', 't2.id' ), + 'conds' => array( 'alias' => 'text' ), + 'options' => array( 'LIMIT' => 1, 'ORDER BY' => 'field' ), + 'join_conds' => array( 't2' => array( + 'LEFT JOIN', 'tid = t2.id' + )), + ), + "SELECT tid,field,field2 AS alias,t2.id " . + "FROM `unittest_table` LEFT JOIN `unittest_table2` `t2` ON ((tid = t2.id)) " . + "WHERE alias = 'text' " . + "ORDER BY field " . + "LIMIT 1" + ), + ); + } +} \ No newline at end of file -- 2.20.1