Hey folks,

when saving a newly created node with some fields empty, cck tries to save these empty values into the database, but an empty value already exists. Here is the error message:

user warning: Duplicate entry '287-0' for key 1 query: INSERT INTO intern_content_field_wr_files (vid, nid, delta, field_wr_files_fid, field_wr_files_list, field_wr_files_data) VALUES (287, 166, 0, NULL, NULL, NULL) in /htdocs/sites/all/modules/cck/content.module on line 1213.

I get three of these messages, as there are three fields left blank.

The node is saved properly and I can edit and save it again withour errors.

The field types (in this case) are: file, link and node reference. There is no error message for a fourth field, that I left blank. The field type of that field is text.

Any ideas on that?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

nikitas’s picture

have you checked how are those fields are saved into database?could it be because a unique feature is activated for either the cck field or is something from the administration panel that is checked?

Anonymous’s picture

I couldn't find a 'unique' feature for cck fields. In my opinion, empty fields should not be stored in DB at all!

I have some more information about that issue:

- it only appears, if I set the number of values to a number higher than '1' (includes unlimited)
- if I use a fixed number of items, the error occurs in that same ammount (2 items - 2 warnings)
- with one fixed item, there is no erro
- with an 'unlimited' number of items, there is ony one warning.

I can't remember that warning prior to updating to cck 2.6, but have no idea what change could cause this.

The table intern_content_field_wr_files (for example) contains 79 rows, most of them with NULL values. Is that the way it should be?

I took a closer look at the DB: the values, that should be stored (287-0 in the example) do exist in the DB, so I guess, cck tries to store them twice, for some reason. The shouldn't be stored if they have no value (in my opinion).

Can I trace the call of php functions in cck somehow?

markus_petrux’s picture

Status: Active » Postponed (maintainer needs more info)

When updating a node, CCK deletes all records of the vid in the tables of multiple value fields, then proceeds to insert the new records. When inserting, it uses a loop where delta is the key, so it is not possible to create dups while inserting, and it shouldn't be possible either, if the previous records where removed. See the code:

      // 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);
          }
          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);
          }
        }
      }

So, it seems there's something odd in your system.

Note that CCK deletes when $op is 'update'. This comes from node_save(), and it is set if nid is not empty in node object. So, if CCK does not perform the deletes, it could be that node_save() triggers an insert operation, and that could happen where it shouldn't if the nid is empty on a node object passed to node_save().

Anonymous’s picture

This happens only when creating a new node, so $op should never be 'update' when saving a new node. I guess, that the code you posted (in which file is that code?) is executed twice with $op != 'update'.

I figured out that this error only occurs, when FileField Paths is activated, which is using the token module. Is it possible, that the node needs to be saved, before tokens can be evaluated and the node is saved a second time, after the filefield path has been generated with the use of tokens?

Which values are possible for $op? Would it be possible to delete all lines in the DB, even if the node is saved the first time? I think, this is a performance issue, but that query should be executed very quickly, if there is no line to delete in the table.

I'll have a look at the module(s) causing that issue. Maybe I find something interesting in the code.

Anonymous’s picture

Title: Receiving "duplicate entry" error when saving a node with empty fields » FileField paths causes "duplicate entry" error when saving a node with empty fields
Project: Content Construction Kit (CCK) » File (Field) Paths
Version: 6.x-2.6 » 6.x-1.x-dev
Component: content.module » Code
Status: Postponed (maintainer needs more info) » Active

Moving this to FileField Paths.

Anonymous’s picture

Version: 6.x-1.x-dev » 6.x-1.4

That bug still exists in 1.4. I didn't find out, why this happens. Any idea?

Deciphered’s picture

Hi Earl Grey,

Must have missed this issue when it was moved. Haven't had a chance to look into it yet, but I will try to make some time in the next few days.

Cheers,
Deciphered.

drewmacphee’s picture

I'm having the same issue.

It only happens when creating new nodes that contain content_taxonomy fields.

