From 813e6bcbbda3d7e4b6ad803e2993f9718ebe7daa Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Oct 2007 12:01:28 +0500 Subject: [PATCH] Bug #31155 gis types in union'd select cause crash. We use get_geometry_type() call to decide the exact type of a geometry field to be created (POINT, POLYGON etc) Though this function was only implemented for few items. In the bug's case we need to call this function for the Item_sum instance, where it was not implemented, what is the reason of the crash. Fixed by implementing virtual Item::get_geometry_type(), so it can be called for any Item. sql/item.h: Bug #31155 gis types in union'd select cause crash. virtual Item::geometry_type() added instead of various geometry_type() fucntions. sql/item.cc: Bug #31155 gis types in union'd select cause crash. Unified virtual ::get_geometry_type() function used sql/item_geofunc.cc: Bug #31155 gis types in union'd select cause crash. virtual Item::geometry_type() implemented for geo-Items. Mostly previous ::get_geometry_type() implementation changed sql/item_geofunc.h: Bug #31155 gis types in union'd select cause crash. get_geometry_type() declarations unified --- sql/item.cc | 11 +++-------- sql/item.h | 6 ++++-- sql/item_geofunc.cc | 18 +++++++----------- sql/item_geofunc.h | 7 +++---- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index e9b2904e3da..997ad0972db 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4364,11 +4364,8 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) collation.collation); break; // Blob handled outside of case case MYSQL_TYPE_GEOMETRY: - return new Field_geom(max_length, maybe_null, name, table, - (Field::geometry_type) - ((type() == Item::TYPE_HOLDER) ? - ((Item_type_holder *)this)->get_geometry_type() : - ((Item_geometry_func *)this)->get_geometry_type())); + return new Field_geom(max_length, maybe_null, + name, table, get_geometry_type()); } } @@ -6489,9 +6486,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) 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(); + geometry_type= item->get_geometry_type(); } diff --git a/sql/item.h b/sql/item.h index 3c699c0eda3..3b2df48801b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -870,6 +870,8 @@ public: */ virtual bool result_as_longlong() { return FALSE; } bool is_datetime(); + virtual Field::geometry_type get_geometry_type() const + { return Field::GEOM_GEOMETRY; }; }; @@ -1335,7 +1337,7 @@ 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() + Field::geometry_type get_geometry_type() const { DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY); return field->get_geometry_type(); @@ -2637,7 +2639,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; }; + Field::geometry_type get_geometry_type() const { return geometry_type; }; }; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 6c012277888..966cefea9fe 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -27,7 +27,7 @@ Field *Item_geometry_func::tmp_table_field(TABLE *t_arg) { return new Field_geom(max_length, maybe_null, name, t_arg, - (Field::geometry_type) get_geometry_type()); + get_geometry_type()); } void Item_geometry_func::fix_length_and_dec() @@ -38,10 +38,6 @@ void Item_geometry_func::fix_length_and_dec() maybe_null= 1; } -int Item_geometry_func::get_geometry_type() const -{ - return (int)Field::GEOM_GEOMETRY; -} String *Item_func_geometry_from_text::val_str(String *str) { @@ -160,9 +156,9 @@ String *Item_func_geometry_type::val_str(String *str) } -int Item_func_envelope::get_geometry_type() const +Field::geometry_type Item_func_envelope::get_geometry_type() const { - return (int) Field::GEOM_POLYGON; + return Field::GEOM_POLYGON; } @@ -190,9 +186,9 @@ String *Item_func_envelope::val_str(String *str) } -int Item_func_centroid::get_geometry_type() const +Field::geometry_type Item_func_centroid::get_geometry_type() const { - return (int) Field::GEOM_POINT; + return Field::GEOM_POINT; } @@ -330,9 +326,9 @@ err: */ -int Item_func_point::get_geometry_type() const +Field::geometry_type Item_func_point::get_geometry_type() const { - return (int) Field::GEOM_POINT; + return Field::GEOM_POINT; } diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 9c7970f9e53..e99510f762f 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -33,7 +33,6 @@ public: void fix_length_and_dec(); enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } Field *tmp_table_field(TABLE *t_arg); - virtual int get_geometry_type() const; bool is_null() { (void) val_int(); return null_value; } }; @@ -92,7 +91,7 @@ public: Item_func_centroid(Item *a): Item_geometry_func(a) {} const char *func_name() const { return "centroid"; } String *val_str(String *); - int get_geometry_type() const; + Field::geometry_type get_geometry_type() const; }; class Item_func_envelope: public Item_geometry_func @@ -101,7 +100,7 @@ public: Item_func_envelope(Item *a): Item_geometry_func(a) {} const char *func_name() const { return "envelope"; } String *val_str(String *); - int get_geometry_type() const; + Field::geometry_type get_geometry_type() const; }; class Item_func_point: public Item_geometry_func @@ -111,7 +110,7 @@ public: Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {} const char *func_name() const { return "point"; } String *val_str(String *); - int get_geometry_type() const; + Field::geometry_type get_geometry_type() const; }; class Item_func_spatial_decomp: public Item_geometry_func