Commit 7a013ca6 authored by unknown's avatar unknown

added collation processing in UNION merging

temporary table BLOB now is longblob


mysql-test/r/create.result:
  blob size changed for safety
mysql-test/r/type_blob.result:
  blob size changed for safety
mysql-test/r/type_ranges.result:
  blob size changed for safety
mysql-test/r/union.result:
  blob size changed for safety
  new tests of UNION types merging
mysql-test/t/union.test:
  new tests of UNION types merging
sql/field.h:
  blob size changed for safety
sql/item.cc:
  processing of collation added
  added comment
sql/item.h:
  joining of UNION fields may failed now, because of incompatibility of collations
sql/sql_union.cc:
  joining of UNION fields may failed now, because of incompatibility of collations
parent 7cc69268
...@@ -404,7 +404,7 @@ d date 0000-00-00 ...@@ -404,7 +404,7 @@ d date 0000-00-00
e char(1) e char(1)
f datetime 0000-00-00 00:00:00 f datetime 0000-00-00 00:00:00
g time 00:00:00 g time 00:00:00
h mediumblob h longblob
dd time 00:00:00 dd time 00:00:00
select * from t2; select * from t2;
a b c d e f g h dd a b c d e f g h dd
......
...@@ -508,5 +508,5 @@ drop table t1; ...@@ -508,5 +508,5 @@ drop table t1;
create table t1 select load_file('../../std_data/words.dat'); create table t1 select load_file('../../std_data/words.dat');
show full fields from t1; show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
load_file('../../std_data/words.dat') mediumblob NULL YES NULL select,insert,update,references load_file('../../std_data/words.dat') longblob NULL YES NULL select,insert,update,references
drop table t1; drop table t1;
...@@ -271,8 +271,8 @@ Field Type Collation Null Key Default Extra Privileges Comment ...@@ -271,8 +271,8 @@ Field Type Collation Null Key Default Extra Privileges Comment
auto bigint(17) unsigned NULL PRI 0 select,insert,update,references auto bigint(17) unsigned NULL PRI 0 select,insert,update,references
t1 bigint(1) NULL 0 select,insert,update,references t1 bigint(1) NULL 0 select,insert,update,references
t2 char(1) latin1_swedish_ci select,insert,update,references t2 char(1) latin1_swedish_ci select,insert,update,references
t3 mediumtext latin1_swedish_ci select,insert,update,references t3 longtext latin1_swedish_ci select,insert,update,references
t4 mediumtext latin1_bin select,insert,update,references t4 longtext latin1_bin select,insert,update,references
select * from t2; select * from t2;
auto t1 t2 t3 t4 auto t1 t2 t3 t4
11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
......
...@@ -556,8 +556,8 @@ t1 CREATE TABLE `t1` ( ...@@ -556,8 +556,8 @@ t1 CREATE TABLE `t1` (
`a` double(4,1) NOT NULL default '0.0' `a` double(4,1) NOT NULL default '0.0'
) TYPE=MyISAM DEFAULT CHARSET=latin1 ) TYPE=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); 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);
insert into t2 values (NULL, 1, 3, 4, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest'); insert into t2 values (NULL, 1, 3, 4, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest', 'teeeeeeeeeeeest');
create table t1 SELECT it2 from t2 UNION select it1 from t2; create table t1 SELECT it2 from t2 UNION select it1 from t2;
select * from t1; select * from t1;
it2 it2
...@@ -720,7 +720,7 @@ tetetetetest ...@@ -720,7 +720,7 @@ tetetetetest
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`dt` blob `dt` longblob
) TYPE=MyISAM DEFAULT CHARSET=latin1 ) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
create table t1 SELECT sv from t2 UNION select b from t2; create table t1 SELECT sv from t2 UNION select b from t2;
...@@ -731,7 +731,7 @@ tetetetetest ...@@ -731,7 +731,7 @@ tetetetetest
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`sv` blob `sv` longblob
) TYPE=MyISAM DEFAULT CHARSET=latin1 ) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2; create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2;
...@@ -745,4 +745,61 @@ Table Create Table ...@@ -745,4 +745,61 @@ Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`i` blob `i` blob
) TYPE=MyISAM DEFAULT CHARSET=latin1 ) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT sv from t2 UNION select tx from t2;
select * from t1;
sv
testv
teeeeeeeeeeeest
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`sv` text
) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 SELECT b from t2 UNION select tx from t2;
select * from t1;
b
tetetetetest
teeeeeeeeeeeest
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`b` longblob
) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2; drop table t1,t2;
create table t1 (d decimal(10,1));
create table t2 (d decimal(10,9));
insert into t1 values ("100000000.0");
insert into t2 values ("1.23456780");
create table t3 select * from t2 union select * from t1;
select * from t3;
d
1.234567800
100000000.0
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`d` decimal(10,9) default NULL
) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1,t2,t3;
create table t1 select 1 union select -1;
select * from t1;
1
1
-1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`1` bigint(1) NOT NULL default '0'
) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 select _latin1"test" union select _latin2"testt" ;
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'UNION'
create table t1 select _latin2"test" union select _latin2"testt" ;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`test` char(5) character set latin2 NOT NULL default ''
) TYPE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
...@@ -321,8 +321,8 @@ select * from t1; ...@@ -321,8 +321,8 @@ select * from t1;
show create table t1; show create table t1;
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); 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);
insert into t2 values (NULL, 1, 3, 4, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest'); insert into t2 values (NULL, 1, 3, 4, 1.5, 2.5, 1972, '1972-10-22', '1972-10-22 11:50', 'testc', 'testv', 'tetetetetest', 'teeeeeeeeeeeest');
create table t1 SELECT it2 from t2 UNION select it1 from t2; create table t1 SELECT it2 from t2 UNION select it1 from t2;
select * from t1; select * from t1;
...@@ -391,4 +391,29 @@ drop table t1; ...@@ -391,4 +391,29 @@ drop table t1;
create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2; create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2;
select * from t1; select * from t1;
show create table t1; show create table t1;
drop table t1;
create table t1 SELECT sv from t2 UNION select tx from t2;
select * from t1;
show create table t1;
drop table t1;
create table t1 SELECT b from t2 UNION select tx from t2;
select * from t1;
show create table t1;
drop table t1,t2; drop table t1,t2;
create table t1 (d decimal(10,1));
create table t2 (d decimal(10,9));
insert into t1 values ("100000000.0");
insert into t2 values ("1.23456780");
create table t3 select * from t2 union select * from t1;
select * from t3;
show create table t3;
drop table t1,t2,t3;
create table t1 select 1 union select -1;
select * from t1;
show create table t1;
drop table t1;
-- error 1266
create table t1 select _latin1"test" union select _latin2"testt" ;
create table t1 select _latin2"test" union select _latin2"testt" ;
show create table t1;
drop table t1;
\ No newline at end of file
...@@ -941,7 +941,7 @@ class Field_blob :public Field_str { ...@@ -941,7 +941,7 @@ class Field_blob :public Field_str {
struct st_table *table_arg, CHARSET_INFO *cs) struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg, cs), NONE, field_name_arg, table_arg, cs),
geom_flag(true), packlength(3) geom_flag(true), packlength(4)
{ {
flags|= BLOB_FLAG; flags|= BLOB_FLAG;
} }
......
...@@ -2005,17 +2005,24 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) ...@@ -2005,17 +2005,24 @@ 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;
collation.set(item->collation);
} }
// STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT /*
STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT
ROW_RESULT should never appear in Item_type_holder::join_types,
but it is included in following table just to make table full
(there DBUG_ASSERT in function to catch ROW_RESULT)
*/
static Item_result type_convertor[4][4]= static Item_result type_convertor[4][4]=
{{STRING_RESULT, STRING_RESULT, STRING_RESULT, ROW_RESULT}, {{STRING_RESULT, STRING_RESULT, STRING_RESULT, ROW_RESULT},
{STRING_RESULT, REAL_RESULT, REAL_RESULT, ROW_RESULT}, {STRING_RESULT, REAL_RESULT, REAL_RESULT, ROW_RESULT},
{STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT}, {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT},
{ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT}}; {ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT}};
void Item_type_holder::join_types(THD *thd, Item *item) bool Item_type_holder::join_types(THD *thd, Item *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()];
...@@ -2045,14 +2052,20 @@ void Item_type_holder::join_types(THD *thd, Item *item) ...@@ -2045,14 +2052,20 @@ void Item_type_holder::join_types(THD *thd, Item *item)
(max_length < item->max_length) || (max_length < item->max_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) ||
(item_type == STRING_RESULT && new_type == STRING_RESULT &&
!my_charset_same(collation.collation, item->collation.collation)))
{ {
// 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 > item->max_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) ||
(item_type == STRING_RESULT &&
new_type == STRING_RESULT &&
!my_charset_same(collation.collation,
item->collation.collation)));
/* /*
It is safe assign pointer on field, because it will be used just after It is safe assign pointer on field, because it will be used just after
all JOIN::prepare calls and before any SELECT execution all JOIN::prepare calls and before any SELECT execution
...@@ -2062,12 +2075,25 @@ void Item_type_holder::join_types(THD *thd, Item *item) ...@@ -2062,12 +2075,25 @@ void Item_type_holder::join_types(THD *thd, Item *item)
else else
field_example= ((Item_field*) item)->field; field_example= ((Item_field*) item)->field;
const char *old_cs= collation.collation->name,
*old_derivation= collation.derivation_name();
if (item_type == STRING_RESULT && collation.aggregate(item->collation))
{
my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
old_cs, old_derivation,
item->collation.collation->name,
item->collation.derivation_name(),
"UNION");
return 1;
}
max_length= max(max_length, item->max_length); max_length= max(max_length, item->max_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;
} }
DBUG_ASSERT(item_type != ROW_RESULT); DBUG_ASSERT(item_type != ROW_RESULT);
return 0;
} }
......
...@@ -1005,7 +1005,7 @@ class Item_type_holder: public Item ...@@ -1005,7 +1005,7 @@ class Item_type_holder: public Item
double val(); double val();
longlong val_int(); longlong val_int();
String *val_str(String*); String *val_str(String*);
void join_types(THD *thd, Item *); bool join_types(THD *thd, Item *);
Field *example() { return field_example; } Field *example() { return field_example; }
}; };
......
...@@ -197,7 +197,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result) ...@@ -197,7 +197,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *sel_result)
Item *type, *item; Item *type, *item;
while((type= tp++, item= it++)) while((type= tp++, item= it++))
{ {
((Item_type_holder*)type)->join_types(thd, item); if (((Item_type_holder*)type)->join_types(thd, item))
DBUG_RETURN(-1)
} }
} }
} }
......
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