From f7a520ef13db203f8460030118a0dee70a53b07e Mon Sep 17 00:00:00 2001
From: Vladimir Davydov <vdavydov@tarantool.org>
Date: Thu, 19 May 2022 11:16:30 +0300
Subject: [PATCH] box: don't apply space upgrade func to DML result except for
 DELETE

There's no need to apply a space upgrade function to the tuple returned
by INSERT, REPLACE, UPDATE, or UPSERT, because it must match the new
format anyway. We only need to process tuples returned by DELETE
requests. That being said, let's move the result processing from
box_process_rw() to memtx_space_execute_delete(). Note, we don't need to
patch vinyl_space_execute_delete(), because in Vinyl DELETE doesn't
return the deleted tuple.

Follow-up commit 21e2def9dec94 ("box: introduce result processor").

NO_DOC=refactoring
NO_TEST=refactoring
NO_CHANGELOG=refactoring
---
 src/box/box.cc        | 11 ++---------
 src/box/memtx_space.c |  5 +++--
 src/box/result.h      | 17 +++++++++++++++++
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/src/box/box.cc b/src/box/box.cc
index 08a19fc093..8819327274 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -307,8 +307,6 @@ box_process_rw(struct request *request, struct space *space,
 	bool return_tuple = false;
 	struct txn *txn = in_txn();
 	bool is_autocommit = txn == NULL;
-	struct result_processor res_proc;
-	int rc;
 	if (is_autocommit && (txn = txn_begin()) == NULL)
 		return -1;
 	assert(iproto_type_is_dml(request->type));
@@ -317,19 +315,14 @@ box_process_rw(struct request *request, struct space *space,
 		goto rollback;
 	if (txn_begin_stmt(txn, space, request->type) != 0)
 		goto rollback;
-	result_process_prepare(&res_proc, space);
-	rc = space_execute_dml(space, txn, request, &tuple);
-	if (result == NULL)
-		tuple = NULL;
-	result_process_perform(&res_proc, &rc, &tuple);
-	if (rc != 0) {
+	if (space_execute_dml(space, txn, request, &tuple) != 0) {
 		txn_rollback_stmt(txn);
 		goto rollback;
 	}
 	if (result != NULL)
 		*result = tuple;
 
-	return_tuple = tuple != NULL;
+	return_tuple = result != NULL && tuple != NULL;
 	if (return_tuple) {
 		/*
 		 * Pin the tuple locally before the commit,
diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c
index 17d61e2f98..1eac915fe2 100644
--- a/src/box/memtx_space.c
+++ b/src/box/memtx_space.c
@@ -45,6 +45,7 @@
 #include "sequence.h"
 #include "memtx_tuple_compression.h"
 #include "schema.h"
+#include "result.h"
 
 /*
  * Yield every 1K tuples while building a new index or checking
@@ -437,8 +438,8 @@ memtx_space_execute_delete(struct space *space, struct txn *txn,
 	if (memtx_space_replace_tuple(space, stmt, old_tuple, NULL,
 				      DUP_REPLACE_OR_INSERT) != 0)
 		return -1;
-	*result = stmt->old_tuple;
-	return 0;
+	*result = result_process(space, stmt->old_tuple);
+	return *result == NULL ? -1 : 0;
 }
 
 static int
diff --git a/src/box/result.h b/src/box/result.h
index a443b36b7e..9bb9cd9ae0 100644
--- a/src/box/result.h
+++ b/src/box/result.h
@@ -60,6 +60,23 @@ result_process_perform(struct result_processor *p, int *rc,
 	space_upgrade_unref(p->upgrade);
 }
 
+/**
+ * A shortcut for
+ *
+ *   int rc = 0;
+ *   struct result_processor res_proc;
+ *   result_process_prepare(&res_proc, space);
+ *   result_process_perform(&res_proc, &rc, &tuple);
+ */
+static inline struct tuple *
+result_process(struct space *space, struct tuple *tuple)
+{
+	if (unlikely(space->upgrade != NULL))
+		return space_upgrade_apply(space->upgrade, tuple);
+	else
+		return tuple;
+}
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
-- 
GitLab