| Project: | File (Field) Paths |
| Version: | 6.x-1.4 |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Issue Summary
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?
Comments
#1
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?
#2
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?
#3
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:
<?php// 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().
#4
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.
#5
Moving this to FileField Paths.
#6
That bug still exists in 1.4. I didn't find out, why this happens. Any idea?
#7
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.
#8
I'm having the same issue.
It only happens when creating new nodes that contain content_taxonomy fields.
#9
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.
#10
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.
#11
In case of empty field $file['field'] is empty, so I suggest to skip such files in the loop.
#12
Another fix attempt is in #721454: Active updating tries to move non-existent file. Waiting for the official fix. :)
#13
unfortunately, #11 doesn't solve the problem. I created a screenshot with dpm() inserted at the mentioned position (see attachement).
#14
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.
#15
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.
#16
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?
#17
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.
#18
Double post, sorry
#19
@Earl Grey (#16): That's The Solution!
GREAT.
Thank you so much!
#20
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:
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 turnmodule_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.
#21
subscribe
#22
This issue was driving me crazy... #16 did the trick for me :-)
Thanks for the (temporary) fix Earl!
#23
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
#24
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?