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 7 Jun 2009 12:02:11 -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.14 diff -u -p -r1.238.2.14 system.install --- modules/system/system.install 27 Apr 2009 12:50:13 -0000 1.238.2.14 +++ modules/system/system.install 7 Jun 2009 12:07:18 -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. @@ -2563,6 +2568,20 @@ function system_update_6050() { cache_clear_all('router:', 'cache_menu', TRUE); return $ret; } + +/** + * Add the substr_index() function to PostgreSQL. + */ +function system_update_6051() { + $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"