mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -864,4 +864,25 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL;
|
|||||||
Overlaps(@horiz1, @point2)
|
Overlaps(@horiz1, @point2)
|
||||||
0
|
0
|
||||||
DROP TABLE t1;
|
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
|
End of 5.0 tests
|
||||||
|
@ -557,4 +557,17 @@ SELECT Overlaps(@horiz1, @point2) FROM DUAL;
|
|||||||
|
|
||||||
DROP TABLE t1;
|
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
|
--echo End of 5.0 tests
|
||||||
|
@ -360,7 +360,11 @@ public:
|
|||||||
{
|
{
|
||||||
return field_length / charset()->mbmaxlen;
|
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 bool reopen_table(THD *,struct st_table *,bool);
|
||||||
friend int cre_myisam(my_string name, register TABLE *form, uint options,
|
friend int cre_myisam(my_string name, register TABLE *form, uint options,
|
||||||
ulonglong auto_increment_value);
|
ulonglong auto_increment_value);
|
||||||
@ -1325,6 +1329,7 @@ public:
|
|||||||
uint get_key_image(char *buff,uint length,imagetype type);
|
uint get_key_image(char *buff,uint length,imagetype type);
|
||||||
uint size_of() const { return sizeof(*this); }
|
uint size_of() const { return sizeof(*this); }
|
||||||
int reset(void) { return !maybe_null() || Field_blob::reset(); }
|
int reset(void) { return !maybe_null() || Field_blob::reset(); }
|
||||||
|
geometry_type get_geometry_type() { return geom_type; };
|
||||||
};
|
};
|
||||||
#endif /*HAVE_SPATIAL*/
|
#endif /*HAVE_SPATIAL*/
|
||||||
|
|
||||||
|
@ -4317,7 +4317,9 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
|
|||||||
case MYSQL_TYPE_GEOMETRY:
|
case MYSQL_TYPE_GEOMETRY:
|
||||||
return new Field_geom(max_length, maybe_null, name, table,
|
return new Field_geom(max_length, maybe_null, name, table,
|
||||||
(Field::geometry_type)
|
(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)
|
if (Field::result_merge_type(fld_type) == INT_RESULT)
|
||||||
decimals= 0;
|
decimals= 0;
|
||||||
prev_decimal_int_part= item->decimal_int_part();
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1304,6 +1304,11 @@ public:
|
|||||||
int fix_outer_field(THD *thd, Field **field, Item **reference);
|
int fix_outer_field(THD *thd, Field **field, Item **reference);
|
||||||
virtual Item *update_value_transformer(byte *select_arg);
|
virtual Item *update_value_transformer(byte *select_arg);
|
||||||
void print(String *str);
|
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_default_value;
|
||||||
friend class Item_insert_value;
|
friend class Item_insert_value;
|
||||||
friend class st_select_lex_unit;
|
friend class st_select_lex_unit;
|
||||||
@ -2563,6 +2568,7 @@ class Item_type_holder: public Item
|
|||||||
protected:
|
protected:
|
||||||
TYPELIB *enum_set_typelib;
|
TYPELIB *enum_set_typelib;
|
||||||
enum_field_types fld_type;
|
enum_field_types fld_type;
|
||||||
|
Field::geometry_type geometry_type;
|
||||||
|
|
||||||
void get_full_info(Item *item);
|
void get_full_info(Item *item);
|
||||||
|
|
||||||
@ -2582,6 +2588,7 @@ public:
|
|||||||
Field *make_field_by_type(TABLE *table);
|
Field *make_field_by_type(TABLE *table);
|
||||||
static uint32 display_length(Item *item);
|
static uint32 display_length(Item *item);
|
||||||
static enum_field_types get_real_type(Item *);
|
static enum_field_types get_real_type(Item *);
|
||||||
|
Field::geometry_type get_geometry_type() { return geometry_type; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user