Commit d1607a11 authored by bar@bar.mysql.r18.ru's avatar bar@bar.mysql.r18.ru

FIELD() now takes in account arguments collations

parent 07f94cb7
...@@ -278,6 +278,25 @@ row('A','b','c') = row('a' COLLATE latin1_bin,'b','c') ...@@ -278,6 +278,25 @@ 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 FIELD('b','A','B');
FIELD('b','A','B')
2
select FIELD('B','A','B');
FIELD('B','A','B')
2
select FIELD('b' COLLATE latin1_bin,'A','B');
FIELD('b' COLLATE latin1_bin,'A','B')
0
select FIELD('b','A' COLLATE latin1_bin,'B');
FIELD('b','A' COLLATE latin1_bin,'B')
0
select FIELD(_latin2'b','A','B');
ERROR HY000: Illegal mix of collations for operation 'field'
select FIELD('b',_latin2'A','B');
ERROR HY000: Illegal mix of collations for operation 'field'
select FIELD('b',_latin2'A','B',1);
FIELD('b',_latin2'A','B',1)
1
select POSITION(_latin1'B' IN _latin1'abcd'); select POSITION(_latin1'B' IN _latin1'abcd');
POSITION(_latin1'B' IN _latin1'abcd') POSITION(_latin1'B' IN _latin1'abcd')
2 2
......
...@@ -152,6 +152,19 @@ select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); ...@@ -152,6 +152,19 @@ 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');
#
# Test FIELD() and collations
#
select FIELD('b','A','B');
select FIELD('B','A','B');
select FIELD('b' COLLATE latin1_bin,'A','B');
select FIELD('b','A' COLLATE latin1_bin,'B');
--error 1269
select FIELD(_latin2'b','A','B');
--error 1269
select FIELD('b',_latin2'A','B');
select FIELD('b',_latin2'A','B',1);
select POSITION(_latin1'B' IN _latin1'abcd'); select POSITION(_latin1'B' IN _latin1'abcd');
select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin);
......
...@@ -1118,19 +1118,65 @@ longlong Item_func_locate::val_int() ...@@ -1118,19 +1118,65 @@ longlong Item_func_locate::val_int()
longlong Item_func_field::val_int() longlong Item_func_field::val_int()
{ {
String *field; if (cmp_type == STRING_RESULT)
if (!(field=item->val_str(&value)))
return 0; // -1 if null ?
for (uint i=0 ; i < arg_count ; i++)
{ {
String *tmp_value=args[i]->val_str(&tmp); String *field;
if (tmp_value && field->length() == tmp_value->length() && if (!(field=item->val_str(&value)))
!memcmp(field->ptr(),tmp_value->ptr(),tmp_value->length())) return 0; // -1 if null ?
return (longlong) (i+1); for (uint i=0 ; i < arg_count ; i++)
{
String *tmp_value=args[i]->val_str(&tmp);
if (tmp_value && field->length() == tmp_value->length() &&
!sortcmp(field,tmp_value,cmp_collation.collation))
return (longlong) (i+1);
}
}
else if (cmp_type == INT_RESULT)
{
longlong val= item->val_int();
for (uint i=0; i < arg_count ; i++)
{
if (val == args[i]->val_int())
return (longlong) (i+1);
}
}
else
{
double val= item->val();
for (uint i=0; i < arg_count ; i++)
{
if (val == args[i]->val())
return (longlong) (i+1);
}
} }
return 0; return 0;
} }
void Item_func_field::fix_length_and_dec()
{
maybe_null=0; max_length=3;
used_tables_cache|= item->used_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
cmp_type= item->result_type();
for (uint i=0; i < arg_count ; i++)
cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
if (cmp_type == STRING_RESULT)
{
cmp_collation.set(item->collation);
for (uint i=0 ; i < arg_count ; i++)
{
if (cmp_collation.aggregate(args[i]->collation))
{
my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),func_name());
return;
}
}
}
}
void Item_func_field::split_sum_func(Item **ref_pointer_array, void Item_func_field::split_sum_func(Item **ref_pointer_array,
List<Item> &fields) List<Item> &fields)
......
...@@ -624,6 +624,8 @@ class Item_func_field :public Item_int_func ...@@ -624,6 +624,8 @@ class Item_func_field :public Item_int_func
{ {
Item *item; Item *item;
String value,tmp; String value,tmp;
Item_result cmp_type;
DTCollation cmp_collation;
public: public:
Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {} Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {}
~Item_func_field() { delete item; } ~Item_func_field() { delete item; }
...@@ -641,13 +643,7 @@ public: ...@@ -641,13 +643,7 @@ public:
const_item_cache&= item->const_item(); const_item_cache&= item->const_item();
} }
const char *func_name() const { return "field"; } const char *func_name() const { return "field"; }
void fix_length_and_dec() void fix_length_and_dec();
{
maybe_null=0; max_length=3;
used_tables_cache|= item->used_tables();
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
void set_outer_resolving() void set_outer_resolving()
{ {
item->set_outer_resolving(); item->set_outer_resolving();
......
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