| Project: | Printer, e-mail and PDF versions |
| Version: | 6.x-1.11 |
| Component: | Code |
| Category: | bug report |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
Since updating to 6x-1.11 yesterday, the module throws this error when I update the content of a node:
* user warning: Duplicate entry '97' for key 'PRIMARY' query: INSERT INTO print_node_conf (nid, link, comments, url_list) VALUES (97, 1, 0, 1) in /var/www/sites/all/modules/print/print.module on line 553.
* user warning: Duplicate entry '97' for key 'PRIMARY' query: INSERT INTO print_mail_node_conf (nid, link, comments, url_list) VALUES (97, 1, 0, 1) in /var/www/sites/all/modules/print/print_mail/print_mail.module on line 347.
* user warning: Duplicate entry '97' for key 'PRIMARY' query: INSERT INTO print_pdf_node_conf (nid, link, comments, url_list) VALUES (97, 1, 0, 1) in /var/www/sites/all/modules/print/print_pdf/print_pdf.module on line 380.
Comments
#1
I also I have the same problem after updating to version 6.x-1.11
I get that poster every time I edit, or I create a node.
* user warning: Duplicate entry '491' for key 'PRIMARY' query: INSERT INTO print_node_conf (nid, link, comments, url_list) VALUES (491, 1, 0, 1) in /var/www/adrianfrancisconi.com.ar/sites/all/modules/print/print.module on line 553.* user warning: Duplicate entry '491' for key 'PRIMARY' query: INSERT INTO print_mail_node_conf (nid, link, comments, url_list) VALUES (491, 1, 0, 1) in /var/www/adrianfrancisconi.com.ar/sites/all/modules/print/print_mail/print_mail.module on line 347.
.
#2
can fix it as follows:
disable all the modules of "Printer, e-mail and PDF versions"
then you uninstall (admin / build / modules / uninstall)
and then reinstall the module.
#3
This is a moranesque problem because you're using MySQL instead of PostgreSQL. Obviously PostgreSQL is much better overall... and you should be using that system!
This being said, in the following db_affected_rows() returns 0 when the UPDATE doesn't do anything to the database (i.e. finds a row, but does not change [affect] it.)
There are tons of such reports all around Drupal because the Core people had a fix by MySQL broke it!
The only solution is to do a SELECT to know whether the UPDATE worked. Do the SELECT inside the if() block and eventually testing whether pgsql is running (if so, skip the select).
Note: The mini module can be used to test this problem.
<?phpfunction _print_node_conf_modify($nid, $link, $comments, $url_list) {
db_query("UPDATE {print_node_conf} SET link = %d, comments = %d, url_list = %d WHERE nid = %d", $link
if (!db_affected_rows()) {
db_query("INSERT INTO {print_node_conf} (nid, link, comments, url_list) VALUES (%d, %d, %d, %d)", $
}
}
?>
Thank you.
Alexis Wilke
P.S. db_affected_rows() is used in several places and obviously needs to be fixed in all places.
#4
@ #3 AlexisWilke:
The best way for MySQL is
INSERT INTO {print_node_conf} (nid, link, comments, url_list) VALUES (%d, %d, %d, %d) ON DUPLICATE KEY UPDATE SET link = %d, comments = %d, url_list = %dBut I think we can't do that in Drupal because we support PostgreSQL ;-)
I think the problem could be solved by changing the order of the statements like the other modules do:
<?phpfunction _print_node_conf_modify($nid, $link, $comments, $url_list) {
@db_query("INSERT INTO {print_node_conf} (nid, link, comments, url_list) VALUES (%d, %d, %d, %d)", $
if (!db_affected_rows()) {
db_query("UPDATE {print_node_conf} SET link = %d, comments = %d, url_list = %d WHERE nid = %d", $link
}
}
?>
It's ugly but the common way in Drupal 6.
Please try my patch.
#5
I have installed the patch and it has worked. Thank you for the fix.
#6
Hi mkalkbrenner,
Actually, the REPLACE instruction in MySQL is better than UPDATE + on error INSERT.
http://dev.mysql.com/doc/refman/5.1/en/replace.html
And with PostgreSQL, we could program a REPLACE command... but D7 now has to be compatible with 10 different database systems! Including Oracle and MS SQL... So using anything too specific will definitively break one or the other.
Otherwise, I checked your code and it looks good.
My concern with an @db_query() is that, if you're like me, while development, you write completely stupid SQL code and on those line you won't see it at all... As long as as you don't have to change them, you should be fine, though.
Thank you.
Alexis
P.S. As a side note, you may want to run http://drupal.org/project/coder against your code...
#7
Hi,
Sorry to disagree, but in these cases I usually do what Core does.
Searching for db_affected_rows in Drupal core gave me several results where the fix for this problem was to simply add an '@' before the INSERT db_query.
AlexisWilke: As to the coder suggestion, I already run it at maximum level and the 2 types of warnings that it still issues are ignored by me on purpose. Unless of course, you're having different results..
João
#8
João,
Core does a lot of things I disagree with... I don't run with a 1:1 copy of Core... 8-)
This being said, they do a good job in most cases. It is just that some things are not PostgreSQL compatible (especially the threaded comments, what a joke!).
In regard to coder, it is certainly another module I have seen problems in... Sorry! I had to update over 10 modules! 8-}
Thank you for the quick fix.
Alexis
#9
I know that this is off topic but I have to answer.
@AlexisWilke
But I think we can't do that in Drupal because we support PostgreSQL ;-)
This was not an attack against PostgreSQL. Everybody should use the database he likes.
Actually, the REPLACE instruction in MySQL is better than UPDATE + on error INSERT.
REPLACE in MySQL causes a DELETE + INSERT what might be slow and might have different side effects.
My concern with an @db_query() is that, if you're like me, while development, you write completely stupid SQL code and on those line you won't see it at all...
I agree.
Core does a lot of things I disagree with... I don't run with a 1:1 copy of Core... 8-)
Again, I agree. In Cocomore Drupal Core we introduced a global variable for the database type and do it like that:
<?php
global $db_type;
if (strpos($db_type, 'mysql') === 0) {
db_query("INSERT INTO {node_counter} (nid, daycount, totalcount, timestamp) VALUES (%d, 1, 1, %d) ON DUPLICATE KEY UPDATE daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d", arg(1), time(), time());
}
else {
db_query('UPDATE {node_counter} SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d', time(), arg(1));
if (!db_affected_rows()) {
@db_query('INSERT INTO {node_counter} (nid, daycount, totalcount, timestamp) VALUES (%d, 1, 1, %d)', arg(1), time());
}
}
?>
If you have suggestions how to improve the PostreSQL part we'll welcome your patches.
P.S. As a side note, you may want to run http://drupal.org/project/coder against your code...
I think I know what you're talking about ...
Now any further discussion should be continued somewhere else. Feel free to contact me.
#10
Automatically closed -- issue fixed for 2 weeks with no activity.