diff options
author | bar@bar.myoffice.izhnet.ru <> | 2007-08-03 17:16:02 +0500 |
---|---|---|
committer | bar@bar.myoffice.izhnet.ru <> | 2007-08-03 17:16:02 +0500 |
commit | fb8dff9721c99fc7b9b07bdffc54b671eb5624f9 (patch) | |
tree | 35a4ca131042aba598547cd40d5d5926942e3068 /sql/item.cc | |
parent | f42cf05ad4a7e988403a2ff60f1999d69cf98e87 (diff) | |
parent | 4eebfd09c2b045258615bf07990deb6f0f73f729 (diff) | |
download | mariadb-git-fb8dff9721c99fc7b9b07bdffc54b671eb5624f9.tar.gz |
Merge mysql.com:/home/bar/mysql-work/mysql-5.0.b28875
into mysql.com:/home/bar/mysql-work/mysql-5.1.b28875
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/sql/item.cc b/sql/item.cc index 593915ef172..006595a39a9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1358,6 +1358,25 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, } +static bool +left_is_superset(DTCollation *left, DTCollation *right) +{ + /* Allow convert to Unicode */ + if (left->collation->state & MY_CS_UNICODE && + (left->derivation < right->derivation || + (left->derivation == right->derivation && + !(right->collation->state & MY_CS_UNICODE)))) + return TRUE; + /* Allow convert from ASCII */ + if (right->repertoire == MY_REPERTOIRE_ASCII && + (left->derivation < right->derivation || + (left->derivation == right->derivation && + !(left->repertoire == MY_REPERTOIRE_ASCII)))) + return TRUE; + /* Disallow conversion otherwise */ + return FALSE; +} + /* Aggregate two collations together taking into account their coercibility (aka derivation): @@ -1422,18 +1441,12 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) ; // Do nothing } else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && - collation->state & MY_CS_UNICODE && - (derivation < dt.derivation || - (derivation == dt.derivation && - !(dt.collation->state & MY_CS_UNICODE)))) + left_is_superset(this, &dt)) { // Do nothing } else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && - dt.collation->state & MY_CS_UNICODE && - (dt.derivation < derivation || - (dt.derivation == derivation && - !(collation->state & MY_CS_UNICODE)))) + left_is_superset(&dt, this)) { set(dt); } @@ -1452,7 +1465,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) else { // Cannot apply conversion - set(0, DERIVATION_NONE); + set(0, DERIVATION_NONE, 0); return 1; } } @@ -1474,8 +1487,8 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) { if (derivation == DERIVATION_EXPLICIT) { - set(0, DERIVATION_NONE); - return 1; + set(0, DERIVATION_NONE, 0); + return 1; } if (collation->state & MY_CS_BINSORT) return 0; @@ -1489,6 +1502,7 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) set(bin, DERIVATION_NONE); } } + repertoire|= dt.repertoire; return 0; } @@ -1632,12 +1646,16 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, { Item* conv; uint32 dummy_offset; - if (!String::needs_conversion(0, coll.collation, - (*arg)->collation.collation, + if (!String::needs_conversion(0, (*arg)->collation.collation, + coll.collation, &dummy_offset)) continue; - if (!(conv= (*arg)->safe_charset_converter(coll.collation))) + if (!(conv= (*arg)->safe_charset_converter(coll.collation)) && + ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII)) + conv= new Item_func_conv_charset(*arg, coll.collation, 1); + + if (!conv) { if (nargs >=2 && nargs <= 3) { |