Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.461
diff -u -p -r1.461 bootstrap.inc
--- includes/bootstrap.inc	1 Jan 2011 22:46:02 -0000	1.461
+++ includes/bootstrap.inc	3 Jan 2011 17:24:21 -0000
@@ -2639,9 +2639,18 @@ function ip_address() {
  *   The name of the table. If not given, the schema of all tables is returned.
  * @param $rebuild
  *   If true, the schema will be rebuilt instead of retrieved from the cache.
+ *
+ * @return
+ *   When $table is NULL, returns the full schema array, when $table is set
+ *   returns the schema for the table specified. Or FALSE if none is found.
  */
 function drupal_get_schema($table = NULL, $rebuild = FALSE) {
-  static $schema = array();
+  // Use the advanced drupal_static() pattern, since this is called very often.
+  static $drupal_static_fast;
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['schema'] = &drupal_static(__FUNCTION__);
+  }
+  $schema = &$drupal_static_fast['schema'];
 
   if (empty($schema) || $rebuild) {
     // Try to load the schema from cache.
@@ -2680,6 +2689,9 @@ function drupal_get_schema($table = NULL
       // If the schema is empty, avoid saving it: some database engines require
       // the schema to perform queries, and this could lead to infinite loops.
       if (!empty($schema) && (drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL)) {
+        // @todo: the schema cache can be very large, so could exceed the
+        // maximum storage size for certain cache backends. Consider
+        // alternatives to storing the item as a single array.
         cache_set('schema', $schema);
       }
     }
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1283
diff -u -p -r1.1283 common.inc
--- includes/common.inc	3 Jan 2011 06:51:00 -0000	1.1283
+++ includes/common.inc	3 Jan 2011 17:24:36 -0000
@@ -6636,6 +6636,7 @@ function _drupal_schema_initialize(&$sch
  * @return An array of fields.
  **/
 function drupal_schema_fields_sql($table, $prefix = NULL) {
+  // Get table schema.
   $schema = drupal_get_schema($table);
   $fields = array_keys($schema['fields']);
   if ($prefix) {
@@ -6682,6 +6683,7 @@ function drupal_write_record($table, &$r
     $primary_keys = array($primary_keys);
   }
 
+  // Get table schema.
   $schema = drupal_get_schema($table);
   if (empty($schema)) {
     return FALSE;
Index: includes/entity.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/entity.inc,v
retrieving revision 1.19
diff -u -p -r1.19 entity.inc
--- includes/entity.inc	30 Nov 2010 19:31:46 -0000	1.19
+++ includes/entity.inc	3 Jan 2011 17:24:38 -0000
@@ -1067,6 +1067,7 @@ class EntityFieldQuery {
       throw new EntityFieldQueryException(t('Entity %entity has no base table.', array('%entity' => $entity_type)));
     }
     $base_table = $entity_info['base table'];
+    // Get table schema.
     $base_table_schema = drupal_get_schema($base_table);
     $select_query = db_select($base_table);
     $select_query->addExpression(':entity_type', 'entity_type', array(':entity_type' => $entity_type));
Index: includes/install.core.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.core.inc,v
retrieving revision 1.48
diff -u -p -r1.48 install.core.inc
--- includes/install.core.inc	28 Dec 2010 18:17:27 -0000	1.48
+++ includes/install.core.inc	3 Jan 2011 17:24:42 -0000
@@ -1428,16 +1428,6 @@ function install_configure_form($form, &
   // Build menu to allow clean URL check.
   menu_rebuild();
 
-  // Cache a fully-built schema. This is necessary for any invocation of
-  // index.php because: (1) setting cache table entries requires schema
-  // information, (2) that occurs during bootstrap before any module are
-  // loaded, so (3) if there is no cached schema, drupal_get_schema() will
-  // try to generate one but with no loaded modules will return nothing.
-  //
-  // This logically could be done during the 'install_finished' task, but the
-  // clean URL check requires it now.
-  drupal_get_schema(NULL, TRUE);
-
   // Return the form.
   return _install_configure_form($form, $form_state, $install_state);
 }
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.429
diff -u -p -r1.429 menu.inc
--- includes/menu.inc	17 Dec 2010 01:08:15 -0000	1.429
+++ includes/menu.inc	3 Jan 2011 17:24:48 -0000
@@ -2376,14 +2376,16 @@ function menu_link_get_preferred($path =
     $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
     $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
     $query->fields('ml');
-    // Weight must be taken from {menu_links}, not {menu_router}.
-    $query->fields('m', array_diff(drupal_schema_fields_sql('menu_router'), array('weight')));
+    $query->fields('m');
     $query->condition('ml.menu_name', $menu_names, 'IN');
     $query->condition('ml.link_path', $path_candidates, 'IN');
+    // Weight must be taken from {menu_links}, not {menu_router}.
+    $query->addField('ml', 'weight', 'link_weight');
 
     // Sort candidates by link path and menu name.
     $candidates = array();
     foreach ($query->execute() as $candidate) {
+      $candidate['weight'] = $candidate['link_weight'];
       $candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;
     }
 
@@ -2502,10 +2504,12 @@ function menu_link_load($mlid) {
     $query = db_select('menu_links', 'ml');
     $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
     $query->fields('ml');
-    // Weight should be taken from {menu_links}, not {menu_router}.
-    $query->fields('m', array_diff(drupal_schema_fields_sql('menu_router'), array('weight')));
+    $query->fields('m');
     $query->condition('ml.mlid', $mlid);
+    // Weight should be taken from {menu_links}, not {menu_router}.
+    $query->addField('ml', 'weight', 'link_weight');
     if ($item = $query->execute()->fetchAssoc()) {
+      $item['weight'] = $item['link_weight'];
       _menu_link_translate($item);
       return $item;
     }
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.209
diff -u -p -r1.209 module.inc
--- includes/module.inc	27 Nov 2010 20:41:38 -0000	1.209
+++ includes/module.inc	3 Jan 2011 17:24:52 -0000
@@ -421,14 +421,14 @@ function module_enable($module_list, $en
       _system_update_bootstrap_status();
       // Update the registry to include it.
       registry_update();
-      // Refresh the schema to include it.
-      drupal_get_schema(NULL, TRUE);
       // Clear entity cache.
       entity_info_cache_clear();
 
       // Now install the module if necessary.
       if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
         drupal_install_schema($module);
+        // Refresh the schema to include it.
+        drupal_get_schema(NULL, TRUE);
 
         // Set the schema version to the number of the last update provided
         // by the module.
Index: modules/field/modules/field_sql_storage/field_sql_storage.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/field_sql_storage/field_sql_storage.module,v
retrieving revision 1.58
diff -u -p -r1.58 field_sql_storage.module
--- modules/field/modules/field_sql_storage/field_sql_storage.module	21 Dec 2010 04:11:12 -0000	1.58
+++ modules/field/modules/field_sql_storage/field_sql_storage.module	3 Jan 2011 17:24:54 -0000
@@ -216,6 +216,7 @@ function field_sql_storage_field_storage
   foreach ($schema as $name => $table) {
     db_create_table($name, $table);
   }
+  // Cleans whole schema cache.
   drupal_get_schema(NULL, TRUE);
 }
 
@@ -273,6 +274,7 @@ function field_sql_storage_field_storage
       }
     }
   }
+  // Cleans whole schema cache.
   drupal_get_schema(NULL, TRUE);
 }
 
@@ -294,6 +296,7 @@ function field_sql_storage_field_storage
   $revision_new_table = _field_sql_storage_revision_tablename($field);
   db_rename_table($table, $new_table);
   db_rename_table($revision_table, $revision_new_table);
+  // Cleans whole schema cache.
   drupal_get_schema(NULL, TRUE);
 }
 
Index: modules/profile/profile.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.admin.inc,v
retrieving revision 1.44
diff -u -p -r1.44 profile.admin.inc
--- modules/profile/profile.admin.inc	28 Oct 2010 02:27:09 -0000	1.44
+++ modules/profile/profile.admin.inc	3 Jan 2011 17:24:55 -0000
@@ -314,6 +314,7 @@ function profile_field_form_validate($fo
     form_set_error('name', t('The specified form name contains one or more illegal characters. Spaces or any other special characters except dash (-) and underscore (_) are not allowed.'));
   }
 
+  // Get table schema.
   $users_table = drupal_get_schema('users');
   if (!empty($users_table['fields'][$form_state['values']['name']])) {
     form_set_error('name', t('The specified form name is reserved for use by Drupal.'));
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.257
diff -u -p -r1.257 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	2 Jan 2011 23:54:05 -0000	1.257
+++ modules/simpletest/drupal_web_test_case.php	3 Jan 2011 17:25:02 -0000
@@ -1403,11 +1403,6 @@ class DrupalWebTestCase extends DrupalTe
     // Reset the list of enabled modules.
     module_list(TRUE);
 
-    // Reset cached schema for new database prefix. This must be done before
-    // drupal_flush_all_caches() so rebuilds can make use of the schema of
-    // modules enabled on the cURL side.
-    drupal_get_schema(NULL, TRUE);
-
     // Perform rebuilds and flush remaining caches.
     drupal_flush_all_caches();
 
@@ -1455,7 +1450,7 @@ class DrupalWebTestCase extends DrupalTe
     file_unmanaged_delete_recursive($this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10));
 
     // Remove all prefixed tables (all the tables in the schema).
-    $schema = drupal_get_schema(NULL, TRUE);
+    $schema = drupal_get_schema(NULL);
     foreach ($schema as $name => $table) {
       db_drop_table($name);
     }
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1229
diff -u -p -r1.1229 user.module
--- modules/user/user.module	28 Dec 2010 21:46:23 -0000	1.1229
+++ modules/user/user.module	3 Jan 2011 17:25:10 -0000
@@ -404,6 +404,7 @@ function user_load_by_name($name) {
 function user_save($account, $edit = array(), $category = 'account') {
   $transaction = db_transaction();
   try {
+    // Get table schema.
     $table = drupal_get_schema('users');
 
     if (!empty($edit['pass'])) {
@@ -1225,6 +1226,7 @@ function user_account_form_validate($for
       // Move text value for user signature into 'signature'.
       $form_state['values']['signature'] = $form_state['values']['signature']['value'];
 
+      // Get table schema.
       $user_schema = drupal_get_schema('users');
       if (drupal_strlen($form_state['values']['signature']) > $user_schema['fields']['signature']['length']) {
         form_set_error('signature', t('The signature is too long: it must be %max characters or less.', array('%max' => $user_schema['fields']['signature']['length'])));
