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)
|
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;
|
|||||||
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;
|
||||||
|
82
sql/item.cc
82
sql/item.cc
@ -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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
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,
|
|||||||
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)
|
|||||||
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,
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user