diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index 72f827f11ede14ed179b356798c34b2893a0cee3..5146c976659d5b20ae75d8b633621c805fae34f8 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/type_decimal.test b/mysql-test/t/type_decimal.test
index c154b2685dd8620fa4c01bc3da2e560a50c2599f..5e6f2b5a091e63462c22100182054fe707e6b992 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 96326ee27282d500a8bd6cf5e443375e97feb9c0..443360625d0b5315f35fba420230ccfcb0420b94 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2008,7 +2008,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;
@@ -2107,18 +2107,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 cbea0e340c6d1f9828b5e080613bd48873688ca2..3176cf6afa72f8df89e7cf5a46c2201ae6928e0a 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;
   }