diff options
author | Monty <monty@mariadb.org> | 2020-04-18 00:22:52 +0300 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2020-04-18 11:51:42 +0300 |
commit | 48eda61cd41725498908308e0004897f10dd7307 (patch) | |
tree | 4e3bacc7c06af093b67f502077b60b052c27cc64 | |
parent | a6d32976aee8e77caae66e1592011df248c7ffbb (diff) | |
download | mariadb-git-48eda61cd41725498908308e0004897f10dd7307.tar.gz |
Fixed memory leak with DEFAULT(f) on Geometry field
MDEV-21056 Assertion `global_status_var.global_memory_used == 0'
failed upon shutdown after query with DEFAULT on a geometry
field
-rw-r--r-- | mysql-test/r/gis.result | 7 | ||||
-rw-r--r-- | mysql-test/t/gis.test | 8 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 8 | ||||
-rw-r--r-- | sql/item.h | 8 |
5 files changed, 29 insertions, 4 deletions
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index ecbdd5b586c..48618a7c2d8 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -2283,5 +2283,12 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1; SET timestamp=default; # +# MDEV-21056 Memory leak after query with DEFAULT on a geometry field +# +CREATE TABLE t1 (f POINT DEFAULT ST_GEOMFROMTEXT('Point(0 0)')); +SELECT ST_GEOMFROMTEXT('Point(1 1)') IN ( DEFAULT( `f` ), ST_GEOMFROMTEXT('Point(2 2)') ) AS x FROM t1; +x +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index f630a6dc8bf..d1dff584c8f 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -1806,5 +1806,13 @@ drop table t1; SET timestamp=default; --echo # +--echo # MDEV-21056 Memory leak after query with DEFAULT on a geometry field +--echo # + +CREATE TABLE t1 (f POINT DEFAULT ST_GEOMFROMTEXT('Point(0 0)')); +SELECT ST_GEOMFROMTEXT('Point(1 1)') IN ( DEFAULT( `f` ), ST_GEOMFROMTEXT('Point(2 2)') ) AS x FROM t1; +DROP TABLE t1; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/sql/field.cc b/sql/field.cc index 857ba8d0e0c..f96755f5f51 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8857,7 +8857,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) my_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, MYF(0), Geometry::ci_collection[geom_type]->m_name.str, - wkt.c_ptr(), db, tab_name, field_name, + wkt.c_ptr_safe(), db, tab_name, field_name, (ulong) table->in_use->get_stmt_da()-> current_row_for_warning()); diff --git a/sql/item.cc b/sql/item.cc index ab7340a4689..141263f7bba 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8968,8 +8968,10 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } if (!(def_field= (Field*) thd->alloc(field_arg->field->size_of()))) goto error; + cached_field= def_field; memcpy((void *)def_field, (void *)field_arg->field, field_arg->field->size_of()); + def_field->reset_fields(); // If non-constant default value expression if (def_field->default_value && def_field->default_value->flags) { @@ -8997,6 +8999,12 @@ error: return TRUE; } +void Item_default_value::cleanup() +{ + delete cached_field; // Free cached blob data + cached_field= 0; + Item_field::cleanup(); +} void Item_default_value::print(String *str, enum_query_type query_type) { diff --git a/sql/item.h b/sql/item.h index 4f02b2085f4..1742ff9e23f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5358,21 +5358,23 @@ class Item_default_value : public Item_field void calculate(); public: Item *arg; + Field *cached_field; Item_default_value(THD *thd, Name_resolution_context *context_arg) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL) {} + arg(NULL), cached_field(NULL) {} Item_default_value(THD *thd, Name_resolution_context *context_arg, Item *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(a) {} + arg(a), cached_field(NULL) {} Item_default_value(THD *thd, Name_resolution_context *context_arg, Field *a) :Item_field(thd, context_arg, (const char *)NULL, (const char *)NULL, (const char *)NULL), - arg(NULL) {} + arg(NULL),cached_field(NULL) {} enum Type type() const { return DEFAULT_VALUE_ITEM; } bool eq(const Item *item, bool binary_cmp) const; bool fix_fields(THD *, Item **); + void cleanup(); void print(String *str, enum_query_type query_type); String *val_str(String *str); double val_real(); |