summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2021-10-09 22:27:31 +0400
committerAlexander Barkov <bar@mariadb.com>2021-10-11 18:03:42 +0400
commit8f04ec288528fd53efd98e2139e5d22ba229d20b (patch)
tree9ea889eb32052021c167e6f574c6a1b835089f0f
parenteadd87880887e6ca73e6f292c9d856df7e56c3c0 (diff)
downloadmariadb-git-8f04ec288528fd53efd98e2139e5d22ba229d20b.tar.gz
MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYEDbb-10.2-bar-MDEV-25925
Also fixes MDEV-24467 Memory not freed after failed INSERT DELAYED Description: In case of an error (e.g. data truncation) during mysql_insert() handling an INSERT DELAYED, the data type specific data in fields (e.g. Field_blob::value) is not taken over by the delayed writer thread. All fields in table_list->table are freed by free_root() immediately after mysql_insert(). To avoid a memory leak, we need to free the specific data before exiting mysql_insert() on error.
-rw-r--r--mysql-test/r/delayed_blob.result17
-rw-r--r--mysql-test/t/delayed_blob-master.opt1
-rw-r--r--mysql-test/t/delayed_blob.test21
-rw-r--r--sql/sql_insert.cc11
4 files changed, 50 insertions, 0 deletions
diff --git a/mysql-test/r/delayed_blob.result b/mysql-test/r/delayed_blob.result
new file mode 100644
index 00000000000..caa2e3ae5fe
--- /dev/null
+++ b/mysql-test/r/delayed_blob.result
@@ -0,0 +1,17 @@
+#
+# MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED
+#
+SET sql_mode='TRADITIONAL';
+CREATE TABLE t1 (c BLOB) ENGINE=MyISAM;
+INSERT DELAYED INTO t1 VALUES (''||'');
+ERROR 22007: Truncated incorrect DOUBLE value: ''
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-24467 Memory not freed after failed INSERT DELAYED
+#
+CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
+ALTER TABLE t1 ADD b BLOB DEFAULT 'x';
+INSERT DELAYED INTO t1 (a) VALUES ('foo');
+ERROR 22001: Data too long for column 'a' at row 1
+DROP TABLE t1;
diff --git a/mysql-test/t/delayed_blob-master.opt b/mysql-test/t/delayed_blob-master.opt
new file mode 100644
index 00000000000..e442a822046
--- /dev/null
+++ b/mysql-test/t/delayed_blob-master.opt
@@ -0,0 +1 @@
+--init_connect="set @a='something unique to have MTR start a dedicated mariadbd for this test and shutdown it after the test'"
diff --git a/mysql-test/t/delayed_blob.test b/mysql-test/t/delayed_blob.test
new file mode 100644
index 00000000000..bf3e01a8825
--- /dev/null
+++ b/mysql-test/t/delayed_blob.test
@@ -0,0 +1,21 @@
+--echo #
+--echo # MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED
+--echo #
+
+SET sql_mode='TRADITIONAL';
+CREATE TABLE t1 (c BLOB) ENGINE=MyISAM;
+--error ER_TRUNCATED_WRONG_VALUE
+INSERT DELAYED INTO t1 VALUES (''||'');
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-24467 Memory not freed after failed INSERT DELAYED
+--echo #
+
+CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
+ALTER TABLE t1 ADD b BLOB DEFAULT 'x';
+--error ER_DATA_TOO_LONG
+INSERT DELAYED INTO t1 (a) VALUES ('foo');
+DROP TABLE t1;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 51b2c84cfea..718682f767e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1257,7 +1257,18 @@ values_loop_end:
abort:
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
+ {
end_delayed_insert(thd);
+ /*
+ In case of an error (e.g. data truncation), the data type specific data
+ in fields (e.g. Field_blob::value) was not taken over
+ by the delayed writer thread. All fields in table_list->table
+ will be freed by free_root() soon. We need to free the specific
+ data before free_root() to avoid a memory leak.
+ */
+ for (Field **ptr= table_list->table->field ; *ptr ; ptr++)
+ (*ptr)->free();
+ }
#endif
if (table != NULL)
table->file->ha_release_auto_increment();