summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-02-14 14:20:48 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2023-02-14 14:28:27 +0530
commit81faf41786cfcded18d5b20d341175367ef1453f (patch)
treee3debb7c405bb13467a42b734be5a11bdaae6954
parent7170db3c3a1a1c59cd7beb591dcab25c69e02847 (diff)
downloadmariadb-git-81faf41786cfcded18d5b20d341175367ef1453f.tar.gz
MDEV-30597 Assertion `flag == 1' failed in row_build_index_entry_low
- InnoDB tries to build the previous version of the record for the virtual index, but the undo log record doesn't contain virtual column information. This leads to assert failure while building the tuple.
-rw-r--r--mysql-test/suite/gcol/r/gcol_rollback.result21
-rw-r--r--mysql-test/suite/gcol/t/gcol_rollback.test23
-rw-r--r--storage/innobase/row/row0vers.cc18
3 files changed, 60 insertions, 2 deletions
diff --git a/mysql-test/suite/gcol/r/gcol_rollback.result b/mysql-test/suite/gcol/r/gcol_rollback.result
index 5ee94d3ef44..0bbf034122b 100644
--- a/mysql-test/suite/gcol/r/gcol_rollback.result
+++ b/mysql-test/suite/gcol/r/gcol_rollback.result
@@ -79,10 +79,29 @@ a b c d
ROLLBACK;
SET DEBUG_SYNC = 'now SIGNAL dml_done';
connection con1;
-disconnect con1;
connection default;
SELECT * FROM t;
a b d
9 10 29
DROP TABLE t;
SET DEBUG_SYNC = 'RESET';
+#
+# MDEV-30597 Assertion `flag == 1' failed in
+# row_build_index_entry_low
+#
+CREATE TABLE t1 (
+col1 INT PRIMARY KEY, col_text TEXT,
+col_text_g TEXT GENERATED ALWAYS AS (SUBSTR(col_text,1,499))
+) ENGINE = InnoDB ROW_FORMAT = Compact;
+connection con1;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+INSERT INTO t1 (col1) VALUES (1) ;
+DELETE FROM t1 WHERE col1 = 1;
+ALTER TABLE t1 ADD UNIQUE INDEX (col_text_g(9));
+BEGIN;
+INSERT INTO t1 (col1) VALUES (1);
+ROLLBACK;
+disconnect con1;
+DROP TABLE t1;
+# End of 10.4 tests
diff --git a/mysql-test/suite/gcol/t/gcol_rollback.test b/mysql-test/suite/gcol/t/gcol_rollback.test
index ba88dda45d7..888e6be861e 100644
--- a/mysql-test/suite/gcol/t/gcol_rollback.test
+++ b/mysql-test/suite/gcol/t/gcol_rollback.test
@@ -103,7 +103,6 @@ SET DEBUG_SYNC = 'now SIGNAL dml_done';
connection con1;
reap;
-disconnect con1;
connection default;
SELECT * FROM t;
@@ -111,5 +110,27 @@ SELECT * FROM t;
DROP TABLE t;
SET DEBUG_SYNC = 'RESET';
+--echo #
+--echo # MDEV-30597 Assertion `flag == 1' failed in
+--echo # row_build_index_entry_low
+--echo #
+CREATE TABLE t1 (
+col1 INT PRIMARY KEY, col_text TEXT,
+col_text_g TEXT GENERATED ALWAYS AS (SUBSTR(col_text,1,499))
+) ENGINE = InnoDB ROW_FORMAT = Compact;
+connection con1;
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection default;
+INSERT INTO t1 (col1) VALUES (1) ;
+DELETE FROM t1 WHERE col1 = 1;
+ALTER TABLE t1 ADD UNIQUE INDEX (col_text_g(9));
+BEGIN;
+INSERT INTO t1 (col1) VALUES (1);
+ROLLBACK;
+disconnect con1;
+DROP TABLE t1;
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+
+--echo # End of 10.4 tests
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index d1ff7bc540e..0679f883897 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -860,6 +860,20 @@ row_vers_build_cur_vrow(
return(cur_vrow);
}
+/** Find out whether data tuple has missing data type
+for virtualcolumn.
+@param tuple data tuple
+@return true if tuple has missing column type */
+static bool dtuple_vcol_data_missing(const dtuple_t &tuple)
+{
+ for (ulint i= 0; i < tuple.n_v_fields; i++)
+ {
+ if (tuple.v_fields[i].type.mtype == DATA_MISSING)
+ return true;
+ }
+ return false;
+}
+
/** Finds out if a version of the record, where the version >= the current
purge view, should have ientry as its secondary index entry. We check
if there is any not delete marked version of the record where the trx
@@ -1088,6 +1102,9 @@ unsafe_to_purge:
if (dict_index_has_virtual(index)) {
if (vrow) {
+ if (dtuple_vcol_data_missing(*vrow)) {
+ goto nochange_index;
+ }
/* Keep the virtual row info for the next
version, unless it is changed */
mem_heap_empty(v_heap);
@@ -1098,6 +1115,7 @@ unsafe_to_purge:
if (!cur_vrow) {
/* Nothing for this index has changed,
continue */
+nochange_index:
version = prev_version;
continue;
}