Commit 002364c2 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

new length detection for non-string in UNION (BUG#4067)

parent 5f8ef7a3
......@@ -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);
......
......@@ -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;
......@@ -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;
......@@ -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()
{
......
......@@ -1199,6 +1199,7 @@ class Item_type_holder: public Item
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");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment