summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2020-04-18 00:22:52 +0300
committerMonty <monty@mariadb.org>2020-04-18 11:51:42 +0300
commit48eda61cd41725498908308e0004897f10dd7307 (patch)
tree4e3bacc7c06af093b67f502077b60b052c27cc64
parenta6d32976aee8e77caae66e1592011df248c7ffbb (diff)
downloadmariadb-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.result7
-rw-r--r--mysql-test/t/gis.test8
-rw-r--r--sql/field.cc2
-rw-r--r--sql/item.cc8
-rw-r--r--sql/item.h8
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();