menu_router error during install

Damien Tournoud - September 25, 2008 - 22:33
Project:Drupal
Version:7.x-dev
Component:install system
Category:bug report
Priority:critical
Assigned:Unassigned
Status:postponed (maintainer needs more info)
Description

I just found a reliable way to reproduce the class of SELECT * FROM menu_router WHERE path IN () ORDER BY fit DESC LIMIT 0, 1-related errors during install.

It turns out lynx cannot install Drupal, and generate that error each time.

Attached is a complete xdebug log, the backtrace is:

   # Time Memory Function Location
   1 0.0055 398860 {main}( ) ../install.php:0
   2 0.0090 626180 install_main( ) ../install.php:1186
   3 0.1077 6469952 install_tasks( $profile = `default`, $task = `profile-install-batch` )
   ../install.php:154
   4 0.1324 8011160 theme( `maintenance_page`, FALSE ) ../install.php:837
   5 0.1326 8018860 call_user_func_array ( `template_preprocess_maintenance_page`, array (0 => array
   (`template_files` => array (...), `content` => ``, `show_blocks` => TRUE, `show_messages` => TRUE,
   `zebra` => `odd`, `id` => 1, `directory` => `themes/garland`, `is_admin` => FALSE, `is_front` =>
   FALSE, `logged_in` => FALSE, `db_is_active` => FALSE, `left` => `<ol class="task-list"><li
   class="done">Choose profile</li><li class="done">Choose language</li><li class="done">Verify
   requirements</li><li class="done">Set up database</li><li class="active">Install profile</li><li
   class="">Configure site</li><li class="">Finished</li></ol>`, `right` => NULL, `header` => NULL,
   `footer` => NULL, `layout` => `left`), 1 => `maintenance_page`) ) ../theme.inc:648
   6 0.1326 8018860 template_preprocess_maintenance_page( $variables = array (`template_files` => array
   (), `content` => ``, `show_blocks` => TRUE, `show_messages` => TRUE, `zebra` => `odd`, `id` => 1,
   `directory` => `themes/garland`, `is_admin` => FALSE, `is_front` => FALSE, `logged_in` => FALSE,
   `db_is_active` => FALSE, `left` => `<ol class="task-list"><li class="done">Choose profile</li><li
   class="done">Choose language</li><li class="done">Verify requirements</li><li class="done">Set up
   database</li><li class="active">Install profile</li><li class="">Configure site</li><li
   class="">Finished</li></ol>`, `right` => NULL, `header` => NULL, `footer` => NULL, `layout` =>
   `left`), `maintenance_page` ) ../theme.inc:0
   7 0.1332 8025856 drupal_get_title( ) ../theme.maintenance.inc:233
   8 0.1332 8025856 menu_get_active_title( ) ../path.inc:187
   9 0.1332 8025856 menu_get_active_trail( ) ../menu.inc:1643
   10 0.1332 8025856 menu_set_active_trail( $new_trail = ??? ) ../menu.inc:1608
   11 0.1332 8026196 menu_get_item( $path = ???, $router_item = ??? ) ../menu.inc:1553
   12 0.1333 8027368 db_query_range( $query = `SELECT * FROM {menu_router} WHERE path IN () ORDER BY fit
   DESC`, $args = array (), $from = 0, $count = 1, $options = ??? ) ../menu.inc:367
   13 0.1334 8028688 DatabaseConnection_mysql->queryRange( $query = `SELECT * FROM {menu_router} WHERE
   path IN () ORDER BY fit DESC`, $args = array (), $from = 0, $count = 1, $options = array (`target` =>
   `default`) ) ../database.inc:1188
   14 0.1334 8029036 DatabaseConnection->query( $query = `SELECT * FROM {menu_router} WHERE path IN ()
   ORDER BY fit DESC LIMIT 0, 1`, $args = array (), $options = array (`target` => `default`) )
   ../database.inc:46

AttachmentSizeStatusTest resultOperations
install-menu-router.txt8.85 KBIgnoredNoneNone

#1

boombatower - September 28, 2008 - 00:01
Priority:normal» critical

This is a blocker for testing.drupal.org.

#2

boombatower - September 28, 2008 - 00:09

