From c72edb0de6c1a07dbae2c4f4bd8d35772ec3a480 Mon Sep 17 00:00:00 2001
From: Mergen Imeev <imeevma@gmail.com>
Date: Mon, 4 Oct 2021 11:24:12 +0300
Subject: [PATCH] sql: do not truncate DECIMAL in LIMIT and OFFSET

This patch removes the DECIMAL truncation in LIMIT and OFFSET, because
according to the implicit casting rules, DECIMAL with digits after the
decimal point cannot be implicitly cast to INTEGER.

Closes #6485
---
 .../unreleased/gh-6485-bug-of-decimal.md      |  8 +++++++
 src/box/sql/mem.c                             |  2 +-
 test/sql-tap/gh-6485-bugs-in-decimal.test.lua | 21 ++++++++++++++++++-
 3 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 changelogs/unreleased/gh-6485-bug-of-decimal.md

diff --git a/changelogs/unreleased/gh-6485-bug-of-decimal.md b/changelogs/unreleased/gh-6485-bug-of-decimal.md
new file mode 100644
index 0000000000..bcf023b316
--- /dev/null
+++ b/changelogs/unreleased/gh-6485-bug-of-decimal.md
@@ -0,0 +1,8 @@
+## bugfix/sql
+
+* Fixed truncation of DECIMAL during implicit cast to INTEGER in LIMIT and
+  OFFSET.
+* Fixed truncation of DECIMAL during implicit cast to INTEGER when value is used
+  in an index.
+* Fixed assert on cast of DECIMAL value that greater than -1.0 and less than 0.0
+  to INTEGER (gh-6485).
diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
index bc6f9b35a9..7e94dc8bbb 100644
--- a/src/box/sql/mem.c
+++ b/src/box/sql/mem.c
@@ -1338,7 +1338,7 @@ mem_to_int_precise(struct Mem *mem)
 	if (mem->type == MEM_TYPE_DOUBLE)
 		return double_to_int_precise(mem);
 	if (mem->type == MEM_TYPE_DEC)
-		return dec_to_int(mem);
+		return dec_to_int_precise(mem);
 	return -1;
 }
 
diff --git a/test/sql-tap/gh-6485-bugs-in-decimal.test.lua b/test/sql-tap/gh-6485-bugs-in-decimal.test.lua
index 0b9b2ea0a5..fc2ac963d1 100755
--- a/test/sql-tap/gh-6485-bugs-in-decimal.test.lua
+++ b/test/sql-tap/gh-6485-bugs-in-decimal.test.lua
@@ -1,6 +1,6 @@
 #!/usr/bin/env tarantool
 local test = require("sqltester")
-test:plan(3)
+test:plan(5)
 
 -- Make sure DECIMAL is not truncated when used in an index.
 test:do_execsql_test(
@@ -35,4 +35,23 @@ test:do_execsql_test(
     ]], {
     })
 
+-- Make sure DECIMAL is not truncated when used in LIMIT and OFFSET.
+test:do_catchsql_test(
+    "gh-6485-4",
+    [[
+        SELECT 1 LIMIT CAST(1.5 AS DECIMAL);
+    ]], {
+        1, [[Failed to execute SQL statement: ]]..
+        [[Only positive integers are allowed in the LIMIT clause]]
+    })
+
+test:do_catchsql_test(
+    "gh-6485-5",
+    [[
+        SELECT 1 LIMIT 1 OFFSET CAST(1.5 AS DECIMAL);
+    ]], {
+        1, [[Failed to execute SQL statement: ]]..
+        [[Only positive integers are allowed in the OFFSET clause]]
+    })
+
 test:finish_test()
-- 
GitLab