From 7a996f22ea7d96da63fa364c536ea8b60dc9aca2 Mon Sep 17 00:00:00 2001
From: Chris Sosnin <k.sosnin@tarantool.org>
Date: Mon, 13 Jan 2020 15:27:20 +0300
Subject: [PATCH] box: frommap() bug fix

- If an optional argument is provided for
  space_object:frommap() (which is {table = true|false}),
  type match for first arguments is omitted, which is
  incorrect. We should return the result only after making
  sure it is possible to build a tuple.

- If there is a type mismatch, however, frommap() does not
  return nil, err as it is mentioned in the description, so we
  change it to be this way.

Closes #4262

(cherry picked from commit ba2deae5acca0bf65e65433c67098a10946e7fd3)
---
 src/box/lua/space.cc    | 12 ++++++++----
 test/box/tuple.result   |  8 +++++++-
 test/box/tuple.test.lua |  1 +
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc
index d0a7e7815f..da363c4827 100644
--- a/src/box/lua/space.cc
+++ b/src/box/lua/space.cc
@@ -576,14 +576,18 @@ lbox_space_frommap(struct lua_State *L)
 		}
 		lua_rawseti(L, -3, fieldno+1);
 	}
-	if (table)
-		return 1;
 
 	lua_replace(L, 1);
 	lua_settop(L, 1);
 	tuple = luaT_tuple_new(L, -1, space->format);
-	if (tuple == NULL)
-		return luaT_error(L);
+	if (tuple == NULL) {
+		struct error *e = diag_last_error(&fiber()->diag);
+		lua_pushnil(L);
+		lua_pushstring(L, e->errmsg);
+		return 2;
+	}
+	if (table)
+		return 1;
 	luaT_pushtuple(L, tuple);
 	return 1;
 usage_error:
diff --git a/test/box/tuple.result b/test/box/tuple.result
index 1082ae84e9..5321ca488c 100644
--- a/test/box/tuple.result
+++ b/test/box/tuple.result
@@ -1121,7 +1121,13 @@ s:frommap()
 ...
 s:frommap({})
 ---
-- error: Tuple field 1 required by space format is missing
+- null
+- Tuple field 1 required by space format is missing
+...
+s:frommap({ddd = 'fail', aaa = 2, ccc = 3, bbb = 4}, {table=true})
+---
+- null
+- 'Tuple field 4 type does not match one required by operation: expected unsigned'
 ...
 s:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = true})
 ---
diff --git a/test/box/tuple.test.lua b/test/box/tuple.test.lua
index 8dd15a0a10..3a77c43ed5 100644
--- a/test/box/tuple.test.lua
+++ b/test/box/tuple.test.lua
@@ -373,6 +373,7 @@ s:frommap({ddd = 1, aaa = 2, bbb = 3})
 s:frommap({ddd = 1, aaa = 2, ccc = 3, eee = 4})
 s:frommap()
 s:frommap({})
+s:frommap({ddd = 'fail', aaa = 2, ccc = 3, bbb = 4}, {table=true})
 s:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = true})
 s:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = false})
 s:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = box.NULL})
-- 
GitLab