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?)
# 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
}
# 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 );
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' ) {
}
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 ) . '"';
}
}
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 );
}
/**
* 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 ) );
}
/**
}
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" );