1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00

MCOL-5708 Calculate precision and scale for constant decimal.

This patch calculates precision and scale for constant decimal
value for SUM aggregation function.
This commit is contained in:
Denis Khalikov 2024-06-11 14:47:24 +00:00
parent e5722b0f02
commit ccb7ba5914
5 changed files with 90 additions and 2 deletions

View File

@ -66,6 +66,41 @@ int128_t TypeAttributesStd::decimal128FromString(const utils::NullString& value,
return decimal128FromString(value.unsafeStringRef(), saturate);
}
// SQL parser checks that given `value` is in a valid format.
// The first symbol can be `-`. The `value` can contain `.` symbol.
void decimalPrecisionAndScale(const utils::NullString& value, int& precision, int& scale)
{
if (value.isNull())
{
scale = 0;
precision = -1;
return;
}
const auto strValue = value.unsafeStringRef();
if (strValue.empty())
{
scale = 0;
precision = -1;
return;
}
const int len = strValue.size();
const auto dotIndex = strValue.find('.');
const int minExists = strValue.front() == '-' ? 1 : 0;
if (dotIndex == std::string::npos)
{
scale = 0;
precision = len - minExists;
}
else
{
scale = len - dotIndex - 1;
precision = len - 1 - minExists;
}
}
const string& TypeHandlerSInt8::name() const
{
static const string xname = "TINYINT";

View File

@ -125,6 +125,8 @@ struct WidthToSIntegralType<16> : _WidthToSIntegralType<16, int128_t>
{
};
void decimalPrecisionAndScale(const utils::NullString& value, int &precision, int &scale);
// XXX: It is assumed here that ALL TYPES have width, scale and precision.
// XXX: And then some of them have the type tag itself.
// XXX: But, all types have type tag, some need explicit width (decimals, for example)

View File

@ -0,0 +1,17 @@
DROP DATABASE IF EXISTS mcol_5708;
CREATE DATABASE mcol_5708;
USE mcol_5708;
CREATE TABLE test (
`f_int` int(10) unsigned NOT NULL DEFAULT 0,
`f_dec14x2` decimal(14,2) NOT NULL DEFAULT 0.00,
`f_dec14x4` decimal(14,4) NOT NULL DEFAULT 0.0000
) ENGINE=columnstore DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
insert into test (f_int,f_dec14x4, f_dec14x2) values (1, 0.1, 0.1);
select
f_int, sum(f_dec14x2), sum(f_dec14x4),
sum(-200.000001), sum(0), sum(0.0), sum(11.000011), sum(12e-4), sum(1e+4),
sum(-0.0), sum(-1 - 1.1), sum(--12), sum(+20), sum(13)
from test group by 1;
f_int sum(f_dec14x2) sum(f_dec14x4) sum(-200.000001) sum(0) sum(0.0) sum(11.000011) sum(12e-4) sum(1e+4) sum(-0.0) sum(-1 - 1.1) sum(--12) sum(+20) sum(13)
1 0.10 0.1000 -200.000001 0 0.0 11.000011 0.0012 10000 0.0 -2.1 12 20 13
DROP DATABASE mcol_5708;

View File

@ -0,0 +1,31 @@
#
# MCOL-5708
#
--source ../include/have_columnstore.inc
--disable_warnings
DROP DATABASE IF EXISTS mcol_5708;
--enable_warnings
CREATE DATABASE mcol_5708;
USE mcol_5708;
CREATE TABLE test (
`f_int` int(10) unsigned NOT NULL DEFAULT 0,
`f_dec14x2` decimal(14,2) NOT NULL DEFAULT 0.00,
`f_dec14x4` decimal(14,4) NOT NULL DEFAULT 0.0000
) ENGINE=columnstore DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;
insert into test (f_int,f_dec14x4, f_dec14x2) values (1, 0.1, 0.1);
select
f_int, sum(f_dec14x2), sum(f_dec14x4),
sum(-200.000001), sum(0), sum(0.0), sum(11.000011), sum(12e-4), sum(1e+4),
sum(-0.0), sum(-1 - 1.1), sum(--12), sum(+20), sum(13)
from test group by 1;
--disable_warnings
DROP DATABASE mcol_5708;
--enable_warnings

View File

@ -3702,10 +3702,13 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
auto width = fRow.getColumnWidth(colOut);
if (width == datatypes::MAXDECIMALWIDTH)
{
int precision, scale;
// MCOL-5708 Calculate precision and scale based on the given value.
datatypes::decimalPrecisionAndScale(aggData.fConstValue, precision, scale);
datatypes::TypeHolderStd colType;
colType.colWidth = width;
colType.precision = fRow.getPrecision(i);
colType.scale = fRow.getScale(i);
colType.precision = precision;
colType.scale = scale;
colType.colDataType = colDataType;
int128_t constValue = colType.decimal128FromString(aggData.fConstValue);
int128_t sum;