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 73FE96EC58; Mon, 2 Aug 2021 20:26:28 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 73FE96EC58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1627925188; 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=t/5jtpkmyVTeBAESNe9rSz2pnWS9VYiOvmq38BnQlXMOQMaWp0rqlUx2rfWWAiBWn do/2wwwxu53j1X5RKn0p4ZjELHfgvjXiJPy5fyykdBhbuHLlhSCPYYArcGfa4YdZsD j3iqvfbhBIiF6hMkM7APN4isDKwI40ctBK505T18= Received: from smtp17.mail.ru (smtp17.mail.ru [94.100.176.154]) (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 62BC16F3E0 for ; Mon, 2 Aug 2021 20:25:30 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 62BC16F3E0 Received: by smtp17.mail.ru with esmtpa (envelope-from ) id 1mAbgv-0003CR-KA; Mon, 02 Aug 2021 20:25:30 +0300 To: imun@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Mon, 2 Aug 2021 20:25:29 +0300 Message-Id: <776c13cb0dffcf5b1fce107e89d2ebda4d1dc159.1627925076.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: 4F1203BC0FB41BD941C43E597735A9C366EE405EC28A2001F8302D8429E0DE58182A05F538085040CE469CD68D543E309AC91BEAE7DB997A589CA968AB7221B6D0BAA002E6A996B9 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE741A8F2705CF52F55EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637BC9F889FE9D346E88638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8187762682D897E1A2A64390831800813117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAE9A1BBD95851C5BA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751F28451B159A507268D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE38D4DC57D478E6886B91AC3BD56FC247D8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE364A52DF3AE21010FC0837EA9F3D19764C4224003CC836476EA7A3FFF5B025636E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F7900637870CFFD37CCFDD3AEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C85811CA530B50491D43348B189F39CE5CBC5BF6BD3082BD29C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF03D88DA7F5FEDC25699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34C75F910DBB8BE8982D425F19F5C61E98014F830E4AF3FA1B5100C5B7D46F8A53968BC6AF197786B61D7E09C32AA3244C78E9AE17752F317B83677D408CA11906A90944CA99CF22E3729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2bioj9N286KAyvN6d2gBwkEHoJA== X-Mailru-Sender: 83DC58D0E026EF5214980281B38C45571ED59F68AA3B29A69AC91BEAE7DB997A7962F9E9328436E15105BD0848736F9966FEC6BF5C9C28D97E07721503EA2E00ED97202A5A4E92BF7402F9BA4338D657ED14614B50AE0675 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