hatsch’s picture

I have a very similar issue file filefield_paths. using versin 6.x-1.4 (maybe not the same ? )

i have 3 filefields, where only one is filled in by the user. the rest is generated by cron.php using media_mover. so two fields are always empty on submission. but all the fields have a filefield_path.

i have to state that everythings just works as expected. also when storing files to cck with mediamver the corrent filefield_path is used.

but there are errors showing up when i submit a post.

    * The selected file /var/www/drupal-6.15 could not be copied.
    * The selected file could not be copied, because no file by that name exists. Please check that you supplied  the correct filename.
    * The selected file /var/www/drupal-6.15 could not be copied.

those filefields are not marked as required, so filefield_path should not try to copy them when they don't exist.

Deciphered’s picture

Status: Active » Postponed (maintainer needs more info)

Guys,

Can you possibly do some debugging for me to help me figure out the issue, as I have yet to be able to reproduce it?

Simply install the Devel module, then insert the following code between lines #424 and #425 of filefield_paths.module:

      dpm($file);

Then post the results here so I can best determine the issue.

Cheers,
Deciphered.

maximpodorov’s picture

FileSize
470 bytes

In case of empty field $file['field'] is empty, so I suggest to skip such files in the loop.

maximpodorov’s picture

Another fix attempt is in #721454: Active updating tries to move non-existent file. Waiting for the official fix. :)

Anonymous’s picture

FileSize
96.13 KB

unfortunately, #11 doesn't solve the problem. I created a screenshot with dpm() inserted at the mentioned position (see attachement).

GuyPaddock’s picture

I am also seeing what I believe to be the same issue. In my case, I have an optional filefield, and I get a similar error whenever a field is left blank (no file selected):

user warning: Duplicate entry '163-0' for key 1 query: INSERT INTO content_field_optional_file (vid, nid, delta, field_optional_file_fid, field_optional_file_list, field_optional_file_data) VALUES (163, 128, 0, NULL, NULL, NULL) in sites/all/modules/cck/content.module on line 1213.

I can't install Devel right now, but a backtrace created with debug_print_backtrace() is attached.

keinstein’s picture

For me it looks like a race condition with some module calling save_node as in #732382 .

To solve it you must find out, which module actually inserts the record into the table. The backtrace you posted is only the one, that triggers the error messag, but not the one which insterts the record and thus shows the error.
So please check all backtraces which insert some record in {content_field_optional_file} if there is called some hook_nodeapi as in your backtrace. For a first start compare the last ones in each backtrace. If they are different try to separate them by changing the weight in {system}.

I did my backtraces in database.mysqli.inc, setting the default parameter $debug = 1 and changing the debug code to

  if ($debug && stripos($query,'insert')===0 && stripos($query,'content_field_optional_file')!==false) {
	  $handle = fopen ('/tmp/querylog.log','a');
	  fprintf($handle,"\nquery: %s\n\nerror: %s\n", $query,mysqli_error($active_db));
	  fprintf($handle,"\nbacktrace: \n%s\n\n ",print_r(debug_backtrace(),true));
	  fclose($handle);
  }

This log might become very large.

Anonymous’s picture

Status: Postponed (maintainer needs more info) » Needs work

Like I posted in #732382: Duplicate entry '690-0' for key 1 query: INSERT INTO content_field_photo... /sites/all/modules/cck/content.module on line 1213., changing the weight of the content module to -1 or the weight of FileField paths to 1 solves the problem. I cound't see any unwanted side effects. Would it be possible to ship the FileField paths module with a weight ot 1 by default?

markusbroman’s picture

Hey Hatsch! I am having the exact same problem and I cant figure it out. Have you by any chance solved this?

I would very much appreciate if you have a solution.

markusbroman’s picture

Double post, sorry

eliosh’s picture

@Earl Grey (#16): That's The Solution!
GREAT.
Thank you so much!

kaare’s picture

Just another confirmation of this bug and its fix. But! This comment has a patch! :-)

