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 &#039;evenement&#039; for key &#039;PRIMARY&#039;: 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.

CommentFileSizeAuthor
#1 merci-fix_for_pdo_error-1803028.patch824 bytesjpoesen
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jpoesen’s picture

Adding a patch.

Dustin@PI’s picture

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

Dustin@PI’s picture

FYI 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!

Dustin@PI’s picture

Issue summary: View changes
Status: Active » Reviewed & tested by the community

FYI 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!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 1: merci-fix_for_pdo_error-1803028.patch, failed testing.