diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 24be10a7a29b44e9a70e136bde79d61e00791a43..71be41b106fad9776285f08ff992e5af00432e6c 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1509,6 +1509,26 @@ SELECT 1 FROM t1 GROUP BY @b := @a, @b;
 1
 1
 DROP TABLE t1;
+CREATE TABLE t1 SELECT 0.123456789012345678901234567890123456 AS f1;
+Warnings:
+Note	1265	Data truncated for column 'f1' at row 1
+DESC t1;
+Field	Type	Null	Key	Default	Extra
+f1	decimal(31,30)	NO		0.000000000000000000000000000000	
+SELECT f1 FROM t1;
+f1
+0.123456789012345678901234567890
+DROP TABLE t1;
+CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
+Warnings:
+Warning	1264	Out of range value for column 'f1' at row 1
+DESC t1;
+Field	Type	Null	Key	Default	Extra
+f1	decimal(59,30)	NO		0.000000000000000000000000000000	
+SELECT f1 FROM t1;
+f1
+99999999999999999999999999999.999999999999999999999999999999
+DROP TABLE t1;
 End of 5.0 tests
 select cast(143.481 as decimal(4,1));
 cast(143.481 as decimal(4,1))
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index b1776d09744c69b9ca4913a471141010c58057ac..4b052a3d1fbfe1c2da800fb31337d9a84a522173 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1205,6 +1205,27 @@ SELECT 1 FROM t1 GROUP BY @b := @a, @b;
 
 DROP TABLE t1;
 
+#
+# Bug #24907: unpredictable (display) precission, if input precission
+#             increases
+#
+
+# As per 10.1.1. Overview of Numeric Types, type (new) DECIMAL has a
+# maxmimum precision of 30 places after the decimal point. Show that
+# temp field creation beyond that works and throws a truncation warning.
+# DECIMAL(37,36) should be adjusted to DECIMAL(31,30).
+CREATE TABLE t1 SELECT 0.123456789012345678901234567890123456 AS f1;
+DESC t1;
+SELECT f1 FROM t1;
+DROP TABLE t1;
+
+# too many decimal places, AND too many digits altogether (90 = 45+45).
+# should preserve integers (65 = 45+20)
+CREATE TABLE t1 SELECT 123451234512345123451234512345123451234512345.678906789067890678906789067890678906789067890 AS f1;
+DESC t1;
+SELECT f1 FROM t1;
+DROP TABLE t1;
+
 --echo End of 5.0 tests
 
 #
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 2e28663e3832cc9f11c4f1c185852ea03b770652..7f757228133c511995f245f27ea985c37702f45a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9205,9 +9205,43 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
     new_field->set_derivation(item->collation.derivation);
     break;
   case DECIMAL_RESULT:
-    new_field= new Field_new_decimal(item->max_length, maybe_null, item->name,
-                                     item->decimals, item->unsigned_flag);
+  {
+    uint8 dec= item->decimals;
+    uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
+    uint8 len= item->max_length;
+
+    /*
+      Trying to put too many digits overall in a DECIMAL(prec,dec)
+      will always throw a warning. We must limit dec to
+      DECIMAL_MAX_SCALE however to prevent an assert() later.
+    */
+
+    if (dec > 0)
+    {
+      signed int overflow;
+
+      dec= min(dec, DECIMAL_MAX_SCALE);
+
+      /*
+        If the value still overflows the field with the corrected dec,
+        we'll throw out decimals rather than integers. This is still
+        bad and of course throws a truncation warning.
+        +1: for decimal point
+      */
+
+      overflow= my_decimal_precision_to_length(intg + dec, dec,
+                                               item->unsigned_flag) - len;
+
+      if (overflow > 0)
+        dec= max(0, dec - overflow);            // too long, discard fract
+      else
+        len -= item->decimals - dec;            // corrected value fits
+    }
+
+    new_field= new Field_new_decimal(len, maybe_null, item->name,
+                                     dec, item->unsigned_flag);
     break;
+  }
   case ROW_RESULT:
   default:
     // This case should never be choosen