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	30 Dec 2010 07:54:50 -0000
@@ -2691,16 +2691,9 @@ function _menu_navigation_links_rebuild(
     // Make sure no child comes before its parent.
     array_multisort($sort, SORT_NUMERIC, $menu_links);
 
-    foreach ($menu_links as $item) {
+    foreach ($menu_links as &$item) {
       $existing_item = db_select('menu_links')
-        ->fields('menu_links', array(
-          'mlid',
-          'menu_name',
-          'plid',
-          'customized',
-          'has_children',
-          'updated',
-        ))
+        ->fields('menu_links')
         ->condition('link_path', $item['path'])
         ->condition('module', 'system')
         ->execute()->fetchAssoc();
@@ -2721,7 +2714,7 @@ function _menu_navigation_links_rebuild(
       }
       if (!$existing_item || !$existing_item['customized']) {
         $item = _menu_link_build($item);
-        menu_link_save($item);
+        menu_link_save($item, $existing_item, $menu_links);
       }
     }
   }
@@ -2910,12 +2903,16 @@ function _menu_delete_item($item, $force
  *   - mlid: Set to an existing value, or 0 or NULL to insert a new link.
  *   - plid: The mlid of the parent.
  *   - router_path: The path of the relevant router item.
+ * @param $existing_item
+ *   Optional, the current record from the {menu_links} table as an array.
+ * @param $menu_links
+ *   Optional. Used by _menu_navigation_links_rebuild() only.
  *
  * @return
  *   The mlid of the saved menu link, or FALSE if the menu link could not be
  *   saved.
  */
-function menu_link_save(&$item) {
+function menu_link_save(&$item, $existing_item = array(), $menu_links = array()) {
   drupal_alter('menu_link', $item);
 
   // This is the easiest way to handle the unique internal path '<front>',
@@ -2934,15 +2931,14 @@ function menu_link_save(&$item) {
     'customized' => 0,
     'updated' => 0,
   );
-  $existing_item = FALSE;
   if (isset($item['mlid'])) {
-    if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) {
+    if ($existing_item) {
       $existing_item['options'] = unserialize($existing_item['options']);
     }
   }
 
   // Try to find a parent link. If found, assign it and derive its menu.
-  $parent = _menu_link_find_parent($item);
+  $parent = _menu_link_find_parent($item, $menu_links);
   if (!empty($parent['mlid'])) {
     $item['plid'] = $parent['mlid'];
     $item['menu_name'] = $parent['menu_name'];
@@ -3080,7 +3076,7 @@ function menu_link_save(&$item) {
  *   A menu link structure of the possible parent or FALSE if no valid parent
  *   has been found.
  */
-function _menu_link_find_parent($menu_link) {
+function _menu_link_find_parent($menu_link, $menu_links) {
   $parent = FALSE;
 
   // This item is explicitely top-level, skip the rest of the parenting.
@@ -3102,9 +3098,18 @@ function _menu_link_find_parent($menu_li
   }
 
   foreach ($candidates as $mlid) {
-    $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc();
-    if ($parent) {
-      return $parent;
+    if (!empty($menu_links)) {
+      foreach ($menu_links as $link) {
+        if ($link['mlid'] == $mlid) {
+          return $link;
+        }
+      }
+    }
+    else {
+      $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $mlid))->fetchAssoc();
+      if ($parent) {
+        return $parent;
+      }
     }
   }
 
