From eff16d7593c4ec7e6cdf1adc71561ddc3749f3ff Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 9 Feb 2024 23:50:26 +0100 Subject: [PATCH] Revert "MDEV-15458 Segfault in heap_scan() upon UPDATE after ADD SYSTEM VERSIONING" This partially reverts 43623f04a98 Engines have to set ::position() after ::write_row(), otherwise the server won't be able to refer to the row just inserted. This is important for high-level indexes. heap part isn't reverted, so heap doesn't support high-level indexes. to fix this, it'll need info->lastpos in addition to info->current_ptr --- sql/sql_delete.cc | 25 ++++++++++++++++--------- storage/maria/ma_write.c | 4 ++-- storage/myisam/mi_write.c | 1 + 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f6fee04e776..7120fa21189 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -296,15 +296,22 @@ int TABLE::delete_row() store_record(this, record[1]); vers_update_end(); - int err= file->ha_update_row(record[1], record[0]); - /* - MDEV-23644: we get HA_ERR_FOREIGN_DUPLICATE_KEY iff we already got history - row with same trx_id which is the result of foreign key action, so we - don't need one more history row. - */ - if (err == HA_ERR_FOREIGN_DUPLICATE_KEY) - return file->ha_delete_row(record[0]); - return err; + int err; + if ((err= file->extra(HA_EXTRA_REMEMBER_POS))) + return err; + if ((err= file->ha_update_row(record[1], record[0]))) + { + /* + MDEV-23644: we get HA_ERR_FOREIGN_DUPLICATE_KEY iff we already got + history row with same trx_id which is the result of foreign key action, + so we don't need one more history row. + */ + if (err == HA_ERR_FOREIGN_DUPLICATE_KEY) + file->ha_delete_row(record[0]); + else + return err; + } + return file->extra(HA_EXTRA_RESTORE_POS); } diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index ba8583cacc8..80cd0c416e3 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -89,7 +89,7 @@ int maria_write(MARIA_HA *info, const uchar *record) MARIA_SHARE *share= info->s; uint i; int save_errno; - MARIA_RECORD_POS filepos, oldpos= info->cur_row.lastpos; + MARIA_RECORD_POS filepos; uchar *buff; my_bool lock_tree= share->lock_key_trees; my_bool fatal_error; @@ -303,7 +303,7 @@ int maria_write(MARIA_HA *info, const uchar *record) share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED; info->state->changed= 1; - info->cur_row.lastpos= oldpos; + info->cur_row.lastpos= filepos; _ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE); if (info->invalidator != 0) { diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c index 71d4b62026b..57fa58cfb24 100644 --- a/storage/myisam/mi_write.c +++ b/storage/myisam/mi_write.c @@ -153,6 +153,7 @@ int mi_write(MI_INFO *info, const uchar *record) info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN | HA_STATE_ROW_CHANGED); info->state->records++; + info->lastpos=filepos; myisam_log_record(MI_LOG_WRITE,info,record,filepos,0); (void) _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE); if (info->invalidator != 0)