[Tarantool-patches] [PATCH v1 1/2] sql: show varbinary in type mismatch error

imeevma at tarantool.org imeevma at tarantool.org
Thu Jun 24 13:30:32 MSK 2021


Currently, the word "varbinary" is printed instead of the value in the
description of the type mismatch error. This is due to the problem of
outputting binary values. However, this sometimes leads to confusion
because in most other cases the value is printed. After this patch,
instead of the word "varbinary", the actual value will be output in
hexadecimal format in the description of the type mismatch error.

Follow up #4356
---
 src/box/sql/mem.c                             | 16 ++++++-
 test/sql-tap/cast.test.lua                    |  4 +-
 test/sql-tap/func.test.lua                    |  8 ++--
 .../gh-5913-segfault-on-select-uuid.test.lua  |  4 +-
 test/sql-tap/sql-errors.test.lua              | 42 +++++++++++++++----
 test/sql-tap/tkt-80e031a00f.test.lua          |  4 +-
 test/sql-tap/uuid.test.lua                    |  4 +-
 test/sql/types.result                         | 28 ++++++-------
 8 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
index 6f3bf52e5..c89c31fdc 100644
--- a/src/box/sql/mem.c
+++ b/src/box/sql/mem.c
@@ -86,8 +86,20 @@ mem_str(const struct Mem *mem)
 	case MEM_TYPE_DOUBLE:
 		sql_snprintf(BUF_SIZE, &buf[0], "%!.15g", mem->u.r);
 		return tt_sprintf("%s", buf);
-	case MEM_TYPE_BIN:
-		return "varbinary";
+	case MEM_TYPE_BIN: {
+		uint32_t svp = region_used(&fiber()->gc);
+		char *str = region_alloc(&fiber()->gc, mem->n * 2 + 1);
+		for (int i = 0; i < mem->n; ++i) {
+			int n = (mem->z[i] & 0xF0) >> 4;
+			str[2 * i] = n < 10 ? ('0' + n) : ('A' + n - 10);
+			n = (mem->z[i] & 0x0F);
+			str[2 * i + 1] = n < 10 ? ('0' + n) : ('A' + n - 10);
+		}
+		str[2 * mem->n] = '\0';
+		const char *res = tt_sprintf("x'%s'", str);
+		region_truncate(&fiber()->gc, svp);
+		return res;
+	}
 	case MEM_TYPE_MAP:
 	case MEM_TYPE_ARRAY:
 		return mp_str(mem->z);
diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
index 7de4b79df..4d098307c 100755
--- a/test/sql-tap/cast.test.lua
+++ b/test/sql-tap/cast.test.lua
@@ -70,7 +70,7 @@ test:do_catchsql_test(
         SELECT CAST(x'616263' AS NUMBER)
     ]], {
         -- <cast-1.5>
-        1, 'Type mismatch: can not convert varbinary to number'
+        1, "Type mismatch: can not convert x'616263' to number"
         -- </cast-1.5>
     })
 
@@ -100,7 +100,7 @@ test:do_catchsql_test(
         SELECT CAST(x'616263' AS integer)
     ]], {
         -- <cast-1.9>
-        1, 'Type mismatch: can not convert varbinary to integer'
+        1, "Type mismatch: can not convert x'616263' to integer"
         -- </cast-1.9>
     })
 
diff --git a/test/sql-tap/func.test.lua b/test/sql-tap/func.test.lua
index 5e259f7ef..ae6bc9ddd 100755
--- a/test/sql-tap/func.test.lua
+++ b/test/sql-tap/func.test.lua
@@ -2931,7 +2931,7 @@ test:do_catchsql_test(
         SELECT ROUND(X'FF')
     ]], {
         -- <func-76.1>
-        1, "Type mismatch: can not convert varbinary to numeric"
+        1, "Type mismatch: can not convert x'FF' to numeric"
         -- </func-76.1>
     })
 
@@ -2941,7 +2941,7 @@ test:do_catchsql_test(
         SELECT RANDOMBLOB(X'FF')
     ]], {
         -- <func-76.2>
-        1, "Type mismatch: can not convert varbinary to numeric"
+        1, "Type mismatch: can not convert x'FF' to numeric"
         -- </func-76.2>
     })
 
