mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
new length detection for non-string in UNION (BUG#4067)
This commit is contained in:
@ -1075,24 +1075,24 @@ CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` bigint(1) NOT NULL default '0',
|
`a` bigint(20) NOT NULL default '0',
|
||||||
`(SELECT 1)` bigint(1) NOT NULL default '0'
|
`(SELECT 1)` bigint(20) NOT NULL default '0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
|
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` bigint(1) NOT NULL default '0',
|
`a` bigint(20) NOT NULL default '0',
|
||||||
`(SELECT a)` bigint(1) NOT NULL default '0'
|
`(SELECT a)` bigint(20) NOT NULL default '0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
|
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` bigint(1) NOT NULL default '0',
|
`a` bigint(20) NOT NULL default '0',
|
||||||
`(SELECT a+0)` bigint(17) NOT NULL default '0'
|
`(SELECT a+0)` bigint(20) NOT NULL default '0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
|
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;
|
SHOW CREATE TABLE t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` bigint(17) NOT NULL default '0'
|
`a` bigint(20) NOT NULL default '0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
|
@ -546,7 +546,7 @@ aa
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` char(2) NOT NULL default ''
|
`a` char(20) NOT NULL default ''
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 SELECT 12 as a UNION select 12.2 as a;
|
create table t1 SELECT 12 as a UNION select 12.2 as a;
|
||||||
@ -557,7 +557,7 @@ a
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
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
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
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);
|
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;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`f` binary(12) default NULL
|
`f` binary(24) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 SELECT y from t2 UNION select da from t2;
|
create table t1 SELECT y from t2 UNION select da from t2;
|
||||||
@ -795,7 +795,7 @@ select * from t1;
|
|||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`1` bigint(1) NOT NULL default '0'
|
`1` bigint(20) NOT NULL default '0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 select _latin1"test" union select _latin2"testt" ;
|
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;
|
explain (select * from t1) union (select * from t2) order by not_existing_column;
|
||||||
ERROR 42S22: Unknown column 'not_existing_column' in 'order clause'
|
ERROR 42S22: Unknown column 'not_existing_column' in 'order clause'
|
||||||
drop table t1, t2;
|
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
|
--error 1054
|
||||||
explain (select * from t1) union (select * from t2) order by not_existing_column;
|
explain (select * from t1) union (select * from t2) order by not_existing_column;
|
||||||
drop table t1, t2;
|
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;
|
||||||
|
72
sql/item.cc
72
sql/item.cc
@ -2419,6 +2419,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
|||||||
field_example= ((Item_field*) item)->field;
|
field_example= ((Item_field*) item)->field;
|
||||||
else
|
else
|
||||||
field_example= 0;
|
field_example= 0;
|
||||||
|
max_length= real_length(item);
|
||||||
collation.set(item->collation);
|
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)
|
bool Item_type_holder::join_types(THD *thd, Item *item)
|
||||||
{
|
{
|
||||||
|
uint32 new_length= real_length(item);
|
||||||
bool change_field= 0, skip_store_field= 0;
|
bool change_field= 0, skip_store_field= 0;
|
||||||
Item_result new_type= type_convertor[item_type][item->result_type()];
|
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
|
// size/type should be changed
|
||||||
if (change_field ||
|
if (change_field ||
|
||||||
(new_type != item_type) ||
|
(new_type != item_type) ||
|
||||||
(max_length < item->max_length) ||
|
(max_length < new_length) ||
|
||||||
((new_type == INT_RESULT) &&
|
((new_type == INT_RESULT) &&
|
||||||
(decimals < item->decimals)) ||
|
(decimals < item->decimals)) ||
|
||||||
(!maybe_null && item->maybe_null) ||
|
(!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
|
// new field has some parameters worse then current
|
||||||
skip_store_field|= (change_field &&
|
skip_store_field|= (change_field &&
|
||||||
(max_length > item->max_length) ||
|
(max_length > new_length) ||
|
||||||
((new_type == INT_RESULT) &&
|
((new_type == INT_RESULT) &&
|
||||||
(decimals > item->decimals)) ||
|
(decimals > item->decimals)) ||
|
||||||
(maybe_null && !item->maybe_null) ||
|
(maybe_null && !item->maybe_null) ||
|
||||||
@ -2501,7 +2503,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
max_length= max(max_length, item->max_length);
|
max_length= max(max_length, new_length);
|
||||||
decimals= max(decimals, item->decimals);
|
decimals= max(decimals, item->decimals);
|
||||||
maybe_null|= item->maybe_null;
|
maybe_null|= item->maybe_null;
|
||||||
item_type= new_type;
|
item_type= new_type;
|
||||||
@ -2510,6 +2512,70 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
|||||||
return 0;
|
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()
|
double Item_type_holder::val()
|
||||||
{
|
{
|
||||||
|
@ -1199,6 +1199,7 @@ public:
|
|||||||
String *val_str(String*);
|
String *val_str(String*);
|
||||||
bool join_types(THD *thd, Item *);
|
bool join_types(THD *thd, Item *);
|
||||||
Field *example() { return field_example; }
|
Field *example() { return field_example; }
|
||||||
|
static uint32 real_length(Item *item);
|
||||||
void cleanup()
|
void cleanup()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_type_holder::cleanup");
|
DBUG_ENTER("Item_type_holder::cleanup");
|
||||||
|
Reference in New Issue
Block a user