summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc171
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()
{