@@ -2951,7 +2951,7 @@ test:do_catchsql_test(
         SELECT SOUNDEX(X'FF')
     ]], {
         -- <func-76.3>
-        1, "Type mismatch: can not convert varbinary to text"
+        1, "Type mismatch: can not convert x'FF' to text"
         -- </func-76.3>
     })
 
@@ -2961,7 +2961,7 @@ test:do_catchsql_test(
         SELECT SUM(X'FF')
     ]], {
         -- <func-76.4>
-        1, "Type mismatch: can not convert varbinary to number"
+        1, "Type mismatch: can not convert x'FF' to number"
         -- </func-76.4>
     })
 
diff --git a/test/sql-tap/gh-5913-segfault-on-select-uuid.test.lua b/test/sql-tap/gh-5913-segfault-on-select-uuid.test.lua
index 7dcebe5d3..59a76000a 100755
--- a/test/sql-tap/gh-5913-segfault-on-select-uuid.test.lua
+++ b/test/sql-tap/gh-5913-segfault-on-select-uuid.test.lua
@@ -40,7 +40,7 @@ test:do_catchsql_test(
     [[
         INSERT INTO t1 SELECT i, NULL, d FROM t;
     ]], {
-        1, "Type mismatch: can not convert varbinary to decimal"
+        1, "Type mismatch: can not convert x'C70501030111111C' to decimal"
     })
 
 --
@@ -77,7 +77,7 @@ test:do_catchsql_test(
     [[
         UPDATE td SET d = d;
     ]], {
-        1, "Type mismatch: can not convert varbinary to decimal"
+        1, "Type mismatch: can not convert x'C70501030111111C' to decimal"
     })
 
 test:finish_test()
diff --git a/test/sql-tap/sql-errors.test.lua b/test/sql-tap/sql-errors.test.lua
index 469193a2b..25e14fb93 100755
--- a/test/sql-tap/sql-errors.test.lua
+++ b/test/sql-tap/sql-errors.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 local test = require("sqltester")
-test:plan(72)
+test:plan(74)
 
 test:execsql([[
 	CREATE TABLE t0 (i INT PRIMARY KEY, a INT);
@@ -687,7 +687,7 @@ test:do_catchsql_test(
 		-- </sql-errors-1.63>
 	})
 
--- gh-4356: Make sure that 'varbinary' is printed instead of the
+-- gh-4356: Make sure that varbinary is printed in hex instead of the
 -- binary data itself (since binary data can contain unprintable symbols).
 --
 test:do_catchsql_test(
@@ -696,7 +696,7 @@ test:do_catchsql_test(
 		SELECT X'ff' + 1;
 	]], {
 		-- <sql-errors-2.1>
-		1, "Type mismatch: can not convert varbinary to numeric"
+		1, "Type mismatch: can not convert x'FF' to numeric"
 		-- </sql-errors-2.1>
 	})
 
@@ -706,7 +706,7 @@ test:do_catchsql_test(
 		SELECT X'ff' - 1;
 	]], {
 		-- <sql-errors-2.2>
-		1, "Type mismatch: can not convert varbinary to numeric"
+		1, "Type mismatch: can not convert x'FF' to numeric"
 		-- </sql-errors-2.2>
 	})
 
@@ -716,7 +716,7 @@ test:do_catchsql_test(
 		SELECT X'ff' * 1;
 	]], {
 		-- <sql-errors-2.3>
-		1, "Type mismatch: can not convert varbinary to numeric"
+		1, "Type mismatch: can not convert x'FF' to numeric"
 		-- </sql-errors-2.3>
 	})
 
@@ -726,7 +726,7 @@ test:do_catchsql_test(
 		SELECT X'ff' / 1;
 	]], {
 		-- <sql-errors-2.4>
-		1, "Type mismatch: can not convert varbinary to numeric"
+		1, "Type mismatch: can not convert x'FF' to numeric"
 		-- </sql-errors-2.4>
 	})
 
@@ -736,7 +736,7 @@ test:do_catchsql_test(
 		SELECT X'ff' AND true;
 	]], {
 		-- <sql-errors-2.5>
-		1, "Type mismatch: can not convert varbinary to boolean"
+		1, "Type mismatch: can not convert x'FF' to boolean"
 		-- </sql-errors-2.5>
 	})
 
@@ -746,7 +746,7 @@ test:do_catchsql_test(
 		SELECT X'ff' OR false;
 	]], {
 		-- <sql-errors-2.6>
-		1, "Type mismatch: can not convert varbinary to boolean"
+		1, "Type mismatch: can not convert x'FF' to boolean"
 		-- </sql-errors-2.6>
 	})
 
@@ -756,7 +756,7 @@ test:do_catchsql_test(
 		SELECT false OR X'ff';
 	]], {
 		-- <sql-errors-2.7>
-		1, "Type mismatch: can not convert varbinary to boolean"
+		1, "Type mismatch: can not convert x'FF' to boolean"
 		-- </sql-errors-2.7>
 	})
 
@@ -780,4 +780,28 @@ test:do_catchsql_test(
 		-- </sql-errors-2.9>
 	})
 
+test:do_catchsql_test(
+	"sql-errors-2.10",
+	[[
+		SELECT CAST(x'F1' AS UNSIGNED);
+	]], {
+		-- <sql-errors-2.1>
+		1, "Type mismatch: can not convert x'F1' to unsigned"
+		-- </sql-errors-2.1>
+	})
+
+test:execsql('CREATE TABLE test (i INT PRIMARY KEY);')
+
+test:do_catchsql_test(
+	"sql-errors-2.12",
+	[[
+		INSERT INTO test VALUES(x'F1');
+	]], {
+		-- <sql-errors-2.1>
+		1, "Type mismatch: can not convert x'F1' to integer"
+		-- </sql-errors-2.1>
+	})
+
+test:execsql('DROP TABLE test;')
+
 test:finish_test()
diff --git a/test/sql-tap/tkt-80e031a00f.test.lua b/test/sql-tap/tkt-80e031a00f.test.lua
index 82769587b..23ef896c0 100755
--- a/test/sql-tap/tkt-80e031a00f.test.lua
+++ b/test/sql-tap/tkt-80e031a00f.test.lua
@@ -386,7 +386,7 @@ test:do_catchsql_test(
         SELECT x'303132' IN t1
     ]], {
         -- <tkt-80e031a00f.31>
-        1, 'Type mismatch: can not convert varbinary to integer'
+        1, "Type mismatch: can not convert x'303132' to integer"
         -- </tkt-80e031a00f.31>
     })
 
@@ -396,7 +396,7 @@ test:do_catchsql_test(
         SELECT x'303132' NOT IN t1
     ]], {
         -- <tkt-80e031a00f.32>
-        1, 'Type mismatch: can not convert varbinary to integer'
+        1, "Type mismatch: can not convert x'303132' to integer"
         -- </tkt-80e031a00f.32>
     })
 
