Subject: | UTF8 columns may be marked as dirty when they have not been really changed |
I found that some columns are changed by an UPDATE statement even if the
value used in set_column() is the same as the one read from the
database. Also, UPDATEs are sent to the database even if I call update()
with the values read from the database. In other words, in some cases
something like $row->column( $row->column() ) caused the column to be
marked as dirty.
I found that the columns that were unnecessarily updated were
UTF8Columns, containing non-latin1 characters.
I traced this to the set_column method from DBIx::Class::Row, where a
string of characters, $old, is compared with a string of bytes, $ret.
In the case of non-latin1 characters $old and $ret are not equal.
Attached is a test added to t85utf.t to show the problem.
My version of perl is 5.8.5 and DBIx::Class is version 0.08010.
Subject: | t85utf.t.diff |
--- DBIx-Class-0.08010/t/85utf8.t.orig 2007-08-12 00:07:59.000000000 +0300
+++ DBIx-Class-0.08010/t/85utf8.t 2008-09-20 22:55:14.000000000 +0300
@@ -16,7 +16,7 @@
eval 'use utf8; 1' or plan skip_all => 'Need utf8 run this test';
}
-plan tests => 3;
+plan tests => 4;
DBICTest::Schema::CD->load_components('UTF8Columns');
DBICTest::Schema::CD->utf8_columns('title');
@@ -43,3 +43,9 @@
$cd->title($utf8_char);
ok( !utf8::is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
}
+
+my $v = "\x{219}"; # s with comma below (characters outside latin1 are needed)
+$cd->title($v);
+$cd->update;
+$cd->title($v);
+ok( !$cd->is_column_changed('title'), 'column is not dirty after setting the same value' );