diff options
author | unknown <bell@sanja.is.com.ua> | 2004-06-16 16:06:30 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-06-16 16:06:30 +0300 |
commit | a9d4556649750c5a6750b517843be9f011fafde3 (patch) | |
tree | 3f53a24eec02fe30a114eaa94e8e6840596cbe92 | |
parent | cf5d0db657634c9949b4f9968c3bd4a050fe9066 (diff) | |
download | mariadb-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.result | 14 | ||||
-rw-r--r-- | mysql-test/r/union.result | 15 | ||||
-rw-r--r-- | mysql-test/t/union.test | 8 | ||||
-rw-r--r-- | sql/item.cc | 72 | ||||
-rw-r--r-- | sql/item.h | 1 |
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"); |