summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mnogosearch.org>2015-01-17 17:52:03 +0400
committerAlexander Barkov <bar@mnogosearch.org>2015-01-17 17:52:03 +0400
commit6e6750ad6c0a733b78bf106bcc45311f61015a9b (patch)
tree7fb9fcec3a11210a7e21c9535bb2e962366bb7ee /sql/item_cmpfunc.cc
parent252be4c9e75ea126ec32619c136961d53bdabe59 (diff)
downloadmariadb-git-6e6750ad6c0a733b78bf106bcc45311f61015a9b.tar.gz
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)".
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc51
1 files changed, 36 insertions, 15 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 62f63501d86..1f1982ffb80 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -621,17 +621,6 @@ int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type)
}
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)
{
/*
@@ -755,6 +744,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
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 &&
(*b)->result_type() == STRING_RESULT)
{
- DTCollation coll;
- coll.set((*a)->collation.collation);
- if (agg_item_set_converter(coll, owner->func_name(),
- b, 1, MY_COLL_CMP_CONV, 1))
+ /*
+ We must set cmp_collation here as we may be called from for an automatic
+ generated item, like in natural join
+ */
+ if (agg_arg_charsets_for_comparison())
return 1;
}
if (type == INT_RESULT &&