summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-06-16 16:06:30 +0300
committerunknown <bell@sanja.is.com.ua>2004-06-16 16:06:30 +0300
commita9d4556649750c5a6750b517843be9f011fafde3 (patch)
tree3f53a24eec02fe30a114eaa94e8e6840596cbe92
parentcf5d0db657634c9949b4f9968c3bd4a050fe9066 (diff)
downloadmariadb-git-a9d4556649750c5a6750b517843be9f011fafde3.tar.gz
new length detection for non-string in UNION (BUG#4067)
mysql-test/r/subselect.result: new length in UNION mysql-test/r/union.result: new length in UNION test of int with wrong display length mysql-test/t/union.test: test of int with wrong display length sql/item.cc: new length detection for non-string sql/item.h: new length detection for non-string
-rw-r--r--mysql-test/r/subselect.result14
-rw-r--r--mysql-test/r/union.result15
-rw-r--r--mysql-test/t/union.test8
-rw-r--r--sql/item.cc72
-rw-r--r--sql/item.h1
5 files changed, 96 insertions, 14 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 202219d04cf..890fd464c29 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1075,24 +1075,24 @@ CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(1) NOT NULL default '0',
- `(SELECT 1)` bigint(1) NOT NULL default '0'
+ `a` bigint(20) NOT NULL default '0',
+ `(SELECT 1)` bigint(20) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(1) NOT NULL default '0',
- `(SELECT a)` bigint(1) NOT NULL default '0'
+ `a` bigint(20) NOT NULL default '0',
+ `(SELECT a)` bigint(20) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(1) NOT NULL default '0',
- `(SELECT a+0)` bigint(17) NOT NULL default '0'
+ `a` bigint(20) NOT NULL default '0',
+ `(SELECT a+0)` bigint(20) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
@@ -1102,7 +1102,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(17) NOT NULL default '0'
+ `a` bigint(20) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index da4915294b1..bed4e890c18 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -546,7 +546,7 @@ aa
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` char(2) NOT NULL default ''
+ `a` char(20) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT 12 as a UNION select 12.2 as a;
@@ -557,7 +557,7 @@ a
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` double(4,1) NOT NULL default '0.0'
+ `a` double(53,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t2 (it1 tinyint, it2 tinyint not null, i int not null, ib bigint, f float, d double, y year, da date, dt datetime, sc char(10), sv varchar(10), b blob, tx text);
@@ -647,7 +647,7 @@ f
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `f` binary(12) default NULL
+ `f` binary(24) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT y from t2 UNION select da from t2;
@@ -795,7 +795,7 @@ select * from t1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `1` bigint(1) NOT NULL default '0'
+ `1` bigint(20) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 select _latin1"test" union select _latin2"testt" ;
@@ -953,3 +953,10 @@ CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
explain (select * from t1) union (select * from t2) order by not_existing_column;
ERROR 42S22: Unknown column 'not_existing_column' in 'order clause'
drop table t1, t2;
+CREATE TABLE t1 (uid int(1));
+INSERT INTO t1 SELECT 150;
+SELECT 'a' UNION SELECT uid FROM t1;
+a
+a
+150
+drop table t1;
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index f6006a87d47..b21f635162f 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -527,3 +527,11 @@ CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i));
--error 1054
explain (select * from t1) union (select * from t2) order by not_existing_column;
drop table t1, t2;
+
+#
+# length detecting
+#
+CREATE TABLE t1 (uid int(1));
+INSERT INTO t1 SELECT 150;
+SELECT 'a' UNION SELECT uid FROM t1;
+drop table t1;
diff --git a/sql/item.cc b/sql/item.cc
index 8f5cd3df3fd..1bf114b2204 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2419,6 +2419,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
field_example= ((Item_field*) item)->field;
else
field_example= 0;
+ max_length= real_length(item);
collation.set(item->collation);
}
@@ -2438,6 +2439,7 @@ static Item_result type_convertor[4][4]=
bool Item_type_holder::join_types(THD *thd, Item *item)
{
+ uint32 new_length= real_length(item);
bool change_field= 0, skip_store_field= 0;
Item_result new_type= type_convertor[item_type][item->result_type()];
@@ -2463,7 +2465,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
// size/type should be changed
if (change_field ||
(new_type != item_type) ||
- (max_length < item->max_length) ||
+ (max_length < new_length) ||
((new_type == INT_RESULT) &&
(decimals < item->decimals)) ||
(!maybe_null && item->maybe_null) ||
@@ -2472,7 +2474,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
{
// new field has some parameters worse then current
skip_store_field|= (change_field &&
- (max_length > item->max_length) ||
+ (max_length > new_length) ||
((new_type == INT_RESULT) &&
(decimals > item->decimals)) ||
(maybe_null && !item->maybe_null) ||
@@ -2501,7 +2503,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
return 1;
}
- max_length= max(max_length, item->max_length);
+ max_length= max(max_length, new_length);
decimals= max(decimals, item->decimals);
maybe_null|= item->maybe_null;
item_type= new_type;
@@ -2510,6 +2512,70 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
return 0;
}
+uint32 Item_type_holder::real_length(Item *item)
+{
+ if (item->result_type() == STRING_RESULT)
+ return item->max_length;
+ if (item->type() == Item::FIELD_ITEM)
+ {
+ switch (((Item_field *)item)->field_type())
+ {
+ case MYSQL_TYPE_TINY:
+ return 4;
+ case MYSQL_TYPE_SHORT:
+ return 6;
+ case MYSQL_TYPE_LONG:
+ return 11;
+ case MYSQL_TYPE_FLOAT:
+ return 24;
+ case MYSQL_TYPE_DOUBLE:
+ return 53;
+ case MYSQL_TYPE_NULL:
+ return 4;
+ case MYSQL_TYPE_LONGLONG:
+ return 20;
+ case MYSQL_TYPE_INT24:
+ return 8;
+ case MYSQL_TYPE_TINY_BLOB:
+ return 256;
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ return 65535;
+ case MYSQL_TYPE_LONG_BLOB:
+ return (uint32)4294967295;
+ case MYSQL_TYPE_BLOB:
+ return 16777215;
+ case MYSQL_TYPE_SET:
+ case MYSQL_TYPE_ENUM:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_VAR_STRING:
+ case MYSQL_TYPE_STRING:
+ case MYSQL_TYPE_GEOMETRY:
+ return item->max_length;
+ default:
+ DBUG_ASSERT(0); // we should never go there
+ return 0;
+ }
+ }
+ switch (item->result_type())
+ {
+ case STRING_RESULT:
+ return item->max_length;
+ case REAL_RESULT:
+ return 53;
+ case INT_RESULT:
+ return 20;
+ case ROW_RESULT:
+ default:
+ DBUG_ASSERT(0); // we should never go there
+ return 0;
+ }
+}
double Item_type_holder::val()
{
diff --git a/sql/item.h b/sql/item.h
index e373eb112c0..b18897da727 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1199,6 +1199,7 @@ public:
String *val_str(String*);
bool join_types(THD *thd, Item *);
Field *example() { return field_example; }
+ static uint32 real_length(Item *item);
void cleanup()
{
DBUG_ENTER("Item_type_holder::cleanup");