Excerpt from private_nodeapi():
case 'insert':
case 'update':
db_query('UPDATE {private} SET private = %d WHERE nid = %d', $node->private, $node->nid);
if (!db_affected_rows()) {
db_query('INSERT INTO {private} (nid, private) VALUES (%d, %d)', $node->nid, $node->private);
}
break;
In my case, db_affected_rows() returns zero when no change results from the update query (i.e. when re-saving an existing node with no change to the 'private' flag). Thus, the insert query is attempted, which then causes the duplicate entry error message. This patch eliminates the error message.
See also this similar discussion: #798626: Cron produces duplicate entry error in search.module.
Comments
Comment #1
Anonymous (not verified) commentedI tried to reproduce this and don't got the error described. The PHP error supression (@) is bad style. It would be good to reproduce this and work in a better solution than just hidding the error. 1/2 cents.
Comment #2
jaxpax commentedI to get an entry error when trying to save a node that's already been saved. Both from the Privare module as from the UUID module
Comment #3
pieterh commentedI just got the following error
The error is only popping up when i update a private post.
I got this only on a server with my webhosting provider. On my local test/developing server i never got this problem. I started all over with a clean install and still having this error.
Comment #4
_snake_ commentedSubscribe,
Hi, I have the following warning when I'm trying to update a node, but I don't change the private field:
so, looking the code at the private.module file:
I think that when I edit the node, but I don't change the private field, and I click "Save", the line 198 is executed, but there isn't any db_affected_rows(), so the insert query is executed too, throwing the warning. Is that correct?
Tomorrow, I try to know if the insert query is executed, using the following line and looking the log file:
error_log(db_affected_rows());
If it's executed, then I think the best way to solve that is making a SELECT query to the private table to know if the nid is there or not, and make later the UPDATE query or the INSERT query respectively.
Thanks.
Comment #5
David Lesieur commentedAbout the PHP error-control operator (@) in my patch: There are a few instances where Drupal core uses it in the exact same fashion (for example, see variable_set()). I agree that it is not an ideal practice, but it avoids adding an extra query.
Comment #6
timb commentedI am encountering this Duplicate Key error also with Private when saving a previously created node and not changing it's private status.
My set: Ubuntu 10.04: PHP 5.3.2: Drupal 6.20
Comment #7
beatnikdude commentedbump
• Drupal 6.20 w/ Private 6.x-1.1
Duplicate Key error when saving an already existing node.
Comment #8
ezra-g commentedI can confirm this error with the latest dev release, but simply commenting out this line is not an adequate solution.
Comment #9
ezra-g commentedAfter reading further into #638702: insertion errors I learned that this is the approach used in the core user.module. This approach suppresses the error for me. I think this is RTBC ;).
Comment #10
timb commentedWould love to see this committed as opposed to running a patched module
Comment #11
beatnikdude commentedlets commit
Comment #12
timb commentedbump
Comment #13
Anonymous (not verified) commentedA year later, a more conservative patch :-)
db_affected_rows() will only return something different than zero if something changed in the row at the UPDATE execution. This can be confirmed with some simple queries in a MySQL client:
Comment #14
jesusmalaga commentedThere is a much simpler and elegant answer to this. It is probably related to some change in MySQL server behaviour, as we have this module installed in two different servers, and the older one gives no error while the modern is giving the alerts (right alerts, on the other side, as while eriksen noted, there are no update results if status does not change. I have no time now to make a patch, but code change is easy:
============================
.........
case 'insert':
case 'update':
db_query('REPLACE INTO {private} (private,nid) VALUES (%d,%d)', $node->private, $node->nid);
break;
...............
============================
Using this code, as nid is the primary key of table, ensures in a simple sentence that node will be inserted or updated either way
Comment #15
adamps commentedTidy up - close ancient D6 issues. Seems to be fixed in current code using db_merge