Commit af016f72 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE

Don't throw an error after checking the first and the second arguments.
Continue with checking the third and higher arguments and if some of
them is stronger according to coercibility rules,
then this argument's collation is set as result collation.


mysql-test/r/ctype_collate.result:
  test result
mysql-test/t/ctype_collate.test:
  test case
sql/item.cc:
  Don't throw an error after checking the first and the second arguments.
  Continue with checking the third and higher arguments and if some of
  them is stronger according to coercibility rules,
  then this argument's collation is set as result collation.
parent da7dc303
...@@ -611,3 +611,22 @@ check table t1 extended; ...@@ -611,3 +611,22 @@ check table t1 extended;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; drop table t1;
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci);
least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci)
a
create table t1
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` varchar(1) character set latin5 NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate
latin5_turkish_ci then 2 else 3 end;
case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate
latin5_turkish_ci then 2 else 3 end
3
select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci);
concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci)
abc
...@@ -229,3 +229,17 @@ insert into t1 set a=0x6c; ...@@ -229,3 +229,17 @@ insert into t1 set a=0x6c;
insert into t1 set a=0x4c98; insert into t1 set a=0x4c98;
check table t1 extended; check table t1 extended;
drop table t1; drop table t1;
#
# Bug#41627 Illegal mix of collations in LEAST / GREATEST / CASE
#
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci);
create table t1
select least(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci) as f1;
show create table t1;
drop table t1;
select case _latin1'a' when _latin2'b' then 1 when _latin5'c' collate
latin5_turkish_ci then 2 else 3 end;
select concat(_latin1'a',_latin2'b',_latin5'c' collate latin5_turkish_ci);
...@@ -1498,7 +1498,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) ...@@ -1498,7 +1498,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags)
else else
{ {
// Cannot apply conversion // Cannot apply conversion
set(0, DERIVATION_NONE, 0); set(&my_charset_bin, DERIVATION_NONE,
(dt.repertoire|repertoire));
return 1; return 1;
} }
} }
...@@ -1581,15 +1582,31 @@ bool agg_item_collations(DTCollation &c, const char *fname, ...@@ -1581,15 +1582,31 @@ bool agg_item_collations(DTCollation &c, const char *fname,
{ {
uint i; uint i;
Item **arg; Item **arg;
bool unknown_cs= 0;
c.set(av[0]->collation); c.set(av[0]->collation);
for (i= 1, arg= &av[item_sep]; i < count; i++, arg++) for (i= 1, arg= &av[item_sep]; i < count; i++, arg++)
{ {
if (c.aggregate((*arg)->collation, flags)) if (c.aggregate((*arg)->collation, flags))
{ {
if (c.derivation == DERIVATION_NONE &&
c.collation == &my_charset_bin)
{
unknown_cs= 1;
continue;
}
my_coll_agg_error(av, count, fname, item_sep); my_coll_agg_error(av, count, fname, item_sep);
return TRUE; return TRUE;
} }
} }
if (unknown_cs &&
c.derivation != DERIVATION_EXPLICIT)
{
my_coll_agg_error(av, count, fname, item_sep);
return TRUE;
}
if ((flags & MY_COLL_DISALLOW_NONE) && if ((flags & MY_COLL_DISALLOW_NONE) &&
c.derivation == DERIVATION_NONE) c.derivation == DERIVATION_NONE)
{ {
......
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