summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-16 14:33:24 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-16 14:33:24 +0300
commit9aa80fcf466434d45374be789c68487bada49bc0 (patch)
tree5b186c41362e8359e675b22a7b83357da3118782
parentd448cfc92a47b9afbb2078ec6c94f24a6d83c7e8 (diff)
downloadmariadb-git-9aa80fcf466434d45374be789c68487bada49bc0.tar.gz
MDEV-19485: Crash on purge after ADD SPATIAL INDEX
row_build_spatial_index_key(): Return early if the column is missing in the table row tuple. This is a regression that was introduced by commit 0e5a4ac2532c64a545796c787354dc41d61d0e62.
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_add_index.result13
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_add_index.test20
-rw-r--r--storage/innobase/row/row0row.cc5
3 files changed, 38 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb_gis/r/rtree_add_index.result b/mysql-test/suite/innodb_gis/r/rtree_add_index.result
new file mode 100644
index 00000000000..dbd804b18bd
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/r/rtree_add_index.result
@@ -0,0 +1,13 @@
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+CREATE TABLE t1 (g MULTIPOINT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+connect purge_control,localhost,root;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+DELETE FROM t1;
+ALTER TABLE t1 ADD SPATIAL INDEX (g);
+disconnect purge_control;
+InnoDB 0 transactions not purged
+DROP TABLE t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_add_index.test b/mysql-test/suite/innodb_gis/t/rtree_add_index.test
new file mode 100644
index 00000000000..cbc82f62a70
--- /dev/null
+++ b/mysql-test/suite/innodb_gis/t/rtree_add_index.test
@@ -0,0 +1,20 @@
+--source include/have_innodb.inc
+
+SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+
+CREATE TABLE t1 (g MULTIPOINT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+
+connect purge_control,localhost,root;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+
+DELETE FROM t1;
+
+ALTER TABLE t1 ADD SPATIAL INDEX (g);
+
+disconnect purge_control;
+--source ../../innodb/include/wait_all_purged.inc
+DROP TABLE t1;
+SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc
index c200e6fb15c..d4b098d8954 100644
--- a/storage/innobase/row/row0row.cc
+++ b/storage/innobase/row/row0row.cc
@@ -62,6 +62,10 @@ static bool row_build_spatial_index_key(
ulint flag,
mem_heap_t* heap)
{
+ if (dfield2->type.mtype == DATA_MISSING) {
+ return false;
+ }
+
double* mbr;
dfield_copy(dfield, dfield2);
@@ -92,6 +96,7 @@ static bool row_build_spatial_index_key(
if (!dfield_is_ext(dfield2)) {
dptr = static_cast<const byte*>(dfield_get_data(dfield2));
dlen = dfield_get_len(dfield2);
+ ut_ad(dptr != &data_error);
goto write_mbr;
}