summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mhansson/martin@linux-st28.site>2008-01-17 18:22:55 +0100
committerunknown <mhansson/martin@linux-st28.site>2008-01-17 18:22:55 +0100
commit92141cd424b65559bb191f86dd1c2aedeb5e3254 (patch)
tree586f18d7908833a83c5dc560b66953787a263434
parent666efa1c43344a0b4dbe815e57333647d4d8f2b3 (diff)
parentf9440588f5bfbb4aef8934dbbda28f3e8872476f (diff)
downloadmariadb-git-92141cd424b65559bb191f86dd1c2aedeb5e3254.tar.gz
Merge linux-st28.site:/home/martin/mysql/src/bug33143/my50-bug33143-again
into linux-st28.site:/home/martin/mysql/src/bug33143/my51-bug33143 mysql-test/r/type_decimal.result: Auto merged sql/item_func.cc: Auto merged strings/decimal.c: Auto merged
-rw-r--r--mysql-test/r/bdb_notembedded.result35
-rw-r--r--mysql-test/r/type_decimal.result63
-rw-r--r--mysql-test/t/bdb_notembedded.test38
-rw-r--r--mysql-test/t/type_decimal.test43
-rw-r--r--sql/item_func.cc12
-rw-r--r--strings/decimal.c16
6 files changed, 198 insertions, 9 deletions
diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result
new file mode 100644
index 00000000000..14cb5fad915
--- /dev/null
+++ b/mysql-test/r/bdb_notembedded.result
@@ -0,0 +1,35 @@
+set autocommit=1;
+reset master;
+create table bug16206 (a int);
+insert into bug16206 values(1);
+start transaction;
+insert into bug16206 values(2);
+commit;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
+f n Query 1 n use `test`; create table bug16206 (a int)
+f n Query 1 n use `test`; insert into bug16206 values(1)
+f n Query 1 n use `test`; insert into bug16206 values(2)
+drop table bug16206;
+reset master;
+create table bug16206 (a int) engine= bdb;
+insert into bug16206 values(0);
+insert into bug16206 values(1);
+start transaction;
+insert into bug16206 values(2);
+commit;
+insert into bug16206 values(3);
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
+f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
+f n Query 1 n use `test`; insert into bug16206 values(0)
+f n Query 1 n use `test`; insert into bug16206 values(1)
+f n Query 1 n use `test`; BEGIN
+f n Query 1 n use `test`; insert into bug16206 values(2)
+f n Query 1 n use `test`; COMMIT
+f n Query 1 n use `test`; insert into bug16206 values(3)
+drop table bug16206;
+set autocommit=0;
+End of 5.0 tests
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 68c6acc545b..ecef60c7c1e 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -797,7 +797,7 @@ dps tinyint(3) unsigned default NULL
INSERT INTO t1 VALUES (1.1325,3);
SELECT ROUND(qty,3), dps, ROUND(qty,dps) FROM t1;
ROUND(qty,3) dps ROUND(qty,dps)
-1.133 3 1.133
+1.133 3 1.133000
DROP TABLE t1;
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
%
@@ -805,3 +805,64 @@ SELECT 1 % .12345678912345678912345678912345678912345678912345678912345678912345
SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()';
MOD()
0.012345687012345687012345687012345687012345687012345687012345687012345687000000000
+CREATE TABLE t1( a DECIMAL(4, 3), b INT );
+INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
+SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
+a b c
+1.000 5 1.000
+2.000 4 2.000
+3.000 3 3.000
+4.000 2 4.000
+5.000 1 5.000
+SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
+a b c
+5.000 1 5.000
+4.000 2 4.000
+3.000 3 3.000
+2.000 4 2.000
+1.000 5 1.000
+CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
+INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
+( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
+SELECT a, b, MAX(ROUND(c, a))
+FROM t2
+GROUP BY a, b
+ORDER BY b;
+a b MAX(ROUND(c, a))
+0 1 1.0000
+1 2 1.2000
+3 3 1.2350
+2 4 1.2300
+SELECT a, b, ROUND(c, a)
+FROM t2;
+a b ROUND(c, a)
+0 1 1.0000
+1 2 1.2000
+3 3 1.2350
+2 4 1.2300
+CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
+INSERT INTO t3 VALUES( 0, 1.5 );
+SELECT ROUND( b, a ) FROM t3;
+ROUND( b, a )
+2.000
+CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
+INSERT INTO t4 VALUES( -9, 1.5e9 );
+SELECT ROUND( b, a ) FROM t4;
+ROUND( b, a )
+2000000000
+CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
+INSERT INTO t5 VALUES( 0, 1.5 );
+INSERT INTO t5 VALUES( 9, 1.5e-9 );
+SELECT ROUND( b, a ) FROM t5;
+ROUND( b, a )
+2.000000000000
+0.000000002000
+CREATE TABLE t6( a INT );
+INSERT INTO t6 VALUES( 6 / 8 );
+SELECT * FROM t6;
+a
+1
+SELECT ROUND(20061108085411.000002);
+ROUND(20061108085411.000002)
+20061108085411
+DROP TABLE t1, t2, t3, t4, t5, t6;
diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test
new file mode 100644
index 00000000000..24e64ebbfb2
--- /dev/null
+++ b/mysql-test/t/bdb_notembedded.test
@@ -0,0 +1,38 @@
+-- source include/not_embedded.inc
+-- source include/have_bdb.inc
+
+#
+# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
+#
+set autocommit=1;
+
+let $VERSION=`select version()`;
+
+reset master;
+create table bug16206 (a int);
+insert into bug16206 values(1);
+start transaction;
+insert into bug16206 values(2);
+commit;
+--replace_result $VERSION VERSION
+--replace_column 1 f 2 n 5 n
+show binlog events;
+drop table bug16206;
+
+reset master;
+create table bug16206 (a int) engine= bdb;
+insert into bug16206 values(0);
+insert into bug16206 values(1);
+start transaction;
+insert into bug16206 values(2);
+commit;
+insert into bug16206 values(3);
+--replace_result $VERSION VERSION
+--replace_column 1 f 2 n 5 n
+show binlog events;
+drop table bug16206;
+
+set autocommit=0;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index c154b2685dd..5e6f2b5a091 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -416,3 +416,46 @@ DROP TABLE t1;
SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS '%';
SELECT MOD(1, .123456789123456789123456789123456789123456789123456789123456789123456789123456789) AS 'MOD()';
+
+#
+# Bug #33143: Incorrect ORDER BY for ROUND()/TRUNCATE() result
+#
+
+CREATE TABLE t1( a DECIMAL(4, 3), b INT );
+INSERT INTO t1 VALUES ( 1, 5 ), ( 2, 4 ), ( 3, 3 ), ( 4, 2 ), ( 5, 1 );
+SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c;
+SELECT a, b, ROUND( a, b ) AS c FROM t1 ORDER BY c DESC;
+
+CREATE TABLE t2 ( a INT, b INT, c DECIMAL(5, 4) );
+
+INSERT INTO t2 VALUES ( 0, 1, 1.2345 ), ( 1, 2, 1.2345 ),
+ ( 3, 3, 1.2345 ), ( 2, 4, 1.2345 );
+
+SELECT a, b, MAX(ROUND(c, a))
+FROM t2
+GROUP BY a, b
+ORDER BY b;
+
+SELECT a, b, ROUND(c, a)
+FROM t2;
+
+CREATE TABLE t3( a INT, b DECIMAL(6, 3) );
+INSERT INTO t3 VALUES( 0, 1.5 );
+SELECT ROUND( b, a ) FROM t3;
+
+CREATE TABLE t4( a INT, b DECIMAL( 12, 0) );
+INSERT INTO t4 VALUES( -9, 1.5e9 );
+SELECT ROUND( b, a ) FROM t4;
+
+CREATE TABLE t5( a INT, b DECIMAL( 13, 12 ) );
+INSERT INTO t5 VALUES( 0, 1.5 );
+INSERT INTO t5 VALUES( 9, 1.5e-9 );
+SELECT ROUND( b, a ) FROM t5;
+
+CREATE TABLE t6( a INT );
+INSERT INTO t6 VALUES( 6 / 8 );
+SELECT * FROM t6;
+
+SELECT ROUND(20061108085411.000002);
+
+DROP TABLE t1, t2, t3, t4, t5, t6;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 057f86ac230..415a59c9e34 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2005,7 +2005,7 @@ void Item_func_round::fix_length_and_dec()
int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
precision-= decimals_delta - length_increase;
- decimals= decimals_to_set;
+ decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag);
break;
@@ -2104,18 +2104,18 @@ my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
{
my_decimal val, *value= args[0]->val_decimal(&val);
longlong dec= args[1]->val_int();
- if (dec > 0 || (dec < 0 && args[1]->unsigned_flag))
- {
+ if (dec >= 0 || args[1]->unsigned_flag)
dec= min((ulonglong) dec, DECIMAL_MAX_SCALE);
- decimals= (uint8) dec; // to get correct output
- }
else if (dec < INT_MIN)
dec= INT_MIN;
if (!(null_value= (args[0]->null_value || args[1]->null_value ||
my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
- truncate, decimal_value) > 1)))
+ truncate, decimal_value) > 1)))
+ {
+ decimal_value->frac= decimals;
return decimal_value;
+ }
return 0;
}
diff --git a/strings/decimal.c b/strings/decimal.c
index f457014b2b1..0559dd97613 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1601,9 +1601,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;
}