You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by mm...@apache.org on 2011/06/23 19:03:06 UTC
svn commit: r1138991 -
/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
Author: mmartinec
Date: Thu Jun 23 17:03:05 2011
New Revision: 1138991
URL: http://svn.apache.org/viewvc?rev=1138991&view=rev
Log:
Bug 6624: BayesStore/MySQL.pm fails to update tokens due to MySQL server bug (wrong count of rows affected)
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm?rev=1138991&r1=1138990&r2=1138991&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/BayesStore/MySQL.pm Thu Jun 23 17:03:05 2011
@@ -840,14 +840,28 @@ sub _put_token {
return 0;
}
+ # With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
+ # the row is inserted as a new row and 2 if an existing row is updated.
+ #
+ # Due to a MySQL server bug a value of 3 can be seen.
+ # See: http://bugs.mysql.com/bug.php?id=46675
+ # When executing the INSERT ... ON DUPLICATE KEY UPDATE statement
+ # and checking the rows return count:
+ # mysql_client_found_rows = 0: The second INSERT returns a row count
+ # of 2 in all MySQL versions.
+ # mysql_client_found_rows = 1: The second INSERT returns this row count:
+ # Before MySQL 5.1.20: 2
+ # MySQL 5.1.20: undef on Mac OS X, 139775481 on Linux (garbage?)
+ # MySQL 5.1.21 and up: 3
+ #
my $num_rows = $rc;
$sth->finish();
- if ($num_rows == 1 || $num_rows == 2) {
+ if ($num_rows == 1 || $num_rows == 2 || $num_rows == 3) {
my $token_count_update = '';
- $token_count_update = "token_count = token_count + 1," if ($num_rows == 1);
+ $token_count_update = "token_count = token_count + 1," if $num_rows == 1;
$sql = "UPDATE bayes_vars SET
$token_count_update
newest_token_age = GREATEST(newest_token_age, ?),
@@ -872,7 +886,11 @@ sub _put_token {
}
else {
# $num_rows was not what we expected
- dbg("bayes: _put_token: Updated an unexpected number of rows.");
+ my $token_displ = $token;
+ $token_displ =~ s/(.)/sprintf('%02x',ord($1))/egs;
+ dbg("bayes: _put_token: Updated an unexpected number of rows: %s, ".
+ "id: %s, token (hex): %s",
+ $num_rows, $self->{_userid}, $token_displ);
$self->{_dbh}->rollback();
return 0;
}
@@ -987,8 +1005,24 @@ sub _put_tokens {
else {
my $num_rows = $rc;
- $need_atime_update_p = 1 if ($num_rows == 1 || $num_rows == 2);
- $new_tokens++ if ($num_rows == 1);
+ # With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
+ # the row is inserted as a new row and 2 if an existing row is updated.
+ # But see MySQL bug (as above): http://bugs.mysql.com/bug.php?id=46675
+
+ if ($num_rows == 1) {
+ $new_tokens++;
+ $need_atime_update_p = 1;
+ } elsif ($num_rows == 2 || $num_rows == 3) {
+ $need_atime_update_p = 1;
+ } else {
+ # $num_rows was not what we expected
+ my $token_displ = $token;
+ $token_displ =~ s/(.)/sprintf('%02x',ord($1))/egs;
+ dbg("bayes: _put_tokens: Updated an unexpected number of rows: %s, ".
+ "id: %s, token (hex): %s",
+ $num_rows, $self->{_userid}, $token_displ);
+ $error_p = 1;
+ }
}
}
@@ -1026,10 +1060,10 @@ sub _put_tokens {
}
}
else {
- # $num_rows was not what we expected
- dbg("bayes: _put_tokens: Updated an unexpected number of rows.");
- $self->{_dbh}->rollback();
- return 0;
+ info("bayes: _put_tokens: no atime updates needed? Num of tokens: %d",
+ scalar keys %{$tokens});
+# $self->{_dbh}->rollback();
+# return 0;
}
}