Merge "(bug 38406) Properly quote table names in DatabaseBase::tableName()"
authorDemon <chadh@wikimedia.org>
Tue, 14 Aug 2012 17:42:20 +0000 (17:42 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 14 Aug 2012 17:42:20 +0000 (17:42 +0000)
1  2 
includes/db/Database.php

diff --combined includes/db/Database.php
@@@ -462,6 -462,16 +462,6 @@@ abstract class DatabaseBase implements 
                return true;
        }
  
 -      /**
 -       * Returns true if this database requires that SELECT DISTINCT queries require that all
 -         ORDER BY expressions occur in the SELECT list per the SQL92 standard
 -       *
 -       * @return bool
 -       */
 -      function standardSelectDistinct() {
 -              return true;
 -      }
 -
        /**
         * Returns true if this database can do a native search on IP columns
         * e.g. this works as expected: .. WHERE rc_ip = '127.42.12.102/32';
                throw new MWException( 'Database serialization may cause problems, since the connection is not restored on wakeup.' );
        }
  
 -      /**
 -       * Same as new DatabaseMysql( ... ), kept for backward compatibility
 -       * @deprecated since 1.17
 -       *
 -       * @param $server
 -       * @param $user
 -       * @param $password
 -       * @param $dbName
 -       * @param $flags int
 -       * @return DatabaseMysql
 -       */
 -      static function newFromParams( $server, $user, $password, $dbName, $flags = 0 ) {
 -              wfDeprecated( __METHOD__, '1.17' );
 -              return new DatabaseMysql( $server, $user, $password, $dbName, $flags );
 -      }
 -
 -      /**
 -       * Same as new factory( ... ), kept for backward compatibility
 -       * @deprecated since 1.18
 -       * @see Database::factory()
 -       * @return DatabaseBase
 -       */
 -      public final static function newFromType( $dbType, $p = array() ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              if ( isset( $p['tableprefix'] ) ) {
 -                      $p['tablePrefix'] = $p['tableprefix'];
 -              }
 -              return self::factory( $dbType, $p );
 -      }
 -
        /**
         * Given a DB type, construct the name of the appropriate child class of
         * DatabaseBase. This is designed to replace all of the manual stuff like:
         * & = filename; reads the file and inserts as a blob
         *     (we don't use this though...)
         *
 -       * This function should not be used directly by new code outside of the
 -       * database classes. The query wrapper functions (select() etc.) should be
 -       * used instead.
 -       *
         * @param $sql string
         * @param $func string
         *
         * @return array
         */
 -      function prepare( $sql, $func = 'DatabaseBase::prepare' ) {
 +      protected function prepare( $sql, $func = 'DatabaseBase::prepare' ) {
                /* MySQL doesn't support prepared statements (yet), so just
                   pack up the query for reference. We'll manually replace
                   the bits later. */
         * Free a prepared query, generated by prepare().
         * @param $prepared
         */
 -      function freePrepared( $prepared ) {
 +      protected function freePrepared( $prepared ) {
                /* No-op by default */
        }
  
        }
  
        /**
 -       * Prepare & execute an SQL statement, quoting and inserting arguments
 -       * in the appropriate places.
 +       * For faking prepared SQL statements on DBs that don't support it directly.
         *
 -       * This function should not be used directly by new code outside of the
 -       * database classes. The query wrapper functions (select() etc.) should be
 -       * used instead.
 -       *
 -       * @param $query String
 -       * @param $args ...
 -       *
 -       * @return ResultWrapper
 -       */
 -      function safeQuery( $query, $args = null ) {
 -              $prepared = $this->prepare( $query, 'DatabaseBase::safeQuery' );
 -
 -              if ( !is_array( $args ) ) {
 -                      # Pull the var args
 -                      $args = func_get_args();
 -                      array_shift( $args );
 -              }
 -
 -              $retval = $this->execute( $prepared, $args );
 -              $this->freePrepared( $prepared );
 -
 -              return $retval;
 -      }
 -
 -      /**
 -       * For faking prepared SQL statements on DBs that don't support
 -       * it directly.
         * @param $preparedQuery String: a 'preparable' SQL statement
         * @param $args Array of arguments to fill it with
         * @return string executable SQL
         * @param $matches Array
         * @return String
         */
 -      function fillPreparedArg( $matches ) {
 +      protected function fillPreparedArg( $matches ) {
                switch( $matches[1] ) {
                        case '\\?': return '?';
                        case '\\!': return '!';
         *
         * @param $res Mixed: A SQL result
         */
 -      function freeResult( $res ) {
 -      }
 -
 -      /**
 -       * Simple UPDATE wrapper.
 -       * Usually throws a DBQueryError on failure.
 -       * If errors are explicitly ignored, returns success
 -       *
 -       * This function exists for historical reasons, DatabaseBase::update() has a more standard
 -       * calling convention and feature set
 -       *
 -       * @param $table string
 -       * @param $var
 -       * @param $value
 -       * @param $cond
 -       * @param $fname string
 -       *
 -       * @return bool
 -       */
 -      function set( $table, $var, $value, $cond, $fname = 'DatabaseBase::set' ) {
 -              $table = $this->tableName( $table );
 -              $sql = "UPDATE $table SET $var = '" .
 -                $this->strencode( $value ) . "' WHERE ($cond)";
 -
 -              return (bool)$this->query( $sql, $fname );
 -      }
 +      public function freeResult( $res ) {}
  
        /**
         * A SELECT wrapper which returns a single field from a single result row.
  
        /**
         * The equivalent of DatabaseBase::select() except that the constructed SQL
 -       * is returned, instead of being immediately executed.
 +       * is returned, instead of being immediately executed. This can be useful for
 +       * doing UNION queries, where the SQL text of each query is needed. In general,
 +       * however, callers outside of Database classes should just use select().
         *
         * @param $table string|array Table name
         * @param $vars string|array Field names
                $fname = 'DatabaseBase::estimateRowCount', $options = array() )
        {
                $rows = 0;
 -              $res = $this->select ( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options );
 +              $res = $this->select( $table, 'COUNT(*) AS rowcount', $conds, $fname, $options );
  
                if ( $res ) {
                        $row = $this->fetchRow( $res );
         * @param $options array
         * @return string
         */
 -      function makeInsertOptions( $options ) {
 +      protected function makeInsertOptions( $options ) {
                return implode( ' ', $options );
        }
  
         * @param $options Array: The options passed to DatabaseBase::update
         * @return string
         */
 -      function makeUpdateOptions( $options ) {
 +      protected function makeUpdateOptions( $options ) {
                if ( !is_array( $options ) ) {
                        $options = array( $options );
                }
        }
  
        /**
 -       * Bitwise operations
 +       * Return aggregated value alias
 +       *
 +       * @param $valuedata
 +       * @param $valuename string
 +       *
 +       * @return string
         */
 +      public function aggregateValue( $valuedata, $valuename = 'value' ) {
 +              return $valuename;
 +      }
  
        /**
         * @param $field
                return "($fieldLeft | $fieldRight)";
        }
  
 +      /**
 +       * Build a concatenation list to feed into a SQL query
 +       * @param $stringList Array: list of raw SQL expressions; caller is responsible for any quoting
 +       * @return String
 +       */
 +      public function buildConcat( $stringList ) {
 +              return 'CONCAT(' . implode( ',', $stringList ) . ')';
 +      }
 +
        /**
         * Change the current database
         *
  
                # Quote the $database and $table and apply the prefix if not quoted.
                if ( isset( $database ) ) {
-                       $database = ( $format == 'quoted' || $this->isQuotedIdentifier( $database ) ? $database : $this->addIdentifierQuotes( $database ) );
+                       if ( $format == 'quoted' && !$this->isQuotedIdentifier( $database ) ) {
+                               $database = $this->addIdentifierQuotes( $database );
+                       }
                }
  
                $table = "{$prefix}{$table}";
         *
         * @return string
         */
 -      function indexName( $index ) {
 +      protected function indexName( $index ) {
                // Backwards-compatibility hack
                $renamed = array(
                        'ar_usertext_timestamp' => 'usertext_timestamp',
                return $name[0] == '"' && substr( $name, -1, 1 ) == '"';
        }
  
 -      /**
 -       * Backwards compatibility, identifier quoting originated in DatabasePostgres
 -       * which used quote_ident which does not follow our naming conventions
 -       * was renamed to addIdentifierQuotes.
 -       * @deprecated since 1.18 use addIdentifierQuotes
 -       *
 -       * @param $s string
 -       *
 -       * @return string
 -       */
 -      function quote_ident( $s ) {
 -              wfDeprecated( __METHOD__, '1.18' );
 -              return $this->addIdentifierQuotes( $s );
 -      }
 -
 -      /**
 -       * Escape string for safe LIKE usage.
 -       * WARNING: you should almost never use this function directly,
 -       * instead use buildLike() that escapes everything automatically
 -       * @deprecated since 1.17, warnings in 1.17, removed in ???
 -       *
 -       * @param $s string
 -       *
 -       * @return string
 -       */
 -      public function escapeLike( $s ) {
 -              wfDeprecated( __METHOD__, '1.17' );
 -              return $this->escapeLikeInternal( $s );
 -      }
 -
        /**
         * @param $s string
         * @return string
         * If the result of the query is not ordered, then the rows to be returned
         * are theoretically arbitrary.
         *
 -       * $sql is expected to be a SELECT, if that makes a difference.  For
 -       * UPDATE, limitResultForUpdate should be used.
 +       * $sql is expected to be a SELECT, if that makes a difference.
         *
         * The version provided by default works in MySQL and SQLite.  It will very
         * likely need to be overridden for most other DBMSes.
                if ( !is_numeric( $limit ) ) {
                        throw new DBUnexpectedError( $this, "Invalid non-numeric limit passed to limitResult()\n" );
                }
 -
                return "$sql LIMIT "
 -                              . ( ( is_numeric( $offset ) && $offset != 0 ) ? "{$offset}," : "" )
 -                              . "{$limit} ";
 -      }
 -
 -      /**
 -       * @param $sql
 -       * @param $num
 -       * @return string
 -       */
 -      function limitResultForUpdate( $sql, $num ) {
 -              return $this->limitResult( $sql, $num, 0 );
 +                      . ( ( is_numeric( $offset ) && $offset != 0 ) ? "{$offset}," : "" )
 +                      . "{$limit} ";
        }
  
        /**
                }
        }
  
 -      /**
 -       * Return aggregated value alias
 -       *
 -       * @param $valuedata
 -       * @param $valuename string
 -       *
 -       * @return string
 -       */
 -      function aggregateValue ( $valuedata, $valuename = 'value' ) {
 -              return $valuename;
 -      }
 -
        /**
         * Ping the server and try to reconnect if it there is no connection
         *
                return $b;
        }
  
 -      /**
 -       * Override database's default connection timeout
 -       *
 -       * @param $timeout Integer in seconds
 -       * @return void
 -       * @deprecated since 1.19; use setSessionOptions()
 -       */
 -      public function setTimeout( $timeout ) {
 -              wfDeprecated( __METHOD__, '1.19' );
 -              $this->setSessionOptions( array( 'connTimeout' => $timeout ) );
 -      }
 -
        /**
         * Override database's default behavior. $options include:
         *     'connTimeout' : Set the connection timeout value in seconds.
                return $this->indexName( $matches[1] );
        }
  
 -      /**
 -       * Build a concatenation list to feed into a SQL query
 -       * @param $stringList Array: list of raw SQL expressions; caller is responsible for any quoting
 -       * @return String
 -       */
 -      function buildConcat( $stringList ) {
 -              return 'CONCAT(' . implode( ',', $stringList ) . ')';
 -      }
 -
        /**
         * Check to see if a named lock is available. This is non-blocking.
         *