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 B6B526EC58; Wed, 4 Aug 2021 11:24:35 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org B6B526EC58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1628065475; bh=tk/phue8xYmLWR1Xh1SDy6nrwxKCt1evm3S7ypJWrF0=; h=To:Cc:Date:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=fLATMD+nNa/ASDVLh+cjXvH0XwIQ+UkRYYzfbx1nQ5w6WYLrRzpWmxyaULGuLYdIZ CAHCsH8BOJofrRKORU7XJHxP0topK+JXDpPOwk47w1IX1JpMDJ3aCYwl/CtOGLzTnR ZBurOKvPnel2DiSdQqqt62cgQk8aFcR+pCbY1p/Q= 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 BFCAF6EC58 for ; Wed, 4 Aug 2021 11:24:33 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org BFCAF6EC58 Received: by smtpng2.m.smailru.net with esmtpa (envelope-from ) id 1mBCCW-0008Ue-Hl; Wed, 04 Aug 2021 11:24:33 +0300 To: kyukhin@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Wed, 4 Aug 2021 11:24:32 +0300 Message-Id: <56566984f956da0d7532011b8670c18c92a3facc.1628065405.git.imeevma@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD941C43E597735A9C33D83595CA30D6DC5179D1C9A908C47E5182A05F538085040CB58FEDB667AC4B96F4F6DF60F498EF2206E94AF2B710485A48670D22D55D4C9 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE720512D700D096E85EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063721F819F5952827038638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D853ED1BB61D8C20868091FAB3A7B601F0117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC1F8789D36234D406A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735209647ADFADE5905B1F6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA7E827F84554CEF5019E625A9149C048EE9ECD01F8117BC8BEE2021AF6380DFAD18AA50765F790063735872C767BF85DA227C277FBC8AE2E8BDC0F6C5B2EEF3D0C75ECD9A6C639B01B4E70A05D1297E1BBCB5012B2E24CD356 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C30CE973C7F71088DD65BDC8E92E92FDB5D51BA4326EA0B8A9C2B6934AE262D3EE7EAB7254005DCEDD39702B95798B1671E0A4E2319210D9B64D260DF9561598F01A9E91200F654B0257B9C11E3AC915C8E8E86DC7131B365E7726E8460B7C23C X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34F38194B2C99DC128DDFA663CD0BA5F5654071612C973F4FB306803864F4508209B28AEC00DAB2A2A1D7E09C32AA3244C8D0BBC1B6DED7215D0F29CF83D4BBADB250262A5EE9971B0729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojeDyvyeZJDJEfcr3x+DSuLQ== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5DB13574E7967AEB109BA80C97CEB9C5B983D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v1 1/1] sql: fix cast of small negative DOUBLE to INTEGER 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" Prior to this patch when DOUBLE value that less than 0.0 and greater than -1.0 was cast to INTEGER, it was considered to be negative number though the result was 0. This patch fixes this, so now such DOUBLE value will be properly cast to INTEGER and UNSIGNED. Closes #6225 --- https://github.com/tarantool/tarantool/issues/6225 https://github.com/tarantool/tarantool/tree/imeevma/gh-6225-cast-of-small-negative-double-to-int ...225-cast-of-small-negative-double-to-int.md | 4 ++++ src/box/sql/mem.c | 18 +++++++++--------- test/sql-tap/numcast.test.lua | 14 +++++++++++++- 3 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 changelogs/unreleased/gh-6225-cast-of-small-negative-double-to-int.md diff --git a/changelogs/unreleased/gh-6225-cast-of-small-negative-double-to-int.md b/changelogs/unreleased/gh-6225-cast-of-small-negative-double-to-int.md new file mode 100644 index 000000000..9f5d62231 --- /dev/null +++ b/changelogs/unreleased/gh-6225-cast-of-small-negative-double-to-int.md @@ -0,0 +1,4 @@ +## bugfix/sql + +* Fixed assert on cast of DOUBLE value that greater than -1.0 and less than 0.0 + to INTEGER and UNSIGNED (gh-6255). diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c index e4ce233e0..6b95e41d3 100644 --- a/src/box/sql/mem.c +++ b/src/box/sql/mem.c @@ -787,14 +787,14 @@ double_to_int(struct Mem *mem) { assert(mem->type == MEM_TYPE_DOUBLE); double d = mem->u.r; - if (d < 0 && d >= (double)INT64_MIN) { + if (d <= -1.0 && d >= (double)INT64_MIN) { mem->u.i = (int64_t)d; mem->type = MEM_TYPE_INT; assert(mem->flags == 0); mem->field_type = FIELD_TYPE_INTEGER; return 0; } - if (d >= 0 && d < (double)UINT64_MAX) { + if (d > -1.0 && d < (double)UINT64_MAX) { mem->u.u = (uint64_t)d; mem->type = MEM_TYPE_UINT; assert(mem->flags == 0); @@ -809,14 +809,14 @@ double_to_int_precise(struct Mem *mem) { assert(mem->type == MEM_TYPE_DOUBLE); double d = mem->u.r; - if (d < 0 && d >= (double)INT64_MIN && (double)(int64_t)d == d) { + if (d <= -1.0 && d >= (double)INT64_MIN && (double)(int64_t)d == d) { mem->u.i = (int64_t)d; mem->type = MEM_TYPE_INT; assert(mem->flags == 0); mem->field_type = FIELD_TYPE_INTEGER; return 0; } - if (d >= 0 && d < (double)UINT64_MAX && (double)(uint64_t)d == d) { + if (d > -1.0 && d < (double)UINT64_MAX && (double)(uint64_t)d == d) { mem->u.u = (uint64_t)d; mem->type = MEM_TYPE_UINT; assert(mem->flags == 0); @@ -831,7 +831,7 @@ double_to_uint(struct Mem *mem) { assert(mem->type == MEM_TYPE_DOUBLE); double d = mem->u.r; - if (d >= 0 && d < (double)UINT64_MAX) { + if (d > -1.0 && d < (double)UINT64_MAX) { mem->u.u = (uint64_t)d; mem->type = MEM_TYPE_UINT; assert(mem->flags == 0); @@ -846,7 +846,7 @@ double_to_uint_precise(struct Mem *mem) { assert(mem->type == MEM_TYPE_DOUBLE); double d = mem->u.r; - if (d >= 0 && d < (double)UINT64_MAX && (double)(uint64_t)d == d) { + if (d > -1.0 && d < (double)UINT64_MAX && (double)(uint64_t)d == d) { mem->u.u = (uint64_t)d; mem->type = MEM_TYPE_UINT; assert(mem->flags == 0); @@ -1289,12 +1289,12 @@ mem_get_int(const struct Mem *mem, int64_t *i, bool *is_neg) return sql_atoi64(mem->z, i, is_neg, mem->n); if (mem->type == MEM_TYPE_DOUBLE) { double d = mem->u.r; - if (d < 0 && d >= (double)INT64_MIN) { + if (d <= -1.0 && d >= (double)INT64_MIN) { *i = (int64_t)d; *is_neg = true; return 0; } - if (d >= 0 && d < (double)UINT64_MAX) { + if (d > -1.0 && d < (double)UINT64_MAX) { *i = (int64_t)(uint64_t)d; *is_neg = false; return 0; @@ -1322,7 +1322,7 @@ mem_get_uint(const struct Mem *mem, uint64_t *u) } if (mem->type == MEM_TYPE_DOUBLE) { double d = mem->u.r; - if (d >= 0 && d < (double)UINT64_MAX) { + if (d > -1.0 && d < (double)UINT64_MAX) { *u = (uint64_t)d; return 0; } diff --git a/test/sql-tap/numcast.test.lua b/test/sql-tap/numcast.test.lua index 20aea3c4b..56b11da25 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(33) --!./tcltestrunner.lua -- 2013 March 20 @@ -261,4 +261,16 @@ test:do_catchsql_test( 1, "Type mismatch: can not convert double(-2.5) to unsigned" }) +-- +-- gh-6225: Make sure negative DOUBLE is greater than -1.0 and less than 0.0 can +-- be converted to INTEGER and UNSIGNED. +-- +test:do_execsql_test( + "numcast-5", + [[ + SELECT CAST(-0.999 AS INTEGER), CAST(-0.111 AS UNSIGNED); + ]], { + 0, 0 +}) + test:finish_test() -- 2.25.1