#At file:///home/ram/mysql/b11764487-5.1/ based on revid:vinay.fisrekar@stripped
3622 Ramil Kalimullin 2011-05-16
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
Problem: in case of wrong data insert into indexed GEOMETRY fields
(e.g. NULL value for a not NULL field) MyISAM reported
"ERROR 126 (HY000): Incorrect key file for table; try to repair it"
due to misuse of the key deletion function.
Fix: always use R-tree key functions for R-tree based indexes
and B-tree key functions for B-tree based indexes.
@ mysql-test/r/gis.result
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- test result.
@ mysql-test/t/gis.test
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- test case.
@ storage/myisam/mi_update.c
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- handling update errors check for HA_ERR_NULL_IN_SPATIAL as well to be
consistent with mi_write();
- always use keyinfo->ck_delete()/ck_insert() instead of _mi_ck_delete()/_mi_ck_write()
to handle index properly, as it may be of B-tree or R-tree type.
@ storage/myisam/mi_write.c
Bug#11764487: myisam corruption with insert ignore and invalid spatial data
- always use keyinfo->ck_delete() instead of _mi_ck_delete() to handle
index properly, as it may be of B-tree or R-tree type.
modified:
mysql-test/r/gis.result
mysql-test/t/gis.test
storage/myisam/mi_update.c
storage/myisam/mi_write.c
=== modified file 'mysql-test/r/gis.result'
--- a/mysql-test/r/gis.result 2011-03-21 14:01:40 +0000
+++ b/mysql-test/r/gis.result 2011-05-16 18:55:42 +0000
@@ -1075,4 +1075,15 @@ SPATIAL INDEX i1 (col1, col2)
);
ERROR HY000: Incorrect arguments to SPATIAL INDEX
DROP TABLE t0, t1, t2;
+#
+# Bug #57323/11764487: myisam corruption with insert ignore
+# and invalid spatial data
+#
+CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=NULL;
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+DROP TABLE t1;
End of 5.1 tests
=== modified file 'mysql-test/t/gis.test'
--- a/mysql-test/t/gis.test 2011-03-21 14:01:40 +0000
+++ b/mysql-test/t/gis.test 2011-05-16 18:55:42 +0000
@@ -812,4 +812,21 @@ CREATE TABLE t3 (
# cleanup
DROP TABLE t0, t1, t2;
+
+--echo #
+--echo # Bug #57323/11764487: myisam corruption with insert ignore
+--echo # and invalid spatial data
+--echo #
+
+CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+ SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
+
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
+
+--error ER_CANT_CREATE_GEOMETRY_OBJECT
+INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=NULL;
+
+DROP TABLE t1;
+
--echo End of 5.1 tests
=== modified file 'storage/myisam/mi_update.c'
--- a/storage/myisam/mi_update.c 2009-08-28 16:21:54 +0000
+++ b/storage/myisam/mi_update.c 2011-05-16 18:55:42 +0000
@@ -193,8 +193,8 @@ err:
save_errno=my_errno;
if (changed)
key_changed|= HA_STATE_CHANGED;
- if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_OUT_OF_MEM ||
- my_errno == HA_ERR_RECORD_FILE_FULL)
+ if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
+ my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
{
info->errkey= (int) i;
flag=0;
@@ -212,8 +212,9 @@ err:
{
uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
uint old_length= _mi_make_key(info,i,old_key,oldrec,pos);
- if ((flag++ && _mi_ck_delete(info,i,new_key,new_length)) ||
- _mi_ck_write(info,i,old_key,old_length))
+ if ((flag++ &&
+ share->keyinfo[i].ck_delete(info, i, new_key, new_length)) ||
+ share->keyinfo[i].ck_insert(info, i, old_key, old_length))
break;
}
}
=== modified file 'storage/myisam/mi_write.c'
--- a/storage/myisam/mi_write.c 2011-03-28 08:47:30 +0000
+++ b/storage/myisam/mi_write.c 2011-05-16 18:55:42 +0000
@@ -211,7 +211,7 @@ err:
else
{
uint key_length=_mi_make_key(info,i,buff,record,filepos);
- if (_mi_ck_delete(info,i,buff,key_length))
+ if (share->keyinfo[i].ck_delete(info, i, buff, key_length))
{
if (local_lock_tree)
rw_unlock(&share->key_root_lock[i]);
Attachment: [text/bzr-bundle] bzr/ramil@mysql.com-20110516185542-ss1aia11a165qwco.bundle