diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index f908e9cedd1d4b442ab7019934000bdc407711b3..c556b9815e71709782652c7228eb0c869f4dfd74 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -467,14 +467,21 @@ sql_atoi64(const char *z, int64_t *val, bool *is_neg, int length)
 	if (*z == '-')
 		*is_neg = true;
 
+	/*
+	 * BLOB data may not end with '\0'. Because of this, the
+	 * strtoll() and strtoull() functions may return an
+	 * incorrect result. To fix this, let's copy the value for
+	 * decoding into static memory and add '\0' to it.
+	 */
+	if (length > SMALL_STATIC_SIZE - 1)
+		return -1;
+	const char *str_value = tt_cstr(z, length);
 	char *end = NULL;
 	errno = 0;
-	if (*z == '-') {
-		*is_neg = true;
-		*val = strtoll(z, &end, 10);
+	if (*is_neg) {
+		*val = strtoll(str_value, &end, 10);
 	} else {
-		*is_neg = false;
-		uint64_t u_val = strtoull(z, &end, 10);
+		uint64_t u_val = strtoull(str_value, &end, 10);
 		*val = u_val;
 	}
 	/* Overflow and underflow errors. */
diff --git a/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua b/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua
new file mode 100755
index 0000000000000000000000000000000000000000..929870d27789adbdef07697400c3e34ceb2f9b7e
--- /dev/null
+++ b/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua
@@ -0,0 +1,45 @@
+#!/usr/bin/env tarantool
+test = require("sqltester")
+test:plan(3)
+
+--
+-- Make sure that a blob as part of a tuple can be cast to NUMBER,
+-- INTEGER and UNSIGNED. Prior to this patch, an error could
+-- appear due to the absence of '\0' at the end of the BLOB.
+--
+test:do_execsql_test(
+    "gh-4766-1",
+    [[
+        CREATE TABLE t1 (a VARBINARY PRIMARY KEY);
+        INSERT INTO t1 VALUES (X'33'), (X'372020202020');
+        SELECT a, CAST(a AS NUMBER), CAST(a AS INTEGER), CAST(a AS UNSIGNED) FROM t1;
+    ]], {
+        '3', 3, 3, 3, '7     ', 7, 7, 7
+    })
+
+--
+-- Make sure that BLOB longer than 12287 bytes cannot be cast to
+-- INTEGER.
+--
+long_str = string.rep('0', 12284)
+test:do_execsql_test(
+    "gh-4766-2",
+    "SELECT CAST('" .. long_str .. "123'" .. " AS INTEGER);", {
+        123
+    })
+
+
+test:do_catchsql_test(
+    "gh-4766-3",
+    "SELECT CAST('" .. long_str .. "1234'" .. " AS INTEGER);", {
+        1, "Type mismatch: can not convert 000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "0000000000000000000000000000000000000000000000000000000000000000000" ..
+        "000000000000000000000000000000000000000000000"
+    })
+
+test:finish_test()