summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
committerunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
commitf095274fe8c3d3394d6c0ce0a68f4bea04311999 (patch)
tree23bcc9a71fe7237887a111b158e30f5a6bb665d3 /sql/item_func.cc
parentf41bba8c6156a7adf4c67dfa75e16112767a5d3c (diff)
parent5be6c328f5a9f78f37176bbbd88a538fa3b65fe9 (diff)
downloadmariadb-git-f095274fe8c3d3394d6c0ce0a68f4bea04311999.tar.gz
merge with 4.1
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BitKeeper/triggers/post-commit: Auto merged Docs/Support/texi2html: Auto merged Makefile.am: Auto merged client/Makefile.am: Auto merged client/mysql.cc: Auto merged client/mysqldump.c: Auto merged include/my_base.h: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/my_sys.h: Auto merged include/my_time.h: Auto merged include/mysql.h: Auto merged include/mysql_com.h: Auto merged innobase/buf/buf0buf.c: Auto merged innobase/include/row0mysql.h: Auto merged innobase/row/row0sel.c: Auto merged libmysql/libmysql.c: Auto merged libmysqld/examples/Makefile.am: Auto merged myisam/mi_check.c: Auto merged mysql-test/include/ps_modify.inc: Auto merged mysql-test/install_test_db.sh: Auto merged mysql-test/r/alter_table.result: Auto merged mysql-test/r/auto_increment.result: Auto merged mysql-test/r/bdb.result: Auto merged mysql-test/r/ctype_latin1_de.result: Auto merged mysql-test/r/ctype_recoding.result: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/func_gconcat.result: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/func_if.result: Auto merged mysql-test/t/derived.test: Auto merged mysql-test/t/insert.test: merge with 4.1 Fixed test case to not use 'if exists' when it shouldn't mysql-test/t/range.test: merge with 4.1 Added missing drop table sql/ha_ndbcluster.cc: merge with 4.1 Simple optimization: use max() instead of ? : sql/item_func.cc: merge with 4.1 (Added back old variable names for easier merges) sql/opt_range.cc: merge with 4.1 Removed argument 'parent_alloc' from QUICK_RANGE_SELECT as this was not used Added assert if using QUICK_GROUP_MIN_MAX_SELECT with parent_alloc as the init() function can't handle this Changed back get_quick_select_for_ref() to use it's own alloc root becasue this function may be called several times for one query sql/sql_handler.cc: merge with 4.1 change variable 'err' to 'error' as same function had a label named 'err' sql/sql_update.cc: Use multi-update code from 5.0 instead of 4.1 We will fix the locking code shortly in 5.0 to be faster than in 4.1
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc74
1 files changed, 53 insertions, 21 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index fe5112cd75b..58ef44cc225 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -299,20 +299,22 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument)
}
-void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
+void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
+ List<Item> &fields)
{
Item **arg, **arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
{
Item *item=* arg;
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
- item->split_sum_func(ref_pointer_array, fields);
+ item->split_sum_func(thd, ref_pointer_array, fields);
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
{
uint el= fields.elements;
+ Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
fields.push_front(item);
ref_pointer_array[el]= item;
- *arg= new Item_ref(ref_pointer_array + el, arg, 0, item->name);
+ thd->change_item_tree(arg, new_item);
}
}
}
@@ -718,8 +720,8 @@ void Item_func_int_div::fix_length_and_dec()
double Item_func_mod::val()
{
DBUG_ASSERT(fixed == 1);
- double value= floor(args[0]->val()+0.5);
- double val2=floor(args[1]->val()+0.5);
+ double value= args[0]->val();
+ double val2= args[1]->val();
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0.0; /* purecov: inspected */
if (val2 == 0.0)
@@ -747,10 +749,7 @@ longlong Item_func_mod::val_int()
void Item_func_mod::fix_length_and_dec()
{
- max_length=args[1]->max_length;
- decimals=0;
- maybe_null=1;
- find_num_type();
+ Item_num_op::fix_length_and_dec();
}
@@ -1087,21 +1086,38 @@ double Item_func_round::val()
}
-void Item_func_rand::fix_length_and_dec()
+bool Item_func_rand::fix_fields(THD *thd, struct st_table_list *tables,
+ Item **ref)
{
- decimals=NOT_FIXED_DEC;
- max_length=float_length(decimals);
+ Item_real_func::fix_fields(thd, tables, ref);
used_tables_cache|= RAND_TABLE_BIT;
if (arg_count)
{ // Only use argument once in query
- uint32 tmp= (uint32) (args[0]->val_int());
- if ((rand= (struct rand_struct*) sql_alloc(sizeof(*rand))))
- randominit(rand,(uint32) (tmp*0x10001L+55555555L),
- (uint32) (tmp*0x10000001L));
+ /*
+ Allocate rand structure once: we must use thd->current_arena
+ to create rand in proper mem_root if it's a prepared statement or
+ stored procedure.
+ */
+ if (!rand && !(rand= (struct rand_struct*)
+ thd->current_arena->alloc(sizeof(*rand))))
+ return TRUE;
+ /*
+ PARAM_ITEM is returned if we're in statement prepare and consequently
+ no placeholder value is set yet.
+ */
+ if (args[0]->type() != PARAM_ITEM)
+ {
+ /*
+ TODO: do not do reinit 'rand' for every execute of PS/SP if
+ args[0] is a constant.
+ */
+ uint32 tmp= (uint32) args[0]->val_int();
+ randominit(rand, (uint32) (tmp*0x10001L+55555555L),
+ (uint32) (tmp*0x10000001L));
+ }
}
else
{
- THD *thd= current_thd;
/*
No need to send a Rand log event if seed was given eg: RAND(seed),
as it will be replicated in the query as such.
@@ -1115,6 +1131,7 @@ void Item_func_rand::fix_length_and_dec()
thd->rand_saved_seed2=thd->rand.seed2;
rand= &thd->rand;
}
+ return FALSE;
}
void Item_func_rand::update_used_tables()
@@ -1534,10 +1551,11 @@ longlong Item_func_find_in_set::val_int()
{
const char *substr_end= str_end + symbol_len;
bool is_last_item= (substr_end == real_end);
- if (wc == (my_wc_t) separator || is_last_item)
+ bool is_separator= (wc == (my_wc_t) separator);
+ if (is_separator || is_last_item)
{
position++;
- if (is_last_item)
+ if (is_last_item && !is_separator)
str_end= substr_end;
if (!my_strnncoll(cs, (const uchar *) str_begin,
str_end - str_begin,
@@ -2820,7 +2838,21 @@ void Item_func_get_user_var::fix_length_and_dec()
error= get_var_with_binlog(thd, name, &var_entry);
if (var_entry)
+ {
collation.set(var_entry->collation);
+ switch (var_entry->type) {
+ case REAL_RESULT:
+ max_length= DBL_DIG + 8;
+ case INT_RESULT:
+ max_length= MAX_BIGINT_WIDTH;
+ break;
+ case STRING_RESULT:
+ max_length= MAX_BLOB_WIDTH;
+ break;
+ case ROW_RESULT: // Keep compiler happy
+ break;
+ }
+ }
else
null_value= 1;
@@ -2937,10 +2969,10 @@ void Item_func_match::init_search(bool no_order)
if (key == NO_SUCH_KEY)
{
List<Item> fields;
+ fields.push_back(new Item_string(" ",1, cmp_collation.collation));
for (uint i=1; i < arg_count; i++)
fields.push_back(args[i]);
- concat=new Item_func_concat_ws(new Item_string(" ",1,
- cmp_collation.collation), fields);
+ concat=new Item_func_concat_ws(fields);
/*
Above function used only to get value and do not need fix_fields for it:
Item_string - basic constant