From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id CE1C16EC5F; Wed, 4 Aug 2021 11:33:47 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CE1C16EC5F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1628066027; bh=AlO5yZoWmKCAIp2xsKkCn4OQIDo6weR0GpYbaPe6nBk=; h=To:Cc:Date:In-Reply-To:References:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=pNYcIR2Ny/pGoACB24DdVqKeYwrl35kahssPdtSmOBMbo7xQ6ILRm/PePzdn7nWXC jCSh+fr3jtpRHqos4uyshKzDdHahT7Obb9lndIz0jyZ9R5xHppZzHk7BVWIpOcWNQy ATkgMZqvYzIFVTU5yQhnSc2F3oX46yOGEANCrrp4= Received: from smtpng2.i.mail.ru (smtpng2.i.mail.ru [94.100.179.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 6CEEB6E46E for ; Wed, 4 Aug 2021 11:32:49 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 6CEEB6E46E Received: by smtpng2.m.smailru.net with esmtpa (envelope-from ) id 1mBCKW-0004OY-JL; Wed, 04 Aug 2021 11:32:49 +0300 To: kyukhin@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Wed, 4 Aug 2021 11:32:48 +0300 Message-Id: <0b534605699dcfcdd9c2a688f9b03708b2e7b202.1628065890.git.imeevma@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-4EC0790: 10 X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD941C43E597735A9C351B198F4576AC7B2770D7874BA03B4AE182A05F538085040FE7068AEEDD66C6399F7B88CFF83D76D055EE00E284A83615F0B3712441BDC19 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE741A8F2705CF52F55EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637BC9F889FE9D346E88638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D83840B4E13217891B0B5698483B7E0305117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAE9A1BBD95851C5BA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F446042972877693876707352033AC447995A7AD1828451B159A507268D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B66F6A3E018CF4DC80089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C30CE973C7F71088D576E54D4F6F0EEC0F2157B4CFBBDECC89C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF3033054805BDE987699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34C75F910DBB8BE8982D425F19F5C61E98014F830E4AF3FA1B5100C5B7D46F8A53968BC6AF197786B61D7E09C32AA3244C0FB65B17F2AD71635878580398F4909A24AF4FAF06DA24FD729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojeDyvyeZJDJH1d3HteXvn9g== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5DD2822A65108A8B238B7587BC2C303ECE83D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v2 2/3] sql: disallow explicit cast of VARBINARY to number X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Mergen Imeev via Tarantool-patches Reply-To: imeevma@tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" This patch removes explicit cast of VARBINARY values to numeric types. Part of #4470 Closes #4772 Closes #5852 --- src/box/sql/mem.c | 33 ++++--- test/sql-tap/cast.test.lua | 89 +++++++++++++------ ...-4766-wrong-cast-from-blob-to-int.test.lua | 40 --------- test/sql-tap/numcast.test.lua | 18 +--- 4 files changed, 77 insertions(+), 103 deletions(-) delete mode 100755 test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index 8f56cd289..985438663 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -735,9 +735,9 @@ bin_to_uuid(struct Mem *mem) } static inline int -bytes_to_int(struct Mem *mem) +str_to_int(struct Mem *mem) { - assert((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0); + assert(mem->type == MEM_TYPE_STR); bool is_neg; int64_t i; if (sql_atoi64(mem->z, &i, &is_neg, mem->n) != 0) @@ -747,9 +747,9 @@ bytes_to_int(struct Mem *mem) } static inline int -bytes_to_uint(struct Mem *mem) +str_to_uint(struct Mem *mem) { - assert((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0); + assert(mem->type == MEM_TYPE_STR); bool is_neg; int64_t i; if (sql_atoi64(mem->z, &i, &is_neg, mem->n) != 0) @@ -761,9 +761,9 @@ bytes_to_uint(struct Mem *mem) } static inline int -bytes_to_double(struct Mem *mem) +str_to_double(struct Mem *mem) { - assert((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0); + assert(mem->type == MEM_TYPE_STR); double d; if (sqlAtoF(mem->z, &d, mem->n) == 0) return -1; @@ -905,8 +905,8 @@ mem_to_int(struct Mem *mem) assert(mem->type < MEM_TYPE_INVALID); if ((mem->type & (MEM_TYPE_INT | MEM_TYPE_UINT)) != 0) return 0; - if ((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0) - return bytes_to_int(mem); + if (mem->type == MEM_TYPE_STR) + return str_to_int(mem); if (mem->type == MEM_TYPE_DOUBLE) return double_to_int(mem); return -1; @@ -919,7 +919,7 @@ mem_to_int_precise(struct Mem *mem) if ((mem->type & (MEM_TYPE_INT | MEM_TYPE_UINT)) != 0) return 0; if (mem->type == MEM_TYPE_STR) - return bytes_to_int(mem); + return str_to_int(mem); if (mem->type == MEM_TYPE_DOUBLE) return double_to_int_precise(mem); return -1; @@ -934,7 +934,7 @@ mem_to_double(struct Mem *mem) if ((mem->type & (MEM_TYPE_INT | MEM_TYPE_UINT)) != 0) return int_to_double(mem); if (mem->type == MEM_TYPE_STR) - return bytes_to_double(mem); + return str_to_double(mem); return -1; } @@ -944,10 +944,10 @@ mem_to_number(struct Mem *mem) assert(mem->type < MEM_TYPE_INVALID); if (mem_is_num(mem)) return 0; - if ((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0) { - if (bytes_to_int(mem) == 0) + if (mem->type == MEM_TYPE_STR) { + if (str_to_int(mem) == 0) return 0; - return bytes_to_double(mem); + return str_to_double(mem); } return -1; } @@ -1021,8 +1021,7 @@ mem_cast_explicit(struct Mem *mem, enum field_type type) case MEM_TYPE_UINT: return 0; case MEM_TYPE_STR: - case MEM_TYPE_BIN: - return bytes_to_uint(mem); + return str_to_uint(mem); case MEM_TYPE_DOUBLE: return double_to_uint(mem); default: @@ -1158,7 +1157,7 @@ mem_cast_implicit_old(struct Mem *mem, enum field_type type) if (mem->type == MEM_TYPE_DOUBLE) return double_to_uint_precise(mem); if (mem->type == MEM_TYPE_STR) - return bytes_to_uint(mem); + return str_to_uint(mem); return -1; case FIELD_TYPE_STRING: if ((mem->type & (MEM_TYPE_STR | MEM_TYPE_BIN)) != 0) @@ -1182,7 +1181,7 @@ mem_cast_implicit_old(struct Mem *mem, enum field_type type) if ((mem->type & (MEM_TYPE_INT | MEM_TYPE_UINT)) != 0) return 0; if (mem->type == MEM_TYPE_STR) - return bytes_to_int(mem); + return str_to_int(mem); if (mem->type == MEM_TYPE_DOUBLE) return double_to_int_precise(mem); return -1; diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua index 3dc49c38e..997298693 100755 --- a/test/sql-tap/cast.test.lua +++ b/test/sql-tap/cast.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool local test = require("sqltester") -test:plan(91) +test:plan(94) --!./tcltestrunner.lua -- 2005 June 25 @@ -565,23 +565,23 @@ test:do_catchsql_test( -- }) -test:do_execsql_test( +test:do_catchsql_test( "case-1.68", [[ SELECT CAST(x'31' AS NUMBER) ]], { -- - 1.0 + 1, "Type mismatch: can not convert varbinary(x'31') to number" -- }) -test:do_execsql_test( +test:do_catchsql_test( "case-1.69", [[ SELECT typeof(CAST(x'31' AS NUMBER)) ]], { -- - "number" + 1, "Type mismatch: can not convert varbinary(x'31') to number" -- }) @@ -727,49 +727,61 @@ test:do_execsql_test( if true then --test:execsql("PRAGMA encoding")[1][1]=="UTF-8" then - test:do_execsql_test( + test:do_catchsql_test( "cast-3.21", [[ SELECT CAST(x'39323233333732303336383534373734383030' AS integer) ]], { -- - 9223372036854774800LL + 1, "Type mismatch: can not convert ".. + "varbinary(x'39323233333732303336383534373734383030') to integer" -- }) - test:do_execsql_test( + test:do_catchsql_test( "cast-3.22", [[ SELECT CAST(x'393232333337323033363835343737343830302E' AS NUMBER) ]], { -- - 9223372036854774784 + 1, "Type mismatch: can not convert ".. + "varbinary(x'393232333337323033363835343737343830302E') ".. + "to number" -- }) - test:do_execsql_test( + test:do_catchsql_test( "cast-3.24", [[ SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS NUMBER) AS integer) ]], { -- - 9223372036854774800LL + 1, "Type mismatch: can not convert ".. + "varbinary(x'39323233333732303336383534373734383030') to number" -- }) end -test:do_execsql_test( +test:do_catchsql_test( "case-3.25", [[ SELECT CAST(x'31383434363734343037333730393535313631352E' AS NUMBER); - ]], { 1.844674407371e+19 } ) + ]], { + 1, "Type mismatch: can not convert ".. + "varbinary(x'31383434363734343037333730393535313631352E') to number" + }) -test:do_execsql_test( +test:do_catchsql_test( "case-3.26", [[ SELECT CAST(x'3138343436373434303733373039353531363135' AS INT); - ]], { 18446744073709551615LL } ) + ]], { + -- + 1, "Type mismatch: can not convert ".. + "varbinary(x'3138343436373434303733373039353531363135') to integer" + -- + }) test:do_execsql_test( "case-3.31", @@ -863,20 +875,6 @@ test:do_test( -- }) - --- gh-4356: Check that result of blob to number cast if of type --- number. --- -test:do_execsql_test( - "cast-5.1", - [[ - SELECT CAST(x'3138343436373434303733372e33' AS NUMBER) - ]], { - -- - 184467440737.3 - -- - }) - -- gh-4470: Make explicit casts work according to our rules. -- Make sure that explicit cast from BOOLEAN to numeric types throws an error. @@ -977,4 +975,37 @@ test:do_catchsql_test( 1, "Type mismatch: can not convert integer(1) to boolean" }) +-- Make sure that explicit cast from VARBINARY to numeric types throws an error. +test:do_catchsql_test( + "cast-7.1.1", + [[ + SELECT CAST(x'31' AS UNSIGNED); + ]], { + 1, "Type mismatch: can not convert varbinary(x'31') to unsigned" + }) + +test:do_catchsql_test( + "cast-7.1.2", + [[ + SELECT CAST(x'31' AS INTEGER); + ]], { + 1, "Type mismatch: can not convert varbinary(x'31') to integer" + }) + +test:do_catchsql_test( + "cast-7.1.3", + [[ + SELECT CAST(x'31' AS DOUBLE); + ]], { + 1, "Type mismatch: can not convert varbinary(x'31') to double" + }) + +test:do_catchsql_test( + "cast-7.1.4", + [[ + SELECT CAST(x'31' AS NUMBER); + ]], { + 1, "Type mismatch: can not convert varbinary(x'31') to number" + }) + test:finish_test() 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 deleted file mode 100755 index a8cc0e770..000000000 --- a/test/sql-tap/gh-4766-wrong-cast-from-blob-to-int.test.lua +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env tarantool -local 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. --- -local 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 string('0000000000000000000000000" .. - "0000000000000000000000000000000000000000000000000000000000000000000" .. - "000000000000000000000000000000000000...) to integer" - }) - -test:finish_test() diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua index 20aea3c4b..802fe712c 100755 --- a/test/sql-tap/numcast.test.lua +++ b/test/sql-tap/numcast.test.lua @@ -1,6 +1,6 @@ #!/usr/bin/env tarantool local test = require("sqltester") -test:plan(32) +test:plan(30) --!./tcltestrunner.lua -- 2013 March 20 @@ -149,22 +149,6 @@ test:do_execsql_test( -- gh-4233: Make sure that NUMBER can contain UNSIGNED, INTEGER -- and DOUBLE and is not automatically converted to DOUBLE. -- -test:do_execsql_test( - "numcast-3.1", - [[ - SELECT CAST(x'3131313131313131313131313131313131313131' AS NUMBER); - ]], { - 11111111111111111111ULL - }) - -test:do_execsql_test( - "numcast-3.2", - [[ - SELECT CAST(x'31313131313131313131313131313131313131312E' AS NUMBER); - ]], { - 11111111111111110656 - }) - test:do_execsql_test( "numcast-3.3", [[ -- 2.25.1