in function content_storage()

  switch ($op) {
...
    case 'insert':
    case 'update':
...
          // Delete and insert, rather than update, in case a value was added.
          if ($op == 'update') {
            db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid);
          }

Why record is deleted only during the update, but not during insert?

Code after fix:

          if ($op == 'update' || $op == 'insert') {
            db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid);
          }

Patch in attachment.

Problem is related to:
http://drupal.org/node/259837#comment-1108886
http://drupal.org/node/259837#comment-1123160

CommentFileSizeAuthor
#10 content.module.patch652 byteskenorb
#1 content.module.patch610 byteskenorb

Comments

kenorb’s picture

StatusFileSize
new610 bytes

Patch.

andypost’s picture

Delete on insert what for?

dagdag’s picture

I had a similar problem when a tried to save a content type that use a computed field to search in a database, it show me a duplicate warning for this field

so I have applied the patch and it seem works, no more warning message

-drupal 6.8
-cck 6.x-2.1

kenorb’s picture

Problem is as well with NodeReferrer module after converted to 6.x
http://drupal.org/node/259837

Delete on insert, because after few lines there is INSERT.

So cck write the same record twice as follow (see line with function content_write_record()):

        if (count($record) || empty($schema['content fields'])) {
          $record['nid'] = $node->nid;
          $record['vid'] = $node->vid;
          // Can't rely on the insert/update op of the node to decide if this
          // is an insert or an update, a node or revision may have existed
          // before any fields were created, so there may not be an entry here.

          if (db_result(db_query("SELECT COUNT(*) FROM {". $table ."} WHERE vid = %d", $node->vid))) {
            content_write_record($table, $record, array('vid'));
          }
          else {
            content_write_record($table, $record); // <!-- FIRST WRITE HERE !!!
          }
        }
      }

      // Handle multiple fields.
      foreach ($type['fields'] as $field) {
        if ($field['multiple'] && isset($node->$field['field_name'])) {
          $db_info = content_database_info($field);
          // Delete and insert, rather than update, in case a value was added.
          if ($op == 'update') {
            db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid); // <!-- DELETE FIRST WRITE ONLY WHEN UPDATE !
          }
          foreach ($node->$field['field_name'] as $delta => $item) {
            $record = array();
            foreach ($db_info['columns'] as $column => $attributes) {
              $record[$attributes['column']] = $item[$column];
            }
            $record['nid'] = $node->nid;
            $record['vid'] = $node->vid;
            $record['delta'] = $delta;
            content_write_record($db_info['table'], $record); // <!-- SECOND WRITE HERE !!!
dagdag’s picture

Yes, I have this problem now, it insert duplicate values in a vocabulary I was looking but i not used with the drupal development, maybe can be an error in the multiple fields, another aspect is that the code is inserted in a switch structure if you simply let

db_query('DELETE FROM {'. $db_info['table'] .'} WHERE vid = %d', $node->vid);

whithout

if ($op == 'update' || $op == 'insert'){

it eliminates the duplicate warning but the duplicate error is maintained
the switch option for 'insert' is empty, maybe there is the best place to correct the mistake

Flying Drupalist’s picture

subscribe

kenorb’s picture

Status: Needs review » Reviewed & tested by the community
paulludington’s picture

Subscribe.

kenorb’s picture

StatusFileSize
new652 bytes
yched’s picture

Status: Reviewed & tested by the community » Postponed (maintainer needs more info)

I'm sorry but I'll need a little more explanation as to why this is needed.
How can there be, in a per-field table, rows than should be deleted for the vid of the node that is that is just *being created* ?

If this is specific to nodereferrer fields, then please describe briefly the code workflow that leads to this. I'm not familiar with nodereferrer and have little time to dive in there.

On a minor note, and *if* this is actually needed, then the remark in #5 is true : no need to test if ($op == 'update' || $op == 'insert'), the if() test can simply go.

andypost’s picture

Is there some documentation about using new "multiple values" I don't know what the way is right http://drupal.org/node/259837#comment-1318962

yched’s picture

A widget needs to declare "multiple values" => CONTENT_HANDLE_MODULE when one single widget lets the user pick several values (for instance a select with #multiple set to TRUE). This tells CCK that it's not necessary to output several copies of the widget for fields that are 'multiple'.

kenorb’s picture

andypost’s picture

Status: Postponed (maintainer needs more info) » Fixed

Suppose fixed just removing multiple option

nodereferrer cant be multiple... so no need in multiple & required flag at all

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

dagdag’s picture

So I had this problem some months ago even with the 6.13 release but with 6.14 it seems to be fixed

drupal 6.14
cck 6.x 2.5