diff options
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r-- | sql/item_func.cc | 171 |
1 files changed, 115 insertions, 56 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index c740b514c7c..e6120f2e93c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -81,12 +81,12 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) } -bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, +bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, Item **av, uint count) { if (agg_arg_collations(c, av, count)) return TRUE; - + if (c.derivation == DERIVATION_NONE) { my_coll_agg_error(av, count, func_name()); @@ -211,7 +211,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) item= *arg; if (item->maybe_null) maybe_null=1; - + with_sum_func= with_sum_func || item->with_sum_func; used_tables_cache|= item->used_tables(); not_null_tables_cache|= item->not_null_tables(); @@ -287,13 +287,19 @@ void Item_func::print(String *str) { str->append(func_name()); str->append('('); - for (uint i=0 ; i < arg_count ; i++) + print_args(str, 0); + str->append(')'); +} + + +void Item_func::print_args(String *str, uint from) +{ + for (uint i=from ; i < arg_count ; i++) { - if (i) + if (i != from) str->append(','); args[i]->print(str); } - str->append(')'); } @@ -462,6 +468,24 @@ String *Item_num_op::val_str(String *str) } +void Item_func_signed::print(String *str) +{ + str->append("cast(", 5); + args[0]->print(str); + str->append(" as signed)", 11); + +} + + +void Item_func_unsigned::print(String *str) +{ + str->append("cast(", 5); + args[0]->print(str); + str->append(" as unsigned)", 13); + +} + + double Item_func_plus::val() { double value=args[0]->val()+args[1]->val(); @@ -1184,6 +1208,21 @@ longlong Item_func_locate::val_int() } +void Item_func_locate::print(String *str) +{ + str->append("locate(", 7); + args[1]->print(str); + str->append(','); + args[0]->print(str); + if (arg_count == 3) + { + str->append(','); + args[2]->print(str); + } + str->append(')'); +} + + longlong Item_func_field::val_int() { if (cmp_type == STRING_RESULT) @@ -1764,7 +1803,7 @@ void item_user_lock_release(ULL *ull) String tmp(buf,sizeof(buf), system_charset_info); tmp.copy(command, strlen(command), tmp.charset()); tmp.append(ull->key,ull->key_length); - tmp.append("\")"); + tmp.append("\")", 2); Query_log_event qev(current_thd, tmp.ptr(), tmp.length(),1); qev.error_code=0; // this query is always safe to run on slave mysql_bin_log.write(&qev); @@ -2049,6 +2088,19 @@ longlong Item_func_benchmark::val_int() } +void Item_func_benchmark::print(String *str) +{ + str->append("benchmark(", 10); + char buffer[20]; + // my_charset_bin is good enough for numbers + String st(buffer, sizeof(buffer), &my_charset_bin); + st.set((ulonglong)loop_count, &my_charset_bin); + str->append(st); + str->append(','); + args[0]->print(str); + str->append(')'); +} + #define extra_size sizeof(double) static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, @@ -2387,9 +2439,9 @@ String *Item_func_set_user_var::val_str(String *str) void Item_func_set_user_var::print(String *str) { - str->append("(@@",3); - str->append(name.str,name.length); - str->append(":=",2); + str->append("(@", 2); + str->append(name.str, name.length); + str->append(":=", 2); args[0]->print(str); str->append(')'); } @@ -2536,7 +2588,7 @@ enum Item_result Item_func_get_user_var::result_type() const void Item_func_get_user_var::print(String *str) { - str->append('@'); + str->append("(@", 2); str->append(name.str,name.length); str->append(')'); } @@ -2604,9 +2656,13 @@ void Item_func_match::init_search(bool no_order) DBUG_VOID_RETURN; if (key == NO_SUCH_KEY) + { + List<Item> fields; + for (uint i=1; i < arg_count; i++) + fields.push_back(args[i]); concat=new Item_func_concat_ws(new Item_string(" ",1, - default_charset_info), - fields); + cmp_collation.collation), fields); + } if (master) { @@ -2618,20 +2674,25 @@ void Item_func_match::init_search(bool no_order) } String *ft_tmp= 0; - char tmp1[FT_QUERY_MAXLEN]; - String tmp2(tmp1,sizeof(tmp1),default_charset_info); // MATCH ... AGAINST (NULL) is meaningless, but possible - if (!(ft_tmp=key_item()->val_str(&tmp2))) + if (!(ft_tmp=key_item()->val_str(&value))) { - ft_tmp= &tmp2; - tmp2.set("",0,default_charset_info); + ft_tmp= &value; + value.set("",0,cmp_collation.collation); } - ft_handler=table->file->ft_init_ext(mode, key, + if (ft_tmp->charset() != cmp_collation.collation) + { + search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(), + cmp_collation.collation); + ft_tmp= &search_value; + } + + if (join_key && !no_order) flags|=FT_SORTED; + ft_handler=table->file->ft_init_ext(flags, key, (byte*) ft_tmp->ptr(), - ft_tmp->length(), - join_key && !no_order); + ft_tmp->length()); if (join_key) table->file->ft_handler=ft_handler; @@ -2642,7 +2703,6 @@ void Item_func_match::init_search(bool no_order) bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { - List_iterator<Item> li(fields); Item *item; maybe_null=1; @@ -2654,51 +2714,37 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) modifications to find_best and auto_close as complement to auto_init code above. */ - if (Item_func::fix_fields(thd, tlist, ref) || !const_item()) + if (Item_func::fix_fields(thd, tlist, ref) || !args[0]->const_item()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); return 1; } - while ((item=li++)) + const_item_cache=0; + for (uint i=1 ; i < arg_count ; i++) { - if (item->fix_fields(thd, tlist, li.ref()) || item->check_cols(1)) - return 1; + item=args[i]; if (item->type() == Item::REF_ITEM) - li.replace(item= *((Item_ref *)item)->ref); - if (item->type() != Item::FIELD_ITEM || !item->used_tables()) + args[i]= item= *((Item_ref *)item)->ref; + if (item->type() != Item::FIELD_ITEM) key=NO_SUCH_KEY; used_tables_cache|=item->used_tables(); } /* check that all columns come from the same table */ if (my_count_bits(used_tables_cache) != 1) key=NO_SUCH_KEY; - const_item_cache=0; - table=((Item_field *)fields.head())->field->table; - table->fulltext_searched=1; - record=table->record[0]; - if (key == NO_SUCH_KEY && mode != FT_BOOL) + if (key == NO_SUCH_KEY && !(flags & FT_BOOL)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); return 1; } - - return 0; -} - -bool Item_func_match::walk(Item_processor processor, byte *arg) -{ - List_iterator_fast<Item> li(fields); - Item *item; - while ((item= li++)) - if (item->walk(processor, arg)) - return 1; - return Item_func::walk(processor, arg); + table=((Item_field *)item)->field->table; + table->fulltext_searched=1; + return agg_arg_collations_for_comparison(cmp_collation, args+1, arg_count-1); } bool Item_func_match::fix_index() { - List_iterator_fast<Item> li(fields); Item_field *item; uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr; uint max_cnt=0, mkeys=0; @@ -2709,7 +2755,7 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr < table->keys ; keynr++) { if ((table->key_info[keynr].flags & HA_FULLTEXT) && - (table->keys_in_use_for_query & (((key_map)1) << keynr))) + (table->keys_in_use_for_query.is_set(keynr))) { ft_to_key[fts]=keynr; ft_cnt[fts]=0; @@ -2720,8 +2766,9 @@ bool Item_func_match::fix_index() if (!fts) goto err; - while ((item=(Item_field*)(li++))) + for (uint i=1; i < arg_count; i++) { + item=(Item_field*)args[i]; for (keynr=0 ; keynr < fts ; keynr++) { KEY *ft_key=&table->key_info[ft_to_key[keynr]]; @@ -2755,8 +2802,8 @@ bool Item_func_match::fix_index() for (keynr=0 ; keynr <= mkeys ; keynr++) { - // for now, partial keys won't work. SerG - if (max_cnt < fields.elements || + // partial keys doesn't work + if (max_cnt < arg_count-1 || max_cnt < table->key_info[ft_to_key[keynr]].key_parts) continue; @@ -2766,21 +2813,20 @@ bool Item_func_match::fix_index() } err: - if (mode == FT_BOOL) + if (flags & FT_BOOL) { key=NO_SUCH_KEY; return 0; } - my_printf_error(ER_FT_MATCHING_KEY_NOT_FOUND, - ER(ER_FT_MATCHING_KEY_NOT_FOUND),MYF(0)); + my_error(ER_FT_MATCHING_KEY_NOT_FOUND,MYF(0)); return 1; } bool Item_func_match::eq(const Item *item, bool binary_cmp) const { - if (item->type() != FUNC_ITEM || - func_name() != ((Item_func*)item)->func_name()) + if (item->type() != FUNC_ITEM || ((Item_func*)item)->functype() != FT_FUNC || + flags != ((Item_func_match*)item)->flags) return 0; Item_func_match *ifm=(Item_func_match*) item; @@ -2818,9 +2864,22 @@ double Item_func_match::val() (byte *)a->ptr(), a->length())); } else - DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, record, 0)); + DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, + table->record[0], 0)); } +void Item_func_match::print(String *str) +{ + str->append("(match ", 7); + print_args(str, 1); + str->append(" against (", 10); + args[0]->print(str); + if (flags & FT_BOOL) + str->append(" in boolean mode", 16); + else if (flags & FT_EXPAND) + str->append(" with query expansion", 21); + str->append("))", 2); +} longlong Item_func_bit_xor::val_int() { |