1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-4478 MCS now rounds the last digits of an avg() result for wide-DECIMAL argument

This commit is contained in:
Roman Nozdrin
2020-12-30 11:35:51 +00:00
parent cf11e03d4b
commit 5b9689ce55
4 changed files with 40 additions and 23 deletions

View File

@ -2788,7 +2788,7 @@ void RowAggregationUM::calculateAvgColumns()
uint32_t offset = fRow.getOffset(colOut);
uint32_t scale = fRow.getScale(colOut);
// Get multiplied to deliver AVG with the scale closest
// to the expected original scale + 4.
// to the expected original scale + 4.
// There is a counterpart in buildAggregateColumn.
datatypes::Decimal::setScalePrecision4Avg(precision, scale);
int128_t* sumPnt = fRow.getBinaryField_offset<int128_t>(offset);
@ -2800,8 +2800,22 @@ void RowAggregationUM::calculateAvgColumns()
multOp(*sumPnt, datatypes::mcs_pow_10[scaleDiff], sum);
else
sum = *sumPnt;
int128_t avg = sum / cnt;
fRow.setBinaryField_offset(&avg, sizeof(avg), offset);
datatypes::lldiv_t_128 avgAndRem = datatypes::lldiv128(sum, cnt);
// Round the last digit
if (datatypes::abs(avgAndRem.rem) * 2 >= (int128_t)cnt)
{
if (utils::is_negative(avgAndRem.rem))
{
avgAndRem.quot--;
}
else
{
avgAndRem.quot++;
}
}
fRow.setBinaryField_offset(&avgAndRem.quot,
sizeof(avgAndRem.quot),
offset);
}
}
}