summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2018-10-30 18:15:41 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2018-10-30 18:15:41 +0400
commit57898316b6fb8920cb68a473c33edbb583da4d89 (patch)
treeb3bd9f6af00421f23e11cfda27e16189defbe47f /strings
parent65cfc5873e8a9d528451d741b512d12a77eff81f (diff)
downloadmariadb-git-57898316b6fb8920cb68a473c33edbb583da4d89.tar.gz
MDEV-17256 Decimal field multiplication bug.bb-5.5-hf
We should clear trailing zeroes in frac part. Otherwise that tail is growing quickly and forces unnecessary truncating of arguments.
Diffstat (limited to 'strings')
-rw-r--r--strings/decimal.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/strings/decimal.c b/strings/decimal.c
index 3d90a58ea8a..05546aa77a3 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -2077,26 +2077,21 @@ int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
}
}
- /* Now we have to check for -0.000 case */
- if (to->sign)
+ /* Remove trailing zero words in frac part */
+ frac0= ROUND_UP(to->frac);
+
+ if (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0)
{
- dec1 *buf= to->buf;
- dec1 *end= to->buf + intg0 + frac0;
- DBUG_ASSERT(buf != end);
- for (;;)
+ do
{
- if (*buf)
- break;
- if (++buf == end)
- {
- /* We got decimal zero */
- decimal_make_zero(to);
- break;
- }
- }
+ frac0--;
+ } while (frac0 > 0 && to->buf[intg0 + frac0 - 1] == 0);
+ to->frac= DIG_PER_DEC1 * frac0;
}
+
+ /* Remove heading zero words in intg part */
buf1= to->buf;
- d_to_move= intg0 + ROUND_UP(to->frac);
+ d_to_move= intg0 + frac0;
while (!*buf1 && (to->intg > DIG_PER_DEC1))
{
buf1++;
@@ -2109,6 +2104,14 @@ int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
for (; d_to_move--; cur_d++, buf1++)
*cur_d= *buf1;
}
+
+ /* Now we have to check for -0.000 case */
+ if (to->sign && to->frac == 0 && to->buf[0] == 0)
+ {
+ DBUG_ASSERT(to->intg <= DIG_PER_DEC1);
+ /* We got decimal zero */
+ decimal_make_zero(to);
+ }
return error;
}