From 453b14d5b894a9d5be4360e6c93e1e37a06215e7 Mon Sep 17 00:00:00 2001 From: Aleksandr Lyapunov <alyapunov@tarantool.org> Date: Wed, 7 Apr 2021 18:46:47 +0300 Subject: [PATCH] box: store request type implicitly instead of faking xrow Part of #5958 --- src/box/applier.cc | 4 ++-- src/box/box.cc | 2 +- src/box/lua/space.cc | 3 +-- src/box/memtx_engine.c | 2 +- src/box/space.c | 10 ---------- src/box/txn.c | 23 +++-------------------- src/box/txn.h | 8 ++++++-- src/box/vy_scheduler.c | 2 +- 8 files changed, 15 insertions(+), 39 deletions(-) diff --git a/src/box/applier.cc b/src/box/applier.cc index 4898f9f7bb..40fc5ce867 100644 --- a/src/box/applier.cc +++ b/src/box/applier.cc @@ -247,7 +247,7 @@ apply_snapshot_row(struct xrow_header *row) * Master only sends confirmed rows during join. */ txn_set_flags(txn, TXN_FORCE_ASYNC); - if (txn_begin_stmt(txn, space) != 0) + if (txn_begin_stmt(txn, space, request.type) != 0) goto rollback; /* no access checks here - applier always works with admin privs */ struct tuple *unused; @@ -277,7 +277,7 @@ process_nop(struct request *request) { assert(request->type == IPROTO_NOP); struct txn *txn = in_txn(); - if (txn_begin_stmt(txn, NULL) != 0) + if (txn_begin_stmt(txn, NULL, request->type) != 0) return -1; return txn_commit_stmt(txn, request); } diff --git a/src/box/box.cc b/src/box/box.cc index 70b3251809..2d2ae233c4 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -216,7 +216,7 @@ box_process_rw(struct request *request, struct space *space, rmean_collect(rmean_box, request->type, 1); if (access_check_space(space, PRIV_W) != 0) goto rollback; - if (txn_begin_stmt(txn, space) != 0) + if (txn_begin_stmt(txn, space, request->type) != 0) goto rollback; if (space_execute_dml(space, txn, request, &tuple) != 0) { txn_rollback_stmt(txn); diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 8d4d8cc23b..77a589ec44 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -75,9 +75,8 @@ lbox_push_txn_stmt(struct lua_State *L, void *event) } /* @todo: maybe the space object has to be here */ lua_pushstring(L, stmt->space->def->name); - assert(stmt->row != NULL); /* operation type: INSERT/UPDATE/UPSERT/REPLACE/DELETE */ - lua_pushstring(L, iproto_type_name(stmt->row->type)); + lua_pushstring(L, iproto_type_name(stmt->type)); return 4; } diff --git a/src/box/memtx_engine.c b/src/box/memtx_engine.c index 763e7d83e8..8e0622f122 100644 --- a/src/box/memtx_engine.c +++ b/src/box/memtx_engine.c @@ -253,7 +253,7 @@ memtx_engine_recover_snapshot_row(struct memtx_engine *memtx, struct txn *txn = txn_begin(); if (txn == NULL) return -1; - if (txn_begin_stmt(txn, space) != 0) + if (txn_begin_stmt(txn, space, request.type) != 0) goto rollback; /* no access checks here - applier always works with admin privs */ struct tuple *unused; diff --git a/src/box/space.c b/src/box/space.c index 6d1d771178..a3adf4bd32 100644 --- a/src/box/space.c +++ b/src/box/space.c @@ -481,15 +481,6 @@ after_old_tuple_lookup:; assert(stmt->old_tuple == NULL && stmt->new_tuple == NULL); stmt->old_tuple = old_tuple; stmt->new_tuple = new_tuple; - /* - * A fake row attached to txn_stmt during execution - * of before_replace triggers to store operation type. - * It is pushed to the before_replace trigger in lua. - */ - struct xrow_header temp_header; - temp_header.type = type; - assert(stmt->row == NULL); - stmt->row = &temp_header; int rc = trigger_run(&space->before_replace, txn); @@ -502,7 +493,6 @@ after_old_tuple_lookup:; assert(stmt->old_tuple == old_tuple); stmt->old_tuple = NULL; stmt->new_tuple = NULL; - stmt->row = NULL; if (rc != 0) goto out; diff --git a/src/box/txn.c b/src/box/txn.c index 40061ff096..959a3c3ee9 100644 --- a/src/box/txn.c +++ b/src/box/txn.c @@ -306,7 +306,7 @@ txn_begin_in_engine(struct engine *engine, struct txn *txn) } int -txn_begin_stmt(struct txn *txn, struct space *space) +txn_begin_stmt(struct txn *txn, struct space *space, uint16_t type) { assert(txn == in_txn()); assert(txn != NULL); @@ -340,6 +340,7 @@ txn_begin_stmt(struct txn *txn, struct space *space) goto fail; stmt->space = space; + stmt->type = type; if (engine_begin_statement(engine, txn) != 0) goto fail; @@ -418,25 +419,7 @@ txn_commit_stmt(struct txn *txn, struct request *request) */ stmt->does_require_old_tuple = true; - int rc = 0; - if(!space_is_temporary(stmt->space)) { - rc = trigger_run(&stmt->space->on_replace, txn); - } else { - /* - * There is no row attached to txn_stmt for - * temporary spaces, since DML operations on - * them are not written to WAL. - * Fake a row to pass operation type to lua - * on_replace triggers. - */ - assert(stmt->row == NULL); - struct xrow_header temp_header; - temp_header.type = request->type; - stmt->row = &temp_header; - rc = trigger_run(&stmt->space->on_replace, txn); - stmt->row = NULL; - } - if (rc != 0) + if(trigger_run(&stmt->space->on_replace, txn) != 0) goto fail; } } diff --git a/src/box/txn.h b/src/box/txn.h index a455180642..8794335cd6 100644 --- a/src/box/txn.h +++ b/src/box/txn.h @@ -212,6 +212,10 @@ struct txn_stmt { * old_tuple to be NULL. */ bool does_require_old_tuple; + /** + * Request type - IPROTO type code + */ + uint16_t type; /** Commit/rollback triggers associated with this statement. */ struct rlist on_commit; struct rlist on_rollback; @@ -557,10 +561,10 @@ txn_n_rows(struct txn *txn) } /** - * Start a new statement. + * Start a new statement in @a space with requst @a type (IPROTO_ constant). */ int -txn_begin_stmt(struct txn *txn, struct space *space); +txn_begin_stmt(struct txn *txn, struct space *space, uint16_t type); int txn_begin_in_engine(struct engine *engine, struct txn *txn); diff --git a/src/box/vy_scheduler.c b/src/box/vy_scheduler.c index b641dd9b8d..7d8324a52b 100644 --- a/src/box/vy_scheduler.c +++ b/src/box/vy_scheduler.c @@ -861,7 +861,7 @@ vy_deferred_delete_process_one(struct space *deferred_delete_space, tuple_unref(delete); struct txn *txn = in_txn(); - if (txn_begin_stmt(txn, deferred_delete_space) != 0) + if (txn_begin_stmt(txn, deferred_delete_space, request.type) != 0) return -1; struct tuple *unused; -- GitLab