diff options
author | Tor Didriksen <tor.didriksen@oracle.com> | 2011-12-05 15:42:45 +0100 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@oracle.com> | 2011-12-05 15:42:45 +0100 |
commit | f337ef3dcf0e84bd8cade16a58730b705af52b4b (patch) | |
tree | 411757003da4dbc4ebbd20eca60c3288a86d885a | |
parent | c188f9437311417099ff137fd4a3227cafe16f22 (diff) | |
download | mariadb-git-f337ef3dcf0e84bd8cade16a58730b705af52b4b.tar.gz |
Bug#13013970 MORE CRASHES IN FIELD_BLOB::GET_KEY_IMAGE
The predicate is re-written from
((`test`.`g1`.`a` = geometryfromtext('')) or ...
to
((`test`.`g1`.`a` = <cache>(geometryfromtext(''))) or ...
The range optimizer calls save_in_field_no_warnings, in order to fetch keys.
save_in_field_no_warnings returns 0 because of the cache wrapper,
and get_mm_leaf() proceeded to call Field_blob::get_key_image()
which accesses un-initialized data.
-rw-r--r-- | mysql-test/r/gis.result | 9 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 11 | ||||
-rw-r--r-- | sql/item.cc | 4 |
3 files changed, 22 insertions, 2 deletions
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 0dc10c56bd0..bcfc95bd905 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1091,4 +1091,13 @@ FORCE INDEX(i) WHERE a = date_sub(now(), interval 2808.4 year_month) Warnings: Warning 1441 Datetime function: datetime field overflow DROP TABLE g1; +# +# Bug#13013970 MORE CRASHES IN FIELD_BLOB::GET_KEY_IMAGE +# +CREATE TABLE g1(a TEXT NOT NULL, KEY(a(255))); +INSERT INTO g1 VALUES ('a'),('a'); +SELECT 1 FROM g1 WHERE a >= ANY +(SELECT 1 FROM g1 WHERE a = geomfromtext('') OR a) ; +1 +DROP TABLE g1; End of 5.5 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 104afddeee5..e75ae732979 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -838,5 +838,16 @@ FORCE INDEX(i) WHERE a = date_sub(now(), interval 2808.4 year_month) DROP TABLE g1; +--echo # +--echo # Bug#13013970 MORE CRASHES IN FIELD_BLOB::GET_KEY_IMAGE +--echo # + +CREATE TABLE g1(a TEXT NOT NULL, KEY(a(255))); + +INSERT INTO g1 VALUES ('a'),('a'); +SELECT 1 FROM g1 WHERE a >= ANY +(SELECT 1 FROM g1 WHERE a = geomfromtext('') OR a) ; + +DROP TABLE g1; --echo End of 5.5 tests diff --git a/sql/item.cc b/sql/item.cc index ca1ae1c4f71..c8c68a3924b 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7924,8 +7924,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val) int Item_cache_str::save_in_field(Field *field, bool no_conversions) { - if (!has_value()) - return 0; + if (!value_cached && !cache_value()) + return -1; // Fatal: couldn't cache the value int res= Item_cache::save_in_field(field, no_conversions); return (is_varbinary && field->type() == MYSQL_TYPE_STRING && value->length() < field->field_length) ? 1 : res; |