[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