From 5ec6043ac37380fac2cbcbc15e4f2e8b76653f15 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Mon, 21 Sep 2009 11:58:15 +0200 Subject: [PATCH] Fix for BUG#35570 "CHECKSUM TABLE unreliable if LINESTRING field (same content/ differen checksum)" The problem was that checksum of GEOMETRY type used memory addresses in the computation, making it un-repeatable thus useless. (This patch is a backport from 6.0 branch) mysql-test/r/myisam.result: test case for bug35570 that same tables give same checksums mysql-test/t/myisam.test: test case for bug35570 that same tables give same checksums sql/sql_table.cc: Type GEOMETRY is implemented on top of type BLOB, so, just like for BLOB, its 'field' contains pointers which it does not make sense to include in the checksum; it rather has to be converted to a string and then we can compute the checksum. --- mysql-test/r/myisam.result | 19 +++++++++++++++++++ mysql-test/t/myisam.test | 15 +++++++++++++++ sql/sql_table.cc | 10 ++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 732b1b260f8..58e2e451a0d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -2252,4 +2252,23 @@ h+0 d + 0 e g + 0 1 1 3 0 1 1 4 0 DROP TABLE t1; +# +# Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field +# (same content / differen checksum) +# +CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)")); +checksum table t1; +Table Checksum +test.t1 326284887 +CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam; +INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)")); +checksum table t2; +Table Checksum +test.t2 326284887 +CREATE TABLE t3 select * from t1; +checksum table t3; +Table Checksum +test.t3 326284887 +drop table t1,t2,t3; End of 5.1 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index ba6bc05cfea..5de7c997a24 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1503,5 +1503,20 @@ SELECT h+0, d + 0, e, g + 0 FROM t1; DROP TABLE t1; +--echo # +--echo # Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field +--echo # (same content / differen checksum) +--echo # + +CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam; +INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)")); +checksum table t1; +CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam; +INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)")); +checksum table t2; +CREATE TABLE t3 select * from t1; +checksum table t3; +drop table t1,t2,t3; + --echo End of 5.1 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9d929c0d1a3..08f3311be9d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7897,8 +7897,14 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, for (uint i= 0; i < t->s->fields; i++ ) { Field *f= t->field[i]; - if ((f->type() == MYSQL_TYPE_BLOB) || - (f->type() == MYSQL_TYPE_VARCHAR)) + enum_field_types field_type= f->type(); + /* + BLOB and VARCHAR have pointers in their field, we must convert + to string; GEOMETRY is implemented on top of BLOB. + */ + if ((field_type == MYSQL_TYPE_BLOB) || + (field_type == MYSQL_TYPE_VARCHAR) || + (field_type == MYSQL_TYPE_GEOMETRY)) { String tmp; f->val_str(&tmp);