Database layer
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | mysql database |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | won't fix |
Jump to:
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
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.