I suspect this bug doesn't show itself often. There is a few criterias that need to be set before:

  • You need a filefield as part of your content type
  • You need at least one field that is multivalue or exists in a different content type (separate table). This is also the field that will cause the duplicate entry.
  • Your module's filename in {system} table must be higer alphabetically than content.module

I suspect the last point is occurs the least, given that users mostly cram all their modules in the same folder, but will trigger given this setup:

mysql> select name,filename,weight from system where name in ('content', 'filefield_paths') order by weight,filename;
+-----------------+----------------------------------------------------------+--------+
| name            | filename                                                 | weight |
+-----------------+----------------------------------------------------------+--------+
| filefield_paths | sites/all/modules/filefield_paths/filefield_paths.module |      0 |
| content         | sites/default/modules/cck/content.module                 |      0 |
+-----------------+----------------------------------------------------------+--------+

which is the order module_list() and in turn module_implements() gets it.

With this setup, filefield_paths will run _content_field_invoke_default('update', $node); before content.module's _content_field_invoke_default('insert', $node); during hook_nodeapi($op = 'insert'). This makes no sense. Why should filefield_paths be the one to inject the fields into their separate tables?

I suspect this bug has lived for this long because most people will have all modules in the same folder. Then everyhing is ok.

Patch attached.

jeffwidman’s picture

subscribe

jvandooren’s picture

This issue was driving me crazy... #16 did the trick for me :-)

Thanks for the (temporary) fix Earl!

STNyborg’s picture

I still get an error stating "The selected file could not be copied, because no file by that name exists. Please check that you supplied the correct filename." when submitting a node with a file attachment.

When reading the log statement it says "FileField Paths failed to move file (uploads/publications/2011/09/test.pdf) to (sites/files/test.pdf).".

I have tried to follow the suggesting from #16 without luck.

Any suggestions?

Regards,

Nyborg

obrienmd’s picture

Status: Needs work » Needs review

I've also had success with #16 (i.e., setting module weight to 1). Would it be possible to set .install and updates to make this 1 by default?

abautu’s picture

FileSize
665 bytes

I believe the problem source is not with the module weights, but the fact that on nodeapi insert operation, FFP module calls (indirectly) _content_field_invoke_default('update', $node). This forces CCK to insert the fields in table while filefield_paths_node_insert is executing. After that, the node module calls indirectly content_insert($node), which basically tries again to save the fields, resulting in the primary key duplication error that you see.

If you change the module weights, thinks happen like this: first cck calls content_insert, then FFP calls _content_field_invoke_default('update', $node) (for the same data). In this case, there is no error, because you do insert follow by update, but you still have the overhead of the not needed CCK update.

Attached is a patch for this.
Cheers,
Andrei

Deciphered’s picture

Status: Needs review » Needs work

This latest patch will most definitely break functionality, as (IIRC) the call it's removing is necessary for saving the updated textfields that referenced the original file path.

I'm not going to mark this as needs work, rather nothing more will happen unless someone gives it a full review and confirms it does not break anything and marks the issue as RTBC.

abautu’s picture

Actually the fields will be saved by content_nodeapi which is called after FFP nodeapi is called (assuming you did not perform the module weighting changes suggested in #16). In my case, content has weight 0 and FFP has weight -10. I don't recall changing them, but i don't see (in code) how -10 might have got in there.

abautu’s picture

Status: Needs work » Needs review

Hi Deciphered,

I'll marking this again as needs review to get your feedback.

So my previous patch, works ok for me because of the module weights. It should be complemented with and install/update that puts FFP ahead of content. If you think this makes sense, I can extend the patch.

Cheers,
Andrei

roball’s picture

Version: 6.x-1.4 » 6.x-1.5
Deciphered’s picture

Issue summary: View changes
Status: Needs review » Closed (won't fix)

No longer supporting Drupal 6 issues for this module.