To clarify I'm using SimpleTest 6.x-2.x to install D7. Submit the database configuration page...then it sticks and only ends up inserting database structure. Appears to be JavaScript/batch API related.

#3

boombatower - September 29, 2008 - 15:53

Once this has a patch I'll try it out and make simpletest to ensure this is tested.

#4

boombatower - September 30, 2008 - 20:38
Status:active» postponed (maintainer needs more info)

It would appear, after looking at Zlender's code and trying in Firefox with JS disabled that changing the op to do_nojs works.

Ending up with something like:

http://drupal-7.dev.loc/install.php?locale=en&profile=default&op=do_nojs&id=1

So this may just need some JavaScript detection. (possibly removed?)

#5

alex_b - February 15, 2009 - 14:10

#4: In order to test whether Drupal installs without JavaScript with Firefox I had to remove the has_js variable from the cookie. Without this variable, D7 installs fine with a JavaScript-disabled Firefox. Maybe I'm stating the obvious, but I just tripped over that.

It seems to me that #2 is not related to the original issue (?).

Now, what I found next may be related. If I disable cookies altogether, submit the install script's DB configuration page I wind up on the web site's root, empty screen except "Fatal error: Class 'DeleteQuery' not found in /path/to/website/root/includes/database/database.inc on line 762 "

When I look at the database, I find 33 tables installed.

When I go back to the install script, on /install.php?profile=default&locale=en I get this error message in a drupal_set_message() box:

PDOException: SELECT menu_router.* FROM {menu_router} menu_router WHERE (path IN ()) ORDER BY fit DESC LIMIT 0, 1 - Array ( ) SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')) ORDER BY fit DESC LIMIT 0, 1' at line 2 in menu_get_item() (line 369 of /opt/local/apache2/htdocs/d7-original/includes/menu.inc).

Line 369 of menu.inc is the same query as in the original issue.

#6

alex_b - February 15, 2009 - 20:12

I'm pretty sure now that the menu_router error occurs if the install script can't jump over the first installation step _after_ the DB configuration form has been submitted. In non-js mode, Drupal sends 5 pages with 200 response code before it jumps to the site configuration page (you can look at it with a http logger like tamper data). This throws off some clients. For example curl: In the attached shell script you'll see that I'm pulling

4 times
install.php?profile=default&locale=en&id=1&op=do_nojs

followed by 1 time
install.php?profile=default&locale=en&id=1&op=finished

to simulate Drupal's install script behavior.

If you remove the tail part of the shell script that starts with the comment "# Step through install script, this shouldn't be necessary" you will wind up with a broken site that throws a menu router error as described in the issue.

AttachmentSizeStatusTest resultOperations
drupaldeploy.txt2.64 KBIgnoredNoneNone

#7

Damien Tournoud - February 15, 2009 - 23:17

Ok, I spend some time debugging this issue during the evening.

It turns out that (at least for Lynx), it is a cookie issue. Here is the mechanism:

  • install.php does the first steps of the installation, then call batch_set($batch) and batch_process($url, $url): you are redirected to http://xxx/install.php?locale=en&profile=default&op=do_nojs&id=1
  • on the next page load, install.php calls _batch_page(), which tries to load the batch. The token verification fails because you don't have the same session, because you have no cookies. The Batch API redirects you to the frontpage by calling drupal_goto(). You have an half-backed install, you see strange error messages.

I'm now convinced that this whole class of errors is simply caused by browsers don't accepting cookies. Lynx doesn't accept the cookie set by Drupal because it sticks to the standards: RFC2109 that browsers should reject cookies that have a domain-path not "domain-matching" the one of the host, and define "host name A domain-matches host name B" as:

* both host names are IP addresses and their host name strings match
exactly; or
* both host names are FQDN strings and their host name strings match
exactly; or
* A is a FQDN string and has the form NB, where N is a non-empty name
string, B has the form .B', and B' is a FQDN string. (So, x.y.com
domain-matches .y.com but not y.com.)

So the cookie set by Drupal with a cookie domain of ".myhost.com" should not be accepted for "myhost.com".

The issue describe by alex_b with curl is different: curl doesn't support the meta refresh urls used by the batch API, so it never redirects.

#8

boombatower - February 16, 2009 - 05:36

#6: #2 is related...sounds like for same reason as Lynx.

