Merge "rdbms: treat cloned temporary tables as "effective write" targets"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 26 Mar 2019 22:02:10 +0000 (22:02 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 26 Mar 2019 22:02:10 +0000 (22:02 +0000)
1  2 
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabasePostgres.php
tests/phpunit/includes/db/DatabaseSqliteTest.php

@@@ -74,27 -74,11 +74,27 @@@ class DBConnRef implements IDatabase 
        }
  
        public function tablePrefix( $prefix = null ) {
 +              if ( $this->conn === null && $prefix === null ) {
 +                      $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
 +                      // Avoid triggering a database connection
 +                      return $domain->getTablePrefix();
 +              } elseif ( $this->conn !== null && $prefix === null ) {
 +                      // This will just return the prefix
 +                      return $this->__call( __FUNCTION__, func_get_args() );
 +              }
                // Disallow things that might confuse the LoadBalancer tracking
                throw new DBUnexpectedError( $this, "Database selection is disallowed to enable reuse." );
        }
  
        public function dbSchema( $schema = null ) {
 +              if ( $this->conn === null && $schema === null ) {
 +                      $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
 +                      // Avoid triggering a database connection
 +                      return $domain->getSchema();
 +              } elseif ( $this->conn !== null && $schema === null ) {
 +                      // This will just return the schema
 +                      return $this->__call( __FUNCTION__, func_get_args() );
 +              }
                // Disallow things that might confuse the LoadBalancer tracking
                throw new DBUnexpectedError( $this, "Database selection is disallowed to enable reuse." );
        }
        }
  
        public function close() {
 -              return $this->__call( __FUNCTION__, func_get_args() );
 +              throw new DBUnexpectedError( $this->conn, 'Cannot close shared connection.' );
        }
  
-       public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
+       public function query( $sql, $fname = __METHOD__, $flags = 0 ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
  
        }
  
        public function getDBname() {
 +              if ( $this->conn === null ) {
 +                      $domain = DatabaseDomain::newFromId( $this->params[self::FLD_DOMAIN] );
 +                      // Avoid triggering a database connection
 +                      return $domain->getDatabase();
 +              }
 +
                return $this->__call( __FUNCTION__, func_get_args() );
        }
  
@@@ -225,39 -225,6 +225,39 @@@ abstract class DatabaseMysqlBase extend
                }
        }
  
 +      protected function doSelectDomain( DatabaseDomain $domain ) {
 +              if ( $domain->getSchema() !== null ) {
 +                      throw new DBExpectedError( $this, __CLASS__ . ": domain schemas are not supported." );
 +              }
 +
 +              $database = $domain->getDatabase();
 +              // A null database means "don't care" so leave it as is and update the table prefix
 +              if ( $database === null ) {
 +                      $this->currentDomain = new DatabaseDomain(
 +                              $this->currentDomain->getDatabase(),
 +                              null,
 +                              $domain->getTablePrefix()
 +                      );
 +
 +                      return true;
 +              }
 +
 +              if ( $database !== $this->getDBname() ) {
 +                      $sql = 'USE ' . $this->addIdentifierQuotes( $database );
 +                      $ret = $this->doQuery( $sql );
 +                      if ( $ret === false ) {
 +                              $error = $this->lastError();
 +                              $errno = $this->lastErrno();
 +                              $this->reportQueryError( $error, $errno, $sql, __METHOD__ );
 +                      }
 +              }
 +
 +              // Update that domain fields on success (no exception thrown)
 +              $this->currentDomain = $domain;
 +
 +              return true;
 +      }
 +
        /**
         * Open a connection to a MySQL server
         *
                $oldName = $this->addIdentifierQuotes( $oldName );
                $query = "CREATE $tmp TABLE $newName (LIKE $oldName)";
  
-               return $this->query( $query, $fname );
+               return $this->query( $query, $fname, $this::QUERY_PSEUDO_PERMANENT );
        }
  
        /**
@@@ -116,7 -116,7 +116,7 @@@ class DatabasePostgres extends Databas
                        $connectVars['port'] = (int)$this->port;
                }
                if ( $this->flags & self::DBO_SSL ) {
 -                      $connectVars['sslmode'] = 1;
 +                      $connectVars['sslmode'] = 'require';
                }
  
                $this->connectString = $this->makeConnectionString( $connectVars );
@@@ -819,8 -819,12 +819,12 @@@ __INDEXATTR__
  
                $temporary = $temporary ? 'TEMPORARY' : '';
  
-               $ret = $this->query( "CREATE $temporary TABLE $newNameE " .
-                       "(LIKE $oldNameE INCLUDING DEFAULTS INCLUDING INDEXES)", $fname );
+               $ret = $this->query(
+                       "CREATE $temporary TABLE $newNameE " .
+                               "(LIKE $oldNameE INCLUDING DEFAULTS INCLUDING INDEXES)",
+                       $fname,
+                       $this::QUERY_PSEUDO_PERMANENT
+               );
                if ( !$ret ) {
                        return $ret;
                }
                        $fieldE = $this->addIdentifierQuotes( $field );
                        $newSeqE = $this->addIdentifierQuotes( $newSeq );
                        $newSeqQ = $this->addQuotes( $newSeq );
-                       $this->query( "CREATE $temporary SEQUENCE $newSeqE OWNED BY $newNameE.$fieldE", $fname );
+                       $this->query(
+                               "CREATE $temporary SEQUENCE $newSeqE OWNED BY $newNameE.$fieldE",
+                               $fname
+                       );
                        $this->query(
                                "ALTER TABLE $newNameE ALTER COLUMN $fieldE SET DEFAULT nextval({$newSeqQ}::regclass)",
                                $fname
@@@ -1346,6 -1353,10 +1353,6 @@@ SQL
                return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
        }
  
 -      public function getServer() {
 -              return $this->server;
 -      }
 -
        public function buildConcat( $stringList ) {
                return implode( ' || ', $stringList );
        }
@@@ -164,9 -164,9 +164,9 @@@ class DatabaseSqliteTest extends MediaW
                $db = DatabaseSqlite::newStandaloneInstance( ':memory:' );
                $this->assertEquals( 'foo', $db->tableName( 'foo' ) );
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
 -              $db->tablePrefix( 'foo' );
 +              $db->tablePrefix( 'foo_' );
                $this->assertEquals( 'sqlite_master', $db->tableName( 'sqlite_master' ) );
 -              $this->assertEquals( 'foobar', $db->tableName( 'bar' ) );
 +              $this->assertEquals( 'foo_bar', $db->tableName( 'bar' ) );
        }
  
        /**
@@@ -531,7 -531,7 +531,7 @@@ class DatabaseSqliteMock extends Databa
                return Database::factory( 'SqliteMock', $p );
        }
  
-       function query( $sql, $fname = '', $tempIgnore = false ) {
+       function query( $sql, $fname = '', $flags = 0 ) {
                return true;
        }