diff options
author | unknown <mhansson/martin@linux-st28.site> | 2008-01-14 16:16:36 +0100 |
---|---|---|
committer | unknown <mhansson/martin@linux-st28.site> | 2008-01-14 16:16:36 +0100 |
commit | f9440588f5bfbb4aef8934dbbda28f3e8872476f (patch) | |
tree | 5c497c1abfefb96d53bfc5b6b9f6267b43613adc /strings | |
parent | 62a7e160bc0e960ec1374a546dde4a7f26120ceb (diff) | |
download | mariadb-git-f9440588f5bfbb4aef8934dbbda28f3e8872476f.tar.gz |
Bug#33143: Incorrect ORDER BY for ROUND()/TRUNCATE() result
The ROUND(X, D) function would change the Item::decimals field during
execution to achieve the effect of a dynamic number of decimal digits.
This caused a series of bugs:
Bug #30617:Round() function not working under some circumstances in InnoDB
Bug #33402:ROUND with decimal and non-constant cannot round to 0 decimal places
Bug #30889:filesort and order by with float/numeric crashes server
Fixed by never changing the number of shown digits for DECIMAL when
used with a nonconstant number of decimal digits.
mysql-test/r/type_decimal.result:
Bug#33143: Test result
mysql-test/t/type_decimal.test:
Bug#33143: Test case
sql/item_func.cc:
Bug#33143:
- Moved the DECIMAL_MAX_SCALE limitation to fix_length_and_dec.
- Removed resetting of Item::decimals field.
- set the frac field of the output value to current scale.
strings/decimal.c:
Bug#33143: It is necessary to set all digits in the buffer following the
rounded one to zero, as they may now be displayed.
Diffstat (limited to 'strings')
-rw-r--r-- | strings/decimal.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/strings/decimal.c b/strings/decimal.c index cbea0e340c6..3176cf6afa7 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1595,9 +1595,21 @@ decimal_round(decimal_t *from, decimal_t *to, int scale, x+=10; *buf1=powers10[pos]*(x-y); } - if (frac0 < 0) + /* + In case we're rounding e.g. 1.5e9 to 2.0e9, the decimal_digit_t's inside + the buffer are as follows. + + Before <1, 5e8> + After <2, 5e8> + + Hence we need to set the 2nd field to 0. + The same holds if we round 1.5e-9 to 2e-9. + */ + if (frac0 < frac1) { - dec1 *end=to->buf+intg0, *buf=buf1+1; + dec1 *buf= to->buf + ((scale == 0 && intg0 == 0) ? 1 : intg0 + frac0); + dec1 *end= to->buf + len; + while (buf < end) *buf++=0; } |