diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 208efc51acb..12969449e3f 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -297,9 +297,9 @@ select FIELD('b','A' COLLATE latin1_bin,'B'); FIELD('b','A' COLLATE latin1_bin,'B') 0 select FIELD(_latin2'b','A','B'); -Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +ERROR HY000: Illegal mix of collations (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' select FIELD('b',_latin2'A','B'); -Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' +ERROR HY000: Illegal mix of collations (latin1_swedish_ci,COERCIBLE), (latin2_general_ci,COERCIBLE), (latin1_swedish_ci,COERCIBLE) for operation 'field' select FIELD('b',_latin2'A','B',1); FIELD('b',_latin2'A','B',1) 1 diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 7748694169f..38633e87c4b 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -167,9 +167,9 @@ 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 1265 +--error 1268 select FIELD(_latin2'b','A','B'); ---error 1265 +--error 1268 select FIELD('b',_latin2'A','B'); select FIELD('b',_latin2'A','B',1); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b25619d0bb1..4e35e90b429 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1660,81 +1660,53 @@ void Item_func_elt::fix_length_and_dec() max_length=0; decimals=0; - if (agg_arg_collations(collation, args, arg_count)) + if (agg_arg_collations(collation, args+1, arg_count-1)) return; - for (uint i=0 ; i < arg_count ; i++) + for (uint i=1 ; i < arg_count ; i++) { set_if_bigger(max_length,args[i]->max_length); set_if_bigger(decimals,args[i]->decimals); } maybe_null=1; // NULL if wrong first arg - with_sum_func= with_sum_func || item->with_sum_func; - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); -} - - -void Item_func_elt::split_sum_func(Item **ref_pointer_array, - List &fields) -{ - if (item->with_sum_func && item->type() != SUM_FUNC_ITEM) - item->split_sum_func(ref_pointer_array, fields); - else if (item->used_tables() || item->type() == SUM_FUNC_ITEM) - { - uint el= fields.elements; - fields.push_front(item); - ref_pointer_array[el]= item; - item= new Item_ref(ref_pointer_array + el, 0, item->name); - } - Item_str_func::split_sum_func(ref_pointer_array, fields); -} - - -void Item_func_elt::update_used_tables() -{ - Item_func::update_used_tables(); - item->update_used_tables(); - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); } double Item_func_elt::val() { uint tmp; - if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) + if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) { null_value=1; return 0.0; } null_value=0; - return args[tmp-1]->val(); + return args[tmp]->val(); } longlong Item_func_elt::val_int() { uint tmp; - if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) + if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) { null_value=1; return 0; } null_value=0; - return args[tmp-1]->val_int(); + return args[tmp]->val_int(); } String *Item_func_elt::val_str(String *str) { uint tmp; String *res; - if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) + if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) { null_value=1; return NULL; } null_value=0; - res= args[tmp-1]->val_str(str); + res= args[tmp]->val_str(str); res->set_charset(charset()); return res; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6cc6d730627..7f8d7ade67b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -372,29 +372,13 @@ public: class Item_func_elt :public Item_str_func { - Item *item; - public: - Item_func_elt(Item *a,List &list) :Item_str_func(list),item(a) {} - ~Item_func_elt() { delete item; } + Item_func_elt(List &list) :Item_str_func(list) {} double val(); longlong val_int(); String *val_str(String *str); - bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) - { - return (item->fix_fields(thd, tlist, &item) || - item->check_cols(1) || - Item_func::fix_fields(thd, tlist, ref)); - } - void split_sum_func(Item **ref_pointer_array, List &fields); void fix_length_and_dec(); - void update_used_tables(); const char *func_name() const { return "elt"; } - void set_outer_resolving() - { - item->set_outer_resolving(); - Item_str_func::set_outer_resolving(); - } }; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c07876a18cc..45a647cd8ab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2389,7 +2389,7 @@ simple_expr: | DAY_SYM '(' expr ')' { $$= new Item_func_dayofmonth($3); } | ELT_FUNC '(' expr ',' expr_list ')' - { $$= new Item_func_elt($3, *$5); } + { $5->push_front($3); $$= new Item_func_elt(*$5); } | MAKE_SET_SYM '(' expr ',' expr_list ')' { $$= new Item_func_make_set($3, *$5); } | ENCRYPT '(' expr ')'