[tarantool-patches] [PATCH v2 2/2] sql: rework error handling in box.execute()

imeevma at tarantool.org imeevma at tarantool.org
Wed Jul 31 13:32:24 MSK 2019


Hi! Thank you for review! My answers and new patch below. Also,
new patch appeared before this one that adds new function
luaT_return_error().

On 7/30/19 11:45 PM, Vladislav Shpilevoy wrote:
> Hi! Thanks for the patch!
>
> On 30/07/2019 16:04, imeevma at tarantool.org wrote:
>> In accordance with the Lua coding style in Tarantool, all errors
>> returned in Lua should be returned using 'return nil, error'.
>> However, box.execute() throws an exception in case of an error.
>> This patch causes box.execute() to return an error, as described
>> in the coding style.
>>
>> Closes #4390
>> ---
>> https://github.com/tarantool/tarantool/issues/4390
>> https://github.com/tarantool/tarantool/tree/imeevma/gh-4390-box_execute-should-not-throw
>>
>> diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
>> index 7b7c575..85c5738 100644
>> --- a/src/box/lua/execute.c
>> +++ b/src/box/lua/execute.c
>> @@ -254,13 +254,25 @@ lbox_execute(struct lua_State *L)
>>  		if (! lua_istable(L, 2))
>>  			return luaL_error(L, "Second argument must be a table");
>>  		bind_count = lua_sql_bind_list_decode(L, &bind, 2);
>> -		if (bind_count < 0)
>> -			return luaT_error(L);
>> +		if (bind_count < 0) {
>> +			lua_pushnil(L);
>> +			struct error *e = box_error_last();
>> +			if (e == NULL)
>> +				return 1;
>> +			luaT_pusherror(L, e);
>
> First, how is it possible, that e == NULL? It should not be
> so. I deleted that check, and the tests passed. So please,
> drop it.
>
Fixed.

> Secondly, there are already 4 places, which push exactly the same
> nil + diag error. And 13 more intricate places in lua/fio.c.
> I propose you to introduce a new function to push nil + last box
> error.
>
> Another place is lua_swim_new, which pushes nil implicitly,
> when in the expression:
>
>     *(struct swim **) luaL_pushcdata(L, ctid_swim_ptr) = s;
>
> 's' is NULL. But in fact it is the same case, and here you can
> use than new function too.
>
> Please, introduce and use that new function in a separate commit
> before this one.
Done.


New patch:

>From 03d49126761e232a9ac08719680e08ff21489665 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma at gmail.com>
Date: Tue, 30 Jul 2019 15:50:29 +0300
Subject: [PATCH] sql: rework error handling in box.execute()

In accordance with the Lua coding style in Tarantool, all errors
returned in Lua should be returned using 'return nil, error'.
However, box.execute() throws an exception in case of an error.
This patch causes box.execute() to return an error, as described
in the coding style.

Closes #4390

diff --git a/src/box/lua/execute.c b/src/box/lua/execute.c
index 7b7c575..9b1fc38 100644
--- a/src/box/lua/execute.c
+++ b/src/box/lua/execute.c
@@ -255,12 +255,12 @@ lbox_execute(struct lua_State *L)
 			return luaL_error(L, "Second argument must be a table");
 		bind_count = lua_sql_bind_list_decode(L, &bind, 2);
 		if (bind_count < 0)
-			return luaT_error(L);
+			return luaT_return_error(L);
 	}
 
 	if (sql_prepare_and_execute(sql, length, bind, bind_count, &port,
 				    &fiber()->gc) != 0)
-		return luaT_error(L);
+		return luaT_return_error(L);
 	port_dump_lua(&port, L, false);
 	port_destroy(&port);
 	return 1;
diff --git a/test/sql-tap/gh2548-select-compound-limit.test.lua b/test/sql-tap/gh2548-select-compound-limit.test.lua
index 9589a37..f578870 100755
--- a/test/sql-tap/gh2548-select-compound-limit.test.lua
+++ b/test/sql-tap/gh2548-select-compound-limit.test.lua
@@ -14,30 +14,30 @@ for _, term in ipairs({'UNION', 'UNION ALL', 'INTERSECT', 'EXCEPT'}) do
                  function()
                      for i = 1,table_count do
                          drop_string = 'DROP TABLE IF EXISTS t' .. i .. ';\n'
-                         box.execute(drop_string)
+                         test:execsql(drop_string)
                      end
 
                      for i = 1,table_count do
                          create_string = 'CREATE TABLE t' .. i .. ' (s1 int primary key, s2 int);\n'
-                         box.execute(create_string)
+                         test:execsql(create_string)
                      end
 
                      for i = 1,table_count do
                          insert_string = 'INSERT INTO t' .. i .. ' VALUES (0,' .. i .. ');\n'
-                         box.execute(insert_string)
+                         test:execsql(insert_string)
                      end
 
                      for i = 1,table_count-1 do
                          if i > 1 then select_string = select_string .. ' ' .. term .. ' ' end
                          select_string = select_string .. 'SELECT * FROM t' .. i
                      end
-                     return pcall( function() box.execute(select_string) end)
+                     return pcall( function() test:execsql(select_string) end)
                  end,
                  true)
     test:do_test("Negative COMPOUND "..term,
                  function()
                      select_string = select_string .. ' ' .. term ..' ' .. 'SELECT * FROM t' .. table_count
-                     return  pcall(function() box.execute(select_string) end)
+                     return  pcall(function() test:execsql(select_string) end)
                  end,
                  false)
 
diff --git a/test/sql-tap/lua/sqltester.lua b/test/sql-tap/lua/sqltester.lua
index e83a8e4..0f34114 100644
--- a/test/sql-tap/lua/sqltester.lua
+++ b/test/sql-tap/lua/sqltester.lua
@@ -150,7 +150,10 @@ local function execsql_one_by_one(sql)
     local last_res_rows = nil
     local last_res_metadata = nil
     for _, query in pairs(queries) do
-        local new_res = box.execute(query)
+        local new_res, err = box.execute(query)
+        if err ~= nil then
+            error(err)
+        end
         if new_res ~= nil and new_res.rows ~= nil then
             last_res_rows = new_res.rows
             last_res_metadata = new_res.metadata
diff --git a/test/sql/bind.result b/test/sql/bind.result
index cd0fcc0..1e02620 100644
--- a/test/sql/bind.result
+++ b/test/sql/bind.result
@@ -36,7 +36,13 @@ if remote then
 	cn = netbox.connect(box.cfg.listen)
 	execute = function(...) return cn:execute(...) end
 else
-	execute = box.execute
+	execute = function(...)
+		local res, err = box.execute(...)
+		if err ~= nil then
+			error(err)
+		end
+		return res
+	end
 end;
 ---
 ...
@@ -310,9 +316,11 @@ box.execute('DROP TABLE test')
 ...
 box.execute('SELECT ?', {1, 2})
 ---
-- error: 'Failed to execute SQL statement: The number of parameters is too large'
+- null
+- 'Failed to execute SQL statement: The number of parameters is too large'
 ...
 box.execute('SELECT $2', {1, 2, 3})
 ---
-- error: 'Failed to execute SQL statement: The number of parameters is too large'
+- null
+- 'Failed to execute SQL statement: The number of parameters is too large'
 ...
diff --git a/test/sql/bind.test.lua b/test/sql/bind.test.lua
index f311a0a..2b41af7 100644
--- a/test/sql/bind.test.lua
+++ b/test/sql/bind.test.lua
@@ -15,7 +15,13 @@ if remote then
 	cn = netbox.connect(box.cfg.listen)
 	execute = function(...) return cn:execute(...) end
 else
-	execute = box.execute
+	execute = function(...)
+		local res, err = box.execute(...)
+		if err ~= nil then
+			error(err)
+		end
+		return res
+	end
 end;
 test_run:cmd("setopt delimiter ''");
 --
