Commit 3b09b2f0 authored by unknown's avatar unknown

New methods

  Item_func::agg_arg_collations()
  Item_func::arr_arg_collations_for_comparison()
 to aggregate argument collations.
It helps to reuse a lot of code.

parent c2a4a0ec
...@@ -278,6 +278,12 @@ row('A','b','c') = row('a' COLLATE latin1_bin,'b','c') ...@@ -278,6 +278,12 @@ row('A','b','c') = row('a' COLLATE latin1_bin,'b','c')
0 0
select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c');
ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation '=' ERROR HY000: Illegal mix of collations (latin1_general_ci,EXPLICIT) and (latin1_bin,EXPLICIT) for operation '='
select concat(_latin1'a',_latin2'a');
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE) and (latin2_general_ci,COERCIBLE) for operation 'concat'
select concat(_latin1'a',_latin2'a',_latin5'a');
ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin5_turkish_ci,COERCIBLE) for operation 'concat'
select concat(_latin1'a',_latin2'a',_latin5'a',_latin7'a');
ERROR HY000: Illegal mix of collations for operation 'concat'
select FIELD('b','A','B'); select FIELD('b','A','B');
FIELD('b','A','B') FIELD('b','A','B')
2 2
......
...@@ -152,6 +152,14 @@ select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); ...@@ -152,6 +152,14 @@ select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c');
--error 1265 --error 1265
select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c');
--error 1265
select concat(_latin1'a',_latin2'a');
--error 1268
select concat(_latin1'a',_latin2'a',_latin5'a');
--error 1269
select concat(_latin1'a',_latin2'a',_latin5'a',_latin7'a');
# #
# Test FIELD() and collations # Test FIELD() and collations
# #
......
...@@ -39,6 +39,61 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam ...@@ -39,6 +39,61 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam
fname); fname);
} }
static void my_coll_agg_error(DTCollation &c1,
DTCollation &c2,
DTCollation &c3,
const char *fname)
{
my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0),
c1.collation->name,c1.derivation_name(),
c2.collation->name,c2.derivation_name(),
c3.collation->name,c3.derivation_name(),
fname);
}
static void my_coll_agg_error(Item** args, uint ac, const char *fname)
{
if (2 == ac)
my_coll_agg_error(args[0]->collation, args[1]->collation, fname);
else if (3 == ac)
my_coll_agg_error(args[0]->collation,
args[1]->collation,
args[2]->collation,
fname);
else
my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname);
}
bool Item_func::agg_arg_collations(DTCollation &c, uint from, uint argc)
{
uint i;
c.set(args[from]->collation);
for (i= from+1; i < argc; i++)
{
if (c.aggregate(args[i]->collation))
{
my_coll_agg_error(args+from, argc-from, func_name());
return TRUE;
}
}
return FALSE;
}
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
uint from, uint argc)
{
if (agg_arg_collations(c, from, argc))
return FALSE;
if (c.derivation == DERIVATION_NONE)
{
my_coll_agg_error(args+from, argc-from, func_name());
return TRUE;
}
return FALSE;
}
/* return TRUE if item is a constant */ /* return TRUE if item is a constant */
bool bool
......
...@@ -135,6 +135,9 @@ class Item_func :public Item_result_field ...@@ -135,6 +135,9 @@ class Item_func :public Item_result_field
Field *tmp_table_field(TABLE *t_arg); Field *tmp_table_field(TABLE *t_arg);
void set_outer_resolving(); void set_outer_resolving();
Item *get_tmp_table_item(THD *thd); Item *get_tmp_table_item(THD *thd);
bool agg_arg_collations(DTCollation &c, uint from, uint argc);
bool agg_arg_collations_for_comparison(DTCollation &c, uint from, uint argc);
}; };
......
...@@ -44,18 +44,6 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam ...@@ -44,18 +44,6 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam
fname); fname);
} }
static void my_coll_agg3_error(DTCollation &c1,
DTCollation &c2,
DTCollation &c3,
const char *fname)
{
my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0),
c1.collation->name,c1.derivation_name(),
c2.collation->name,c2.derivation_name(),
c3.collation->name,c3.derivation_name(),
fname);
}
uint nr_of_decimals(const char *str) uint nr_of_decimals(const char *str)
{ {
if ((str=strchr(str,'.'))) if ((str=strchr(str,'.')))
...@@ -336,16 +324,11 @@ void Item_func_concat::fix_length_and_dec() ...@@ -336,16 +324,11 @@ void Item_func_concat::fix_length_and_dec()
bool first_coll= 1; bool first_coll= 1;
max_length=0; max_length=0;
collation.set(args[0]->collation); if (agg_arg_collations(collation, 0, arg_count))
return;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (collation.aggregate(args[i]->collation))
{
my_coll_agg_error(collation, args[i]->collation, func_name());
break;
}
}
if (max_length > MAX_BLOB_WIDTH) if (max_length > MAX_BLOB_WIDTH)
{ {
...@@ -840,13 +823,8 @@ void Item_func_replace::fix_length_and_dec() ...@@ -840,13 +823,8 @@ void Item_func_replace::fix_length_and_dec()
maybe_null=1; maybe_null=1;
} }
collation.set(args[0]->collation); if (agg_arg_collations_for_comparison(collation, 0, 3))
if (!collation.aggregate(args[1]->collation)) return;
collation.aggregate(args[2]->collation);
if (collation.derivation == DERIVATION_NONE)
my_coll_agg3_error(args[0]->collation, args[1]->collation,
args[2]->collation, func_name());
} }
...@@ -1050,9 +1028,9 @@ void Item_func_substr::fix_length_and_dec() ...@@ -1050,9 +1028,9 @@ void Item_func_substr::fix_length_and_dec()
void Item_func_substr_index::fix_length_and_dec() void Item_func_substr_index::fix_length_and_dec()
{ {
max_length= args[0]->max_length; max_length= args[0]->max_length;
if (collation.set(args[0]->collation, args[1]->collation) ||
(collation.derivation == DERIVATION_NONE)) if (agg_arg_collations_for_comparison(collation, 0, 2))
my_coll_agg_error(args[0]->collation, args[1]->collation, func_name()); return;
} }
...@@ -1680,20 +1658,13 @@ void Item_func_elt::fix_length_and_dec() ...@@ -1680,20 +1658,13 @@ void Item_func_elt::fix_length_and_dec()
max_length=0; max_length=0;
decimals=0; decimals=0;
if (agg_arg_collations(collation, 0, arg_count))
return;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
set_if_bigger(max_length,args[i]->max_length); set_if_bigger(max_length,args[i]->max_length);
set_if_bigger(decimals,args[i]->decimals); set_if_bigger(decimals,args[i]->decimals);
if (i == 0)
collation.set(args[0]->collation);
else
{
if (collation.aggregate(args[i]->collation))
{
my_coll_agg_error(collation, args[i]->collation, func_name());
break;
}
}
} }
maybe_null=1; // NULL if wrong first arg maybe_null=1; // NULL if wrong first arg
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
...@@ -1786,16 +1757,13 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, ...@@ -1786,16 +1757,13 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
void Item_func_make_set::fix_length_and_dec() void Item_func_make_set::fix_length_and_dec()
{ {
max_length=arg_count-1; max_length=arg_count-1;
collation.set(args[0]->collation);
if (agg_arg_collations(collation, 0, arg_count))
return;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{
max_length+=args[i]->max_length; max_length+=args[i]->max_length;
if (collation.aggregate(args[i]->collation))
{
my_coll_agg_error(collation, args[i]->collation, func_name());
break;
}
}
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item(); const_item_cache&=item->const_item();
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
...@@ -2463,15 +2431,8 @@ void Item_func_export_set::fix_length_and_dec() ...@@ -2463,15 +2431,8 @@ void Item_func_export_set::fix_length_and_dec()
uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
max_length=length*64+sep_length*63; max_length=length*64+sep_length*63;
collation.set(args[1]->collation); if (agg_arg_collations(collation,1, min(4,arg_count)))
for (i=2 ; i < 4 && i < arg_count ; i++) return;
{
if (collation.aggregate(args[i]->collation))
{
my_coll_agg_error(collation, args[i]->collation, func_name());
break;
}
}
} }
String* Item_func_inet_ntoa::val_str(String* str) String* Item_func_inet_ntoa::val_str(String* str)
......
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