Commit ca48cfbf authored by bar@mysql.com's avatar bar@mysql.com

item_cmpfunc.cc:

  Bug#7834 Illegal mix of collations in IN operator
  IN was the first function supporting 
  character set convertion.
  agg_arg_charsets() was written afterwards,
  which is more flexible.
  Now IN just reuses this function.
parent 187dce64
...@@ -157,6 +157,14 @@ a ...@@ -157,6 +157,14 @@ a
bbbb bbbb
цццц цццц
drop table t1; drop table t1;
create table t1 (a char(10) character set latin1 not null);
insert into t1 values ('a'),('b'),('c');
select a from t1 where a IN ('a','b','c') order by a;
a
a
b
c
drop table t1;
set names latin1; set names latin1;
select '1.0' in (1,2); select '1.0' in (1,2);
'1.0' in (1,2) '1.0' in (1,2)
......
...@@ -80,6 +80,11 @@ create table t1 (a char(10) character set utf8 not null); ...@@ -80,6 +80,11 @@ create table t1 (a char(10) character set utf8 not null);
insert into t1 values ('bbbb'),(_koi8r'ÃÃÃÃ'),(_latin1'ÄÄÄÄ'); insert into t1 values ('bbbb'),(_koi8r'ÃÃÃÃ'),(_latin1'ÄÄÄÄ');
select a from t1 where a in ('bbbb',_koi8r'ÃÃÃÃ',_latin1'ÄÄÄÄ') order by a; select a from t1 where a in ('bbbb',_koi8r'ÃÃÃÃ',_latin1'ÄÄÄÄ') order by a;
drop table t1; drop table t1;
# Bug#7834 Illegal mix of collations in IN operator
create table t1 (a char(10) character set latin1 not null);
insert into t1 values ('a'),('b'),('c');
select a from t1 where a IN ('a','b','c') order by a;
drop table t1;
set names latin1; set names latin1;
select '1.0' in (1,2); select '1.0' in (1,2);
......
...@@ -1749,64 +1749,13 @@ void Item_func_in::fix_length_and_dec() ...@@ -1749,64 +1749,13 @@ void Item_func_in::fix_length_and_dec()
agg_cmp_type(&cmp_type, args, arg_count); agg_cmp_type(&cmp_type, args, arg_count);
if (cmp_type == STRING_RESULT &&
agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV))
return;
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
const_itm&= arg[0]->const_item(); const_itm&= arg[0]->const_item();
if (cmp_type == STRING_RESULT)
{
/*
We allow consts character set conversion for
item IN (const1, const2, const3, ...)
if item is in a superset for all arguments,
and if it is a stong side according to coercibility rules.
TODO: add covnersion for non-constant IN values
via creating Item_func_conv_charset().
*/
if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count,
MY_COLL_ALLOW_SUPERSET_CONV))
return;
if ((!my_charset_same(args[0]->collation.collation,
cmp_collation.collation) || !const_itm))
{
if (agg_arg_collations_for_comparison(cmp_collation, args, arg_count))
return;
}
else
{
/*
Conversion is possible:
All IN arguments are constants.
*/
Item_arena *arena, backup;
arena= thd->change_arena_if_needed(&backup);
for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++)
{
if (!arg[0]->null_value &&
!my_charset_same(cmp_collation.collation,
arg[0]->collation.collation))
{
Item_string *conv;
String tmp, cstr, *ostr= arg[0]->val_str(&tmp);
uint dummy_errors;
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(),
cmp_collation.collation, &dummy_errors);
conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(),
arg[0]->collation.derivation);
conv->str_value.copy();
arg[0]= conv;
}
}
if (arena)
thd->restore_backup_item_arena(arena, &backup);
}
}
/* /*
Row item with NULLs inside can return NULL or FALSE => Row item with NULLs inside can return NULL or FALSE =>
they can't be processed as static they can't be processed as static
......
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