[server 1/4] space: introduce space_execute_dml helper
Vladimir Davydov
vdavydov.dev at gmail.com
Tue Jan 23 19:28:55 MSK 2018
I'm planning to call BEFORE triggers in space.c. Since a BEFORE trigger
can change the request type, we can't call it from functions handling
particular kinds of requests (space_execute_replace() and others).
So let's move the switch-case statement that executes different space
callbacks depending on the request type from process_rw() to a new
function, space_execute_dml(), defined in space.c. We will execute
BEFORE triggers from this new function, right before dispatching the
request by its type.
Needed for #2993
---
src/box/box.cc | 22 +-------------
src/box/memtx_space.c | 20 +++++++++----
src/box/space.c | 83 ++++++++++++++++++++++++---------------------------
src/box/space.h | 57 ++++-------------------------------
4 files changed, 59 insertions(+), 123 deletions(-)
diff --git a/src/box/box.cc b/src/box/box.cc
index 0d4a35a7..98790dc5 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -168,28 +168,8 @@ process_rw(struct request *request, struct space *space, struct tuple **result)
struct txn *txn = txn_begin_stmt(space);
if (txn == NULL)
return -1;
- int rc;
struct tuple *tuple;
- switch (request->type) {
- case IPROTO_INSERT:
- case IPROTO_REPLACE:
- rc = space_execute_replace(space, txn, request, &tuple);
- break;
- case IPROTO_UPDATE:
- rc = space_execute_update(space, txn, request, &tuple);
- break;
- case IPROTO_DELETE:
- rc = space_execute_delete(space, txn, request, &tuple);
- break;
- case IPROTO_UPSERT:
- rc = space_execute_upsert(space, txn, request);
- tuple = NULL;
- break;
- default:
- rc = 0;
- tuple = NULL;
- }
- if (rc != 0) {
+ if (space_execute_dml(space, txn, request, &tuple) != 0) {
txn_rollback_stmt();
return -1;
}
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index 599a68e1..c78651a8 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -293,6 +293,7 @@ dup_replace_mode(uint32_t op)
static int
memtx_space_apply_initial_join_row(struct space *space, struct request *request)
{
+ struct memtx_space *memtx_space = (struct memtx_space *)space;
if (request->type != IPROTO_INSERT) {
diag_set(ClientError, ER_UNKNOWN_REQUEST_TYPE, request->type);
return -1;
@@ -301,13 +302,20 @@ memtx_space_apply_initial_join_row(struct space *space, struct request *request)
struct txn *txn = txn_begin_stmt(space);
if (txn == NULL)
return -1;
- struct tuple *unused;
- if (space_execute_replace(space, txn, request, &unused) != 0) {
- say_error("rollback: %s", diag_last_error(diag_get())->errmsg);
- txn_rollback_stmt();
- return -1;
- }
+ struct txn_stmt *stmt = txn_current_stmt(txn);
+ stmt->new_tuple = memtx_tuple_new(space->format, request->tuple,
+ request->tuple_end);
+ if (stmt->new_tuple == NULL)
+ goto rollback;
+ tuple_ref(stmt->new_tuple);
+ if (memtx_space->replace(space, stmt, DUP_INSERT) != 0)
+ goto rollback;
return txn_commit_stmt(txn, request);
+
+rollback:
+ say_error("rollback: %s", diag_last_error(diag_get())->errmsg);
+ txn_rollback_stmt();
+ return -1;
}
static int
diff --git a/src/box/space.c b/src/box/space.c
index c02eb886..aeebf10a 100644
--- a/src/box/space.c
+++ b/src/box/space.c
@@ -429,51 +429,46 @@ request_handle_sequence(struct request *request, struct space *space)
}
int
-space_execute_replace(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result)
+space_execute_dml(struct space *space, struct txn *txn,
+ struct request *request, struct tuple **result)
{
- assert(request->type == IPROTO_INSERT ||
- request->type == IPROTO_REPLACE);
- if (space->sequence != NULL &&
- request_handle_sequence(request, space) != 0)
- return -1;
- return space->vtab->execute_replace(space, txn, request, result);
-}
-
-int
-space_execute_delete(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result)
-{
- assert(request->type == IPROTO_DELETE);
- if (space->vtab->execute_delete(space, txn, request, result) != 0)
- return -1;
- if (*result != NULL && request->index_id != 0)
- request_rebind_to_primary_key(request, space, *result);
- return 0;
-}
-
-int
-space_execute_update(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result)
-{
- assert(request->type == IPROTO_UPDATE);
- if (space->vtab->execute_update(space, txn, request, result) != 0)
- return -1;
- if (*result != NULL && request->index_id != 0) {
- /*
- * XXX: this is going to break with sync replication
- * for cases when tuple is NULL, since the leader
- * will be unable to certify such updates correctly.
- */
- request_rebind_to_primary_key(request, space, *result);
+ switch (request->type) {
+ case IPROTO_INSERT:
+ case IPROTO_REPLACE:
+ if (space->sequence != NULL &&
+ request_handle_sequence(request, space) != 0)
+ return -1;
+ if (space->vtab->execute_replace(space, txn,
+ request, result) != 0)
+ return -1;
+ break;
+ case IPROTO_UPDATE:
+ if (space->vtab->execute_update(space, txn,
+ request, result) != 0)
+ return -1;
+ if (*result != NULL && request->index_id != 0) {
+ /*
+ * XXX: this is going to break with sync replication
+ * for cases when tuple is NULL, since the leader
+ * will be unable to certify such updates correctly.
+ */
+ request_rebind_to_primary_key(request, space, *result);
+ }
+ break;
+ case IPROTO_DELETE:
+ if (space->vtab->execute_delete(space, txn,
+ request, result) != 0)
+ return -1;
+ if (*result != NULL && request->index_id != 0)
+ request_rebind_to_primary_key(request, space, *result);
+ break;
+ case IPROTO_UPSERT:
+ *result = NULL;
+ if (space->vtab->execute_upsert(space, txn, request) != 0)
+ return -1;
+ break;
+ default:
+ *result = NULL;
}
return 0;
}
-
-int
-space_execute_upsert(struct space *space, struct txn *txn,
- struct request *request)
-{
- assert(request->type == IPROTO_UPSERT);
- return space->vtab->execute_upsert(space, txn, request);
-}
diff --git a/src/box/space.h b/src/box/space.h
index 678817a1..69dea2a2 100644
--- a/src/box/space.h
+++ b/src/box/space.h
@@ -313,21 +313,12 @@ space_apply_initial_join_row(struct space *space, struct request *request)
return space->vtab->apply_initial_join_row(space, request);
}
+/**
+ * Execute a DML request on the given space.
+ */
int
-space_execute_replace(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result);
-
-int
-space_execute_delete(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result);
-
-int
-space_execute_update(struct space *space, struct txn *txn,
- struct request *request, struct tuple **result);
-
-int
-space_execute_upsert(struct space *space, struct txn *txn,
- struct request *request);
+space_execute_dml(struct space *space, struct txn *txn,
+ struct request *request, struct tuple **result);
static inline void
init_system_space(struct space *space)
@@ -518,44 +509,6 @@ space_apply_initial_join_row_xc(struct space *space, struct request *request)
diag_raise();
}
-static inline struct tuple *
-space_execute_replace_xc(struct space *space, struct txn *txn,
- struct request *request)
-{
- struct tuple *result;
- if (space_execute_replace(space, txn, request, &result) != 0)
- diag_raise();
- return result;
-}
-
-static inline struct tuple *
-space_execute_delete_xc(struct space *space, struct txn *txn,
- struct request *request)
-{
- struct tuple *result;
- if (space_execute_delete(space, txn, request, &result) != 0)
- diag_raise();
- return result;
-}
-
-static inline struct tuple *
-space_execute_update_xc(struct space *space, struct txn *txn,
- struct request *request)
-{
- struct tuple *result;
- if (space_execute_update(space, txn, request, &result) != 0)
- diag_raise();
- return result;
-}
-
-static inline void
-space_execute_upsert_xc(struct space *space, struct txn *txn,
- struct request *request)
-{
- if (space_execute_upsert(space, txn, request) != 0)
- diag_raise();
-}
-
static inline void
space_check_index_def_xc(struct space *space, struct index_def *index_def)
{
--
2.11.0
More information about the Tarantool-patches
mailing list