diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index fbd4f8e11dc..7820cd1d6ff 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1033,3 +1033,81 @@ a No aaa,bbb drop table t1,t2,t3,t4; +create table t1 as +(select _latin1'test') union +(select _latin1'TEST') union +(select _latin1'TeST'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `test` char(4) NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +1 +drop table t1; +create table t1 as +(select _latin1'test' collate latin1_bin) union +(select _latin1'TEST') union +(select _latin1'TeST'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `_latin1'test' collate latin1_bin` char(4) character set latin1 collate latin1_bin NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +3 +drop table t1; +create table t1 as +(select _latin1'test') union +(select _latin1'TEST' collate latin1_bin) union +(select _latin1'TeST'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `test` char(4) character set latin1 collate latin1_bin NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +3 +drop table t1; +create table t1 as +(select _latin1'test') union +(select _latin1'TEST') union +(select _latin1'TeST' collate latin1_bin); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `test` char(4) character set latin1 collate latin1_bin NOT NULL default '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select count(*) from t1; +count(*) +3 +drop table t1; +create table t2 ( +a char character set latin1 collate latin1_swedish_ci, +b char character set latin1 collate latin1_bin); +create table t1 as +(select a from t2) union +(select b from t2); +ERROR HY000: Illegal mix of collations for operation 'UNION' +create table t1 as +(select a collate latin1_german1_ci from t2) union +(select b from t2); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a collate latin1_german1_ci` char(1) character set latin1 collate latin1_german1_ci default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 as +(select a from t2) union +(select b collate latin1_german1_ci from t2); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) character set latin1 collate latin1_german1_ci default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +drop table t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c5e72e85835..6e16a2b02aa 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -595,3 +595,58 @@ select a as a from t3 union select "1"; select a as a from t4 union select a from t3; select a as a from t1 union select a from t4; drop table t1,t2,t3,t4; + +# +# Bug #6139 UNION doesn't understand collate in the column of second select +# +create table t1 as +(select _latin1'test') union +(select _latin1'TEST') union +(select _latin1'TeST'); +show create table t1; +select count(*) from t1; +drop table t1; + +create table t1 as +(select _latin1'test' collate latin1_bin) union +(select _latin1'TEST') union +(select _latin1'TeST'); +show create table t1; +select count(*) from t1; +drop table t1; + +create table t1 as +(select _latin1'test') union +(select _latin1'TEST' collate latin1_bin) union +(select _latin1'TeST'); +show create table t1; +select count(*) from t1; +drop table t1; + +create table t1 as +(select _latin1'test') union +(select _latin1'TEST') union +(select _latin1'TeST' collate latin1_bin); +show create table t1; +select count(*) from t1; +drop table t1; + +create table t2 ( +a char character set latin1 collate latin1_swedish_ci, +b char character set latin1 collate latin1_bin); +--error 1271 +create table t1 as +(select a from t2) union +(select b from t2); +create table t1 as +(select a collate latin1_german1_ci from t2) union +(select b from t2); +show create table t1; +drop table t1; +create table t1 as +(select a from t2) union +(select b collate latin1_german1_ci from t2); +show create table t1; +drop table t1; +drop table t2; + diff --git a/sql/item.cc b/sql/item.cc index 0366ea29485..304579d65a2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2558,8 +2558,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item) if (use_new_field || use_expression_type || (new_result_type != item_type) || (new_length > max_length) || (!maybe_null && item->maybe_null) || - (item_type == STRING_RESULT && - !my_charset_same(collation.collation, item->collation.collation))) + (item_type == STRING_RESULT && + collation.collation != item->collation.collation)) { if (use_expression_type || item->type() != Item::FIELD_ITEM) field_example= 0; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b46cfc05538..6b5d27270c9 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -264,6 +264,23 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } + { + /* + Check that it was possible to aggregate all collations together. + */ + List_iterator_fast tp(types); + Item *type; + while ((type= tp++)) + { + if (type->result_type() == STRING_RESULT && + type->collation.derivation == DERIVATION_NONE) + { + my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION"); + goto err; + } + } + } + // it is not single select if (first_select->next_select()) {