diff options
author | unknown <evgen@moonbone.local> | 2007-06-08 00:33:03 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2007-06-08 00:33:03 +0400 |
commit | 18310fabf48626767c9aeb632be1be69d3756ed0 (patch) | |
tree | a11429eec4336ad7b099061931d3686f45876dff | |
parent | 81d32d9a87e0769cce419379de40bd5a0770b7ee (diff) | |
download | mariadb-git-18310fabf48626767c9aeb632be1be69d3756ed0.tar.gz |
Bug#28763: Selecting geometry fields in UNION caused server crash.
This bug was introduced by the fix for the bug#27300. In this fix a section
of code was added to the Item::tmp_table_field_from_field_type method.
This section intended to create Field_geom fields for the Item_geometry_func
class and its descendants. In order to get the geometry type of the current
item it casted "this" to the Item_geometry_func* type. But the
Item::tmp_table_field_from_field_type method is also used for creation of
fields for UNION and in this case this method is called for an object of the
Item_type_holder class and the cast to the Item_geometry_func* type causes
a server crash.
Now the Item::tmp_table_field_from_field_type method correctly works when it's
called for both the Item_type_holder and the Item_geometry_func classes.
The new geometry_type variable is added to the Item_type_holder class.
The new method called get_geometry_type is added to the Item_field
and the Field classes. It returns geometry type from the field for the
Item_field and the Field_geom classes and fails an assert for other Field
descendants.
sql/field.h:
Bug#28763: Selecting geometry fields in UNION caused server crash.
The new method called get_geometry_type is added to the Field class.
It returns geometry type of the field for the Field_geom class
and fails an assert for other Field descendants.
sql/item.cc:
Bug#28763: Selecting geometry fields in UNION caused server crash.
Now the Item::tmp_table_field_from_field_type method correctly works when it's
called for both the Item_type_holder and the Item_geometry_func classes.
mysql-test/r/gis.result:
Added a test case for the bug#28763: Selecting geometry fields in UNION caused server crash.
mysql-test/t/gis.test:
Added a test case for the bug#28763: Selecting geometry fields in UNION caused server crash.
sql/item.h:
Bug#28763: Selecting geometry fields in UNION caused server crash.
The new method called get_geometry_type is added to the Item_field class.
It returns geometry type from the field.
The new geometry_type variable is added to the Item_type_holder class.
-rw-r--r-- | mysql-test/r/gis.result | 21 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 13 | ||||
-rw-r--r-- | sql/field.h | 7 | ||||
-rw-r--r-- | sql/item.cc | 8 | ||||
-rw-r--r-- | sql/item.h | 7 |
5 files changed, 54 insertions, 2 deletions
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 73e5b054f80..d1f292cda0c 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -864,4 +864,25 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL; Overlaps(@horiz1, @point2) 0 DROP TABLE t1; +create table t1(f1 geometry, f2 point, f3 linestring); +select f1 from t1 union select f1 from t1; +f1 +insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'), +GeomFromText('LINESTRING(0 0,1 1,2 2)')); +select AsText(f2),AsText(f3) from t1; +AsText(f2) AsText(f3) +POINT(1 1) LINESTRING(0 0,1 1,2 2) +select AsText(a) from (select f2 as a from t1 union select f3 from t1) t; +AsText(a) +POINT(1 1) +LINESTRING(0 0,1 1,2 2) +create table t2 as select f2 as a from t1 union select f3 from t1; +desc t2; +Field Type Null Key Default Extra +a point YES NULL +select AsText(a) from t2; +AsText(a) +POINT(1 1) +LINESTRING(0 0,1 1,2 2) +drop table t1, t2; End of 5.0 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index ccc38db8dea..95ccc6272e2 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -557,4 +557,17 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL; DROP TABLE t1; +# +# Bug#28763: Selecting geometry fields in UNION caused server crash. +# +create table t1(f1 geometry, f2 point, f3 linestring); +select f1 from t1 union select f1 from t1; +insert into t1 (f2,f3) values (GeomFromText('POINT(1 1)'), + GeomFromText('LINESTRING(0 0,1 1,2 2)')); +select AsText(f2),AsText(f3) from t1; +select AsText(a) from (select f2 as a from t1 union select f3 from t1) t; +create table t2 as select f2 as a from t1 union select f3 from t1; +desc t2; +select AsText(a) from t2; +drop table t1, t2; --echo End of 5.0 tests diff --git a/sql/field.h b/sql/field.h index 37ce6b88453..39378addd4c 100644 --- a/sql/field.h +++ b/sql/field.h @@ -360,7 +360,11 @@ public: { return field_length / charset()->mbmaxlen; } - + virtual geometry_type get_geometry_type() + { + /* shouldn't get here. */ + DBUG_ASSERT(0); + } friend bool reopen_table(THD *,struct st_table *,bool); friend int cre_myisam(my_string name, register TABLE *form, uint options, ulonglong auto_increment_value); @@ -1325,6 +1329,7 @@ public: 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; }; }; #endif /*HAVE_SPATIAL*/ diff --git a/sql/item.cc b/sql/item.cc index 92ea35072f9..59708afdd19 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4317,7 +4317,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) case MYSQL_TYPE_GEOMETRY: return new Field_geom(max_length, maybe_null, name, table, (Field::geometry_type) - ((Item_geometry_func *)this)->get_geometry_type()); + ((type() == Item::TYPE_HOLDER) ? + ((Item_type_holder *)this)->get_geometry_type() : + ((Item_geometry_func *)this)->get_geometry_type())); } } @@ -6422,6 +6424,10 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) if (Field::result_merge_type(fld_type) == INT_RESULT) decimals= 0; prev_decimal_int_part= item->decimal_int_part(); + if (item->field_type() == MYSQL_TYPE_GEOMETRY) + geometry_type= (item->type() == Item::FIELD_ITEM) ? + ((Item_field *)item)->get_geometry_type() : + (Field::geometry_type)((Item_geometry_func *)item)->get_geometry_type(); } diff --git a/sql/item.h b/sql/item.h index 11dce3a7758..96936f0ff88 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1304,6 +1304,11 @@ public: int fix_outer_field(THD *thd, Field **field, Item **reference); virtual Item *update_value_transformer(byte *select_arg); void print(String *str); + Field::geometry_type get_geometry_type() + { + DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY); + return field->get_geometry_type(); + } friend class Item_default_value; friend class Item_insert_value; friend class st_select_lex_unit; @@ -2563,6 +2568,7 @@ class Item_type_holder: public Item protected: TYPELIB *enum_set_typelib; enum_field_types fld_type; + Field::geometry_type geometry_type; void get_full_info(Item *item); @@ -2582,6 +2588,7 @@ public: Field *make_field_by_type(TABLE *table); static uint32 display_length(Item *item); static enum_field_types get_real_type(Item *); + Field::geometry_type get_geometry_type() { return geometry_type; }; }; |