=== modified file 'includes/bootstrap.inc'
--- includes/bootstrap.inc	2010-11-28 07:32:39 +0000
+++ includes/bootstrap.inc	2010-11-28 08:15:06 +0000
@@ -2244,7 +2244,6 @@ function _drupal_bootstrap_database() {
   // The database autoload routine comes first so that we can load the database
   // system without hitting the database. That is especially important during
   // the install or upgrade process.
-  spl_autoload_register('db_autoload');
   spl_autoload_register('drupal_autoload_class');
   spl_autoload_register('drupal_autoload_interface');
 }

=== modified file 'includes/database/database.inc'
--- includes/database/database.inc	2010-11-28 07:32:39 +0000
+++ includes/database/database.inc	2010-11-28 08:15:06 +0000
@@ -648,13 +648,20 @@ abstract class DatabaseConnection extend
    *
    * @param string $class
    *   The class for which we want the potentially driver-specific class.
+   * @param array $files
+   *   The name of the files in which the driver-specific class can be.
+   * @param $use_autoload
+   *   If TRUE, attempt to load classes using PHP's autoload capability
+   *   as well as the manual approach here.
    * @return string
    *   The name of the class that should be used for this driver.
    */
-  public function getDriverClass($class) {
+  public function getDriverClass($class, array $files = array(), $use_autoload = FALSE) {
     if (empty($this->driverClasses[$class])) {
-      $this->driverClasses[$class] = $class . '_' . $this->driver();
-      if (!class_exists($this->driverClasses[$class])) {
+      $driver = $this->driver();
+      $this->driverClasses[$class] = $class . '_' . $driver;
+      Database::loadDriverFile($driver, $files);
+      if (!class_exists($this->driverClasses[$class], $use_autoload)) {
         $this->driverClasses[$class] = $class;
       }
     }
@@ -681,7 +688,7 @@ abstract class DatabaseConnection extend
    * @see SelectQuery
    */
   public function select($table, $alias = NULL, array $options = array()) {
-    $class = $this->getDriverClass('SelectQuery');
+    $class = $this->getDriverClass('SelectQuery', array('query.inc', 'select.inc'));
     return new $class($table, $alias, $this, $options);
   }
 
@@ -697,7 +704,7 @@ abstract class DatabaseConnection extend
    * @see InsertQuery
    */
   public function insert($table, array $options = array()) {
-    $class = $this->getDriverClass('InsertQuery');
+    $class = $this->getDriverClass('InsertQuery', array('query.inc'));
     return new $class($this, $table, $options);
   }
 
@@ -713,7 +720,7 @@ abstract class DatabaseConnection extend
    * @see MergeQuery
    */
   public function merge($table, array $options = array()) {
-    $class = $this->getDriverClass('MergeQuery');
+    $class = $this->getDriverClass('MergeQuery', array('query.inc'));
     return new $class($this, $table, $options);
   }
 
@@ -730,7 +737,7 @@ abstract class DatabaseConnection extend
    * @see UpdateQuery
    */
   public function update($table, array $options = array()) {
-    $class = $this->getDriverClass('UpdateQuery');
+    $class = $this->getDriverClass('UpdateQuery', array('query.inc'));
     return new $class($this, $table, $options);
   }
 
@@ -746,7 +753,7 @@ abstract class DatabaseConnection extend
    * @see DeleteQuery
    */
   public function delete($table, array $options = array()) {
-    $class = $this->getDriverClass('DeleteQuery');
+    $class = $this->getDriverClass('DeleteQuery', array('query.inc'));
     return new $class($this, $table, $options);
   }
 
@@ -762,7 +769,7 @@ abstract class DatabaseConnection extend
    * @see TruncateQuery
    */
   public function truncate($table, array $options = array()) {
-    $class = $this->getDriverClass('TruncateQuery');
+    $class = $this->getDriverClass('TruncateQuery', array('query.inc'));
     return new $class($this, $table, $options);
   }
 
@@ -776,7 +783,7 @@ abstract class DatabaseConnection extend
    */
   public function schema() {
     if (empty($this->schema)) {
-      $class = $this->getDriverClass('DatabaseSchema');
+      $class = $this->getDriverClass('DatabaseSchema', array('schema.inc'));
       if (class_exists($class)) {
         $this->schema = new $class($this);
       }
@@ -1581,6 +1588,34 @@ abstract class Database {
     self::$ignoreTargets[$key][$target] = TRUE;
   }
 
+  /**
+   * Load a file for the database that might hold a class.
+   *
+   * @param $driver
+   *   The name of the driver.
+   * @param array $files
+   *   The name of the files the driver specific class can be.
+   */
+  public static function loadDriverFile($driver, array $files = array()) {
+    static $base_path;
+
+    if (empty($base_path)) {
+      $base_path = dirname(realpath(__FILE__));
+    }
+
+    $driver_base_path = "$base_path/$driver";
+    foreach ($files as $file) {
+      // Load the base file first so that classes extending base classes will
+      // have the base class loaded.
+      foreach (array("$base_path/$file", "$driver_base_path/$file") as $filename) {
+        // The OS caches file_exists() and PHP caches require_once(), so
+        // we'll let both of those take care of performance here.
+        if (file_exists($filename)) {
+          require_once $filename;
+        }
+      }
+    }
+  }
 }
 
 /**
@@ -2109,82 +2144,6 @@ class DatabaseStatementEmpty implements 
 }
 
 /**
- * Autoload callback for the database system.
- */
-function db_autoload($class) {
-  static $base_path = '';
-  static $checked = array();
-
-  static $files = array(
-    'query.inc' => array(
-      'QueryPlaceholderInterface',
-      'QueryConditionInterface', 'DatabaseCondition',
-      'Query', 'DeleteQuery', 'InsertQuery', 'UpdateQuery', 'MergeQuery', 'TruncateQuery',
-      'QueryAlterableInterface',
-    ),
-    'select.inc' => array('QueryAlterableInterface', 'SelectQueryInterface', 'SelectQuery', 'SelectQueryExtender'),
-    'database.inc' => array('DatabaseConnection'),
-    'log.inc' => array('DatabaseLog'),
-    'prefetch.inc' => array('DatabaseStatementPrefetch'),
-    'schema.inc' => array('DatabaseSchema'),
-  );
-
-  // If a class doesn't exist, it may get checked a second time
-  // by class_exists().  If so, just bail out now.
-  if (isset($checked[$class])) {
-    return;
-  }
-  $checked[$class] = TRUE;
-
-  if (empty($base_path)) {
-    $base_path = dirname(realpath(__FILE__));
-  }
-
-  // If there is an underscore in the class name, we know it's a
-  // driver-specific file so check for those.  If not, it's a generic.
-  // Note that we use require_once here instead of require because of a
-  // quirk in class_exists().  By default, class_exists() will try to
-  // autoload a class if it's not found.  However, we cannot tell
-  // at this point whether or not the class is going to exist, only
-  // the file that it would be in if it does exist.  That means we may
-  // try to include a file that was already included by another
-  // autoload call, which would break.  Using require_once() neatly
-  // avoids that issue.
-  if (strpos($class, '_') !== FALSE) {
-    list($base, $driver) = explode('_', $class);
-
-    // Drivers have an extra file, and may put their SelectQuery implementation
-    // in the main query file since it's so small.
-    $driver_files = $files;
-    $driver_files['query.inc'][] = 'SelectQuery';
-    $driver_files['install.inc'] = array('DatabaseTasks');
-
-    foreach ($driver_files as $file => $classes) {
-      if (in_array($base, $classes)) {
-        $filename = "{$base_path}/{$driver}/{$file}";
-        // We might end up looking in a file that doesn't exist, so check that.
-        if (file_exists($filename)) {
-          require_once $filename;
-          // If the class now exists, we're done. Otherwise keep searching in
-          // additional files.
-          if (class_exists($class, FALSE) || interface_exists($class, FALSE)) {
-            return;
-          }
-        }
-      }
-    }
-  }
-  else {
-    foreach ($files as $file => $classes) {
-      if (in_array($class, $classes)) {
-        require_once $base_path . '/' . $file;
-        return;
-      }
-    }
-  }
-}
-
-/**
  * The following utility functions are simply convenience wrappers.
  *
  * They should never, ever have any database-specific code in them.
@@ -2915,4 +2874,3 @@ function db_ignore_slave() {
     $_SESSION['ignore_slave_server'] = REQUEST_TIME + $duration;
   }
 }
-

=== modified file 'includes/database/pgsql/query.inc'
--- includes/database/pgsql/query.inc	2010-09-24 21:24:13 +0000
+++ includes/database/pgsql/query.inc	2010-11-28 08:07:53 +0000
@@ -208,95 +208,3 @@ class UpdateQuery_pgsql extends UpdateQu
     return $stmt->rowCount();
   }
 }
-
-class SelectQuery_pgsql extends SelectQuery {
-
-  public function orderRandom() {
-    $alias = $this->addExpression('RANDOM()', 'random_field');
-    $this->orderBy($alias);
-    return $this;
-  }
-
-  /**
-   * Overrides SelectQuery::orderBy().
-   *
-   * PostgreSQL adheres strictly to the SQL-92 standard and requires that when
-   * using DISTINCT or GROUP BY conditions, fields and expressions that are
-   * ordered on also need to be selected. This is a best effort implementation
-   * to handle the cases that can be automated by adding the field if it is not
-   * yet selected.
-   *
-   * @code
-   *   $query = db_select('node', 'n');
-   *   $query->join('node_revision', 'nr', 'n.vid = nr.vid');
-   *   $query
-   *     ->distinct()
-   *     ->fields('n')
-   *     ->orderBy('timestamp');
-   * @endcode
-   *
-   * In this query, it is not possible (without relying on the schema) to know
-   * whether timestamp belongs to node_revisions and needs to be added or
-   * belongs to node and is already selected. Queries like this will need to be
-   * corrected in the original query by adding an explicit call to
-   * SelectQuery::addField() or SelectQuery::fields().
-   *
-   * Since this has a small performance impact, both by the additional
-   * processing in this function and in the database that needs to return the
-   * additional fields, this is done as an override instead of implementing it
-   * directly in SelectQuery::orderBy().
-   */
-  public function orderBy($field, $direction = 'ASC') {
-    // Call parent function to order on this.
-    $return = parent::orderBy($field, $direction);
-
-    // If there is a table alias specified, split it up.
-    if (strpos($field, '.') !== FALSE) {
-      list($table, $table_field) = explode('.', $field);
-    }
-    // Figure out if the field has already been added.
-    foreach ($this->fields as $existing_field) {
-      if (!empty($table)) {
-        // If table alias is given, check if field and table exists.
-        if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
-          return $return;
-        }
-      }
-      else {
-        // If there is no table, simply check if the field exists as a field or
-        // an aliased field.
-        if ($existing_field['alias'] == $field) {
-          return $return;
-        }
-      }
-    }
-
-    // Also check expression aliases.
-    foreach ($this->expressions as $expression) {
-      if ($expression['alias'] == $field) {
-        return $return;
-      }
-    }
-
-    // If a table loads all fields, it can not be added again. It would
-    // result in an ambigious alias error because that field would be loaded
-    // twice: Once through table_alias.* and once directly. If the field
-    // actually belongs to a different table, it must be added manually.
-    foreach ($this->tables as $table) {
-      if (!empty($table['all_fields'])) {
-        return $return;
-      }
-    }
-
-    // If $field contains an characters which are not allowed in a field name
-    // it is considered an expression, these can't be handeld automatically
-    // either.
-    if ($this->connection->escapeField($field) != $field) {
-      return $return;
-    }
-
-    // This is a case that can be handled automatically, add the field.
-    $this->addField(NULL, $field);
-    return $return;
-  }
-}

=== added file 'includes/database/pgsql/select.inc'
--- includes/database/pgsql/select.inc	1970-01-01 00:00:00 +0000
+++ includes/database/pgsql/select.inc	2010-11-28 08:08:19 +0000
@@ -0,0 +1,109 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Select builder for PostgreSQL database engine.
+ */
+
+/**
+ * @ingroup database
+ * @{
+ */
+
+class SelectQuery_pgsql extends SelectQuery {
+
+  public function orderRandom() {
+    $alias = $this->addExpression('RANDOM()', 'random_field');
+    $this->orderBy($alias);
+    return $this;
+  }
+
+  /**
+   * Overrides SelectQuery::orderBy().
+   *
+   * PostgreSQL adheres strictly to the SQL-92 standard and requires that when
+   * using DISTINCT or GROUP BY conditions, fields and expressions that are
+   * ordered on also need to be selected. This is a best effort implementation
+   * to handle the cases that can be automated by adding the field if it is not
+   * yet selected.
+   *
+   * @code
+   *   $query = db_select('node', 'n');
+   *   $query->join('node_revision', 'nr', 'n.vid = nr.vid');
+   *   $query
+   *     ->distinct()
+   *     ->fields('n')
+   *     ->orderBy('timestamp');
+   * @endcode
+   *
+   * In this query, it is not possible (without relying on the schema) to know
+   * whether timestamp belongs to node_revisions and needs to be added or
+   * belongs to node and is already selected. Queries like this will need to be
+   * corrected in the original query by adding an explicit call to
+   * SelectQuery::addField() or SelectQuery::fields().
+   *
+   * Since this has a small performance impact, both by the additional
+   * processing in this function and in the database that needs to return the
+   * additional fields, this is done as an override instead of implementing it
+   * directly in SelectQuery::orderBy().
+   */
+  public function orderBy($field, $direction = 'ASC') {
+    // Call parent function to order on this.
+    $return = parent::orderBy($field, $direction);
+
+    // If there is a table alias specified, split it up.
+    if (strpos($field, '.') !== FALSE) {
+      list($table, $table_field) = explode('.', $field);
+    }
+    // Figure out if the field has already been added.
+    foreach ($this->fields as $existing_field) {
+      if (!empty($table)) {
+        // If table alias is given, check if field and table exists.
+        if ($existing_field['table'] == $table && $existing_field['field'] == $table_field) {
+          return $return;
+        }
+      }
+      else {
+        // If there is no table, simply check if the field exists as a field or
+        // an aliased field.
+        if ($existing_field['alias'] == $field) {
+          return $return;
+        }
+      }
+    }
+
+    // Also check expression aliases.
+    foreach ($this->expressions as $expression) {
+      if ($expression['alias'] == $field) {
+        return $return;
+      }
+    }
+
+    // If a table loads all fields, it can not be added again. It would
+    // result in an ambigious alias error because that field would be loaded
+    // twice: Once through table_alias.* and once directly. If the field
+    // actually belongs to a different table, it must be added manually.
+    foreach ($this->tables as $table) {
+      if (!empty($table['all_fields'])) {
+        return $return;
+      }
+    }
+
+    // If $field contains an characters which are not allowed in a field name
+    // it is considered an expression, these can't be handeld automatically
+    // either.
+    if ($this->connection->escapeField($field) != $field) {
+      return $return;
+    }
+
+    // This is a case that can be handled automatically, add the field.
+    $this->addField(NULL, $field);
+    return $return;
+  }
+}
+
+/**
+ * @} End of "ingroup database".
+ */
+

=== modified file 'includes/database/schema.inc'
--- includes/database/schema.inc	2010-11-28 07:32:39 +0000
+++ includes/database/schema.inc	2010-11-28 08:15:06 +0000
@@ -6,6 +6,8 @@
  * Generic Database schema code.
  */
 
+require_once dirname(__FILE__) . '/query.inc';
+
 /**
  * @defgroup schemaapi Schema API
  * @{

=== modified file 'includes/database/select.inc'
--- includes/database/select.inc	2010-11-28 07:32:39 +0000
+++ includes/database/select.inc	2010-11-28 08:15:06 +0000
@@ -6,6 +6,8 @@
  * @{
  */
 
+require_once dirname(__FILE__) . '/query.inc';
+
 /**
  * Interface for extendable query objects.
  *
@@ -642,7 +644,9 @@ class SelectQueryExtender implements Sel
   /* Implementations of QueryExtendableInterface. */
 
   public function extend($extender_name) {
-    $class = $this->connection->getDriverClass($extender_name);
+    // The extender can be anywhere so this needs to go to the registry, which
+    // is surely loaded by now.
+    $class = $this->connection->getDriverClass($extender_name, array(), TRUE);
     return new $class($this, $this->connection);
   }
 

=== modified file 'includes/database/sqlite/query.inc'
--- includes/database/sqlite/query.inc	2010-09-25 01:41:26 +0000
+++ includes/database/sqlite/query.inc	2010-11-28 08:09:26 +0000
@@ -12,16 +12,6 @@
  */
 
 /**
- * SQLite specific query builder for SELECT statements.
- */
-class SelectQuery_sqlite extends SelectQuery {
-  public function forUpdate($set = TRUE) {
-    // SQLite does not support FOR UPDATE so nothing to do.
-    return $this;
-  }
-}
-
-/**
  * SQLite specific implementation of InsertQuery.
  *
  * We ignore all the default fields and use the clever SQLite syntax:

=== added file 'includes/database/sqlite/select.inc'
--- includes/database/sqlite/select.inc	1970-01-01 00:00:00 +0000
+++ includes/database/sqlite/select.inc	2010-11-28 08:05:25 +0000
@@ -0,0 +1,28 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Select builder for SQLite embedded database engine.
+ */
+
+/**
+ * @ingroup database
+ * @{
+ */
+
+/**
+ * SQLite specific query builder for SELECT statements.
+ */
+class SelectQuery_sqlite extends SelectQuery {
+  public function forUpdate($set = TRUE) {
+    // SQLite does not support FOR UPDATE so nothing to do.
+    return $this;
+  }
+}
+
+/**
+ * @} End of "ingroup database".
+ */
+
+

=== modified file 'includes/install.core.inc'
--- includes/install.core.inc	2010-11-28 07:32:39 +0000
+++ includes/install.core.inc	2010-11-28 08:15:06 +0000
@@ -289,7 +289,6 @@ function install_begin_request(&$install
     // Initialize the database system. Note that the connection
     // won't be initialized until it is actually requested.
     require_once DRUPAL_ROOT . '/includes/database/database.inc';
-    spl_autoload_register('db_autoload');
 
     // Verify the last completed task in the database, if there is one.
     $task = install_verify_completed_task();

=== modified file 'includes/install.inc'
--- includes/install.inc	2010-11-28 07:32:39 +0000
+++ includes/install.inc	2010-11-28 08:15:06 +0000
@@ -238,7 +238,6 @@ function drupal_detect_database_types() 
   // Because we have no registry yet, we need to also include the install.inc
   // file for the driver explicitly.
   require_once DRUPAL_ROOT . '/includes/database/database.inc';
-  spl_autoload_register('db_autoload');
   foreach (file_scan_directory(DRUPAL_ROOT . '/includes/database', '/^[a-z]*$/i', array('recurse' => FALSE)) as $file) {
     if (file_exists($file->uri . '/database.inc') && file_exists($file->uri . '/install.inc')) {
       $drivers[$file->filename] = $file->uri;
@@ -246,8 +245,7 @@ function drupal_detect_database_types() 
   }
 
   foreach ($drivers as $driver => $file) {
-    $class = 'DatabaseTasks_' . $driver;
-    $installer = new $class();
+    $installer = db_installer_object($driver);
     if ($installer->installable()) {
       $databases[$driver] = $installer->name();
     }
@@ -1123,8 +1121,18 @@ function install_profile_info($profile, 
  * encoding.
  */
 function db_run_tasks($driver) {
-  $task_class = 'DatabaseTasks_' . $driver;
-  $DatabaseTasks = new $task_class();
-  $DatabaseTasks->runTasks();
+  db_installer_object($driver)->runTasks();
   return TRUE;
 }
+
+/**
+ * Returns a database installer object.
+ *
+ * @param $driver
+ *   The name of the driver.
+ */
+function db_installer_object($driver) {
+  Database::loadDriverFile($driver, array('install.inc'));
+  $task_class = 'DatabaseTasks_' . $driver;
+  return new $task_class();
+}

=== modified file 'includes/theme.maintenance.inc'
--- includes/theme.maintenance.inc	2010-11-28 07:32:39 +0000
+++ includes/theme.maintenance.inc	2010-11-28 08:15:06 +0000
@@ -41,7 +41,6 @@ function _drupal_maintenance_theme() {
     // to work. See _drupal_log_error().
     if (!class_exists('Database', FALSE)) {
       require_once DRUPAL_ROOT . '/includes/database/database.inc';
-      spl_autoload_register('db_autoload');
     }
 
     // We use the default theme as the maintenance theme. If a default theme

=== modified file 'modules/simpletest/drupal_web_test_case.php'
--- modules/simpletest/drupal_web_test_case.php	2010-11-28 07:32:39 +0000
+++ modules/simpletest/drupal_web_test_case.php	2010-11-28 08:15:06 +0000
@@ -611,8 +611,6 @@ class DrupalUnitTestCase extends DrupalT
     // Store necessary current values before switching to the test environment.
     $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files');
 
-    spl_autoload_register('db_autoload');
-
     // Reset all statics so that test is performed with a clean environment.
     drupal_static_reset();
 

