diff options
author | unknown <bar@mysql.com> | 2004-11-02 16:02:12 +0400 |
---|---|---|
committer | unknown <bar@mysql.com> | 2004-11-02 16:02:12 +0400 |
commit | fc04692c8b5fb192b9be52d4672423aa41ebc6b1 (patch) | |
tree | bfda701b872e8feb1aace99aa6e20993e2150d6b /sql/item_cmpfunc.cc | |
parent | 0d92f0c777e170b4de4eff45e3f1ed08f3ccc836 (diff) | |
download | mariadb-git-fc04692c8b5fb192b9be52d4672423aa41ebc6b1.tar.gz |
Many files:
Allow mixing of different character sets for more SQL functions.
item_func.h:
Allow mixing of different character sets for more SQL functions..
sql/item_cmpfunc.cc:
Allow mixing of different character sets for more SQL functions.
sql/item_func.cc:
Allow mixing of different character sets for more SQL functions.
sql/item_func.h:
Allow mixing of different character sets for more SQL functions..
sql/item_strfunc.cc:
Allow mixing of different character sets for more SQL functions.
sql/item.cc:
Allow mixing of different character sets for more SQL functions.
sql/item.h:
Allow mixing of different character sets for more SQL functions.
mysql-test/t/ctype_recoding.test:
Allow mixing of different character sets for more SQL functions.
mysql-test/r/ctype_recoding.result:
Allow mixing of different character sets for more SQL functions.
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 96 |
1 files changed, 9 insertions, 87 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d9db07e2289..701894cacb5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -173,89 +173,11 @@ void Item_bool_func2::fix_length_and_dec() if (!args[0] || !args[1]) return; - /* - 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. - */ - - uint32 dummy_offset; DTCollation coll; - if (args[0]->result_type() == STRING_RESULT && args[1]->result_type() == STRING_RESULT && - String::needs_conversion(0, args[0]->collation.collation, - args[1]->collation.collation, - &dummy_offset) && - !coll.set(args[0]->collation, args[1]->collation, - MY_COLL_ALLOW_SUPERSET_CONV | - MY_COLL_ALLOW_COERCIBLE_CONV)) - { - Item* conv= 0; - Item_arena *arena= thd->current_arena, backup; - uint strong= coll.strong; - uint weak= strong ? 0 : 1; - /* - In case we're in statement prepare, create conversion item - in its memory: it will be reused on each execute. - */ - if (arena->is_stmt_prepare()) - thd->set_n_backup_item_arena(arena, &backup); - if (args[weak]->type() == STRING_ITEM) - { - uint conv_errors; - String tmp, cstr, *ostr= args[weak]->val_str(&tmp); - cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), - args[strong]->collation.collation, &conv_errors); - if (conv_errors) - { - /* - We could not convert a string into the character set - of the stronger side of the operation without data loss. - It can happen if we tried to combine a column with a string - constant, and the column charset does not cover all the - characters from the string. Operation cannot be done - correctly. Return an error. - */ - my_coll_agg_error(args[0]->collation, args[1]->collation, - func_name()); - return; - } - conv= new Item_string(cstr.ptr(),cstr.length(),cstr.charset(), - args[weak]->collation.derivation); - ((Item_string*)conv)->str_value.copy(); - } - else - { - if (!(coll.collation->state & MY_CS_UNICODE)) - { - /* - Don't allow automatic conversion to non-Unicode charsets, - as it potentially loses data. - */ - my_coll_agg_error(args[0]->collation, args[1]->collation, - func_name()); - return; - } - conv= new Item_func_conv_charset(args[weak], - args[strong]->collation.collation); - conv->collation.set(args[weak]->collation.derivation); - conv->fix_fields(thd, 0, &conv); - } - if (arena->is_stmt_prepare()) - thd->restore_backup_item_arena(arena, &backup); - args[weak]= conv ? conv : args[weak]; - } + agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV)) + return; // Make a special case of compare with fields to get nicer DATE comparisons @@ -871,7 +793,7 @@ void Item_func_between::fix_length_and_dec() return; agg_cmp_type(&cmp_type, args, 3); if (cmp_type == STRING_RESULT && - agg_arg_collations_for_comparison(cmp_collation, args, 3)) + agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV)) return; /* @@ -987,7 +909,7 @@ Item_func_ifnull::fix_length_and_dec() decimals=max(args[0]->decimals,args[1]->decimals); agg_result_type(&cached_result_type, args, 2); if (cached_result_type == STRING_RESULT) - agg_arg_collations(collation, args, arg_count); + agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV); else if (cached_result_type != REAL_RESULT) decimals= 0; @@ -1083,7 +1005,7 @@ 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_collations(collation, args+1, 2)) + if (agg_arg_charsets(collation, args+1, 2, MY_COLL_ALLOW_CONV)) return; } else @@ -1354,7 +1276,7 @@ void Item_func_case::fix_length_and_dec() agg_result_type(&cached_result_type, agg, nagg); if ((cached_result_type == STRING_RESULT) && - agg_arg_collations(collation, agg, nagg)) + agg_arg_charsets(collation, agg, nagg, MY_COLL_ALLOW_CONV)) return; @@ -1370,7 +1292,7 @@ void Item_func_case::fix_length_and_dec() nagg++; agg_cmp_type(&cmp_type, agg, nagg); if ((cmp_type == STRING_RESULT) && - agg_arg_collations_for_comparison(cmp_collation, agg, nagg)) + agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV)) return; } @@ -1477,7 +1399,7 @@ void Item_func_coalesce::fix_length_and_dec() set_if_bigger(decimals,args[i]->decimals); } if (cached_result_type == STRING_RESULT) - agg_arg_collations(collation, args, arg_count); + agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV); else if (cached_result_type != REAL_RESULT) decimals= 0; } @@ -2423,7 +2345,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) max_length= 1; decimals= 0; - if (agg_arg_collations(cmp_collation, args, 2)) + if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV)) return 1; used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); |