From 1bcf63a436c8e1bacdfd9ef0eb772a9682f43edd Mon Sep 17 00:00:00 2001 From: Akhmad Oripov <96055449+AestheticAkhmad@users.noreply.github.com> Date: Mon, 31 Mar 2025 15:59:40 +0200 Subject: [PATCH] Fix(MCOL-4611): mod loses precision on huge narrow decimal (#3473) --- .../columnstore/bugfixes/mcol_4611.result | 17 +++++++++++ .../columnstore/bugfixes/mcol_4611.test | 28 +++++++++++++++++++ utils/funcexp/func_mod.cpp | 2 +- utils/funcexp/functor_real.h | 2 +- 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 mysql-test/columnstore/bugfixes/mcol_4611.result create mode 100644 mysql-test/columnstore/bugfixes/mcol_4611.test diff --git a/mysql-test/columnstore/bugfixes/mcol_4611.result b/mysql-test/columnstore/bugfixes/mcol_4611.result new file mode 100644 index 000000000..21cd1e0ad --- /dev/null +++ b/mysql-test/columnstore/bugfixes/mcol_4611.result @@ -0,0 +1,17 @@ +DROP DATABASE IF EXISTS mcol_4611; +CREATE DATABASE mcol_4611; +USE mcol_4611; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a DECIMAL(18,0)) ENGINE=ColumnStore; +INSERT INTO t1 VALUES (999999999999999999); +SELECT a MOD 10000 FROM t1; +a MOD 10000 +9999 +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a DECIMAL(18,0)) ENGINE=ColumnStore; +INSERT INTO t1 VALUES (999999999999999999); +SELECT RAND(9999), RAND(a MOD 10000) FROM t1; +RAND(9999) RAND(a MOD 10000) +0.7361292641015065 0.7361292641015065 +DROP TABLE IF EXISTS t1; +DROP DATABASE mcol_4611; diff --git a/mysql-test/columnstore/bugfixes/mcol_4611.test b/mysql-test/columnstore/bugfixes/mcol_4611.test new file mode 100644 index 000000000..f96ee3120 --- /dev/null +++ b/mysql-test/columnstore/bugfixes/mcol_4611.test @@ -0,0 +1,28 @@ +-- source ../include/have_columnstore.inc +--disable_warnings +DROP DATABASE IF EXISTS mcol_4611; +--enable_warnings +CREATE DATABASE mcol_4611; +USE mcol_4611; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a DECIMAL(18,0)) ENGINE=ColumnStore; +INSERT INTO t1 VALUES (999999999999999999); +SELECT a MOD 10000 FROM t1; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (a DECIMAL(18,0)) ENGINE=ColumnStore; +INSERT INTO t1 VALUES (999999999999999999); +SELECT RAND(9999), RAND(a MOD 10000) FROM t1; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--disable_warnings +DROP DATABASE mcol_4611; +--enable_warnings diff --git a/utils/funcexp/func_mod.cpp b/utils/funcexp/func_mod.cpp index 11c542168..a7b99430a 100644 --- a/utils/funcexp/func_mod.cpp +++ b/utils/funcexp/func_mod.cpp @@ -106,7 +106,7 @@ IDB_Decimal Func_mod::getDecimalVal(Row& row, FunctionParm& parm, bool& isNull, } IDB_Decimal d = parm[0]->data()->getDecimalVal(row, isNull); - int64_t value = d.value / pow(10.0, d.scale); + int64_t value = d.value / static_cast(pow(10.0, d.scale)); int lefto = d.value % (int)pow(10.0, d.scale); int64_t mod = (value % div) * pow(10.0, d.scale) + lefto; diff --git a/utils/funcexp/functor_real.h b/utils/funcexp/functor_real.h index a2f0e608d..1c5fdc75d 100644 --- a/utils/funcexp/functor_real.h +++ b/utils/funcexp/functor_real.h @@ -381,7 +381,7 @@ class Func_mod : public Func_Real return static_cast(integralRemainder.toTFloat128() + intAndFract.second); } } - int64_t value = d.value / pow(10.0, d.scale); + int64_t value = d.value / static_cast(pow(10.0, d.scale)); return value % div; } };