diff --git a/test/sql-tap/uuid.test.lua b/test/sql-tap/uuid.test.lua
index 77ba06c2d..f19eb4a9c 100755
--- a/test/sql-tap/uuid.test.lua
+++ b/test/sql-tap/uuid.test.lua
@@ -697,7 +697,7 @@ test:do_catchsql_test(
     [[
         SELECT cast(randomblob(10) as UUID) FROM t2 LIMIT 1;
     ]], {
-        1, "Type mismatch: can not convert varbinary to uuid"
+        1, "Type mismatch: can not convert x'819192E578DE3FA24AF3' to uuid"
     })
 
 test:execsql([[
@@ -858,7 +858,7 @@ test:do_catchsql_test(
     [[
         INSERT INTO tsu VALUES ('8_varbinary', randomblob(10));
     ]], {
-        1, "Type mismatch: can not convert varbinary to uuid"
+        1, "Type mismatch: can not convert x'733CA8769291A0FEE366' to uuid"
     })
 
 test:execsql([[
diff --git a/test/sql/types.result b/test/sql/types.result
index 687ca3b15..f9fc606a7 100644
--- a/test/sql/types.result
+++ b/test/sql/types.result
@@ -339,7 +339,7 @@ box.execute("INSERT INTO tboolean VALUES (TRUE);")
 box.execute("SELECT * FROM tboolean WHERE s1 = x'44';")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to boolean'
+- 'Type mismatch: can not convert x''44'' to boolean'
 ...
 box.execute("SELECT * FROM tboolean WHERE s1 = 'abc';")
 ---
@@ -1265,17 +1265,17 @@ box.execute("SELECT * FROM t WHERE v = x'616263'")
 box.execute("SELECT sum(v) FROM t;")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to number'
+- 'Type mismatch: can not convert x''616263'' to number'
 ...
 box.execute("SELECT avg(v) FROM t;")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to number'
+- 'Type mismatch: can not convert x''616263'' to number'
 ...
 box.execute("SELECT total(v) FROM t;")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to number'
+- 'Type mismatch: can not convert x''616263'' to number'
 ...
 box.execute("SELECT min(v) FROM t;")
 ---
@@ -1747,12 +1747,12 @@ box.execute("SELECT CAST('1.123' AS DOUBLE);")
 box.execute("SELECT CAST(x'' AS DOUBLE);")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to double'
+- 'Type mismatch: can not convert x'''' to double'
 ...
 box.execute("SELECT CAST(x'35' AS DOUBLE);")
 ---
 - null
-- 'Type mismatch: can not convert varbinary to double'
+- 'Type mismatch: can not convert x''35'' to double'
 ...
 box.execute("SELECT CAST(CAST(x'35' AS STRING) AS DOUBLE);")
 ---
@@ -2218,7 +2218,7 @@ box.execute([[INSERT INTO ti(i) VALUES ('33');]])
 box.execute([[INSERT INTO ti(i) VALUES (X'3434');]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to integer'
+- 'Type mismatch: can not convert x''3434'' to integer'
 ...
 box.execute([[SELECT * FROM ti;]])
 ---
@@ -2268,7 +2268,7 @@ box.execute([[INSERT INTO td(d) VALUES ('33');]])
 box.execute([[INSERT INTO td(d) VALUES (X'3434');]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to double'
+- 'Type mismatch: can not convert x''3434'' to double'
 ...
 box.execute([[SELECT * FROM td;]])
 ---
@@ -2312,7 +2312,7 @@ box.execute([[INSERT INTO tb(b) VALUES ('33');]])
 box.execute([[INSERT INTO tb(b) VALUES (X'3434');]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to boolean'
+- 'Type mismatch: can not convert x''3434'' to boolean'
 ...
 box.execute([[SELECT * FROM tb;]])
 ---
@@ -2355,7 +2355,7 @@ box.execute([[INSERT INTO tt(t) VALUES ('33');]])
 box.execute([[INSERT INTO tt(t) VALUES (X'3434');]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to string'
+- 'Type mismatch: can not convert x''3434'' to string'
 ...
 box.execute([[SELECT * FROM tt;]])
 ---
@@ -2571,7 +2571,7 @@ box.execute([[UPDATE ti SET i = '33' WHERE a = 1;]])
 box.execute([[UPDATE ti SET i = X'3434' WHERE a = 1;]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to integer'
+- 'Type mismatch: can not convert x''3434'' to integer'
 ...
 box.execute([[SELECT * FROM ti;]])
 ---
@@ -2612,7 +2612,7 @@ box.execute([[UPDATE td SET d = '33' WHERE a = 1;]])
 box.execute([[UPDATE td SET d = X'3434' WHERE a = 1;]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to double'
+- 'Type mismatch: can not convert x''3434'' to double'
 ...
 box.execute([[SELECT * FROM td;]])
 ---
@@ -2650,7 +2650,7 @@ box.execute([[UPDATE tb SET b = '33' WHERE a = 1;]])
 box.execute([[UPDATE tb SET b = X'3434' WHERE a = 1;]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to boolean'
+- 'Type mismatch: can not convert x''3434'' to boolean'
 ...
 box.execute([[SELECT * FROM tb;]])
 ---
@@ -2688,7 +2688,7 @@ box.execute([[UPDATE tt SET t = '33' WHERE a = 1;]])
 box.execute([[UPDATE tt SET t = X'3434' WHERE a = 1;]])
 ---
 - null
-- 'Type mismatch: can not convert varbinary to string'
+- 'Type mismatch: can not convert x''3434'' to string'
 ...
 box.execute([[SELECT * FROM tt;]])
 ---
-- 
2.25.1



More information about the Tarantool-patches mailing list