summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorbar@bar.myoffice.izhnet.ru <>2007-08-03 17:16:02 +0500
committerbar@bar.myoffice.izhnet.ru <>2007-08-03 17:16:02 +0500
commitfb8dff9721c99fc7b9b07bdffc54b671eb5624f9 (patch)
tree35a4ca131042aba598547cd40d5d5926942e3068 /sql/item.cc
parentf42cf05ad4a7e988403a2ff60f1999d69cf98e87 (diff)
parent4eebfd09c2b045258615bf07990deb6f0f73f729 (diff)
downloadmariadb-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.cc46
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)
{