From 5aa0edf34c4bf83eace609e2e60b448fcb9553fe Mon Sep 17 00:00:00 2001
From: "holyfoot@hf-ibm.(none)" <>
Date: Fri, 6 May 2005 19:04:58 +0500
Subject: [PATCH] Trimmed fix for bug #9546 (Crashing with huge decimals)

---
 mysql-test/r/type_newdecimal.result | 11 +++++++++++
 mysql-test/t/type_newdecimal.test   |  6 ++++++
 sql/my_decimal.cc                   |  6 +++---
 strings/decimal.c                   |  8 +++++++-
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 6702676fa35..840073aed29 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -846,3 +846,14 @@ set sql_mode='';
 select 0/0;
 0/0
 NULL
+select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x;
+x
+999999999999999999999999999999999999999999999999999999999999999999999999999999999
+Warnings:
+Error	1292	Truncated incorrect DECIMAL value: ''
+select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
+x
+NULL
+Warnings:
+Error	1292	Truncated incorrect DECIMAL value: ''
+Error	1292	Truncated incorrect DECIMAL value: ''
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 19230c02743..75f35ba0796 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -876,3 +876,9 @@ select 10.3330000000000/12.34500000;
 
 set sql_mode='';
 select 0/0;
+
+#
+# bug #9546
+#
+select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 as x;
+select 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 1 as x;
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 14c15cdc4ef..f188d27ff78 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -43,9 +43,9 @@ int decimal_operation_results(int result)
     break;
   case E_DEC_OVERFLOW:
     push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-			ER_WARN_DATA_OUT_OF_RANGE,
-			ER(ER_WARN_DATA_OUT_OF_RANGE),
-			"", (long)-1);
+                        ER_TRUNCATED_WRONG_VALUE,
+                        ER(ER_TRUNCATED_WRONG_VALUE),
+			"DECIMAL", "");
     break;
   case E_DEC_DIV_ZERO:
     push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
diff --git a/strings/decimal.c b/strings/decimal.c
index 4b7dc8803ee..b06a50fc86b 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1612,13 +1612,19 @@ static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
   x=intg1 > intg2 ? from1->buf[0] :
     intg2 > intg1 ? from2->buf[0] :
     from1->buf[0] + from2->buf[0] ;
-  if (unlikely(x > DIG_MASK*9)) /* yes, there is */
+  if (unlikely(x > DIG_MAX-1)) /* yes, there is */
   {
     intg0++;
     to->buf[0]=0; /* safety */
   }
 
   FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error);
+  if (unlikely(error == E_DEC_OVERFLOW))
+  {
+    max_decimal(to->len * DIG_PER_DEC1, 0, to);
+    return error;
+  }
+
   buf0=to->buf+intg0+frac0;
 
   to->sign=from1->sign;
-- 
2.30.9