MDEV-7366 SELECT 'a' = BINARY 'A' returns 1 (utf8 charset, utf8_unicode_ci collation)
Fixing a wrong assymetric code in Arg_comparator::set_cmp_func(). It existed for a long time, but showed up in 10.0.14 after the fix for "MDEV-6666 Malformed result for CONCAT(utf8_column, binary_string)".
This commit is contained in:
parent
252be4c9e7
commit
6e6750ad6c
@ -13126,5 +13126,15 @@ DROP TABLE t1;
|
|||||||
# END of ctype_myanmar.inc
|
# END of ctype_myanmar.inc
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
# MDEV-7366 SELECT 'a' = BINARY 'A' returns 1 (utf8 charset, utf8_unicode_ci collation)
|
||||||
|
#
|
||||||
|
SET NAMES utf8 COLLATE utf8_unicode_ci;
|
||||||
|
SELECT 'a' = BINARY 'A';
|
||||||
|
'a' = BINARY 'A'
|
||||||
|
0
|
||||||
|
SELECT BINARY 'A' = 'a';
|
||||||
|
BINARY 'A' = 'a'
|
||||||
|
0
|
||||||
|
#
|
||||||
# End of MariaDB-10.0 tests
|
# End of MariaDB-10.0 tests
|
||||||
#
|
#
|
||||||
|
@ -587,6 +587,13 @@ SET NAMES utf8 COLLATE utf8_myanmar_ci;
|
|||||||
SET collation_connection=ucs2_myanmar_ci;
|
SET collation_connection=ucs2_myanmar_ci;
|
||||||
--source include/ctype_myanmar.inc
|
--source include/ctype_myanmar.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-7366 SELECT 'a' = BINARY 'A' returns 1 (utf8 charset, utf8_unicode_ci collation)
|
||||||
|
--echo #
|
||||||
|
SET NAMES utf8 COLLATE utf8_unicode_ci;
|
||||||
|
SELECT 'a' = BINARY 'A';
|
||||||
|
SELECT BINARY 'A' = 'a';
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of MariaDB-10.0 tests
|
--echo # End of MariaDB-10.0 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -621,17 +621,6 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
|
|||||||
}
|
}
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
We must set cmp_charset here as we may be called from for an automatic
|
|
||||||
generated item, like in natural join
|
|
||||||
*/
|
|
||||||
if (cmp_collation.set((*a)->collation, (*b)->collation) ||
|
|
||||||
cmp_collation.derivation == DERIVATION_NONE)
|
|
||||||
{
|
|
||||||
my_coll_agg_error((*a)->collation, (*b)->collation,
|
|
||||||
owner->func_name());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (cmp_collation.collation == &my_charset_bin)
|
if (cmp_collation.collation == &my_charset_bin)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -754,6 +743,37 @@ bool get_mysql_time_from_str(THD *thd, String *str, timestamp_type warn_type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Aggregate comparator argument charsets for comparison.
|
||||||
|
One of the arguments ("a" or "b") can be replaced,
|
||||||
|
typically by Item_string or Item_func_conv_charset.
|
||||||
|
|
||||||
|
@return Aggregation result
|
||||||
|
@retval false - if no conversion is needed,
|
||||||
|
or if one of the arguments was converted
|
||||||
|
@retval true - on error, if arguments are not comparable.
|
||||||
|
|
||||||
|
TODO: get rid of this method eventually and refactor the calling code.
|
||||||
|
Argument conversion should happen on the Item_func level.
|
||||||
|
Arg_comparator should get comparable arguments.
|
||||||
|
*/
|
||||||
|
bool Arg_comparator::agg_arg_charsets_for_comparison()
|
||||||
|
{
|
||||||
|
if (cmp_collation.set((*a)->collation, (*b)->collation, MY_COLL_CMP_CONV) ||
|
||||||
|
cmp_collation.derivation == DERIVATION_NONE)
|
||||||
|
{
|
||||||
|
my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (agg_item_set_converter(cmp_collation, owner->func_name(),
|
||||||
|
a, 1, MY_COLL_CMP_CONV, 1) ||
|
||||||
|
agg_item_set_converter(cmp_collation, owner->func_name(),
|
||||||
|
b, 1, MY_COLL_CMP_CONV, 1))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Prepare the comparator (set the comparison function) for comparing
|
Prepare the comparator (set the comparison function) for comparing
|
||||||
items *a1 and *a2 in the context of 'type'.
|
items *a1 and *a2 in the context of 'type'.
|
||||||
@ -781,10 +801,11 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
|
|||||||
(*a)->result_type() == STRING_RESULT &&
|
(*a)->result_type() == STRING_RESULT &&
|
||||||
(*b)->result_type() == STRING_RESULT)
|
(*b)->result_type() == STRING_RESULT)
|
||||||
{
|
{
|
||||||
DTCollation coll;
|
/*
|
||||||
coll.set((*a)->collation.collation);
|
We must set cmp_collation here as we may be called from for an automatic
|
||||||
if (agg_item_set_converter(coll, owner->func_name(),
|
generated item, like in natural join
|
||||||
b, 1, MY_COLL_CMP_CONV, 1))
|
*/
|
||||||
|
if (agg_arg_charsets_for_comparison())
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (type == INT_RESULT &&
|
if (type == INT_RESULT &&
|
||||||
|
@ -48,6 +48,14 @@ class Arg_comparator: public Sql_alloc
|
|||||||
THD *thd;
|
THD *thd;
|
||||||
Item *a_cache, *b_cache; // Cached values of a and b items
|
Item *a_cache, *b_cache; // Cached values of a and b items
|
||||||
// when one of arguments is NULL.
|
// when one of arguments is NULL.
|
||||||
|
int set_compare_func(Item_result_field *owner, Item_result type);
|
||||||
|
inline int set_compare_func(Item_result_field *owner_arg)
|
||||||
|
{
|
||||||
|
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
|
||||||
|
(*b)->result_type()));
|
||||||
|
}
|
||||||
|
bool agg_arg_charsets_for_comparison();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DTCollation cmp_collation;
|
DTCollation cmp_collation;
|
||||||
/* Allow owner function to use string buffers. */
|
/* Allow owner function to use string buffers. */
|
||||||
@ -58,12 +66,6 @@ public:
|
|||||||
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), set_null(TRUE),
|
Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), set_null(TRUE),
|
||||||
comparators(0), thd(0), a_cache(0), b_cache(0) {};
|
comparators(0), thd(0), a_cache(0), b_cache(0) {};
|
||||||
|
|
||||||
int set_compare_func(Item_result_field *owner, Item_result type);
|
|
||||||
inline int set_compare_func(Item_result_field *owner_arg)
|
|
||||||
{
|
|
||||||
return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
|
|
||||||
(*b)->result_type()));
|
|
||||||
}
|
|
||||||
int set_cmp_func(Item_result_field *owner_arg,
|
int set_cmp_func(Item_result_field *owner_arg,
|
||||||
Item **a1, Item **a2,
|
Item **a1, Item **a2,
|
||||||
Item_result type);
|
Item_result type);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user