Problem
Under some circumstances attempting a cron (manually or with drush) or a feature-revert leads to the following PDO exception:
WD php: PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'evenement' for key 'PRIMARY': INSERT INTO {merci_node_type} (type, [error]
merci_type_setting, merci_max_hours_per_reservation, merci_allow_overnight, merci_allow_weekends, merci_late_fee_per_hour, merci_rate_per_hour, merci_fee_free_hours,
merci_active_status, merci_spare_items, merci_min_cancel_hours, merci_autocheckout, merci_autocheckin, merci_selfcheckout, merci_auto_assign_bucket_item) 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); Array
(
[:db_insert_placeholder_0] => evenement
[:db_insert_placeholder_1] => disabled
[:db_insert_placeholder_2] => 0
[:db_insert_placeholder_3] => 0
[:db_insert_placeholder_4] => 0
[:db_insert_placeholder_5] => 0
[:db_insert_placeholder_6] => 0
[:db_insert_placeholder_7] => 0
[:db_insert_placeholder_8] => 0
[:db_insert_placeholder_9] => 0
[:db_insert_placeholder_10] => 0
[:db_insert_placeholder_11] => 0
[:db_insert_placeholder_12] => 0
[:db_insert_placeholder_13] => 0
[:db_insert_placeholder_14] => 0
)
in drupal_write_record() (line 7013 of /Users/<me>/project/www/includes/common.inc).
Cannot modify header information - headers already sent by (output started at /opt/drush/includes/output.inc:37) bootstrap.inc:1239 [warning]
PDOException : SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'evenement' for key 'PRIMARY': INSERT INTO {merci_node_type} (type, merci_type_setting, merci_max_hours_per_reservation, merci_allow_overnight, merci_allow_weekends, merci_late_fee_per_hour, merci_rate_per_hour, merci_fee_free_hours, merci_active_status, merci_spare_items, merci_min_cancel_hours, merci_autocheckout, merci_autocheckin, merci_selfcheckout, merci_auto_assign_bucket_item) 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); Array
(
[:db_insert_placeholder_0] => evenement
[:db_insert_placeholder_1] => disabled
[:db_insert_placeholder_2] => 0
[:db_insert_placeholder_3] => 0
[:db_insert_placeholder_4] => 0
[:db_insert_placeholder_5] => 0
[:db_insert_placeholder_6] => 0
[:db_insert_placeholder_7] => 0
[:db_insert_placeholder_8] => 0
[:db_insert_placeholder_9] => 0
[:db_insert_placeholder_10] => 0
[:db_insert_placeholder_11] => 0
[:db_insert_placeholder_12] => 0
[:db_insert_placeholder_13] => 0
[:db_insert_placeholder_14] => 0
)
dans drupal_write_record() (ligne 7013 dans /Users/<me>/project/www/includes/common.inc).
Drush command terminated abnormally due to an unrecoverable error.
I am unable to provide steps to reproduce on a clean D7, however the problem occurs on different systems (mac, linux and windows) using the same codebase and database dump.
Proposed resolution
As far as I can tell the problem occurs in function merci_node_type_update_variables() in merci/includes/database.inc which receives as 2nd parameter a boolean ($existing) to indicate whether drupal_write_record needs to insert or update.
When it goes wrong it seems that the value of $existing that is being passed is, incorrectly, FALSE, so drupal_write_record tries to insert a new record in the merci_node_type table, instead of updating it, prompting the "Integrity constraint violation: 1062 Duplicate entry" error.
I haven't tracked down under which circumstances this problem occurs. However, if we simply rewrite this:
if (!$existing) {
$return = drupal_write_record('merci_node_type', $settings);
else {
$return = drupal_write_record('merci_node_type', $settings, 'type');
}
into a standard merge query like this :
db_merge('merci_node_type')
->key(array('type' => $info->type))
->fields($settings)
->execute();
we circumvent the bug altogether and have more robust code. We won't need the $existing argument anymore either.
To make this work I also needed to unset($settings['merci_status']) since there's no matching db column in table merci_node_type. In fact, 'merci_status' seems to be a leftover from the olden days since AFAIK it's never used anywhere.
Comment | File | Size | Author |
---|---|---|---|
#1 | merci-fix_for_pdo_error-1803028.patch | 824 bytes | jpoesen |
Comments
Comment #1
jpoesen CreditAttribution: jpoesen commentedAdding a patch.
Comment #2
Dustin@PI CreditAttribution: Dustin@PI commentedI just got the same error on adding exporting and adding a feature back to our dev site.
We were building up a number of complex event types, we export the feature and then re-added it to the site.
Now any time we save a content type or clear cache we get this error. The content type that is listed as a duplicate violation changes each time--but seems to always be one of the types that were in the feature.
I'll try the Patch and see if it fixes the error.
Comment #3
Dustin@PI CreditAttribution: Dustin@PI commentedFYI the Patch also fixed the issue that I was having.
I am unable to recreate the issue on a clean install, but the code change is rather simple (elegant).
Thanks @jpoesen!
Comment #4
Dustin@PI CreditAttribution: Dustin@PI commentedFYI the Patch also fixed the issue that I was having.
I am unable to recreate the issue on a clean install, but the code change is rather simple (elegant).
Thanks @jpoesen!