summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
authorAlexander Barkov <alexander.barkov@oracle.com>2011-04-08 17:15:23 +0400
committerAlexander Barkov <alexander.barkov@oracle.com>2011-04-08 17:15:23 +0400
commitece1996b5afeb53b9266719be481656d7c1c0409 (patch)
tree2709dddaf34dda1e528467d7759bf2355f9f0503 /sql/item.h
parent6a293922899ed406d30b43d9018503f2bab2c5b7 (diff)
downloadmariadb-git-ece1996b5afeb53b9266719be481656d7c1c0409.tar.gz
Bug#11926811 / Bug#60625 Illegal mix of collations
Problem: comparison of a DATETIME sp variable and NOW() led to Illegal mix of collations error when character_set_connection=utf8. Introduced by "WL#2649 Number-to-string conversions". Error happened in Arg_comparator::set_compare_func(), because the first argument was errouneously converted to utf8, while the second argument was not. Fix: separate agg_arg_charsets_for_comparison() into two functions: - agg_arg_charsets_for_comparison() - for pure comparison, when we don't need to return any string result and therefore don't need to convert arguments to @@character_set_connection: SELECT a = b; - agg_arg_charsets_for_string_results_with_comparison() - when we need to return a string result, but we also need to do comparison internally: SELECT REPLACE(a,b,c) If all arguments are numbers: SELECT REPLACE(123,2,3) -> 133 we convert arguments to @@character_set_connection. @ mysql-test/include/ctype_numconv.inc @ mysql-test/r/ctype_binary.result @ mysql-test/r/ctype_cp1251.result @ mysql-test/r/ctype_latin1.result @ mysql-test/r/ctype_ucs.result @ mysql-test/r/ctype_utf8.result Adding tests @ sql/item.cc @ sql/item.h @ sql/item_func.cc @ sql/item_func.h @ sql/item_strfunc.cc Introducing and using new function agg_item_charsets_for_string_result_with_comparison() and its Item_func wrapper agg_arg_charsets_for_string_result_with_comparison().
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/sql/item.h b/sql/item.h
index 3e67ffacfc8..96b8c9eb2e4 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -53,6 +53,8 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
(i.e. constant).
MY_COLL_ALLOW_CONV - allow any kind of conversion
(combination of the above two)
+ MY_COLL_ALLOW_NUMERIC_CONV - if all items were numbers, convert to
+ @@character_set_connection
MY_COLL_DISALLOW_NONE - don't allow return DERIVATION_NONE
(e.g. when aggregating for comparison)
MY_COLL_CMP_CONV - combination of MY_COLL_ALLOW_CONV
@@ -62,6 +64,7 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
#define MY_COLL_ALLOW_SUPERSET_CONV 1
#define MY_COLL_ALLOW_COERCIBLE_CONV 2
#define MY_COLL_DISALLOW_NONE 4
+#define MY_COLL_ALLOW_NUMERIC_CONV 8
#define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV)
#define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE)
@@ -1561,7 +1564,8 @@ agg_item_charsets_for_string_result(DTCollation &c, const char *name,
int item_sep= 1)
{
uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
- MY_COLL_ALLOW_COERCIBLE_CONV;
+ MY_COLL_ALLOW_COERCIBLE_CONV |
+ MY_COLL_ALLOW_NUMERIC_CONV;
return agg_item_charsets(c, name, items, nitems, flags, item_sep);
}
inline bool
@@ -1574,6 +1578,19 @@ agg_item_charsets_for_comparison(DTCollation &c, const char *name,
MY_COLL_DISALLOW_NONE;
return agg_item_charsets(c, name, items, nitems, flags, item_sep);
}
+inline bool
+agg_item_charsets_for_string_result_with_comparison(DTCollation &c,
+ const char *name,
+ Item **items, uint nitems,
+ int item_sep= 1)
+{
+ uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
+ MY_COLL_ALLOW_COERCIBLE_CONV |
+ MY_COLL_ALLOW_NUMERIC_CONV |
+ MY_COLL_DISALLOW_NONE;
+ return agg_item_charsets(c, name, items, nitems, flags, item_sep);
+}
+
class Item_num: public Item_basic_constant
{