diff --git a/src/box/memtx_tx.c b/src/box/memtx_tx.c index aa16ea7ac1b3..96b42775820a 100644 --- a/src/box/memtx_tx.c +++ b/src/box/memtx_tx.c @@ -1980,6 +1980,7 @@ memtx_tx_history_add_insert_stmt(struct txn_stmt *stmt, &old_tuple, mode, &is_own_change); if (rc != 0) goto fail; + stmt->is_own_change = is_own_change; /* Create add_story and replaced_story if necessary. */ add_story = memtx_tx_story_new(space, new_tuple); @@ -2022,8 +2023,7 @@ memtx_tx_history_add_insert_stmt(struct txn_stmt *stmt, else del_story = memtx_tx_story_get(old_tuple); memtx_tx_story_link_deleted_by(del_story, stmt); - } else if (is_own_change) - stmt->is_pure_insert = true; + } /* * In case of DUP_INSERT there must be no visible replaced tuple. It is @@ -2090,6 +2090,9 @@ memtx_tx_history_add_delete_stmt(struct txn_stmt *stmt, if (tuple_has_flag(old_tuple, TUPLE_IS_DIRTY)) { del_story = memtx_tx_story_get(old_tuple); + if (del_story->add_stmt != NULL) + stmt->is_own_change = + del_story->add_stmt->txn == stmt->txn; } else { assert(stmt->txn != NULL); del_story = memtx_tx_story_new(space, old_tuple); @@ -2313,7 +2316,8 @@ memtx_tx_history_prepare_insert_stmt(struct txn_stmt *stmt) struct txn_stmt *test_stmt = test->add_stmt; if (test_stmt->txn == stmt->txn) continue; - if (test_stmt->is_pure_insert) + if (test_stmt->is_own_change && + test_stmt->del_story == NULL) continue; if (test_stmt->del_story != NULL) { assert(test_stmt->del_story->add_stmt->txn @@ -2388,7 +2392,8 @@ memtx_tx_history_prepare_insert_stmt(struct txn_stmt *stmt) struct txn_stmt *test_stmt = test->add_stmt; if (test_stmt->txn == stmt->txn) continue; - if (test_stmt->is_pure_insert) + if (test_stmt->is_own_change && + test_stmt->del_story == NULL) continue; if (test_stmt->del_story == story) continue; diff --git a/src/box/txn.c b/src/box/txn.c index cf8b1b00d3b4..16f44c730ee6 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -306,7 +306,7 @@ txn_stmt_new(struct txn *txn) stmt->engine_savepoint = NULL; stmt->row = NULL; stmt->has_triggers = false; - stmt->is_pure_insert = false; + stmt->is_own_change = false; return stmt; } diff --git a/src/box/txn.h b/src/box/txn.h index 610df490b1a9..03ef60a25360 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -302,13 +302,13 @@ struct txn_stmt { /** on_commit and/or on_rollback list is not empty. */ bool has_triggers; /* - * `insert` statement is guaranteed not to delete anything - * from the transaction's point of view (i.e., there was a preceding - * `delete` in the scope of the same transaction): no linking to the - * list of `delete` statements is required during preparation of insert - * statements that add preceding stories. + * Flag that shows whether this statement overwrites own transaction + * statement. For example if a transaction makes two replaces of the + * same key, the second statement will be with is_own_change = true. + * Or if a transaction deletes some key and then inserts that key, + * the insertion statement will be with is_own_change = true. */ - bool is_pure_insert; + bool is_own_change; /** * Request type - IPROTO type code */