From a5b04a3ba914f1da39fbb7ef925be38328d4bb7e Mon Sep 17 00:00:00 2001
From: "gkodinov/kgeorge@magare.gmz" <>
Date: Wed, 30 May 2007 09:55:38 +0300
Subject: [PATCH] Bug #28492: subselect returns LONG in >5.0.24a and LONGLONG
 in <=5.0.24a

Integer values with 10 digits may or may not fit into an int column
(e.g. 2147483647 vs 6147483647).
Thus when creating a temp table column for such an int we must
use bigint instead.
Fixed to use bigint.
Also subsituted a "magic number" with a named constant.
---
 mysql-test/r/analyse.result  | 24 ++++++++++++------------
 mysql-test/r/metadata.result | 11 +++++++++++
 mysql-test/r/olap.result     |  4 ++--
 mysql-test/r/sp.result       |  2 +-
 mysql-test/r/view.result     |  2 +-
 mysql-test/t/metadata.test   | 11 +++++++++++
 sql/field.h                  |  2 +-
 sql/sql_select.cc            |  9 +++++++--
 8 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/mysql-test/r/analyse.result b/mysql-test/r/analyse.result
index 0ecc462fb70..49722d5b0ab 100644
--- a/mysql-test/r/analyse.result
+++ b/mysql-test/r/analyse.result
@@ -39,10 +39,10 @@ t2	CREATE TABLE `t2` (
   `Field_name` varbinary(255) NOT NULL default '',
   `Min_value` varbinary(255) default NULL,
   `Max_value` varbinary(255) default NULL,
-  `Min_length` int(11) NOT NULL default '0',
-  `Max_length` int(11) NOT NULL default '0',
-  `Empties_or_zeros` int(11) NOT NULL default '0',
-  `Nulls` int(11) NOT NULL default '0',
+  `Min_length` bigint(11) NOT NULL default '0',
+  `Max_length` bigint(11) NOT NULL default '0',
+  `Empties_or_zeros` bigint(11) NOT NULL default '0',
+  `Nulls` bigint(11) NOT NULL default '0',
   `Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
   `Std` varbinary(255) default NULL,
   `Optimal_fieldtype` varbinary(64) NOT NULL default ''
@@ -58,10 +58,10 @@ t2	CREATE TABLE `t2` (
   `Field_name` varbinary(255) NOT NULL default '',
   `Min_value` varbinary(255) default NULL,
   `Max_value` varbinary(255) default NULL,
-  `Min_length` int(11) NOT NULL default '0',
-  `Max_length` int(11) NOT NULL default '0',
-  `Empties_or_zeros` int(11) NOT NULL default '0',
-  `Nulls` int(11) NOT NULL default '0',
+  `Min_length` bigint(11) NOT NULL default '0',
+  `Max_length` bigint(11) NOT NULL default '0',
+  `Empties_or_zeros` bigint(11) NOT NULL default '0',
+  `Nulls` bigint(11) NOT NULL default '0',
   `Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
   `Std` varbinary(255) default NULL,
   `Optimal_fieldtype` varbinary(64) NOT NULL default ''
@@ -81,10 +81,10 @@ t2	CREATE TABLE `t2` (
   `Field_name` varbinary(255) NOT NULL default '',
   `Min_value` varbinary(255) default NULL,
   `Max_value` varbinary(255) default NULL,
-  `Min_length` int(11) NOT NULL default '0',
-  `Max_length` int(11) NOT NULL default '0',
-  `Empties_or_zeros` int(11) NOT NULL default '0',
-  `Nulls` int(11) NOT NULL default '0',
+  `Min_length` bigint(11) NOT NULL default '0',
+  `Max_length` bigint(11) NOT NULL default '0',
+  `Empties_or_zeros` bigint(11) NOT NULL default '0',
+  `Nulls` bigint(11) NOT NULL default '0',
   `Avg_value_or_avg_length` varbinary(255) NOT NULL default '',
   `Std` varbinary(255) default NULL,
   `Optimal_fieldtype` varbinary(64) NOT NULL default ''
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 34e961395c4..d33fb038b79 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -130,3 +130,14 @@ def			v3		renamed	8	12	0	Y	32896	0	63
 renamed
 drop table t1;
 drop view v1,v2,v3;
+select a.* from (select 2147483648 as v_large) a;
+Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+def			a	v_large	v_large	8	10	10	N	32769	0	63
+v_large
+2147483648
+select a.* from (select 214748364 as v_small) a;
+Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+def			a	v_small	v_small	3	9	9	N	32769	0	63
+v_small
+214748364
+End of 5.0 tests
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
index b1c29a5aadb..4a54b17316d 100644
--- a/mysql-test/r/olap.result
+++ b/mysql-test/r/olap.result
@@ -696,8 +696,8 @@ CREATE VIEW v1 AS
 SELECT a, LENGTH(a), COUNT(*) FROM t1 GROUP BY a WITH ROLLUP;
 DESC v1;
 Field	Type	Null	Key	Default	Extra
-a	int(11)	YES		0	
-LENGTH(a)	int(10)	YES		NULL	
+a	bigint(11)	YES		NULL	
+LENGTH(a)	bigint(10)	YES		NULL	
 COUNT(*)	bigint(21)	NO		0	
 SELECT * FROM v1;
 a	LENGTH(a)	COUNT(*)
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index b5b79af031e..4514bae1494 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4909,7 +4909,7 @@ create table t3 as select * from v1|
 show create table t3|
 Table	Create Table
 t3	CREATE TABLE `t3` (
-  `j` int(11) default NULL
+  `j` bigint(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 select * from t3|
 j
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 13239af41ad..f333e7db474 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2779,7 +2779,7 @@ CREATE TABLE t1 (i int, j int);
 CREATE VIEW v1 AS SELECT COALESCE(i,j) FROM t1;
 DESCRIBE v1;
 Field	Type	Null	Key	Default	Extra
-COALESCE(i,j)	int(11)	YES		NULL	
+COALESCE(i,j)	bigint(11)	YES		NULL	
 CREATE TABLE t2 SELECT COALESCE(i,j) FROM t1;
 DESCRIBE t2;
 Field	Type	Null	Key	Default	Extra
diff --git a/mysql-test/t/metadata.test b/mysql-test/t/metadata.test
index a6ebfdc14c1..df4acec2021 100644
--- a/mysql-test/t/metadata.test
+++ b/mysql-test/t/metadata.test
@@ -81,3 +81,14 @@ drop view v1,v2,v3;
 --disable_metadata
 
 # End of 4.1 tests
+
+#
+# Bug #28492: subselect returns LONG in >5.0.24a and LONGLONG in <=5.0.24a
+#
+--enable_metadata
+select a.* from (select 2147483648 as v_large) a;
+select a.* from (select 214748364 as v_small) a;
+--disable_metadata
+
+
+--echo End of 5.0 tests
diff --git a/sql/field.h b/sql/field.h
index 997ae1f2cd4..37ce6b88453 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -675,7 +675,7 @@ class Field_long :public Field_num {
   void sort_string(char *buff,uint length);
   uint32 pack_length() const { return 4; }
   void sql_type(String &str) const;
-  uint32 max_display_length() { return 11; }
+  uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
 };
 
 
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 57dff4b23a5..54ea4a8496c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -8869,8 +8869,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
 			       item->name, table, item->decimals, TRUE);
     break;
   case INT_RESULT:
-    /* Select an integer type with the minimal fit precision */
-    if (item->max_length > MY_INT32_NUM_DECIMAL_DIGITS)
+    /* 
+      Select an integer type with the minimal fit precision.
+      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
+      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
+      Field_long : make them Field_longlong.  
+    */
+    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
       new_field=new Field_longlong(item->max_length, maybe_null,
                                    item->name, table, item->unsigned_flag);
     else
-- 
2.30.9