mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
5.0-bugteam->5.1-bugteam merge
This commit is contained in:
@ -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)
|
||||
0
|
||||
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;
|
||||
SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
|
||||
|
||||
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;
|
||||
|
82
sql/item.cc
82
sql/item.cc
@ -1641,48 +1641,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, 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:
|
||||
@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)
|
||||
bool agg_item_set_converter(DTCollation &coll, const char *fname,
|
||||
Item **args, uint nargs, uint flags, int item_sep)
|
||||
{
|
||||
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.
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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)
|
||||
{
|
||||
tmp_field->table_name= tmp_field->org_table_name= table_name;
|
||||
|
@ -1303,6 +1303,8 @@ bool agg_item_collations(DTCollation &c, const char *name,
|
||||
Item **items, uint nitems, uint flags, int item_sep);
|
||||
bool agg_item_collations_for_comparison(DTCollation &c, const char *name,
|
||||
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,
|
||||
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)
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), (*a)->element_index(i)->cols());
|
||||
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;
|
||||
}
|
||||
@ -894,6 +895,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
|
||||
get_value_func= &get_time_value;
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user