From f524482f2d1f44cdec68b7150c5f7d9ca227cb14 Mon Sep 17 00:00:00 2001 From: Platonides Date: Tue, 12 Apr 2011 18:54:51 +0000 Subject: [PATCH] Change the duplicateTableStructure() to use the original names. It is now duplicateTableStructure() duty to addIdentifierQuotes() them. Fixed bug for mysql < 4.1 where the new name would be quoted twice. Always quote identifier in Oracle, doing otherwise seems a bug (can someone confirm?) --- includes/db/CloneDatabase.php | 6 +++--- includes/db/DatabaseMysql.php | 6 ++++-- includes/db/DatabaseOracle.php | 19 ++++++++++++++----- includes/db/DatabasePostgres.php | 2 ++ includes/db/DatabaseSqlite.php | 9 ++++----- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/includes/db/CloneDatabase.php b/includes/db/CloneDatabase.php index b3015f69b0..d5da296cea 100644 --- a/includes/db/CloneDatabase.php +++ b/includes/db/CloneDatabase.php @@ -92,14 +92,14 @@ class CloneDatabase { # fix back and forth so tableName() works right. self::changePrefix( $this->oldTablePrefix ); - $oldTableName = $this->db->tableName( $tbl ); + $oldTableName = $this->db->tableName( $tbl, false ); self::changePrefix( $this->newTablePrefix ); - $newTableName = $this->db->tableName( $tbl ); + $newTableName = $this->db->tableName( $tbl, false ); if( $this->dropCurrentTables && !in_array( $this->db->getType(), array( 'postgres' ) ) ) { $this->db->dropTable( $tbl, __METHOD__ ); - wfDebug( __METHOD__." dropping {$this->newTablePrefix}{$oldTableName}\n", true); + wfDebug( __METHOD__." dropping {$newTableName}\n", true); //Dropping the oldTable because the prefix was changed } diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index 1289e88719..07e1e4f085 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -516,16 +516,18 @@ class DatabaseMysql extends DatabaseBase { # Note that we don't bother changing around the prefixes here be- # cause we know we're using MySQL anyway. - $res = $this->query( "SHOW CREATE TABLE $oldName" ); + $res = $this->query( 'SHOW CREATE TABLE ' . $this->addIdentifierQuotes( $oldName ) ); $row = $this->fetchRow( $res ); $oldQuery = $row[1]; $query = preg_replace( '/CREATE TABLE `(.*?)`/', - "CREATE $tmp TABLE `$newName`", $oldQuery ); + "CREATE $tmp TABLE " . $this->addIdentifierQuotes( $newName ), $oldQuery ); if ($oldQuery === $query) { # Couldn't do replacement throw new MWException( "could not create temporary table $newName" ); } } else { + $newName = $this->addIdentifierQuotes( $newName ); + $oldName = $this->addIdentifierQuotes( $oldName ); $query = "CREATE $tmp TABLE $newName (LIKE $oldName)"; } $this->query( $query, $fname ); diff --git a/includes/db/DatabaseOracle.php b/includes/db/DatabaseOracle.php index 7113d1badb..a1dc46f66c 100644 --- a/includes/db/DatabaseOracle.php +++ b/includes/db/DatabaseOracle.php @@ -783,16 +783,19 @@ class DatabaseOracle extends DatabaseBase { function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseOracle::duplicateTableStructure' ) { global $wgDBprefix; + $this->setFlag( DBO_DDLMODE ); $temporary = $temporary ? 'TRUE' : 'FALSE'; - $newName = trim( strtoupper( $newName ), '"'); - $oldName = trim( strtoupper( $oldName ), '"'); + $newName = strtoupper( $newName ); + $oldName = strtoupper( $oldName ); - $tabName = substr( $newName, strlen( $wgDBprefix ) ); - $oldPrefix = substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) ); + $tabName = $this->addIdentifierQuotes( substr( $newName, strlen( $wgDBprefix ) ) ); + $oldPrefix = $this->addIdentifierQuotes( substr( $oldName, 0, strlen( $oldName ) - strlen( $tabName ) ) ); + $newPrefix = $this->addIdentifierQuotes( $wgDBprefix ); - return $this->doQuery( 'BEGIN DUPLICATE_TABLE(\'' . $tabName . '\', \'' . $oldPrefix . '\', \'' . strtoupper( $wgDBprefix ) . '\', ' . $temporary . '); END;' ); + $this->clearFlag( DBO_DDLMODE ); + return $this->doQuery( "BEGIN DUPLICATE_TABLE( $tabName, $oldPrefix, $newPrefix, $temporary ); END;" ); } function listTables( $prefix = null, $fname = 'DatabaseOracle::listTables' ) { @@ -1075,6 +1078,12 @@ class DatabaseOracle extends DatabaseBase { } public function addIdentifierQuotes( $s ) { + return parent::addIdentifierQuotes( $s ); + + /* Does this old code make any sense? + * We could always use quoted identifier. + * See http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements008.htm + */ if ( !$this->mFlags & DBO_DDLMODE ) { $s = '"' . str_replace( '"', '""', $s ) . '"'; } diff --git a/includes/db/DatabasePostgres.php b/includes/db/DatabasePostgres.php index 41e5f57d9e..a1c1d14ab7 100644 --- a/includes/db/DatabasePostgres.php +++ b/includes/db/DatabasePostgres.php @@ -748,6 +748,8 @@ class DatabasePostgres extends DatabaseBase { } function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabasePostgres::duplicateTableStructure' ) { + $newName = $this->addIdentifierQuotes( $newName ); + $oldName = $this->addIdentifierQuotes( $oldName ); return $this->query( 'CREATE ' . ( $temporary ? 'TEMPORARY ' : '' ) . " TABLE $newName (LIKE $oldName INCLUDING DEFAULTS)", $fname ); } diff --git a/includes/db/DatabaseSqlite.php b/includes/db/DatabaseSqlite.php index 654376a4ab..6861a63729 100644 --- a/includes/db/DatabaseSqlite.php +++ b/includes/db/DatabaseSqlite.php @@ -254,10 +254,10 @@ class DatabaseSqlite extends DatabaseBase { /** * Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks */ - function tableName( $name ) { + function tableName( $name, $quoted = true ) { // table names starting with sqlite_ are reserved if ( strpos( $name, 'sqlite_' ) === 0 ) return $name; - return str_replace( '"', '', parent::tableName( $name ) ); + return str_replace( '"', '', parent::tableName( $name, $quoted ) ); } /** @@ -596,14 +596,13 @@ class DatabaseSqlite extends DatabaseBase { } function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = 'DatabaseSqlite::duplicateTableStructure' ) { - - $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name='$oldName' AND type='table'", $fname ); + $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name=" . $this->addQuotes( $oldName ) . " AND type='table'", $fname ); $obj = $this->fetchObject( $res ); if ( !$obj ) { throw new MWException( "Couldn't retrieve structure for table $oldName" ); } $sql = $obj->sql; - $sql = preg_replace( '/\b' . preg_quote( $oldName ) . '\b/', $newName, $sql, 1 ); + $sql = preg_replace( '/(?<=\W)"?' . preg_quote( trim( $this->addIdentifierQuotes( $oldName ), '"' ) ) . '"?(?=\W)/', $this->addIdentifierQuotes( $newName ), $sql, 1 ); if ( $temporary ) { if ( preg_match( '/^\\s*CREATE\\s+VIRTUAL\\s+TABLE\b/i', $sql ) ) { wfDebug( "Table $oldName is virtual, can't create a temporary duplicate.\n" ); -- 2.20.1