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 EDA626EC55; Wed, 21 Jul 2021 18:07:02 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org EDA626EC55 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1626880023; 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=y+0MOtPk3bVQk2DiLwZMPJ0bslUc/zw0zvgMS1wb0wQjlWbpnT7ZHRlNqryG94l/2 0Uyv9XygAnt0BCAaR3FmWPvipcuMwuhij+lVWVsQInV72Tleo5ShHHWAO7GMlVN2e7 oUPJf81cKZc5fqw8cEx94CSQsxZGfpoK39tktOds= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (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 CE2C96EC55 for ; Wed, 21 Jul 2021 18:07:01 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CE2C96EC55 Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1m6DoL-0003VB-6x; Wed, 21 Jul 2021 18:07:01 +0300 To: v.shpilevoy@tarantool.org Cc: tarantool-patches@dev.tarantool.org Date: Wed, 21 Jul 2021 18:07:00 +0300 Message-Id: <1a255e29a58457eb9046cd1cd9940f2be1acc4e6.1626879974.git.imeevma@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD941C43E597735A9C36A98DBA789EBB6AEFB5A483DCE5E7579182A05F5380850403C5617AFC3710EDC0C9824BEE7DABCE60A6F55EB3AE937D16E06568DB585C9B2 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE720512D700D096E85EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F790063721F819F5952827038638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D869ED20C4FB8305D580E9C1D40F4E0D37117882F4460429724CE54428C33FAD305F5C1EE8F4F765FC1BE95B8C87527B4BA471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F4460429728776938767073520B28585415E75ADA96FD1C55BDD38FC3FD2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B62CFFCC7B69C47339089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975C16CF367659D795C0215F0AF86F7EE86A3A0EE29C4BD7C7559C2B6934AE262D3EE7EAB7254005DCEDD39702B95798B1671E0A4E2319210D9B64D260DF9561598F01A9E91200F654B0AEA200A0D3D80EA68E8E86DC7131B365E7726E8460B7C23C X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34F38194B2C99DC128DDFA663CD0BA5F5654071612C973F4FB306803864F4508209B28AEC00DAB2A2A1D7E09C32AA3244CA536CE3EA6D88B9CB63DA8322CA25704F26BFA4C8A6946B8729B2BEF169E0186 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojJX8TSRcb/SjkxFOR6aTTAA== X-Mailru-Sender: 689FA8AB762F7393C37E3C1AEC41BA5D0866432BDC1604FDA31010C727277F6883D72C36FC87018B9F80AB2734326CD2FB559BB5D741EB96352A0ABBE4FDA4210A04DAD6CC59E33667EA787935ED9F1B 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