Index: includes/path.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/path.inc,v
retrieving revision 1.19.2.1
diff -u -p -r1.19.2.1 path.inc
--- includes/path.inc	13 Oct 2008 21:06:41 -0000	1.19.2.1
+++ includes/path.inc	10 Jul 2009 18:03:08 -0000
@@ -46,25 +46,35 @@ function drupal_init_path() {
 function drupal_lookup_path($action, $path = '', $path_language = '') {
   global $language;
   // $map is an array with language keys, holding arrays of Drupal paths to alias relations
-  static $map = array(), $no_src = array(), $count;
+  static $map = array(), $no_src = array(), $whitelist;
 
   $path_language = $path_language ? $path_language : $language->language;
 
-  // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
-  if (!isset($count)) {
-    $count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
+  // Retrieve the path alias whitelist.
+  if (!isset($whitelist)) {
+    $whitelist = variable_get('path_alias_whitelist', NULL);
+    if (!isset($whitelist)) {
+      $whitelist = drupal_path_alias_whitelist_rebuild();
+    }
   }
 
   if ($action == 'wipe') {
     $map = array();
     $no_src = array();
-    $count = NULL;
+
+    $whitelist = drupal_path_alias_whitelist_rebuild();
   }
-  elseif ($count > 0 && $path != '') {
+  elseif ($whitelist && $path != '') {
     if ($action == 'alias') {
       if (isset($map[$path_language][$path])) {
         return $map[$path_language][$path];
       }
+      // Check the path whitelist, if the top_level part before the first /
+      // is not in the list, then there is no need to do anything further,
+      // it is not in the database.
+      elseif (!isset($whitelist[strtok($path, '/')])) {
+        return FALSE;
+      }
       // Get the most fitting result falling back with alias without language
       $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language));
       $map[$path_language][$path] = $alias;
@@ -241,3 +251,22 @@ function drupal_match_path($path, $patte
   }
   return preg_match($regexps[$patterns], $path);
 }
+
+/**
+ * Rebuild the path alias white list.
+ *
+ * @return
+ *   An array containing a white list of path aliases.
+ */
+function drupal_path_alias_whitelist_rebuild() {
+  // For each alias in the database, get the top level component of the system
+  // path it corresponds to. This is the portion of the path before the first /
+  // if present, otherwise the whole path itself.
+  $whitelist = array();
+  $result = db_query("SELECT SUBSTRING_INDEX(src, '/', 1) AS path FROM {url_alias} GROUP BY path");
+  while ($row = db_fetch_object($result)) {
+    $whitelist[$row->path] = TRUE;
+  }
+  variable_set('path_alias_whitelist', $whitelist);
+  return $whitelist;
+}
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.238.2.15
diff -u -p -r1.238.2.15 system.install
--- modules/system/system.install	1 Jul 2009 20:51:56 -0000	1.238.2.15
+++ modules/system/system.install	10 Jul 2009 18:06:55 -0000
@@ -350,6 +350,11 @@ function system_install() {
       \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
       LANGUAGE \'sql\''
     );
+
+    db_query('CREATE OR REPLACE FUNCTION "substring_index"(text, text, integer) RETURNS text AS
+      \'SELECT array_to_string((string_to_array($1, $2)) [1:$3], $2);\'
+      LANGUAGE \'sql\''
+    );
   }
 
   // Create tables.
@@ -2598,6 +2603,20 @@ function system_update_6051() {
 }
 
 /**
+ * Add the substr_index() function to PostgreSQL.
+ */
+function system_update_6052() {
+  $ret = array();
+  if ($GLOBALS['db_type'] == 'pgsql') {
+    $ret[] = update_sql('CREATE OR REPLACE FUNCTION "substring_index"(text, text, integer) RETURNS text AS
+      \'SELECT array_to_string((string_to_array($1, $2)) [1:$3], $2);\'
+      LANGUAGE \'sql\''
+    );
+  }
+  return $ret;
+}
+
+/**
  * @} End of "defgroup updates-6.x-extra"
  * The next series of updates should start at 7000.
  */
