Database layer

cafuego - June 21, 2009 - 02:06
Project:Drupal
Version:7.x-dev
Component:mysql database
Category:bug report
Priority:normal
Assigned:Unassigned
Status:won't fix
Description

The database layer seems to not want to parse queries that include sets of integers stored as a single string. As far as I can tell from the documentation the query:

db_query("INSERT INTO {filter_format} (name, roles, cache) VALUES ('%s', ',%d,%d,', %d)", 'Filtered HTML',  1, 2, 1);

should work fine. However, when that query is enabled, the install process halts with:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens' in /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/database/database.inc:1691 Stack trace: #0 /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/database/database.inc(1691): PDOStatement->execute(Array) #1 /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/database/database.inc(577): DatabaseStatementBase->execute(Array, Array) #2 /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/database/database.inc(1779): DatabaseConnection->query('INSERT INTO {fi...', Array, Array) #3 /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/modules/system/system.install(394): db_query('INSERT INTO {fi...', 'Filtered HTML', 1, 2, 1) #4 [internal function]: system_install() #5 /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/module.inc(435): call_user_func_array('system_install', Array) #6 / in /home/cafuego/Documents/Development/Drupal/drupal-7.x-dev/includes/database/database.inc on line 1691.

If I rewrite the query as:

db_query("INSERT INTO {filter_format} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Filtered HTML', sprintf(",%d,%d,", DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID), 1);

the install process completes just fine. It's a bit of a kludgy work-around, but it seems that the database layer refuses to parse integer arguments if the place holder is quoted.

I realise the D7 db_query() docs note that the function shouldn't be used for INSERT queries, but all of system.install currently does that.

#1

sun - June 21, 2009 - 02:17
Status:active» won't fix

As mentioned in IRC, in a case like this you either know that the values are already safe (i.e. not provided by the user), or you have to prepare the string for %s in PHP yourself.

 
 

Drupal is a registered trademark of Dries Buytaert.