diff options
-rw-r--r-- | mysql-test/include/gis_keys.inc | 46 | ||||
-rw-r--r-- | mysql-test/r/bdb_gis.result | 39 | ||||
-rw-r--r-- | mysql-test/r/gis-rtree.result | 4 | ||||
-rw-r--r-- | mysql-test/r/gis.result | 39 | ||||
-rw-r--r-- | mysql-test/r/innodb_gis.result | 39 | ||||
-rw-r--r-- | mysql-test/t/bdb_gis.test | 1 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 2 | ||||
-rw-r--r-- | mysql-test/t/innodb_gis.test | 1 | ||||
-rw-r--r-- | sql/field.cc | 30 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/sql_select.h | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | sql/table.cc | 6 |
14 files changed, 181 insertions, 39 deletions
diff --git a/mysql-test/include/gis_keys.inc b/mysql-test/include/gis_keys.inc new file mode 100644 index 00000000000..295e0c48234 --- /dev/null +++ b/mysql-test/include/gis_keys.inc @@ -0,0 +1,46 @@ +--source include/have_geometry.inc + +# +# Spatial objects with keys +# + +# +# Bug #30825: Problems when putting a non-spatial index on a GIS column +# + +CREATE TABLE t1 (p POINT); +CREATE TABLE t2 (p POINT, INDEX(p)); +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); + +-- no index, returns 1 as expected +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); + +-- with index, returns 1 as expected +-- EXPLAIN shows that the index is not used though +-- due to the "most rows covered anyway, so a scan is more effective" rule +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); + +-- adding another row to the table so that +-- the "most rows covered" rule doesn't kick in anymore +-- now EXPLAIN shows the index used on the table +-- and we're getting the wrong result again +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +EXPLAIN +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); + +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); + +EXPLAIN +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); + +DROP TABLE t1, t2; + +--echo End of 5.0 tests diff --git a/mysql-test/r/bdb_gis.result b/mysql-test/r/bdb_gis.result index d48b5a26e1d..6651421b51c 100644 --- a/mysql-test/r/bdb_gis.result +++ b/mysql-test/r/bdb_gis.result @@ -542,3 +542,42 @@ Overlaps(@horiz1, @point2) 0 DROP TABLE t1; End of 5.0 tests +CREATE TABLE t1 (p POINT); +CREATE TABLE t2 (p POINT, INDEX(p)); +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +EXPLAIN +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL p NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +DROP TABLE t1, t2; +End of 5.0 tests diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 621402e87a9..99bfede3ee0 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -167,7 +167,7 @@ count(*) 150 EXPLAIN SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range g g 32 NULL 8 Using where +1 SIMPLE t1 range g g 34 NULL 8 Using where SELECT fid, AsText(g) FROM t1 WHERE Within(g, GeomFromText('Polygon((140 140,160 140,160 160,140 160,140 140))')); fid AsText(g) 1 LINESTRING(150 150,150 150) @@ -301,7 +301,7 @@ count(*) EXPLAIN SELECT fid, AsText(g) FROM t2 WHERE Within(g, GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 range g g 32 NULL 4 Using where +1 SIMPLE t2 range g g 34 NULL 4 Using where SELECT fid, AsText(g) FROM t2 WHERE Within(g, GeomFromText('Polygon((40 40,60 40,60 60,40 60,40 40))')); fid AsText(g) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 55f42141adb..40c70721347 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -894,4 +894,43 @@ drop table t1, t2; SELECT 1; 1 1 +CREATE TABLE t1 (p POINT); +CREATE TABLE t2 (p POINT, INDEX(p)); +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system p NULL NULL NULL 1 +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +EXPLAIN +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +DROP TABLE t1, t2; +End of 5.0 tests End of 5.0 tests diff --git a/mysql-test/r/innodb_gis.result b/mysql-test/r/innodb_gis.result index 2c62537aa94..bfe8c984b7b 100644 --- a/mysql-test/r/innodb_gis.result +++ b/mysql-test/r/innodb_gis.result @@ -542,3 +542,42 @@ Overlaps(@horiz1, @point2) 0 DROP TABLE t1; End of 5.0 tests +CREATE TABLE t1 (p POINT); +CREATE TABLE t2 (p POINT, INDEX(p)); +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +1 +INSERT INTO t1 VALUES (POINTFROMTEXT('POINT(1 2)')); +INSERT INTO t2 VALUES (POINTFROMTEXT('POINT(1 2)')); +EXPLAIN +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref p p 28 const 1 Using where +SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +EXPLAIN +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +SELECT COUNT(*) FROM t2 IGNORE INDEX(p) WHERE p=POINTFROMTEXT('POINT(1 2)'); +COUNT(*) +2 +DROP TABLE t1, t2; +End of 5.0 tests diff --git a/mysql-test/t/bdb_gis.test b/mysql-test/t/bdb_gis.test index 88dcbb7cbe9..cb6d0683874 100644 --- a/mysql-test/t/bdb_gis.test +++ b/mysql-test/t/bdb_gis.test @@ -1,3 +1,4 @@ -- source include/have_bdb.inc SET storage_engine=bdb; --source include/gis_generic.inc +--source include/gis_keys.inc diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 730f046dd27..b7da7db1d76 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -598,4 +598,6 @@ SELECT AsText(GeometryFromText(CONCAT( --enable_query_log SELECT 1; +-- source include/gis_keys.inc + --echo End of 5.0 tests diff --git a/mysql-test/t/innodb_gis.test b/mysql-test/t/innodb_gis.test index 142b526af92..024d17c5363 100644 --- a/mysql-test/t/innodb_gis.test +++ b/mysql-test/t/innodb_gis.test @@ -1,3 +1,4 @@ --source include/have_innodb.inc SET storage_engine=innodb; --source include/gis_generic.inc +--source include/gis_keys.inc diff --git a/sql/field.cc b/sql/field.cc index e6e4195ba1e..ded31972a7f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7416,36 +7416,6 @@ uint Field_blob::max_packed_col_length(uint max_length) #ifdef HAVE_SPATIAL -uint Field_geom::get_key_image(char *buff, uint length, imagetype type) -{ - char *blob; - const char *dummy; - MBR mbr; - ulong blob_length= get_length(ptr); - Geometry_buffer buffer; - Geometry *gobj; - const uint image_length= SIZEOF_STORED_DOUBLE*4; - - if (blob_length < SRID_SIZE) - { - bzero(buff, image_length); - return image_length; - } - get_ptr(&blob); - gobj= Geometry::construct(&buffer, blob, blob_length); - if (!gobj || gobj->get_mbr(&mbr, &dummy)) - bzero(buff, image_length); - else - { - float8store(buff, mbr.xmin); - float8store(buff + 8, mbr.xmax); - float8store(buff + 16, mbr.ymin); - float8store(buff + 24, mbr.ymax); - } - return image_length; -} - - void Field_geom::sql_type(String &res) const { CHARSET_INFO *cs= &my_charset_latin1; diff --git a/sql/field.h b/sql/field.h index 4fcdb50f8c7..8c01931fa21 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1326,7 +1326,6 @@ public: int store(double nr); int store(longlong nr, bool unsigned_val); int store_decimal(const my_decimal *); - uint get_key_image(char *buff,uint length,imagetype type); uint size_of() const { return sizeof(*this); } int reset(void) { return !maybe_null() || Field_blob::reset(); } geometry_type get_geometry_type() { return geom_type; }; diff --git a/sql/sql_select.h b/sql/sql_select.h index d84fbcb8c2d..4fc32e7fdb3 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -521,9 +521,13 @@ public: store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length) :null_key(0), null_ptr(null), err(0) { - if (field_arg->type() == FIELD_TYPE_BLOB) + if (field_arg->type() == FIELD_TYPE_BLOB + || field_arg->type() == FIELD_TYPE_GEOMETRY) { - /* Key segments are always packed with a 2 byte length prefix */ + /* + Key segments are always packed with a 2 byte length prefix. + See mi_rkey for details. + */ to_field=new Field_varstring(ptr, length, 2, (uchar*) null, 1, Field::NONE, field_arg->field_name, field_arg->table, field_arg->charset()); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6cbe98fe862..20b8c7a4278 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1287,7 +1287,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == Field::GEOM_POINT) - column->length= 21; + column->length= 25; if (!column->length) { my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 553cc6d24d5..3b2709b15b1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3216,7 +3216,7 @@ type: spatial_type: GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } - | POINT_SYM { Lex->length= (char*)"21"; + | POINT_SYM { Lex->length= (char*)"25"; $$= Field::GEOM_POINT; } | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } diff --git a/sql/table.cc b/sql/table.cc index a393f1a676b..7fe9aa774f3 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -732,9 +732,11 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, keyinfo->key_length+= HA_KEY_NULL_LENGTH; } if (field->type() == FIELD_TYPE_BLOB || - field->real_type() == MYSQL_TYPE_VARCHAR) + field->real_type() == MYSQL_TYPE_VARCHAR || + field->type() == FIELD_TYPE_GEOMETRY) { - if (field->type() == FIELD_TYPE_BLOB) + if (field->type() == FIELD_TYPE_BLOB || + field->type() == FIELD_TYPE_GEOMETRY) key_part->key_part_flag|= HA_BLOB_PART; else key_part->key_part_flag|= HA_VAR_LENGTH_PART; |