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

Comments

boombatower’s picture

Priority: Normal » Critical

This is a blocker for testing.drupal.org.

boombatower’s picture

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.

boombatower’s picture

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

boombatower’s picture

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?)

alex_b’s picture

#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.

alex_b’s picture

StatusFileSize
new2.64 KB

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.

damien tournoud’s picture

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.

boombatower’s picture

#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: Internal browser instead of custom scripts.

Freso’s picture

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).
damien tournoud’s picture

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

kenorb’s picture

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

sun.core’s picture

Status: Postponed (maintainer needs more info) » Active

Delete the has_js cookie?

donquixote’s picture

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.

sun.core’s picture

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?

Anonymous’s picture

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.

Anonymous’s picture

I've also found that if I create the DB with phpmyadmin I am having issues during the install. I'm using InnoDB and the .frm files will not be created for some unknown reason. If I create the DB with the mysql command line I have success with the install. I'm installing version 6.15.

EDIT: I've proven this statement false!! It must be the sheer number of tries and luck that I'm able to complete a install.

Anonymous’s picture

Following up here. I've found innodb_file_per_table option to be buggy in version 5.0.51a-3ubuntu5.4. I was having multiple issues with getting a file lock and other errors when doing mass operations that caused mysql to crash. I disabled this option and executed ``mysqlcheck --optimize --all-databases -u root -p'' to move the individual table files back to the global ibdata1 file.

I don't like this option because once ibdata1 is expanded it never shrinks but I would rather deal with that than to always be presented with a crashing mysql. Others having this issue should check whether this option is on or not. Executing ``mysqladmin variables -u root -p | grep innodb_file_per_table'' will let you know. Removing the option from my.cnf or setting it equal to 0 will cause the option to not be used.

HTH,
Earnie

damien tournoud’s picture

Status: Postponed (maintainer needs more info) » Closed (duplicate)