diff --git a/test/sql/checks.result b/test/sql/checks.result
index b205149..f919862 100644
--- a/test/sql/checks.result
+++ b/test/sql/checks.result
@@ -73,7 +73,8 @@ box.space._ck_constraint:count({})
 ...
 box.execute("INSERT INTO \"test\" VALUES(5);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_01'': X<5'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_01'': X<5'
 ...
 box.space.test:insert({5})
 ---
@@ -89,7 +90,8 @@ box.execute("INSERT INTO \"test\" VALUES(5);")
 ...
 box.execute("INSERT INTO \"test\" VALUES(6);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_01'': X<=5'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_01'': X<=5'
 ...
 box.space.test:insert({6})
 ---
@@ -126,7 +128,8 @@ box.space._ck_constraint:count()
 ...
 box.execute("INSERT INTO t1 VALUES (7, 1, 1)")
 ---
-- error: 'Check constraint failed ''ONE'': x<5'
+- null
+- 'Check constraint failed ''ONE'': x<5'
 ...
 box.space.T1:insert({7, 1, 1})
 ---
@@ -134,7 +137,8 @@ box.space.T1:insert({7, 1, 1})
 ...
 box.execute("INSERT INTO t1 VALUES (2, 1, 1)")
 ---
-- error: 'Check constraint failed ''TWO'': y>x'
+- null
+- 'Check constraint failed ''TWO'': y>x'
 ...
 box.space.T1:insert({2, 1, 1})
 ---
@@ -155,7 +159,8 @@ box.execute("DROP TABLE t1")
 -- Test space creation rollback on spell error in ck constraint.
 box.execute("CREATE TABLE first (id NUMBER PRIMARY KEY CHECK(id < 5), a INT CONSTRAINT ONE CHECK(a >< 5));")
 ---
-- error: Syntax error near '<'
+- null
+- Syntax error near '<'
 ...
 box.space.FIRST == nil
 ---
@@ -184,14 +189,16 @@ _ = box.space._ck_constraint:insert({s.id, 'physics', false, 'SQL', 'X<Y'})
 ...
 box.execute("INSERT INTO \"test\" VALUES(2, 1);")
 ---
-- error: 'Check constraint failed ''physics'': X<Y'
+- null
+- 'Check constraint failed ''physics'': X<Y'
 ...
 s:format({{name='Y', type='integer'}, {name='X', type='integer'}})
 ---
 ...
 box.execute("INSERT INTO \"test\" VALUES(1, 2);")
 ---
-- error: 'Check constraint failed ''physics'': X<Y'
+- null
+- 'Check constraint failed ''physics'': X<Y'
 ...
 box.execute("INSERT INTO \"test\" VALUES(2, 1);")
 ---
@@ -202,7 +209,8 @@ s:truncate()
 ...
 box.execute("INSERT INTO \"test\" VALUES(1, 2);")
 ---
-- error: 'Check constraint failed ''physics'': X<Y'
+- null
+- 'Check constraint failed ''physics'': X<Y'
 ...
 s:format({})
 ---
@@ -234,11 +242,13 @@ _ = box.space._ck_constraint:insert({s.id, 'conflict', false, 'SQL', 'X>10'})
 ...
 box.execute("INSERT INTO \"test\" VALUES(1, 2);")
 ---
-- error: 'Check constraint failed ''conflict'': X>10'
+- null
+- 'Check constraint failed ''conflict'': X>10'
 ...
 box.execute("INSERT INTO \"test\" VALUES(11, 11);")
 ---
-- error: 'Check constraint failed ''physics'': X<Y'
+- null
+- 'Check constraint failed ''physics'': X<Y'
 ...
 box.execute("INSERT INTO \"test\" VALUES(12, 11);")
 ---
@@ -249,7 +259,8 @@ s:drop()
 ...
 box.execute("CREATE TABLE T2(ID INT PRIMARY KEY, CONSTRAINT CK1 CHECK(ID > 0), CONSTRAINT CK1 CHECK(ID < 0))")
 ---
-- error: Constraint CK1 already exists
+- null
+- Constraint CK1 already exists
 ...
 box.space.T2
 ---
@@ -264,20 +275,23 @@ box.space._ck_constraint:select()
 --
 box.execute("CREATE TABLE w2 (s1 INT PRIMARY KEY, CHECK ((SELECT COUNT(*) FROM w2) = 0));")
 ---
-- error: 'Failed to create check constraint ''CK_CONSTRAINT_1_W2'': Subqueries are
-    prohibited in a ck constraint definition'
+- null
+- 'Failed to create check constraint ''CK_CONSTRAINT_1_W2'': Subqueries are prohibited
+  in a ck constraint definition'
 ...
 box.execute("DROP TABLE w2;")
 ---
-- error: Space 'W2' does not exist
+- null
+- Space 'W2' does not exist
 ...
 --
 -- gh-3653: Dissallow bindings for DDL
 --
 box.execute("CREATE TABLE t5(x INT PRIMARY KEY, y INT, CHECK( x*y < ? ));")
 ---
-- error: 'Failed to create check constraint ''CK_CONSTRAINT_1_T5'': bindings are not
-    allowed in DDL'
+- null
+- 'Failed to create check constraint ''CK_CONSTRAINT_1_T5'': bindings are not allowed
+  in DDL'
 ...
 -- Test trim CK constraint code correctness.
 box.execute("CREATE TABLE t1(x TEXT PRIMARY KEY CHECK(x    LIKE     '1  a'))")
@@ -290,11 +304,13 @@ box.space._ck_constraint:select()[1].code
 ...
 box.execute("INSERT INTO t1 VALUES('1 a')")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': x LIKE ''1  a'''
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': x LIKE ''1  a'''
 ...
 box.execute("INSERT INTO t1 VALUES('1   a')")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': x LIKE ''1  a'''
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': x LIKE ''1  a'''
 ...
 box.execute("INSERT INTO t1 VALUES('1  a')")
 ---
diff --git a/test/sql/clear.result b/test/sql/clear.result
index 2fb1761..afa6520 100644
--- a/test/sql/clear.result
+++ b/test/sql/clear.result
@@ -176,7 +176,8 @@ box.execute("DROP TABLE zoobar")
 --
 box.execute("CREATE TABLE t1(id INT PRIMARY KEY, CONSTRAINT ck1 CHECK(id > 0), CONSTRAINT ck1 CHECK(id < 0));")
 ---
-- error: Constraint CK1 already exists
+- null
+- Constraint CK1 already exists
 ...
 box.space.t1
 ---
@@ -188,7 +189,8 @@ box.space._ck_constraint:select()
 ...
 box.execute("CREATE TABLE t2(id INT PRIMARY KEY, CONSTRAINT fk1 FOREIGN KEY(id) REFERENCES t2, CONSTRAINT fk1 FOREIGN KEY(id) REFERENCES t2);")
 ---
-- error: Constraint FK1 already exists
+- null
+- Constraint FK1 already exists
 ...
 box.space.t2
 ---
@@ -204,7 +206,8 @@ box.space._fk_constraint:select()
 --
 box.execute("CREATE TABLE t3(id INT PRIMARY KEY, CONSTRAINT ck1 CHECK(id > 0), CONSTRAINT ck1 FOREIGN KEY(id) REFERENCES t3, CONSTRAINT fk1 FOREIGN KEY(id) REFERENCES t3, CONSTRAINT ck1 CHECK(id < 0));")
 ---
-- error: Constraint CK1 already exists
+- null
+- Constraint CK1 already exists
 ...
 box.space.t1
 ---
diff --git a/test/sql/collation.result b/test/sql/collation.result
index 436ce32..11962ef 100644
--- a/test/sql/collation.result
+++ b/test/sql/collation.result
@@ -15,23 +15,28 @@ box.execute('pragma sql_default_engine=\''..engine..'\'')
 -- All of these tests should throw error "near "COLLATE": syntax error"
 box.execute("SELECT 1 LIMIT 1 COLLATE BINARY;")
 ---
-- error: Syntax error near 'COLLATE'
+- null
+- Syntax error near 'COLLATE'
 ...
 box.execute("SELECT 1 LIMIT 1 COLLATE BINARY OFFSET 1;")
 ---
-- error: Syntax error near 'COLLATE'
+- null
+- Syntax error near 'COLLATE'
 ...
 box.execute("SELECT 1 LIMIT 1 OFFSET 1 COLLATE BINARY;")
 ---
-- error: Syntax error near 'COLLATE'
+- null
+- Syntax error near 'COLLATE'
 ...
 box.execute("SELECT 1 LIMIT 1, 1 COLLATE BINARY;")
 ---
-- error: Syntax error near 'COLLATE'
+- null
+- Syntax error near 'COLLATE'
 ...
 box.execute("SELECT 1 LIMIT 1 COLLATE BINARY, 1;")
 ---
-- error: Syntax error near 'COLLATE'
+- null
+- Syntax error near 'COLLATE'
 ...
 -- gh-3052: upper/lower support only default locale
 -- For tr-TR result depends on collation
@@ -253,7 +258,8 @@ box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = b;")
 ...
 box.execute("SELECT * FROM t WHERE b = c;")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("SELECT * FROM t WHERE b COLLATE \"binary\" = c;")
 ---
@@ -283,22 +289,26 @@ box.execute("SELECT * FROM t WHERE a = c;")
 ...
 box.execute("SELECT * FROM t WHERE a COLLATE \"binary\" = c COLLATE \"unicode\";")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 -- Compound queries perform implicit comparisons between values.
 -- Hence, rules for collations compatibilities are the same.
 --
 box.execute("SELECT 'abc' COLLATE \"binary\" UNION SELECT 'ABC' COLLATE \"unicode_ci\"")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("SELECT 'abc' COLLATE \"unicode_ci\" UNION SELECT 'ABC' COLLATE binary")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("SELECT c FROM t UNION SELECT b FROM t;")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("SELECT b FROM t UNION SELECT a FROM t;")
 ---
@@ -345,7 +355,8 @@ box.session.su('tmp')
 -- Error: read access to space is denied.
 box.execute("pragma collation_list")
 ---
-- error: Read access to space '_collation' is denied for user 'tmp'
+- null
+- Read access to space '_collation' is denied for user 'tmp'
 ...
 box.session.su('admin')
 ---
@@ -426,7 +437,8 @@ box.execute("INSERT INTO t1 VALUES (1,'a');")
 -- Should fail.
 box.execute("UPDATE t0 SET s1 = 'A';")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 box.execute("SELECT * FROM t1;")
 ---
@@ -496,11 +508,13 @@ box.execute("SELECT c FROM t4a WHERE (a COLLATE \"binary\"||'') = b;")
 --
 box.execute("SELECT c FROM t4a WHERE (a COLLATE \"binary\"||'' COLLATE \"unicode_ci\") = b;")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("SELECT c FROM t4a WHERE (a COLLATE \"binary\"||'') = b COLLATE \"unicode\";")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 -- No collation is used since LHS and RHS of concatenation
 -- operator have different implicit collations.
@@ -555,7 +569,8 @@ box.execute("SELECT c FROM t4a WHERE (a||b COLLATE \"binary\")=(b||a);")
 ...
 box.execute("SELECT c FROM t4a WHERE (a||b COLLATE \"binary\")=(b COLLATE \"unicode_ci\"||a);")
 ---
-- error: Illegal mix of collations
+- null
+- Illegal mix of collations
 ...
 box.execute("INSERT INTO t4b VALUES('abc', 'xxx', 2);")
 ---
@@ -676,7 +691,8 @@ box.execute("INSERT INTO t3b VALUES ('A');")
 ...
 box.execute("INSERT INTO t3b VALUES ('a');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3B_1' in space 'T3B'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3B_1' in space 'T3B'
 ...
 box.execute("SELECT * FROM t3b;")
 ---
@@ -740,7 +756,8 @@ box.execute("INSERT INTO t3c VALUES ('A');")
 ...
 box.execute("INSERT INTO t3c VALUES ('a');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3C_1' in space 'T3C'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3C_1' in space 'T3C'
 ...
 box.execute("SELECT * FROM t3c;")
 ---
@@ -804,7 +821,8 @@ box.execute("INSERT INTO t3d VALUES ('A');")
 ...
 box.execute("INSERT INTO t3d VALUES ('a');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3D_1' in space 'T3D'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3D_1' in space 'T3D'
 ...
 box.execute("SELECT * FROM t3d;")
 ---
@@ -834,7 +852,8 @@ box.execute("INSERT INTO t3e VALUES ('a');")
 ...
 box.execute("INSERT INTO t3e VALUES ('A');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3E_1' in space 'T3E'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3E_1' in space 'T3E'
 ...
 box.execute("SELECT * FROM t3e;")
 ---
@@ -897,7 +916,8 @@ box.execute("INSERT INTO t3f VALUES ('A');")
 ...
 box.execute("INSERT INTO t3f VALUES ('a');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3F_1' in space 'T3F'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3F_1' in space 'T3F'
 ...
 box.execute("SELECT * FROM t3f;")
 ---
@@ -927,7 +947,8 @@ box.execute("INSERT INTO t3g VALUES ('a');")
 ...
 box.execute("INSERT INTO t3g VALUES ('A');")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_T3G_1' in space 'T3G'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_T3G_1' in space 'T3G'
 ...
 box.execute("SELECT * FROM t3g;")
 ---
diff --git a/test/sql/delete.result b/test/sql/delete.result
index 0bc389f..e27c79d 100644
--- a/test/sql/delete.result
+++ b/test/sql/delete.result
@@ -57,7 +57,8 @@ box.execute("DROP TABLE t1;");
 --
 box.execute("DELETE FROM t1;")
 ---
-- error: Space 'T1' does not exist
+- null
+- Space 'T1' does not exist
 ...
 box.execute("CREATE TABLE t2 (s1 INT PRIMARY KEY);")
 ---
@@ -69,7 +70,8 @@ box.execute("CREATE TRIGGER t2 BEFORE INSERT ON t2 FOR EACH ROW BEGIN DELETE FRO
 ...
 box.execute("INSERT INTO t2 VALUES (0);")
 ---
-- error: Space 'T1' does not exist
+- null
+- Space 'T1' does not exist
 ...
 box.execute("DROP TABLE t2;")
 ---
@@ -81,7 +83,8 @@ box.execute("DROP TABLE t2;")
 -- can't truncate system table.
 box.execute("TRUNCATE TABLE \"_fk_constraint\";")
 ---
-- error: Can't truncate a system space, space '_fk_constraint'
+- null
+- Can't truncate a system space, space '_fk_constraint'
 ...
 box.execute("CREATE TABLE t1(id INT PRIMARY KEY, a INT, b TEXT);")
 ---
@@ -128,8 +131,9 @@ box.execute("CREATE VIEW v1 AS SELECT * FROM t1;")
 ...
 box.execute("TRUNCATE TABLE v1;")
 ---
-- error: 'Failed to execute SQL statement: can not truncate space ''V1'' because space
-    is a view'
+- null
+- 'Failed to execute SQL statement: can not truncate space ''V1'' because space is
+  a view'
 ...
 -- Can't truncate table with FK.
 box.execute("CREATE TABLE t2(x INT PRIMARY KEY REFERENCES t1(id));")
@@ -138,8 +142,9 @@ box.execute("CREATE TABLE t2(x INT PRIMARY KEY REFERENCES t1(id));")
 ...
 box.execute("TRUNCATE TABLE t1;")
 ---
-- error: 'Failed to execute SQL statement: can not truncate space ''T1'' because other
-    objects depend on it'
+- null
+- 'Failed to execute SQL statement: can not truncate space ''T1'' because other objects
+  depend on it'
 ...
 -- Table triggers should be ignored.
 box.execute("DROP TABLE t2;")
diff --git a/test/sql/drop-table.result b/test/sql/drop-table.result
index 48b0010..af8fe38 100644
--- a/test/sql/drop-table.result
+++ b/test/sql/drop-table.result
@@ -32,7 +32,8 @@ box.execute("DROP TABLE zzzoobar")
 -- Table does not exist anymore. Should error here.
 box.execute("INSERT INTO zzzoobar VALUES (111, 222, 'c3', 444)")
 ---
-- error: Space 'ZZZOOBAR' does not exist
+- null
+- Space 'ZZZOOBAR' does not exist
 ...
 -- gh-3712: if space features sequence, data from _sequence_data
 -- must be deleted before space is dropped.
@@ -97,12 +98,14 @@ box.session.su('tmp')
 --
 box.execute('CREATE TABLE t1 (id INT PRIMARY KEY, a INT)')
 ---
-- error: Write access to space '_index' is denied for user 'tmp'
+- null
+- Write access to space '_index' is denied for user 'tmp'
 ...
 -- Error: no such table.
 box.execute('DROP TABLE t1')
 ---
-- error: Space 'T1' does not exist
+- null
+- Space 'T1' does not exist
 ...
 box.session.su('admin')
 ---
@@ -138,7 +141,8 @@ box.session.su('tmp')
 --
 box.execute('CREATE TABLE t2 (id INT PRIMARY KEY AUTOINCREMENT, a INT UNIQUE, b INT UNIQUE, c INT UNIQUE, d INT UNIQUE)')
 ---
-- error: Write access to space '_sequence' is denied for user 'tmp'
+- null
+- Write access to space '_sequence' is denied for user 'tmp'
 ...
 box.session.su('admin')
 ---
@@ -180,8 +184,8 @@ box.execute('CREATE TABLE t3(a INTEGER PRIMARY KEY);')
 --
 box.execute('CREATE TABLE t4(x INTEGER PRIMARY KEY REFERENCES t3, a INT UNIQUE, c TEXT REFERENCES t3);')
 ---
-- error: 'Failed to create foreign key constraint ''FK_CONSTRAINT_2_T4'': field type
-    mismatch'
+- null
+- 'Failed to create foreign key constraint ''FK_CONSTRAINT_2_T4'': field type mismatch'
 ...
 box.execute('DROP TABLE t3;')
 ---
diff --git a/test/sql/errinj.result b/test/sql/errinj.result
index cb15a83..f198d5f 100644
--- a/test/sql/errinj.result
+++ b/test/sql/errinj.result
@@ -189,11 +189,13 @@ box.error.injection.set("ERRINJ_WAL_IO", true)
 ...
 box.execute("CREATE TRIGGER t1t INSERT ON t1 FOR EACH ROW BEGIN INSERT INTO t2 VALUES (1, 1); END;")
 ---
-- error: Failed to write to disk
+- null
+- Failed to write to disk
 ...
 box.execute("CREATE INDEX t1a ON t1(a);")
 ---
-- error: Failed to write to disk
+- null
+- Failed to write to disk
 ...
 box.error.injection.set("ERRINJ_WAL_IO", false)
 ---
@@ -257,7 +259,8 @@ box.error.injection.set("ERRINJ_WAL_IO", true)
 ...
 box.execute("DROP TRIGGER t1t;")
 ---
-- error: Failed to write to disk
+- null
+- Failed to write to disk
 ...
 box.error.injection.set("ERRINJ_WAL_IO", false)
 ---
@@ -334,7 +337,8 @@ errinj.set("ERRINJ_WAL_IO", false)
 ...
 box.execute("INSERT INTO t3 VALUES (1, 2, 2);")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 errinj.set("ERRINJ_WAL_IO", true)
 ---
@@ -342,7 +346,8 @@ errinj.set("ERRINJ_WAL_IO", true)
 ...
 box.execute("ALTER TABLE t3 ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES t3;")
 ---
-- error: Failed to write to disk
+- null
+- Failed to write to disk
 ...
 errinj.set("ERRINJ_WAL_IO", false)
 ---
@@ -366,7 +371,8 @@ box.execute("ALTER TABLE t3 ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES t3;")
 ...
 box.execute("INSERT INTO t3 VALUES(1, 1, 3);")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 errinj.set("ERRINJ_WAL_IO", true)
 ---
@@ -374,11 +380,13 @@ errinj.set("ERRINJ_WAL_IO", true)
 ...
 box.execute("ALTER TABLE t3 DROP CONSTRAINT fk1;")
 ---
-- error: Failed to write to disk
+- null
+- Failed to write to disk
 ...
 box.execute("INSERT INTO t3 VALUES(1, 1, 3);")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 errinj.set("ERRINJ_WAL_IO", false)
 ---
@@ -423,15 +431,18 @@ f = fiber.create(drop_table_yield)
 ...
 box.execute("SELECT * FROM t;")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.execute("INSERT INTO t VALUES (2);")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.execute("UPDATE t SET id = 2;")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 -- Finish drop space.
 errinj.set("ERRINJ_WAL_DELAY", false)
@@ -450,7 +461,8 @@ errinj.set("ERRINJ_SQL_NAME_NORMALIZATION", true)
 ...
 box.execute("CREATE TABLE hello (id INT primary key,x INT,y INT);")
 ---
-- error: Failed to allocate 6 bytes in sqlDbMallocRawNN for res
+- null
+- Failed to allocate 6 bytes in sqlDbMallocRawNN for res
 ...
 dummy_f = function(int) return 1 end
 ---
@@ -490,7 +502,8 @@ _ = box.space._ck_constraint:insert({s.id, 'CK_CONSTRAINT_01', false, 'SQL', 'X<
 ...
 box.execute("INSERT INTO \"test\" VALUES(5);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_01'': X<5'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_01'': X<5'
 ...
 errinj.set("ERRINJ_WAL_IO", true)
 ---
@@ -521,7 +534,8 @@ _ = box.space._ck_constraint:delete({s.id, 'CK_CONSTRAINT_01'})
 ...
 box.execute("INSERT INTO \"test\" VALUES(6);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_01'': X<=5'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_01'': X<=5'
 ...
 errinj.set("ERRINJ_WAL_IO", false)
 ---
@@ -557,11 +571,13 @@ _ = box.space._ck_constraint:insert({s.id, 'Xgreater10', false, 'SQL', 'X > 10'}
 ...
 box.execute("INSERT INTO \"test\" VALUES(1, 2);")
 ---
-- error: 'Check constraint failed ''Xgreater10'': X > 10'
+- null
+- 'Check constraint failed ''Xgreater10'': X > 10'
 ...
 box.execute("INSERT INTO \"test\" VALUES(20, 10);")
 ---
-- error: 'Check constraint failed ''XlessY'': X < Y'
+- null
+- 'Check constraint failed ''XlessY'': X < Y'
 ...
 box.execute("INSERT INTO \"test\" VALUES(20, 100);")
 ---
@@ -584,11 +600,13 @@ errinj.set("ERRINJ_WAL_IO", false)
 ...
 box.execute("INSERT INTO \"test\" VALUES(1, 2);")
 ---
-- error: 'Check constraint failed ''Xgreater10'': X > 10'
+- null
+- 'Check constraint failed ''Xgreater10'': X > 10'
 ...
 box.execute("INSERT INTO \"test\" VALUES(20, 10);")
 ---
-- error: 'Check constraint failed ''XlessY'': X < Y'
+- null
+- 'Check constraint failed ''XlessY'': X < Y'
 ...
 box.execute("INSERT INTO \"test\" VALUES(20, 100);")
 ---
diff --git a/test/sql/foreign-keys.result b/test/sql/foreign-keys.result
index f3cca5c..38b0b14 100644
--- a/test/sql/foreign-keys.result
+++ b/test/sql/foreign-keys.result
@@ -181,7 +181,8 @@ t = box.space._fk_constraint:insert(t)
 --
 box.execute("DROP INDEX i1 on t1;")
 ---
-- error: 'Can''t modify space ''T1'': can not drop a referenced index'
+- null
+- 'Can''t modify space ''T1'': can not drop a referenced index'
 ...
 -- Referenced index can't be altered as well, if alter leads to
 -- rebuild of index (e.g. index still can be renamed).
@@ -395,21 +396,23 @@ box.execute('CREATE TABLE t1 (id INT PRIMARY KEY);')
 ...
 box.execute('CREATE TABLE t2 (id INT PRIMARY KEY REFERENCES t2 ON DELETE CASCADE ON DELETE RESTRICT);')
 ---
-- error: Keyword 'DELETE' is reserved. Please use double quotes if 'DELETE' is an
-    identifier.
+- null
+- Keyword 'DELETE' is reserved. Please use double quotes if 'DELETE' is an identifier.
 ...
 box.execute('CREATE TABLE t2 (id INT PRIMARY KEY REFERENCES t2 ON DELETE CASCADE ON DELETE CASCADE);')
 ---
-- error: Keyword 'DELETE' is reserved. Please use double quotes if 'DELETE' is an
-    identifier.
+- null
+- Keyword 'DELETE' is reserved. Please use double quotes if 'DELETE' is an identifier.
 ...
 box.execute('CREATE TABLE t2 (id INT PRIMARY KEY REFERENCES t2 ON DELETE CASCADE ON UPDATE RESTRICT ON DELETE RESTRICT);')
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute('CREATE TABLE t2 (id INT PRIMARY KEY REFERENCES t2 ON DELETE CASCADE MATCH FULL);')
 ---
-- error: Keyword 'MATCH' is reserved. Please use double quotes if 'MATCH' is an identifier.
+- null
+- Keyword 'MATCH' is reserved. Please use double quotes if 'MATCH' is an identifier.
 ...
 box.space.T1:drop()
 ---
@@ -436,16 +439,18 @@ i1 = box.space.T2:create_index('I1')
 ...
 box.execute("ALTER TABLE t1 ADD CONSTRAINT fk FOREIGN KEY (id) REFERENCES t2;")
 ---
-- error: 'Failed to create foreign key constraint ''FK'': foreign key refers to nonexistent
-    field'
+- null
+- 'Failed to create foreign key constraint ''FK'': foreign key refers to nonexistent
+  field'
 ...
 -- Make sure that if referenced columns (of parent space) are
 -- ommitted and parent space doesn't have PK, then error is raised.
 --
 box.execute("ALTER TABLE t2 ADD CONSTRAINT fk FOREIGN KEY (id) REFERENCES t1;")
 ---
-- error: 'Failed to create foreign key constraint ''FK'': referenced space doesn''t
-    feature PRIMARY KEY'
+- null
+- 'Failed to create foreign key constraint ''FK'': referenced space doesn''t feature
+  PRIMARY KEY'
 ...
 t1:drop()
 ---
diff --git a/test/sql/gh-2929-primary-key.result b/test/sql/gh-2929-primary-key.result
index 815b16e..021d037 100644
--- a/test/sql/gh-2929-primary-key.result
+++ b/test/sql/gh-2929-primary-key.result
@@ -20,19 +20,23 @@ box.execute("CREATE TABLE t1(a INT PRIMARY KEY, b INT UNIQUE)")
 ...
 box.execute("CREATE TABLE t2(a INT UNIQUE, b INT)")
 ---
-- error: 'Failed to create space ''T2'': PRIMARY KEY missing'
+- null
+- 'Failed to create space ''T2'': PRIMARY KEY missing'
 ...
 box.execute("CREATE TABLE t3(a NUMBER)")
 ---
-- error: 'Failed to create space ''T3'': PRIMARY KEY missing'
+- null
+- 'Failed to create space ''T3'': PRIMARY KEY missing'
 ...
 box.execute("CREATE TABLE t4(a NUMBER, b TEXT)")
 ---
-- error: 'Failed to create space ''T4'': PRIMARY KEY missing'
+- null
+- 'Failed to create space ''T4'': PRIMARY KEY missing'
 ...
 box.execute("CREATE TABLE t5(a NUMBER, b NUMBER UNIQUE)")
 ---
-- error: 'Failed to create space ''T5'': PRIMARY KEY missing'
+- null
+- 'Failed to create space ''T5'': PRIMARY KEY missing'
 ...
 box.execute("DROP TABLE t1")
 ---
@@ -43,5 +47,6 @@ box.execute("DROP TABLE t1")
 --
 box.execute("CREATE TABLE tx (a INT, PRIMARY KEY (b));")
 ---
-- error: Can’t resolve field 'B'
+- null
+- Can’t resolve field 'B'
 ...
diff --git a/test/sql/gh-2981-check-autoinc.result b/test/sql/gh-2981-check-autoinc.result
index f03858a..64ae64b 100644
--- a/test/sql/gh-2981-check-autoinc.result
+++ b/test/sql/gh-2981-check-autoinc.result
@@ -29,7 +29,8 @@ box.execute("insert into t1 values (18, null);")
 ...
 box.execute("insert into t1(s2) values (null);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': s1 <> 19'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': s1 <> 19'
 ...
 box.execute("insert into t2 values (18, null);")
 ---
@@ -37,7 +38,8 @@ box.execute("insert into t2 values (18, null);")
 ...
 box.execute("insert into t2(s2) values (null);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T2'': s1 <> 19 AND s1 <> 25'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T2'': s1 <> 19 AND s1 <> 25'
 ...
 box.execute("insert into t2 values (24, null);")
 ---
@@ -45,7 +47,8 @@ box.execute("insert into t2 values (24, null);")
 ...
 box.execute("insert into t2(s2) values (null);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T2'': s1 <> 19 AND s1 <> 25'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T2'': s1 <> 19 AND s1 <> 25'
 ...
 box.execute("insert into t3 values (9, null)")
 ---
@@ -53,7 +56,8 @@ box.execute("insert into t3 values (9, null)")
 ...
 box.execute("insert into t3(s2) values (null)")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T3'': s1 < 10'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T3'': s1 < 10'
 ...
 box.execute("DROP TABLE t1")
 ---
diff --git a/test/sql/gh-3613-idx-alter-update.result b/test/sql/gh-3613-idx-alter-update.result
index 20315df..ba323a6 100644
--- a/test/sql/gh-3613-idx-alter-update.result
+++ b/test/sql/gh-3613-idx-alter-update.result
@@ -33,7 +33,8 @@ box.snapshot()
 test_run:cmd('restart server default')
 box.execute('DROP INDEX i ON j3')
 ---
-- error: No index 'I' is defined in space 'J3'
+- null
+- No index 'I' is defined in space 'J3'
 ...
 box.execute('CREATE INDEX i ON j3 (s1)')
 ---
diff --git a/test/sql/gh-3888-values-blob-assert.result b/test/sql/gh-3888-values-blob-assert.result
index 81b0f52..768448c 100644
--- a/test/sql/gh-3888-values-blob-assert.result
+++ b/test/sql/gh-3888-values-blob-assert.result
@@ -17,30 +17,36 @@ box.execute('pragma sql_default_engine=\''..engine..'\'')
 -- check 'VALUES' against typedef keywords (should fail)
 box.execute('VALUES(scalar)')
 ---
-- error: Syntax error near 'scalar'
+- null
+- Syntax error near 'scalar'
 ...
 box.execute('VALUES(float)')
 ---
-- error: Syntax error near 'float'
+- null
+- Syntax error near 'float'
 ...
 -- check 'SELECT' against typedef keywords (should fail)
 box.execute('SELECT scalar')
 ---
-- error: Syntax error near 'scalar'
+- null
+- Syntax error near 'scalar'
 ...
 box.execute('SELECT float')
 ---
-- error: Syntax error near 'float'
+- null
+- Syntax error near 'float'
 ...
 -- check 'VALUES' against ID (should fail)
 box.execute('VALUES(TheColumnName)')
 ---
-- error: Can’t resolve field 'THECOLUMNNAME'
+- null
+- Can’t resolve field 'THECOLUMNNAME'
 ...
 -- check 'SELECT' against ID (should fail)
 box.execute('SELECT TheColumnName')
 ---
-- error: Can’t resolve field 'THECOLUMNNAME'
+- null
+- Can’t resolve field 'THECOLUMNNAME'
 ...
 -- check 'VALUES' well-formed expression  (returns value)
 box.execute('VALUES(-0.5e-2)')
diff --git a/test/sql/icu-upper-lower.result b/test/sql/icu-upper-lower.result
index dc00c03..88266c8 100644
--- a/test/sql/icu-upper-lower.result
+++ b/test/sql/icu-upper-lower.result
@@ -276,13 +276,16 @@ test_run:cmd("setopt delimiter ''");
 -- Bad test cases
 box.execute("select upper('1', 2)")
 ---
-- error: wrong number of arguments to function UPPER()
+- null
+- wrong number of arguments to function UPPER()
 ...
 box.execute("select upper(\"1\")")
 ---
-- error: Can’t resolve field '1'
+- null
+- Can’t resolve field '1'
 ...
 box.execute("select upper()")
 ---
-- error: wrong number of arguments to function UPPER()
+- null
+- wrong number of arguments to function UPPER()
 ...
diff --git a/test/sql/insert-unique.result b/test/sql/insert-unique.result
index 236046f..1cf44c9 100644
--- a/test/sql/insert-unique.result
+++ b/test/sql/insert-unique.result
@@ -28,12 +28,14 @@ box.execute("INSERT INTO zoobar VALUES (111, 222, 'c3', 444)")
 -- PK must be unique
 box.execute("INSERT INTO zoobar VALUES (112, 222, 'c3', 444)")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_ZOOBAR_1' in space 'ZOOBAR'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_ZOOBAR_1' in space 'ZOOBAR'
 ...
 -- Unique index must be respected
 box.execute("INSERT INTO zoobar VALUES (111, 223, 'c3', 444)")
 ---
-- error: Duplicate key exists in unique index 'ZOOBAR2' in space 'ZOOBAR'
+- null
+- Duplicate key exists in unique index 'ZOOBAR2' in space 'ZOOBAR'
 ...
 -- Cleanup
 box.execute("DROP INDEX zoobar2 ON zoobar")
diff --git a/test/sql/integer-overflow.result b/test/sql/integer-overflow.result
index a9a90f5..223ba02 100644
--- a/test/sql/integer-overflow.result
+++ b/test/sql/integer-overflow.result
@@ -14,7 +14,8 @@ box.execute('pragma sql_default_engine=\''..engine..'\'')
 --
 box.execute('SELECT (2147483647 * 2147483647 * 2147483647);')
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute('SELECT (-9223372036854775808 / -1);')
 ---
@@ -26,7 +27,8 @@ box.execute('SELECT (-9223372036854775808 / -1);')
 ...
 box.execute('SELECT (-9223372036854775808 - 1);')
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute('SELECT (9223372036854775807 + 1);')
 ---
@@ -38,11 +40,13 @@ box.execute('SELECT (9223372036854775807 + 1);')
 ...
 box.execute('SELECT (9223372036854775807 + 9223372036854775807 + 2);')
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute('SELECT 18446744073709551615 * 2;')
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute('SELECT (-9223372036854775807 * (-2));')
 ---
@@ -64,8 +68,9 @@ box.execute('SELECT 9223372036854775808;')
 ...
 box.execute('SELECT -9223372036854775809;')
 ---
-- error: Integer literal -9223372036854775809 exceeds the supported range [-9223372036854775808,
-    18446744073709551615]
+- null
+- Integer literal -9223372036854775809 exceeds the supported range [-9223372036854775808,
+  18446744073709551615]
 ...
 box.execute('SELECT 9223372036854775808 - 1;')
 ---
@@ -85,8 +90,9 @@ box.execute('SELECT 18446744073709551615;')
 ...
 box.execute('SELECT 18446744073709551616;')
 ---
-- error: Integer literal 18446744073709551616 exceeds the supported range [-9223372036854775808,
-    18446744073709551615]
+- null
+- Integer literal 18446744073709551616 exceeds the supported range [-9223372036854775808,
+  18446744073709551615]
 ...
 -- Test that CAST may also leads to overflow.
 --
@@ -100,7 +106,8 @@ box.execute('SELECT CAST(\'9223372036854775808\' AS INTEGER);')
 ...
 box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
 ---
-- error: 'Type mismatch: can not convert 18446744073709551616 to integer'
+- null
+- 'Type mismatch: can not convert 18446744073709551616 to integer'
 ...
 -- Due to inexact represantation of large integers in terms of
 -- floating point numbers, numerics with value < INT64_MAX
@@ -110,7 +117,8 @@ box.execute('SELECT CAST(\'18446744073709551616\' AS INTEGER);')
 --
 box.execute('SELECT CAST(9223372036854775807.0 AS INTEGER);')
 ---
-- error: 'Type mismatch: can not convert 9.22337203685478e+18 to integer'
+- null
+- 'Type mismatch: can not convert 9.22337203685478e+18 to integer'
 ...
 -- gh-3810: make sure that if space contains integers in range
 -- [INT64_MAX, UINT64_MAX], they are handled inside SQL in a
diff --git a/test/sql/message-func-indexes.result b/test/sql/message-func-indexes.result
index eb2d6c7..69e3ee0 100644
--- a/test/sql/message-func-indexes.result
+++ b/test/sql/message-func-indexes.result
@@ -21,7 +21,8 @@ box.execute("CREATE TABLE t2(object INTEGER PRIMARY KEY, price INTEGER, count IN
 -- should return certain message.
 box.execute("CREATE INDEX i1 ON t1(a+1)")
 ---
-- error: Tarantool does not support functional indexes
+- null
+- Tarantool does not support functional indexes
 ...
 box.execute("CREATE INDEX i2 ON t1(a)")
 ---
@@ -29,7 +30,8 @@ box.execute("CREATE INDEX i2 ON t1(a)")
 ...
 box.execute("CREATE INDEX i3 ON t2(price + 100)")
 ---
-- error: Tarantool does not support functional indexes
+- null
+- Tarantool does not support functional indexes
 ...
 box.execute("CREATE INDEX i4 ON t2(price)")
 ---
@@ -37,11 +39,13 @@ box.execute("CREATE INDEX i4 ON t2(price)")
 ...
 box.execute("CREATE INDEX i5 ON t2(count + 1)")
 ---
-- error: Tarantool does not support functional indexes
+- null
+- Tarantool does not support functional indexes
 ...
 box.execute("CREATE INDEX i6 ON t2(count * price)")
 ---
-- error: Tarantool does not support functional indexes
+- null
+- Tarantool does not support functional indexes
 ...
 -- Cleaning up.
 box.execute("DROP TABLE t1")
diff --git a/test/sql/misc.result b/test/sql/misc.result
index bc8b10e..e9bfe89 100644
--- a/test/sql/misc.result
+++ b/test/sql/misc.result
@@ -19,13 +19,13 @@ box.execute('select 1;')
 ...
 box.execute('select 1; select 2;')
 ---
-- error: Keyword 'select' is reserved. Please use double quotes if 'select' is an
-    identifier.
+- null
+- Keyword 'select' is reserved. Please use double quotes if 'select' is an identifier.
 ...
 box.execute('create table t1 (id INT primary key); select 100;')
 ---
-- error: Keyword 'select' is reserved. Please use double quotes if 'select' is an
-    identifier.
+- null
+- Keyword 'select' is reserved. Please use double quotes if 'select' is an identifier.
 ...
 box.space.t1 == nil
 ---
@@ -33,35 +33,40 @@ box.space.t1 == nil
 ...
 box.execute(';')
 ---
-- error: Failed to execute an empty SQL statement
+- null
+- Failed to execute an empty SQL statement
 ...
 box.execute('')
 ---
-- error: Failed to execute an empty SQL statement
+- null
+- Failed to execute an empty SQL statement
 ...
 box.execute('     ;')
 ---
-- error: Failed to execute an empty SQL statement
+- null
+- Failed to execute an empty SQL statement
 ...
 box.execute('\n\n\n\t\t\t   ')
 ---
-- error: Failed to execute an empty SQL statement
+- null
+- Failed to execute an empty SQL statement
 ...
 -- gh-3820: only table constraints can have a name.
 --
 box.execute('CREATE TABLE test (id INTEGER PRIMARY KEY, b INTEGER CONSTRAINT c1 NULL)')
 ---
-- error: Keyword 'NULL' is reserved. Please use double quotes if 'NULL' is an identifier.
+- null
+- Keyword 'NULL' is reserved. Please use double quotes if 'NULL' is an identifier.
 ...
 box.execute('CREATE TABLE test (id INTEGER PRIMARY KEY, b INTEGER CONSTRAINT c1 DEFAULT 300)')
 ---
-- error: Keyword 'DEFAULT' is reserved. Please use double quotes if 'DEFAULT' is an
-    identifier.
+- null
+- Keyword 'DEFAULT' is reserved. Please use double quotes if 'DEFAULT' is an identifier.
 ...
 box.execute('CREATE TABLE test (id INTEGER PRIMARY KEY, b TEXT CONSTRAINT c1 COLLATE "binary")')
 ---
-- error: Keyword 'COLLATE' is reserved. Please use double quotes if 'COLLATE' is an
-    identifier.
+- null
+- Keyword 'COLLATE' is reserved. Please use double quotes if 'COLLATE' is an identifier.
 ...
 -- Make sure that type of literals in meta complies with its real
 -- type. For instance, typeof(0.5) is number, not integer.
diff --git a/test/sql/no-pk-space.result b/test/sql/no-pk-space.result
index f4f6059..025f363 100644
--- a/test/sql/no-pk-space.result
+++ b/test/sql/no-pk-space.result
@@ -19,19 +19,23 @@ s = box.schema.create_space('test', {format = format})
 ...
 box.execute("SELECT * FROM \"test\";")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.execute("INSERT INTO \"test\" VALUES (1);")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.execute("DELETE FROM \"test\";")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.execute("UPDATE \"test\" SET id = 3;")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 s:drop()
 ---
@@ -54,7 +58,8 @@ box.space.T1:drop()
 ...
 box.execute("SELECT * FROM v1;")
 ---
-- error: SQL does not support spaces without primary key
+- null
+- SQL does not support spaces without primary key
 ...
 box.space.V1:drop()
 ---
diff --git a/test/sql/on-conflict.result b/test/sql/on-conflict.result
index 2c3dfa7..6851e21 100644
--- a/test/sql/on-conflict.result
+++ b/test/sql/on-conflict.result
@@ -14,57 +14,69 @@ box.execute('pragma sql_default_engine=\''..engine..'\'')
 --
 box.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, v INTEGER UNIQUE ON CONFLICT ABORT)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE q (id INTEGER PRIMARY KEY, v INTEGER UNIQUE ON CONFLICT FAIL)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE p (id INTEGER PRIMARY KEY, v INTEGER UNIQUE ON CONFLICT IGNORE)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE g (id INTEGER PRIMARY KEY, v INTEGER UNIQUE ON CONFLICT REPLACE)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE e (id INTEGER PRIMARY KEY ON CONFLICT REPLACE, v INTEGER)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE t1(a INT PRIMARY KEY ON CONFLICT REPLACE)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 box.execute("CREATE TABLE t2(a INT PRIMARY KEY ON CONFLICT IGNORE)")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 -- CHECK constraint is illegal with REPLACE option.
 --
 box.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, a INTEGER CHECK (a > 5) ON CONFLICT REPLACE);")
 ---
-- error: Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
+- null
+- Keyword 'ON' is reserved. Please use double quotes if 'ON' is an identifier.
 ...
 --
 -- gh-3473: Primary key can't be declared with NULL.
 --
 box.execute("CREATE TABLE te17 (s1 INT NULL PRIMARY KEY NOT NULL);")
 ---
-- error: Primary index of space 'TE17' can not contain nullable parts
+- null
+- Primary index of space 'TE17' can not contain nullable parts
 ...
 box.execute("CREATE TABLE te17 (s1 INT NULL PRIMARY KEY);")
 ---
-- error: Primary index of space 'TE17' can not contain nullable parts
+- null
+- Primary index of space 'TE17' can not contain nullable parts
 ...
 box.execute("CREATE TABLE test (a int PRIMARY KEY, b int NULL ON CONFLICT IGNORE);")
 ---
-- error: 'Failed to execute SQL statement: NULL declaration for column ''B'' of table
-    ''TEST'' has been already set to ''none'''
+- null
+- 'Failed to execute SQL statement: NULL declaration for column ''B'' of table ''TEST''
+  has been already set to ''none'''
 ...
 box.execute("CREATE TABLE test (a int, b int NULL, c int, PRIMARY KEY(a, b, c))")
 ---
-- error: Primary index of space 'TEST' can not contain nullable parts
+- null
+- Primary index of space 'TEST' can not contain nullable parts
 ...
 -- Several NOT NULL REPLACE constraints work
 --
diff --git a/test/sql/persistency.result b/test/sql/persistency.result
index fcb5d23..f8f992c 100644
--- a/test/sql/persistency.result
+++ b/test/sql/persistency.result
@@ -31,7 +31,8 @@ box.execute("INSERT INTO foobar VALUES (1000, 'foobar')")
 ...
 box.execute("INSERT INTO foobar VALUES (1, 'duplicate')")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
 ...
 -- simple select
 box.execute("SELECT bar, foo, 42, 'awesome' FROM foobar")
@@ -369,7 +370,8 @@ box.execute("SELECT \"name\", \"opts\" FROM \"_trigger\"");
 -- ... functional
 box.execute("INSERT INTO foobar VALUES ('foobar trigger test', 8888)")
 ---
-- error: 'Type mismatch: can not convert foobar trigger test to integer'
+- null
+- 'Type mismatch: can not convert foobar trigger test to integer'
 ...
 box.execute("SELECT * FROM barfoo WHERE foo = 9999");
 ---
@@ -400,7 +402,8 @@ box.execute("DROP TRIGGER tfoobar")
 -- Should error
 box.execute("DROP TRIGGER tfoobar")
 ---
-- error: Trigger 'TFOOBAR' doesn't exist
+- null
+- Trigger 'TFOOBAR' doesn't exist
 ...
 -- Should be empty
 box.execute("SELECT \"name\", \"opts\" FROM \"_trigger\"")
@@ -415,7 +418,8 @@ box.execute("SELECT \"name\", \"opts\" FROM \"_trigger\"")
 -- prove barfoo2 still exists
 box.execute("INSERT INTO barfoo VALUES ('xfoo', 1)")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
 ...
 box.execute("SELECT * FROM barfoo")
 ---
diff --git a/test/sql/row-count.result b/test/sql/row-count.result
index ed7e319..fb96e21 100644
--- a/test/sql/row-count.result
+++ b/test/sql/row-count.result
@@ -272,7 +272,8 @@ box.execute("SELECT ROW_COUNT();")
 ...
 box.execute("COMMIT;")
 ---
-- error: 'Failed to execute SQL statement: cannot commit - no transaction is active'
+- null
+- 'Failed to execute SQL statement: cannot commit - no transaction is active'
 ...
 box.execute("SELECT ROW_COUNT();")
 ---
diff --git a/test/sql/savepoints.result b/test/sql/savepoints.result
index d20e0ed..7895717 100644
--- a/test/sql/savepoints.result
+++ b/test/sql/savepoints.result
@@ -14,15 +14,18 @@ box.execute('pragma sql_default_engine=\''..engine..'\'')
 --
 box.execute('SAVEPOINT t1;');
 ---
-- error: No active transaction
+- null
+- No active transaction
 ...
 box.execute('RELEASE SAVEPOINT t1;');
 ---
-- error: No active transaction
+- null
+- No active transaction
 ...
 box.execute('ROLLBACK TO SAVEPOINT t1;');
 ---
-- error: No active transaction
+- null
+- No active transaction
 ...
 box.begin() box.execute('SAVEPOINT t1;') box.execute('RELEASE SAVEPOINT t1;') box.commit();
 ---
@@ -61,13 +64,16 @@ release_sv_fail = function()
     box.execute('SAVEPOINT t2;')
     box.execute('RELEASE SAVEPOINT t2;')
     box.execute('RELEASE SAVEPOINT t1;')
-    box.execute('ROLLBACK TO t1;')
+    local _, err = box.execute('ROLLBACK TO t1;')
+    if err ~= nil then
+        return err
+    end
 end;
 ---
 ...
 release_sv_fail();
 ---
-- error: 'Can not rollback to savepoint: the savepoint does not exist'
+- 'Can not rollback to savepoint: the savepoint does not exist'
 ...
 box.commit();
 ---
diff --git a/test/sql/savepoints.test.lua b/test/sql/savepoints.test.lua
index b4c6fee..d96b046 100644
--- a/test/sql/savepoints.test.lua
+++ b/test/sql/savepoints.test.lua
@@ -37,7 +37,10 @@ release_sv_fail = function()
     box.execute('SAVEPOINT t2;')
     box.execute('RELEASE SAVEPOINT t2;')
     box.execute('RELEASE SAVEPOINT t1;')
-    box.execute('ROLLBACK TO t1;')
+    local _, err = box.execute('ROLLBACK TO t1;')
+    if err ~= nil then
+        return err
+    end
 end;
 release_sv_fail();
 box.commit();
diff --git a/test/sql/transition.result b/test/sql/transition.result
index e779474..9738092 100644
--- a/test/sql/transition.result
+++ b/test/sql/transition.result
@@ -28,7 +28,8 @@ box.execute("INSERT INTO foobar VALUES (1000, 'foobar')")
 ...
 box.execute("INSERT INTO foobar VALUES (1, 'duplicate')")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_FOOBAR_1' in space 'FOOBAR'
 ...
 -- simple select
 box.execute("SELECT bar, foo, 42, 'awesome' FROM foobar")
@@ -311,7 +312,8 @@ box.execute("INSERT INTO barfoo VALUES ('foobar', 1000)")
 -- prove barfoo2 was created
 box.execute("INSERT INTO barfoo VALUES ('xfoo', 1)")
 ---
-- error: Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
+- null
+- Duplicate key exists in unique index 'pk_unnamed_BARFOO_1' in space 'BARFOO'
 ...
 box.execute("SELECT foo, bar FROM barfoo")
 ---
@@ -383,8 +385,8 @@ box.execute("DROP TABLE barfoo")
 -- attempt to create a table lacking PRIMARY KEY
 box.execute("CREATE TABLE without_rowid_lacking_primary_key(x SCALAR)")
 ---
-- error: 'Failed to create space ''WITHOUT_ROWID_LACKING_PRIMARY_KEY'': PRIMARY KEY
-    missing'
+- null
+- 'Failed to create space ''WITHOUT_ROWID_LACKING_PRIMARY_KEY'': PRIMARY KEY missing'
 ...
 -- create a table with implicit indices (used to SEGFAULT)
 box.execute("CREATE TABLE implicit_indices(a INT PRIMARY KEY,b INT,c INT,d TEXT UNIQUE)")
diff --git a/test/sql/transitive-transactions.result b/test/sql/transitive-transactions.result
index ee9b421..29c7316 100644
--- a/test/sql/transitive-transactions.result
+++ b/test/sql/transitive-transactions.result
@@ -39,13 +39,16 @@ box.execute('CREATE TABLE child(id INT PRIMARY KEY, x INT REFERENCES parent(y) D
 fk_violation_1 = function()
     box.begin()
     box.execute('INSERT INTO child VALUES (1, 1);')
-    box.execute('COMMIT;')
+    local _, err = box.execute('COMMIT;')
+    if err ~= nil then
+        return err
+    end
 end;
 ---
 ...
 fk_violation_1();
 ---
-- error: 'Can not commit transaction: deferred foreign keys violations are not resolved'
+- 'Can not commit transaction: deferred foreign keys violations are not resolved'
 ...
 box.space.CHILD:select();
 ---
@@ -92,7 +95,10 @@ box.execute('CREATE TABLE child(id INT PRIMARY KEY, x INT REFERENCES parent(y))'
 
 fk_defer = function()
     box.begin()
-    box.execute('INSERT INTO child VALUES (1, 2);')
+    local _, err = box.execute('INSERT INTO child VALUES (1, 2);')
+    if err ~= nil then
+        return err
+    end
     box.execute('INSERT INTO parent VALUES (2, 2);')
     box.commit()
 end;
@@ -100,7 +106,7 @@ end;
 ...
 fk_defer();
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 box.space.CHILD:select();
 ---
diff --git a/test/sql/transitive-transactions.test.lua b/test/sql/transitive-transactions.test.lua
index 54f1273..4633f07 100644
--- a/test/sql/transitive-transactions.test.lua
+++ b/test/sql/transitive-transactions.test.lua
@@ -19,7 +19,10 @@ box.execute('CREATE TABLE child(id INT PRIMARY KEY, x INT REFERENCES parent(y) D
 fk_violation_1 = function()
     box.begin()
     box.execute('INSERT INTO child VALUES (1, 1);')
-    box.execute('COMMIT;')
+    local _, err = box.execute('COMMIT;')
+    if err ~= nil then
+        return err
+    end
 end;
 fk_violation_1();
 box.space.CHILD:select();
@@ -49,7 +52,10 @@ box.execute('CREATE TABLE child(id INT PRIMARY KEY, x INT REFERENCES parent(y))'
 
 fk_defer = function()
     box.begin()
-    box.execute('INSERT INTO child VALUES (1, 2);')
+    local _, err = box.execute('INSERT INTO child VALUES (1, 2);')
+    if err ~= nil then
+        return err
+    end
     box.execute('INSERT INTO parent VALUES (2, 2);')
     box.commit()
 end;
diff --git a/test/sql/triggers.result b/test/sql/triggers.result
index 76e87c8..9dfe981 100644
--- a/test/sql/triggers.result
+++ b/test/sql/triggers.result
@@ -322,7 +322,8 @@ box.execute("INSERT INTO n VALUES (0, '',null);")
 ...
 box.execute("UPDATE m SET s1 = 'The Rain In Spain';")
 ---
-- error: A multi-statement transaction can not use multiple storage engines
+- null
+- A multi-statement transaction can not use multiple storage engines
 ...
 -- ANALYZE banned in gh-4069
 -- box.sql.execute("ANALYZE m;")
@@ -365,7 +366,8 @@ box.execute("INSERT INTO n VALUES (0, '',null);")
 ...
 box.execute("UPDATE m SET s1 = 'The Rain In Spain';")
 ---
-- error: A multi-statement transaction can not use multiple storage engines
+- null
+- A multi-statement transaction can not use multiple storage engines
 ...
 -- ANALYZE banned in gh-4069
 -- box.sql.execute("ANALYZE n;")
@@ -408,7 +410,8 @@ box.execute("INSERT INTO test VALUES (1)")
 ...
 box.execute("SELECT * FROM test2")
 ---
-- error: A multi-statement transaction can not use multiple storage engines
+- null
+- A multi-statement transaction can not use multiple storage engines
 ...
 box.execute("ROLLBACK;")
 ---
@@ -483,7 +486,8 @@ space_id = box.space.T1.id
 ...
 box.execute("CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW WHEN new.a = ? BEGIN SELECT 1; END;")
 ---
-- error: bindings are not allowed in DDL
+- null
+- bindings are not allowed in DDL
 ...
 tuple = {"TR1", space_id, {sql = [[CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW WHEN new.a = ? BEGIN SELECT 1; END;]]}}
 ---
@@ -508,8 +512,8 @@ space_id = box.space.T1.id
 ...
 box.execute("CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN ; END;")
 ---
-- error: FOR EACH STATEMENT triggers are not implemented, please supply FOR EACH ROW
-    clause
+- null
+- FOR EACH STATEMENT triggers are not implemented, please supply FOR EACH ROW clause
 ...
 box.execute("DROP TABLE t1;")
 ---
@@ -539,7 +543,8 @@ box.session.su('tester')
 --
 box.execute([[CREATE TRIGGER r1 AFTER INSERT ON t1 FOR EACH ROW BEGIN SELECT 1; END; ]])
 ---
-- error: Space 'T1' does not exist
+- null
+- Space 'T1' does not exist
 ...
 box.session.su('admin')
 ---
diff --git a/test/sql/types.result b/test/sql/types.result
index 780a23d..604f541 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -8,26 +8,28 @@ test_run = env.new()
 --
 box.execute("CREATE TABLE t1 (id PRIMARY KEY);")
 ---
-- error: Keyword 'PRIMARY' is reserved. Please use double quotes if 'PRIMARY' is an
-    identifier.
+- null
+- Keyword 'PRIMARY' is reserved. Please use double quotes if 'PRIMARY' is an identifier.
 ...
 box.execute("CREATE TABLE t1 (a, id INT PRIMARY KEY);")
 ---
-- error: Syntax error near ','
+- null
+- Syntax error near ','
 ...
 box.execute("CREATE TABLE t1 (id PRIMARY KEY, a INT);")
 ---
-- error: Keyword 'PRIMARY' is reserved. Please use double quotes if 'PRIMARY' is an
-    identifier.
+- null
+- Keyword 'PRIMARY' is reserved. Please use double quotes if 'PRIMARY' is an identifier.
 ...
 box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a);")
 ---
-- error: Syntax error near ')'
+- null
+- Syntax error near ')'
 ...
 box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b UNIQUE);")
 ---
-- error: Keyword 'UNIQUE' is reserved. Please use double quotes if 'UNIQUE' is an
-    identifier.
+- null
+- Keyword 'UNIQUE' is reserved. Please use double quotes if 'UNIQUE' is an identifier.
 ...
 -- gh-3104: real type is stored in space format.
 --
@@ -152,33 +154,40 @@ sp:drop()
 --
 box.execute("SELECT 'abc' || 1;")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
 ...
 box.execute("SELECT 'abc' || 1.123;")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got REAL'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got REAL'
 ...
 box.execute("SELECT 1 || 'abc';")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
 ...
 box.execute("SELECT 1.123 || 'abc';")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got REAL'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got REAL'
 ...
 box.execute("SELECt 'a' || 'b' || 1;")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got UNSIGNED'
 ...
 -- What is more, they must be of the same type.
 --
 box.execute("SELECT 'abc' || randomblob(5);")
 ---
-- error: 'Inconsistent types: expected TEXT got BLOB'
+- null
+- 'Inconsistent types: expected TEXT got BLOB'
 ...
 box.execute("SELECT randomblob(5) || 'x';")
 ---
-- error: 'Inconsistent types: expected BLOB got TEXT'
+- null
+- 'Inconsistent types: expected BLOB got TEXT'
 ...
 -- Result of BLOBs concatenation must be BLOB.
 --
@@ -202,15 +211,18 @@ box.execute("INSERT INTO t1 VALUES (randomblob(5));")
 ...
 box.execute("SELECT * FROM t1 WHERE s LIKE 'blob';")
 ---
-- error: 'Inconsistent types: expected TEXT got BLOB'
+- null
+- 'Inconsistent types: expected TEXT got BLOB'
 ...
 box.execute("SELECT * FROM t1 WHERE 'blob' LIKE s;")
 ---
-- error: 'Inconsistent types: expected TEXT got BLOB'
+- null
+- 'Inconsistent types: expected TEXT got BLOB'
 ...
 box.execute("SELECT * FROM t1 WHERE 'blob' LIKE x'0000';")
 ---
-- error: 'Inconsistent types: expected TEXT got BLOB'
+- null
+- 'Inconsistent types: expected TEXT got BLOB'
 ...
 box.execute("SELECT s LIKE NULL FROM t1;")
 ---
@@ -230,11 +242,13 @@ box.execute("INSERT INTO t1 VALUES (1);")
 ...
 box.execute("SELECT * FROM t1 WHERE s LIKE 'int';")
 ---
-- error: 'Inconsistent types: expected TEXT got UNSIGNED'
+- null
+- 'Inconsistent types: expected TEXT got UNSIGNED'
 ...
 box.execute("SELECT * FROM t1 WHERE 'int' LIKE 4;")
 ---
-- error: 'Inconsistent types: expected TEXT got UNSIGNED'
+- null
+- 'Inconsistent types: expected TEXT got UNSIGNED'
 ...
 box.execute("SELECT NULL LIKE s FROM t1;")
 ---
@@ -355,15 +369,18 @@ box.execute("SELECT unknown = true;")
 ...
 box.execute("SELECT 1 = true;")
 ---
-- error: 'Type mismatch: can not convert UNSIGNED to boolean'
+- null
+- 'Type mismatch: can not convert UNSIGNED to boolean'
 ...
 box.execute("SELECT 'abc' = true;")
 ---
-- error: 'Type mismatch: can not convert TEXT to boolean'
+- null
+- 'Type mismatch: can not convert TEXT to boolean'
 ...
 box.execute("SELECT 1.123 > true;")
 ---
-- error: 'Type mismatch: can not convert REAL to boolean'
+- null
+- 'Type mismatch: can not convert REAL to boolean'
 ...
 box.execute("SELECT true IN (1, 'abc', true)")
 ---
@@ -383,31 +400,37 @@ box.execute("SELECT true IN (1, 'abc', false)")
 ...
 box.execute("SELECT 1 LIMIT true;")
 ---
-- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
-    LIMIT clause'
+- null
+- 'Failed to execute SQL statement: Only positive integers are allowed in the LIMIT
+  clause'
 ...
 box.execute("SELECT 1 LIMIT 1 OFFSET true;")
 ---
-- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
-    OFFSET clause'
+- null
+- 'Failed to execute SQL statement: Only positive integers are allowed in the OFFSET
+  clause'
 ...
 box.execute("SELECT 'abc' || true;")
 ---
-- error: 'Inconsistent types: expected TEXT or BLOB got BOOLEAN'
+- null
+- 'Inconsistent types: expected TEXT or BLOB got BOOLEAN'
 ...
 -- Boolean can take part in arithmetic operations.
 --
 box.execute("SELECT true + false;")
 ---
-- error: 'Type mismatch: can not convert false to numeric'
+- null
+- 'Type mismatch: can not convert false to numeric'
 ...
 box.execute("SELECT true * 1;")
 ---
-- error: 'Type mismatch: can not convert true to numeric'
+- null
+- 'Type mismatch: can not convert true to numeric'
 ...
 box.execute("SELECT false / 0;")
 ---
-- error: 'Type mismatch: can not convert false to numeric'
+- null
+- 'Type mismatch: can not convert false to numeric'
 ...
 box.execute("SELECT not true;")
 ---
@@ -419,19 +442,23 @@ box.execute("SELECT not true;")
 ...
 box.execute("SELECT ~true;")
 ---
-- error: 'Type mismatch: can not convert true to integer'
+- null
+- 'Type mismatch: can not convert true to integer'
 ...
 box.execute("SELECT -true;")
 ---
-- error: 'Type mismatch: can not convert true to numeric'
+- null
+- 'Type mismatch: can not convert true to numeric'
 ...
 box.execute("SELECT true << 1;")
 ---
-- error: 'Type mismatch: can not convert true to integer'
+- null
+- 'Type mismatch: can not convert true to integer'
 ...
 box.execute("SELECT true | 1;")
 ---
-- error: 'Type mismatch: can not convert true to integer'
+- null
+- 'Type mismatch: can not convert true to integer'
 ...
 box.execute("SELECT true and false;")
 ---
@@ -553,22 +580,26 @@ box.execute("SELECT b FROM t GROUP BY b LIMIT 1;")
 ...
 box.execute("SELECT b FROM t LIMIT true;")
 ---
-- error: 'Failed to execute SQL statement: Only positive integers are allowed in the
-    LIMIT clause'
+- null
+- 'Failed to execute SQL statement: Only positive integers are allowed in the LIMIT
+  clause'
 ...
 -- Most of aggregates don't accept boolean arguments.
 --
 box.execute("SELECT sum(b) FROM t;")
 ---
-- error: 'Type mismatch: can not convert true to number'
+- null
+- 'Type mismatch: can not convert true to number'
 ...
 box.execute("SELECT avg(b) FROM t;")
 ---
-- error: 'Type mismatch: can not convert true to number'
+- null
+- 'Type mismatch: can not convert true to number'
 ...
 box.execute("SELECT total(b) FROM t;")
 ---
-- error: 'Type mismatch: can not convert true to number'
+- null
+- 'Type mismatch: can not convert true to number'
 ...
 box.execute("SELECT min(b) FROM t;")
 ---
@@ -626,7 +657,8 @@ box.execute("SELECT upper(b) FROM t;")
 ...
 box.execute("SELECT abs(b) FROM t;")
 ---
-- error: 'Inconsistent types: expected number got boolean'
+- null
+- 'Inconsistent types: expected number got boolean'
 ...
 box.execute("SELECT typeof(b) FROM t;")
 ---
@@ -721,7 +753,8 @@ box.execute("ALTER TABLE t ADD CONSTRAINT fk1 FOREIGN KEY (b) REFERENCES parent
 ...
 box.execute("INSERT INTO t VALUES (1, true);")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 box.execute("INSERT INTO parent VALUES (1, true);")
 ---
@@ -744,7 +777,8 @@ box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a BOOLEAN CHECK (a = true));")
 ...
 box.execute("INSERT INTO t1 VALUES (1, false);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a = true'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a = true'
 ...
 box.execute("INSERT INTO t1 VALUES (1, true);")
 ---
@@ -801,7 +835,8 @@ box.execute("SELECT CAST(true AS TEXT);")
 ...
 box.execute("SELECT CAST(true AS NUMBER);")
 ---
-- error: 'Type mismatch: can not convert true to number'
+- null
+- 'Type mismatch: can not convert true to number'
 ...
 box.execute("SELECT CAST(true AS SCALAR);")
 ---
@@ -845,7 +880,8 @@ box.execute("SELECT CAST(0.00000001 AS BOOLEAN);")
 ...
 box.execute("SELECT CAST('abc' AS BOOLEAN);")
 ---
-- error: 'Type mismatch: can not convert abc to boolean'
+- null
+- 'Type mismatch: can not convert abc to boolean'
 ...
 box.execute("SELECT CAST('  TrUe' AS BOOLEAN);")
 ---
@@ -865,11 +901,13 @@ box.execute("SELECT CAST('  falsE    ' AS BOOLEAN);")
 ...
 box.execute("SELECT CAST('  fals' AS BOOLEAN);")
 ---
-- error: 'Type mismatch: can not convert   fals to boolean'
+- null
+- 'Type mismatch: can not convert   fals to boolean'
 ...
 box.execute("SELECT CAST(X'4D6564766564' AS BOOLEAN);")
 ---
-- error: 'Type mismatch: can not convert Medved to boolean'
+- null
+- 'Type mismatch: can not convert Medved to boolean'
 ...
 -- Make sure that SCALAR can handle boolean values.
 --
@@ -895,11 +933,13 @@ box.execute("INSERT INTO t1 VALUES (3, 'abc'), (4, 12.5);")
 ...
 box.execute("SELECT s FROM t1 WHERE s = true;")
 ---
-- error: 'Type mismatch: can not convert TEXT to boolean'
+- null
+- 'Type mismatch: can not convert TEXT to boolean'
 ...
 box.execute("SELECT s FROM t1 WHERE s < true;")
 ---
-- error: 'Type mismatch: can not convert TEXT to boolean'
+- null
+- 'Type mismatch: can not convert TEXT to boolean'
 ...
 box.execute("SELECT s FROM t1 WHERE s IN (true, 1, 'abcd')")
 ---
@@ -924,7 +964,8 @@ box.execute("CREATE TABLE t1 (id INT PRIMARY KEY);")
 ...
 box.execute("INSERT INTO t1 VALUES (true);")
 ---
-- error: 'Type mismatch: can not convert true to integer'
+- null
+- 'Type mismatch: can not convert true to integer'
 ...
 box.space.T1:drop()
 ---
@@ -979,19 +1020,23 @@ box.execute("INSERT INTO tboolean VALUES (TRUE);")
 ...
 box.execute("SELECT * FROM tboolean WHERE s1 = x'44';")
 ---
-- error: 'Type mismatch: can not convert D to boolean'
+- null
+- 'Type mismatch: can not convert D to boolean'
 ...
 box.execute("SELECT * FROM tboolean WHERE s1 = 'abc';")
 ---
-- error: 'Type mismatch: can not convert abc to boolean'
+- null
+- 'Type mismatch: can not convert abc to boolean'
 ...
 box.execute("SELECT * FROM tboolean WHERE s1 = 1;")
 ---
-- error: 'Type mismatch: can not convert UNSIGNED to boolean'
+- null
+- 'Type mismatch: can not convert UNSIGNED to boolean'
 ...
 box.execute("SELECT * FROM tboolean WHERE s1 = 1.123;")
 ---
-- error: 'Type mismatch: can not convert REAL to boolean'
+- null
+- 'Type mismatch: can not convert REAL to boolean'
 ...
 box.space.TBOOLEAN:drop()
 ---
@@ -1268,7 +1313,8 @@ box.execute("SELECT 1 LIMIT 1 OFFSET 18446744073709551614;")
 ...
 box.execute("SELECT CAST('18446744073' || '709551616' AS INTEGER);")
 ---
-- error: 'Type mismatch: can not convert 18446744073709551616 to integer'
+- null
+- 'Type mismatch: can not convert 18446744073709551616 to integer'
 ...
 box.execute("SELECT CAST('18446744073' || '709551615' AS INTEGER);")
 ---
@@ -1320,7 +1366,8 @@ box.execute("SELECT 18446744073709551615 / -9223372036854775808;")
 ...
 box.execute("SELECT 0 - 18446744073709551610;")
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute("CREATE TABLE t (id INT PRIMARY KEY, i INT);")
 ---
@@ -1378,7 +1425,8 @@ box.execute("SELECT i FROM t ORDER BY i;")
 ...
 box.execute("SELECT i FROM t ORDER BY -i;")
 ---
-- error: 'Failed to execute SQL statement: integer is overflowed'
+- null
+- 'Failed to execute SQL statement: integer is overflowed'
 ...
 box.execute("SELECT i FROM t ORDER BY i LIMIT 1;")
 ---
@@ -1569,7 +1617,8 @@ box.execute("ALTER TABLE t ADD CONSTRAINT fk1 FOREIGN KEY (i) REFERENCES parent
 ...
 box.execute("INSERT INTO t VALUES (1, 18446744073709551615);")
 ---
-- error: 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
+- null
+- 'Failed to execute SQL statement: FOREIGN KEY constraint failed'
 ...
 box.execute("INSERT INTO parent VALUES (2, 18446744073709551615);")
 ---
@@ -1595,11 +1644,13 @@ box.execute("CREATE TABLE t1 (id INT PRIMARY KEY, a INT CHECK (a > 1844674407370
 ...
 box.execute("INSERT INTO t1 VALUES (1, 18446744073709551611);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a > 18446744073709551612'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a > 18446744073709551612'
 ...
 box.execute("INSERT INTO t1 VALUES (1, -1);")
 ---
-- error: 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a > 18446744073709551612'
+- null
+- 'Check constraint failed ''CK_CONSTRAINT_1_T1'': a > 18446744073709551612'
 ...
 box.space.T1:drop()
 ---
@@ -1692,7 +1743,8 @@ box.execute("INSERT INTO t1 VALUES (0), (1), (2);")
 ...
 box.execute("INSERT INTO t1 VALUES (-3);")
 ---
-- error: 'Type mismatch: can not convert -3 to unsigned'
+- null
+- 'Type mismatch: can not convert -3 to unsigned'
 ...
 box.execute("SELECT id FROM t1;")
 ---
@@ -1714,7 +1766,8 @@ box.execute("SELECT CAST(123 AS UNSIGNED);")
 ...
 box.execute("SELECT CAST(-123 AS UNSIGNED);")
 ---
-- error: 'Type mismatch: can not convert -123 to unsigned'
+- null
+- 'Type mismatch: can not convert -123 to unsigned'
 ...
 box.execute("SELECT CAST(1.5 AS UNSIGNED);")
 ---
@@ -1726,7 +1779,8 @@ box.execute("SELECT CAST(1.5 AS UNSIGNED);")
 ...
 box.execute("SELECT CAST(-1.5 AS UNSIGNED);")
 ---
-- error: 'Type mismatch: can not convert -1 to unsigned'
+- null
+- 'Type mismatch: can not convert -1 to unsigned'
 ...
 box.execute("SELECT CAST(true AS UNSIGNED);")
 ---
@@ -1746,7 +1800,8 @@ box.execute("SELECT CAST('123' AS UNSIGNED);")
 ...
 box.execute("SELECT CAST('-123' AS UNSIGNED);")
 ---
-- error: 'Type mismatch: can not convert -123 to unsigned'
+- null
+- 'Type mismatch: can not convert -123 to unsigned'
 ...
 box.space.T1:drop()
 ---
diff --git a/test/sql/view.result b/test/sql/view.result
index 4f02032..d845df8 100644
--- a/test/sql/view.result
+++ b/test/sql/view.result
@@ -22,7 +22,8 @@ box.execute("CREATE VIEW v1 AS SELECT a+b FROM t1;");
 -- View can't have any indexes.
 box.execute("CREATE INDEX i1 on v1(a);");
 ---
-- error: 'Can''t create or modify index ''I1'' in space ''V1'': views can not be indexed'
+- null
+- 'Can''t create or modify index ''I1'' in space ''V1'': views can not be indexed'
 ...
 v1 = box.space.V1;
 ---
@@ -78,8 +79,8 @@ box.schema.create_space('view', {view = true})
 -- Space referenced by a view can't be renamed.
 box.execute("ALTER TABLE t1 RENAME TO new_name;")
 ---
-- error: 'Can''t modify space ''T1'': can not rename space which is referenced by
-    view'
+- null
+- 'Can''t modify space ''T1'': can not rename space which is referenced by view'
 ...
 -- View can be created via straight insertion into _space.
 sp = box.schema.create_space('test');
@@ -148,7 +149,8 @@ box.execute("CREATE VIEW v2 AS SELECT * FROM t2;");
 ...
 box.execute("DROP TABLE t2;");
 ---
-- error: 'Can''t drop space ''T2'': other views depend on this space'
+- null
+- 'Can''t drop space ''T2'': other views depend on this space'
 ...
 sp = box.space._space:get{box.space.T2.id};
 ---
@@ -158,7 +160,8 @@ sp = box.space._space:replace(sp);
 ...
 box.execute("DROP TABLE t2;");
 ---
-- error: 'Can''t drop space ''T2'': other views depend on this space'
+- null
+- 'Can''t drop space ''T2'': other views depend on this space'
 ...
 box.execute("DROP VIEW v2;");
 ---
@@ -216,7 +219,8 @@ box.execute("CREATE VIEW bv (wombat) AS VALUES ((SELECT 'k' FROM b));")
 ...
 box.execute("DROP TABLE b;")
 ---
-- error: 'Can''t drop space ''B'': other views depend on this space'
+- null
+- 'Can''t drop space ''B'': other views depend on this space'
 ...
 box.execute("DROP VIEW bv;")
 ---
@@ -240,7 +244,8 @@ box.execute("CREATE VIEW bcv AS SELECT * FROM b WHERE s1 IN (SELECT * FROM c);")
 ...
 box.execute("DROP TABLE c;")
 ---
-- error: 'Can''t drop space ''C'': other views depend on this space'
+- null
+- 'Can''t drop space ''C'': other views depend on this space'
 ...
 box.execute("DROP VIEW bcv;")
 ---
@@ -260,7 +265,8 @@ box.execute("CREATE VIEW bcv(x, y) AS VALUES((SELECT 'k' FROM b), (VALUES((SELEC
 ...
 box.execute("DROP TABLE c;")
 ---
-- error: 'Can''t drop space ''C'': other views depend on this space'
+- null
+- 'Can''t drop space ''C'': other views depend on this space'
 ...
 box.space.BCV:drop()
 ---
@@ -291,7 +297,8 @@ box.execute("CREATE VIEW v2 AS SELECT * FROM t2;")
 test_run:cmd('restart server default')
 box.execute("DROP TABLE t2;")
 ---
-- error: 'Can''t drop space ''T2'': other views depend on this space'
+- null
+- 'Can''t drop space ''T2'': other views depend on this space'
 ...
 box.execute("SELECT * FROM v2;")
 ---





More information about the Tarantool-patches mailing list