Commit 4f32cd2b authored by bar@mysql.com's avatar bar@mysql.com

Move collation aggregation with superset conversion code

from Item_bool_func2 into DTCollation to make it reusable
for other types of items.
parent 3ee57276
......@@ -265,8 +265,9 @@ CHARSET_INFO *Item::default_charset()
return current_thd->variables.collation_connection;
}
bool DTCollation::aggregate(DTCollation &dt)
bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion)
{
nagg++;
if (!my_charset_same(collation, dt.collation))
{
/*
......@@ -280,15 +281,39 @@ bool DTCollation::aggregate(DTCollation &dt)
if (derivation <= dt.derivation)
; // Do nothing
else
{
set(dt);
strong= nagg;
}
}
else if (dt.collation == &my_charset_bin)
{
if (dt.derivation <= derivation)
{
set(dt);
strong= nagg;
}
else
; // Do nothing
}
else if (superset_conversion)
{
if (derivation < dt.derivation &&
collation->state & MY_CS_UNICODE)
; // Do nothing
else if (dt.derivation < derivation &&
dt.collation->state & MY_CS_UNICODE)
{
set(dt);
strong= nagg;
}
else
{
// Cannot convert to superset
set(0, DERIVATION_NONE);
return 1;
}
}
else
{
set(0, DERIVATION_NONE);
......@@ -302,6 +327,7 @@ bool DTCollation::aggregate(DTCollation &dt)
else if (dt.derivation < derivation)
{
set(dt);
strong= nagg;
}
else
{
......
......@@ -41,16 +41,22 @@ class DTCollation {
public:
CHARSET_INFO *collation;
enum Derivation derivation;
uint nagg; // Total number of aggregated collations.
uint strong; // Number of the strongest collation.
DTCollation()
{
collation= &my_charset_bin;
derivation= DERIVATION_NONE;
nagg= 0;
strong= 0;
}
DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg)
{
collation= collation_arg;
derivation= derivation_arg;
nagg= 0;
strong= 0;
}
void set(DTCollation &dt)
{
......@@ -66,9 +72,9 @@ public:
{ collation= collation_arg; }
void set(Derivation derivation_arg)
{ derivation= derivation_arg; }
bool aggregate(DTCollation &dt);
bool set(DTCollation &dt1, DTCollation &dt2)
{ set(dt1); return aggregate(dt2); }
bool aggregate(DTCollation &dt, bool superset_conversion= FALSE);
bool set(DTCollation &dt1, DTCollation &dt2, bool superset_conversion= FALSE)
{ set(dt1); return aggregate(dt2, superset_conversion); }
const char *derivation_name() const
{
switch(derivation)
......
......@@ -188,25 +188,17 @@ void Item_bool_func2::fix_length_and_dec()
{
uint strong= 0;
uint weak= 0;
DTCollation coll;
if ((args[0]->collation.derivation < args[1]->collation.derivation) &&
if (args[0]->result_type() == STRING_RESULT &&
args[1]->result_type() == STRING_RESULT &&
!my_charset_same(args[0]->collation.collation,
args[1]->collation.collation) &&
(args[0]->collation.collation->state & MY_CS_UNICODE))
{
weak= 1;
}
else if ((args[1]->collation.derivation < args[0]->collation.derivation) &&
!my_charset_same(args[0]->collation.collation,
args[1]->collation.collation) &&
(args[1]->collation.collation->state & MY_CS_UNICODE))
{
strong= 1;
}
if (strong || weak)
!coll.set(args[0]->collation, args[1]->collation, TRUE))
{
Item* conv= 0;
strong= coll.strong;
weak= strong ? 0 : 1;
if (args[weak]->type() == STRING_ITEM)
{
String tmp, cstr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment