diff options
author | Alexander Barkov <bar@mysql.com> | 2010-02-11 08:17:25 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2010-02-11 08:17:25 +0400 |
commit | 702166bcdec5705dd90d8567a88056893433c719 (patch) | |
tree | d6306efc9e4d7e6bc6bf4ae5a58bd6aec40420e9 /sql/item_cmpfunc.cc | |
parent | 6dd93757263fd219fcbd3d1ed100a681ecbc7c92 (diff) | |
download | mariadb-git-702166bcdec5705dd90d8567a88056893433c719.tar.gz |
WL#2649 Number-to-string conversions
added:
include/ctype_numconv.inc
mysql-test/include/ctype_numconv.inc
mysql-test/r/ctype_binary.result
mysql-test/t/ctype_binary.test
Adding tests
modified:
mysql-test/r/bigint.result
mysql-test/r/case.result
mysql-test/r/create.result
mysql-test/r/ctype_cp1251.result
mysql-test/r/ctype_latin1.result
mysql-test/r/ctype_ucs.result
mysql-test/r/func_gconcat.result
mysql-test/r/func_str.result
mysql-test/r/metadata.result
mysql-test/r/ps_1general.result
mysql-test/r/ps_2myisam.result
mysql-test/r/ps_3innodb.result
mysql-test/r/ps_4heap.result
mysql-test/r/ps_5merge.result
mysql-test/r/show_check.result
mysql-test/r/type_datetime.result
mysql-test/r/type_ranges.result
mysql-test/r/union.result
mysql-test/suite/ndb/r/ps_7ndb.result
mysql-test/t/ctype_cp1251.test
mysql-test/t/ctype_latin1.test
mysql-test/t/ctype_ucs.test
mysql-test/t/func_str.test
Fixing tests
@ sql/field.cc
- Return str result using my_charset_numeric.
- Using real multi-byte aware str_to_XXX functions
to handle tricky charset values propely (e.g. UCS2)
@ sql/field.h
- Changing derivation of non-string field types to DERIVATION_NUMERIC.
- Changing binary() for numeric/datetime fields to always
return TRUE even if charset is not my_charset_bin. We need
this to keep ha_base_keytype() return HA_KEYTYPE_BINARY.
- Adding BINARY_FLAG into some fields, because it's not
being set automatically anymore with
"my_charset_bin to my_charset_numeric" change.
- Changing derivation for numeric/datetime datatypes to a weaker
value, to make "SELECT concat('string', field)" use character
set of the string literal for the result of the function.
@ sql/item.cc
- Implementing generic val_str_ascii().
- Using max_char_length() instead of direct read of max_length
to make "tricky" charsets like UCS2 work.
NOTE: in the future we'll possibly remove all direct reads of max_length
- Fixing Item_num::safe_charset_converter().
Previously it alligned binary string to
character string (for example by adding leading 0x00
when doing binary->UCS2 conversion). Now it just
converts from my_charset_numbner to "tocs".
- Using val_str_ascii() in Item::get_time() to make UCS2 arguments work.
- Other misc changes
@ sql/item.h
- Changing MY_COLL_CMP_CONV and MY_COLL_ALLOW_CONV to
bit operations instead of hard-coded bit masks.
- Addding new method DTCollation.set_numeric().
- Adding new methods to Item.
- Adding helper functions to make code look nicer:
agg_item_charsets_for_string_result()
agg_item_charsets_for_comparison()
- Changing charset for Item_num-derived items
from my_charset_bin to my_charset_numeric
(which is an alias for latin1).
@ sql/item_cmpfunc.cc
- Using new helper functions
- Other misc changes
@ sql/item_cmpfunc.h
- Fixing strcmp() to return max_length=2.
Previously it returned 1, which was wrong,
because it did not fit '-1'.
@ sql/item_func.cc
- Using new helper functions
- Other minor changes
@ sql/item_func.h
- Removing unused functions
- Adding helper functions
agg_arg_charsets_for_string_result()
agg_arg_charsets_for_comparison()
- Adding set_numeric() into constructors of numeric items.
- Using fix_length_and_charset() and fix_char_length()
instead of direct write to max_length.
@ sql/item_geofunc.cc
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when character_set_connection=ucs2).
@ sql/item_geofunc.h
- Changing class for Item_func_geometry_type and
Item_func_as_wkt from Item_str_func to
Item_str_ascii_func, to make them return UCS2 result
properly (when @@character_set_connection=ucs2).
@ sql/item_strfunc.cc
- Implementing Item_str_func::val_str().
- Renaming val_str to val_str_ascii for some items,
to make them work with UCS2 properly.
- Using new helper functions
- All single-argument functions that expect string
result now call this method:
agg_arg_charsets_for_string_result(collation, args, 1);
This enables character set conversion to @@character_set_connection
in case of pure numeric input.
@ sql/item_strfunc.h
- Introducing Item_str_ascii_func - for functions
which return pure ASCII data, for performance purposes,
as well as for the cases when the old implementation
of val_str() was heavily 8-bit oriented and implementing
a UCS2-aware version is tricky.
@ sql/item_sum.cc
- Using new helper functions.
@ sql/item_timefunc.cc
- Using my_charset_numeric instead of my_charset_bin.
- Using fix_char_length(), fix_length_and_charset()
and fix_length_and_charset_datetime()
instead of direct write to max_length.
- Using tricky-charset aware function str_to_time_with_warn()
@ sql/item_timefunc.h
- Using new helper functions for charset and length initialization.
- Changing base class for Item_func_get_format() to make
it return UCS2 properly (when character_set_connection=ucs2).
@ sql/item_xmlfunc.cc
- Using new helper function
@ sql/my_decimal.cc
- Adding a new DECIMAL to CHAR converter
with real multibyte support (e.g. UCS2)
@ sql/mysql_priv.h
- Introducing a new derivation level for numeric/datetime data types.
- Adding macros for my_charset_numeric and MY_REPERTOIRE_NUMERIC.
- Adding prototypes for str_set_decimal()
- Adding prototypes for character-set aware str_to_xxx() functions.
@ sql/protocol.cc
- Changing charsetnr to "binary" client-side metadata for
numeric/datetime data types.
@ sql/time.cc
- Adding to_ascii() helper function, to convert a string
in any character set to ascii representation. In the
future can be extended to understand digits written
in various non-Latin word scripts.
- Adding real multy-byte character set aware versions for str_to_XXXX,
to make these these type of queries work correct:
INSERT INTO t1 SET datetime_column=ucs2_expression;
@ strings/ctype-ucs2.c
- endptr was not calculated correctly. INSERTing of UCS2
values into numeric columns returned warnings about
truncated wrong data.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 1da383ce3e9..db4a55bbcd0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -483,7 +483,7 @@ void Item_bool_func2::fix_length_and_dec() DTCollation coll; if (args[0]->result_type() == STRING_RESULT && args[1]->result_type() == STRING_RESULT && - agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(coll, args, 2)) return; args[0]->cmp_context= args[1]->cmp_context= @@ -934,6 +934,7 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, func= &Arg_comparator::compare_datetime; get_value_a_func= &get_datetime_value; get_value_b_func= &get_datetime_value; + cmp_collation.set(&my_charset_numeric); return 0; } else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME && @@ -2173,7 +2174,7 @@ void Item_func_between::fix_length_and_dec() if ( agg_cmp_type(&cmp_type, args, 3)) return; if (cmp_type == STRING_RESULT && - agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(cmp_collation, args, 3)) return; /* @@ -2374,7 +2375,7 @@ Item_func_ifnull::fix_length_and_dec() switch (hybrid_type) { case STRING_RESULT: - agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1); + agg_arg_charsets_for_comparison(collation, args, arg_count); break; case DECIMAL_RESULT: case REAL_RESULT: @@ -2549,12 +2550,12 @@ Item_func_if::fix_length_and_dec() agg_result_type(&cached_result_type, args+1, 2); if (cached_result_type == STRING_RESULT) { - if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV, 1)) + if (agg_arg_charsets_for_string_result(collation, args + 1, 2)) return; } else { - collation.set(&my_charset_bin); // Number + collation.set_numeric(); // Number } cached_field_type= agg_field_type(args + 1, 2); } @@ -2640,7 +2641,7 @@ Item_func_nullif::fix_length_and_dec() unsigned_flag= args[0]->unsigned_flag; cached_result_type= args[0]->result_type(); if (cached_result_type == STRING_RESULT && - agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(collation, args, arg_count)) return; } } @@ -2917,9 +2918,13 @@ void Item_func_case::fix_length_and_dec() agg[nagg++]= args[else_expr_num]; agg_result_type(&cached_result_type, agg, nagg); - if ((cached_result_type == STRING_RESULT) && - agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV, 1)) - return; + if (cached_result_type == STRING_RESULT) + { + if (agg_arg_charsets_for_string_result(collation, agg, nagg)) + return; + } + else + collation.set_numeric(); cached_field_type= agg_field_type(agg, nagg); /* @@ -2944,7 +2949,7 @@ void Item_func_case::fix_length_and_dec() { DBUG_ASSERT((Item_result)i != ROW_RESULT); if ((Item_result)i == STRING_RESULT && - agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(cmp_collation, agg, nagg)) return; if (!(cmp_items[i]= cmp_item::get_comparator((Item_result)i, @@ -3107,7 +3112,7 @@ void Item_func_coalesce::fix_length_and_dec() case STRING_RESULT: count_only_length(); decimals= NOT_FIXED_DEC; - agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1); + agg_arg_charsets_for_string_result(collation, args, arg_count); break; case DECIMAL_RESULT: count_decimal_length(); @@ -3752,7 +3757,7 @@ void Item_func_in::fix_length_and_dec() if (type_cnt == 1) { if (cmp_type == STRING_RESULT && - agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) return; arg_types_compatible= TRUE; } @@ -3930,8 +3935,7 @@ void Item_func_in::fix_length_and_dec() if (found_types & (1 << i) && !cmp_items[i]) { if ((Item_result)i == STRING_RESULT && - agg_arg_charsets(cmp_collation, args, arg_count, - MY_COLL_CMP_CONV, 1)) + agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) return; if (!cmp_items[i] && !(cmp_items[i]= cmp_item::get_comparator((Item_result)i, @@ -4762,7 +4766,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref) max_length= 1; decimals= 0; - if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1)) + if (agg_arg_charsets_for_comparison(cmp_collation, args, 2)) return TRUE; regex_lib_flags= (cmp_collation.collation->state & |