summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <evgen@moonbone.local>2007-06-08 00:33:03 +0400
committerunknown <evgen@moonbone.local>2007-06-08 00:33:03 +0400
commit18310fabf48626767c9aeb632be1be69d3756ed0 (patch)
treea11429eec4336ad7b099061931d3686f45876dff
parent81d32d9a87e0769cce419379de40bd5a0770b7ee (diff)
downloadmariadb-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.result21
-rw-r--r--mysql-test/t/gis.test13
-rw-r--r--sql/field.h7
-rw-r--r--sql/item.cc8
-rw-r--r--sql/item.h7
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; };
};