Curl doesn't support meta refresh, but SimpleTest does :) as of teh patch. Another reason why I would prefer [#366978] instead of custom scripts.

#9

Freso - March 8, 2009 - 08:15

I think I'm getting this on a fresh install of Drupal 7 (HEAD) against Apache 2.2.20, PHP 5.2.8, PostgreSQL 8.1.11 with Firefox 3.0.6 (with cookies enabled and allowed) on "localhost/drupal7".

With JavaScript enabled it finishes the install but has this error:

PDOException: INSERT INTO menu_router (path, load_functions, to_arg_functions, access_callback, access_arguments, page_callback, page_arguments, fit, number_parts, tab_parent, tab_root, title, title_callback, title_arguments, type, block_callback, description, position, weight) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14, :db_insert_placeholder_15, :db_insert_placeholder_16, :db_insert_placeholder_17, :db_insert_placeholder_18), ([...]), (:db_insert_placeholder_2261, :db_insert_placeholder_2262, :db_insert_placeholder_2263, :db_insert_placeholder_2264, :db_insert_placeholder_2265, :db_insert_placeholder_2266, :db_insert_placeholder_2267, :db_insert_placeholder_2268, :db_insert_placeholder_2269, :db_insert_placeholder_2270, :db_insert_placeholder_2271, :db_insert_placeholder_2272, :db_insert_placeholder_2273, :db_insert_placeholder_2274, :db_insert_placeholder_2275, :db_insert_placeholder_2276, :db_insert_placeholder_2277, :db_insert_placeholder_2278, :db_insert_placeholder_2279) -
Array
(
)
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "," at character 359
in _menu_router_build() (line 2614 of /srv/http/localhost/htdocs/drupal7/includes/menu.inc).

Without JavaScript it doesn't even finish the install, and gives this error:

PDOException: SELECT menu_router.*
FROM
{menu_router} menu_router
WHERE (path IN ())
ORDER BY fit DESC LIMIT 1 OFFSET 0 -
Array
(
)
SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near ")" at character 70
in menu_get_item() (line 369 of /srv/http/localhost/htdocs/drupal7/includes/menu.inc).

#10

Damien Tournoud - March 8, 2009 - 08:19

@Freso: Drupal 7.x-dev only supports PostgreSQL 8.3. Make sure to use this version.

#11

kenorb - April 1, 2009 - 13:00

The same problem on 6.x: #234539: Critical SQL error in installer with {menu_router}
Here is some backtrace and description of the problem: http://drupal.org/node/234539#comment-1425476

#12

sun.core - July 8, 2009 - 23:40
Status:postponed (maintainer needs more info)» active

Delete the has_js cookie?

#13

donquixote - September 5, 2009 - 22:15

I got the same SQL error after playing with menu_rebuild().

It turned out that
$masks = variable_get('menu_masks', array());
in menu_get_ancestors() did not return anything, because I messed up that part of menu_rebuild() that should generate these masks and write them to the DB. As a consequence, menu_get_ancestors() returned an empty array.

Is it possible that we have the same problem here?
The functions that call menu_get_ancestors() are not prepared to get an empty result. Imo, this has to change! We should not rely on having the masks properly stored in the DB. There should be either a fallback or a clear error message (I would rather throw an exception, but that is not very useful in the Drupal universe).

Proposed solution:
If menu_get_ancestors() returns an empty array, we set

<?php
      $ancestors
= array('admin');
     
$placeholders = array("'%s'");
?>

or similar, and use that in the menu_router query.

#14

sun.core - January 8, 2010 - 01:54
Status:active» postponed (maintainer needs more info)

Somehow it seems that the follow-ups in here are talking about 4 different issues... on top of that, we have a very fuzzy issue title. Is this still critical?

#15

earnie - February 9, 2010 - 20:47

Sun, I bumped into this issue searching for a resolution to an issue installing Drupal 6.15. I kept getting sql errors on the install where the menu_router table was the first of many issues. I eventually found that somehow Drupal had partially loaded tables into the DB giving this issue. My resolution was to drop the database and recreate it. Once I had completed that it worked like a charm. Note make sure the DB is created with UTF8-GENERAL-CI collation; I've seen issues with creating it in a different collation.

 
 

Drupal is a registered trademark of Dries Buytaert.