Commit bca6863a authored by Sergey Glukhov's avatar Sergey Glukhov

5.0-bugteam->5.1-bugteam merge

parents ac8f752e 6a9de01a
...@@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; ...@@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
ROW(a, 1) IN (SELECT SUM(b), 3) ROW(a, 1) IN (SELECT SUM(b), 3)
0 0
DROP TABLE t1; DROP TABLE t1;
create table t1 (a varchar(200),
b int unsigned not null primary key auto_increment)
default character set 'utf8';
create table t2 (c varchar(200),
d int unsigned not null primary key auto_increment)
default character set 'latin1';
insert into t1 (a) values('abc');
insert into t2 (c) values('abc');
select * from t1,t2 where (a,b) = (c,d);
a b c d
abc 1 abc 1
select host,user from mysql.user where (host,user) = ('localhost','test');
host user
drop table t1,t2;
...@@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a; ...@@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a;
SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a; SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#37601 Cast Is Not Done On Row Comparison
#
create table t1 (a varchar(200),
b int unsigned not null primary key auto_increment)
default character set 'utf8';
create table t2 (c varchar(200),
d int unsigned not null primary key auto_increment)
default character set 'latin1';
insert into t1 (a) values('abc');
insert into t2 (c) values('abc');
select * from t1,t2 where (a,b) = (c,d);
select host,user from mysql.user where (host,user) = ('localhost','test');
drop table t1,t2;
...@@ -1641,48 +1641,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname, ...@@ -1641,48 +1641,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
} }
/** bool agg_item_set_converter(DTCollation &coll, const char *fname,
Collect arguments' character sets together. Item **args, uint nargs, uint flags, int item_sep)
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
@code
collect(A,B,C) ::= collect(collect(A,B),C)
@endcode
Since this function calls THD::change_item_tree() on the passed Item **
pointers, it is necessary to pass the original Item **'s, not copies.
Otherwise their values will not be properly restored (see BUG#20769).
If the items are not consecutive (eg. args[2] and args[5]), use the
item_sep argument, ie.
@code
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
@endcode
*/
bool agg_item_charsets(DTCollation &coll, const char *fname,
Item **args, uint nargs, uint flags, int item_sep)
{ {
Item **arg, *safe_args[2]; Item **arg, *safe_args[2];
LINT_INIT(safe_args[0]);
LINT_INIT(safe_args[1]);
if (agg_item_collations(coll, fname, args, nargs, flags, item_sep))
return TRUE;
/* /*
For better error reporting: save the first and the second argument. For better error reporting: save the first and the second argument.
We need this only if the the number of args is 3 or 2: We need this only if the the number of args is 3 or 2:
...@@ -1762,6 +1725,47 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, ...@@ -1762,6 +1725,47 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
} }
/*
Collect arguments' character sets together.
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
Since this function calls THD::change_item_tree() on the passed Item **
pointers, it is necessary to pass the original Item **'s, not copies.
Otherwise their values will not be properly restored (see BUG#20769).
If the items are not consecutive (eg. args[2] and args[5]), use the
item_sep argument, ie.
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
*/
bool agg_item_charsets(DTCollation &coll, const char *fname,
Item **args, uint nargs, uint flags, int item_sep)
{
Item **arg, *safe_args[2];
if (agg_item_collations(coll, fname, args, nargs, flags, item_sep))
return TRUE;
return agg_item_set_converter(coll, fname, args, nargs, flags, item_sep);
}
void Item_ident_for_show::make_field(Send_field *tmp_field) void Item_ident_for_show::make_field(Send_field *tmp_field)
{ {
tmp_field->table_name= tmp_field->org_table_name= table_name; tmp_field->table_name= tmp_field->org_table_name= table_name;
......
...@@ -1303,6 +1303,8 @@ bool agg_item_collations(DTCollation &c, const char *name, ...@@ -1303,6 +1303,8 @@ bool agg_item_collations(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags, int item_sep); Item **items, uint nitems, uint flags, int item_sep);
bool agg_item_collations_for_comparison(DTCollation &c, const char *name, bool agg_item_collations_for_comparison(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags); Item **items, uint nitems, uint flags);
bool agg_item_set_converter(DTCollation &coll, const char *fname,
Item **args, uint nargs, uint flags, int item_sep);
bool agg_item_charsets(DTCollation &c, const char *name, bool agg_item_charsets(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags, int item_sep); Item **items, uint nitems, uint flags, int item_sep);
......
...@@ -549,7 +549,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) ...@@ -549,7 +549,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols()); my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
return 1; return 1;
} }
comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)); if (comparators[i].set_cmp_func(owner, (*a)->addr(i), (*b)->addr(i)))
return 1;
} }
break; break;
} }
...@@ -894,6 +895,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, ...@@ -894,6 +895,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
get_value_func= &get_time_value; get_value_func= &get_time_value;
return 0; return 0;
} }
else if (type == STRING_RESULT &&
(*a)->result_type() == STRING_RESULT &&
(*b)->result_type() == STRING_RESULT)
{
DTCollation coll;
coll.set((*a)->collation.collation);
if (agg_item_set_converter(coll, owner_arg->func_name(),
b, 1, MY_COLL_CMP_CONV, 1))
return 1;
}
return set_compare_func(owner_arg, type); return set_compare_func(owner_arg, type);
} }
......
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