diff --git a/mysql-test/suite/tianmu/r/alter_delete.result b/mysql-test/suite/tianmu/r/alter_delete.result new file mode 100644 index 0000000000..5ee275f75e --- /dev/null +++ b/mysql-test/suite/tianmu/r/alter_delete.result @@ -0,0 +1,28 @@ +DROP DATABASE IF EXISTS alter_delete; +CREATE DATABASE alter_delete; +USE alter_delete; +CREATE TABLE ttt1(id INT,name VARCHAR(5)); +INSERT INTO ttt1 VALUES(0,"XXX"),(1,'AAA'),(2,'BBB'); +SELECT * FROM ttt1; +id name +0 XXX +1 AAA +2 BBB +DELETE FROM ttt1 WHERE id=1; +SELECT * FROM ttt1; +id name +0 XXX +2 BBB +ALTER TABLE ttt1 CONVERT TO CHARACTER SET utf8; +SELECT * FROM ttt1; +id name +0 XXX +2 BBB +SHOW CREATE TABLE ttt1; +Table Create Table +ttt1 CREATE TABLE `ttt1` ( + `id` int(11) DEFAULT NULL, + `name` varchar(5) DEFAULT NULL +) ENGINE=TIANMU DEFAULT CHARSET=utf8 +DROP TABLE ttt1; +DROP DATABASE alter_delete; diff --git a/mysql-test/suite/tianmu/t/alter_delete.test b/mysql-test/suite/tianmu/t/alter_delete.test new file mode 100644 index 0000000000..3c89f47471 --- /dev/null +++ b/mysql-test/suite/tianmu/t/alter_delete.test @@ -0,0 +1,29 @@ +--source include/have_tianmu.inc + +--disable_warnings +DROP DATABASE IF EXISTS alter_delete; +--enable_warnings + +CREATE DATABASE alter_delete; + +USE alter_delete; + +CREATE TABLE ttt1(id INT,name VARCHAR(5)); + +INSERT INTO ttt1 VALUES(0,"XXX"),(1,'AAA'),(2,'BBB'); + +SELECT * FROM ttt1; + +DELETE FROM ttt1 WHERE id=1; + +SELECT * FROM ttt1; + +ALTER TABLE ttt1 CONVERT TO CHARACTER SET utf8; + +SELECT * FROM ttt1; + +SHOW CREATE TABLE ttt1; + +DROP TABLE ttt1; + +DROP DATABASE alter_delete; diff --git a/storage/tianmu/core/tianmu_table.h b/storage/tianmu/core/tianmu_table.h index 52c15017ee..2cb564534c 100644 --- a/storage/tianmu/core/tianmu_table.h +++ b/storage/tianmu/core/tianmu_table.h @@ -179,6 +179,7 @@ class TianmuTable final : public JustATable { void MoveToRow(int64_t row_id); int64_t GetCurrentRowId() const { return position; } bool Inited() const { return table != nullptr; } + std::vector GetAttrs() { return attrs; } private: void FetchValues(); diff --git a/storage/tianmu/handler/ha_tianmu.cpp b/storage/tianmu/handler/ha_tianmu.cpp index d971792fd0..cbaa1f569f 100644 --- a/storage/tianmu/handler/ha_tianmu.cpp +++ b/storage/tianmu/handler/ha_tianmu.cpp @@ -1107,10 +1107,14 @@ int ha_tianmu::rnd_next(uchar *buf) { int ret = HA_ERR_END_OF_FILE; try { table->status = 0; - if (fill_row(buf) == HA_ERR_END_OF_FILE) { + ret = fill_row(buf); + if (ret == HA_ERR_END_OF_FILE) { table->status = STATUS_NOT_FOUND; DBUG_RETURN(ret); } + if (ret == HA_ERR_RECORD_DELETED) { + DBUG_RETURN(ret); + } ret = 0; } catch (std::exception &e) { my_message(static_cast(common::ErrorCode::UNKNOWN_ERROR), e.what(), MYF(0)); @@ -1369,8 +1373,19 @@ int ha_tianmu::fill_row(uchar *buf) { std::memcpy(buffer.get(), table->record[0], table->s->reclength); } - for (uint col_id = 0; col_id < table->s->fields; col_id++) - core::Engine::ConvertToField(table->field[col_id], *(table_new_iter_.GetData(col_id)), &blob_buffers_[col_id]); + for (uint col_id = 0; col_id < table->s->fields; col_id++) { + // when ConvertToField() return true, to judge whether this line has been deleted. + // if this line has been deleted, data will not be copied. + if (core::Engine::ConvertToField(table->field[col_id], *(table_new_iter_.GetData(col_id)), + &blob_buffers_[col_id]) && + (table_new_iter_.GetAttrs().size() > col_id) && + table_new_iter_.GetAttrs()[col_id]->IsDelete(table_new_iter_.GetCurrentRowId())) { + current_position_ = table_new_iter_.GetCurrentRowId(); + table_new_iter_++; + dbug_tmp_restore_column_map(table->write_set, org_bitmap); + return HA_ERR_RECORD_DELETED; + } + } if (buf != table->record[0]) { std::memcpy(buf, table->record[0], table->s->reclength);