summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.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
commit952c09b308f9f70c2b6c3c2c07ae510527b09656 (patch)
tree23bcc9a71fe7237887a111b158e30f5a6bb665d3 /sql/item_cmpfunc.cc
parented61d47efe31765b0e6bce85266574b5e07c4fef (diff)
parente27f6a502eebce1a0ddef4436d6615dfc0a64503 (diff)
downloadmariadb-git-952c09b308f9f70c2b6c3c2c07ae510527b09656.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_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc80
1 files changed, 50 insertions, 30 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 66af96f671f..ab8acdd465f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -145,7 +145,7 @@ void Item_func_not_all::print(String *str)
1 Item was replaced with an integer version of the item
*/
-static bool convert_constant_item(Field *field, Item **item)
+static bool convert_constant_item(THD *thd, Field *field, Item **item)
{
if ((*item)->const_item())
{
@@ -153,7 +153,7 @@ static bool convert_constant_item(Field *field, Item **item)
{
Item *tmp=new Item_int_with_ref(field->val_int(), *item);
if (tmp)
- *item=tmp;
+ thd->change_item_tree(item, tmp);
return 1; // Item was replaced
}
}
@@ -164,6 +164,7 @@ static bool convert_constant_item(Field *field, Item **item)
void Item_bool_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
+ THD *thd= current_thd;
/*
As some compare functions are generated after sql_yacc,
@@ -188,17 +189,26 @@ void Item_bool_func2::fix_length_and_dec()
{
uint strong= 0;
uint weak= 0;
+ uint32 dummy_offset;
DTCollation coll;
if (args[0]->result_type() == STRING_RESULT &&
args[1]->result_type() == STRING_RESULT &&
- !my_charset_same(args[0]->collation.collation,
- args[1]->collation.collation) &&
+ String::needs_conversion(0, args[0]->collation.collation,
+ args[1]->collation.collation,
+ &dummy_offset) &&
!coll.set(args[0]->collation, args[1]->collation, TRUE))
{
Item* conv= 0;
+ Item_arena *arena= thd->current_arena, backup;
strong= coll.strong;
weak= strong ? 0 : 1;
+ /*
+ In case we're in statement prepare, create conversion item
+ in its memory: it will be reused on each execute.
+ */
+ if (arena->is_stmt_prepare())
+ thd->set_n_backup_item_arena(arena, &backup);
if (args[weak]->type() == STRING_ITEM)
{
String tmp, cstr;
@@ -211,26 +221,13 @@ void Item_bool_func2::fix_length_and_dec()
}
else
{
- THD *thd= current_thd;
- /*
- In case we're in prepared statement, create conversion
- item in its memory: it will be reused on each execute.
- (and don't juggle with mem_root's if it is ordinary statement).
- We come here only during first fix_fields() because after creating
- conversion item we will have arguments with compatible collations.
- */
- Item_arena *arena= thd->current_arena, backup;
- if (arena->is_conventional())
- arena= 0;
- else
- thd->set_n_backup_item_arena(arena, &backup);
conv= new Item_func_conv_charset(args[weak],
args[strong]->collation.collation);
- if (arena)
- thd->restore_backup_item_arena(arena, &backup);
conv->collation.set(args[weak]->collation.derivation);
conv->fix_fields(thd, 0, &conv);
}
+ if (arena->is_stmt_prepare())
+ thd->restore_backup_item_arena(arena, &backup);
if (args[weak]->type() == FIELD_ITEM)
((Item_field *)args[weak])->no_const_subst= 1;
args[weak]= conv ? conv : args[weak];
@@ -248,9 +245,9 @@ void Item_bool_func2::fix_length_and_dec()
if (args[0]->type() == FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
- if (field->store_for_compare())
+ if (field->can_be_compared_as_longlong())
{
- if (convert_constant_item(field,&args[1]))
+ if (convert_constant_item(thd, field,&args[1]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -261,9 +258,9 @@ void Item_bool_func2::fix_length_and_dec()
if (args[1]->type() == FIELD_ITEM /* && !args[1]->const_item() */)
{
Field *field=((Item_field*) args[1])->field;
- if (field->store_for_compare())
+ if (field->can_be_compared_as_longlong())
{
- if (convert_constant_item(field,&args[0]))
+ if (convert_constant_item(thd, field,&args[0]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -841,6 +838,7 @@ longlong Item_func_interval::val_int()
void Item_func_between::fix_length_and_dec()
{
max_length= 1;
+ THD *thd= current_thd;
/*
As some compare functions are generated after sql_yacc,
@@ -861,11 +859,15 @@ void Item_func_between::fix_length_and_dec()
if (args[0]->type() == FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
- if (field->store_for_compare())
+ if (field->can_be_compared_as_longlong())
{
- if (convert_constant_item(field,&args[1]))
+ /*
+ The following can't be recoded with || as convert_constant_item
+ changes the argument
+ */
+ if (convert_constant_item(thd, field,&args[1]))
cmp_type=INT_RESULT; // Works for all types.
- if (convert_constant_item(field,&args[2]))
+ if (convert_constant_item(thd, field,&args[2]))
cmp_type=INT_RESULT; // Works for all types.
}
}
@@ -1167,6 +1169,15 @@ Item_func_nullif::val_str(String *str)
return res;
}
+
+bool
+Item_func_nullif::is_null()
+{
+ if (!cmp.compare())
+ return (null_value=1);
+ return 0;
+}
+
/*
CASE expression
Return the matching ITEM or NULL if all compares (including else) failed
@@ -1751,6 +1762,7 @@ void Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
uint const_itm= 1;
+ THD *thd= current_thd;
agg_cmp_type(&cmp_type, args, arg_count);
@@ -1788,6 +1800,9 @@ void Item_func_in::fix_length_and_dec()
Conversion is possible:
All IN arguments are constants.
*/
+ Item_arena *arena= thd->current_arena, backup;
+ if (arena->is_stmt_prepare())
+ thd->set_n_backup_item_arena(arena, &backup);
for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++)
{
if (!my_charset_same(cmp_collation.collation,
@@ -1803,6 +1818,8 @@ void Item_func_in::fix_length_and_dec()
arg[0]= conv;
}
}
+ if (arena->is_stmt_prepare())
+ thd->restore_backup_item_arena(arena, &backup);
}
}
@@ -1830,7 +1847,7 @@ void Item_func_in::fix_length_and_dec()
DBUG_ASSERT(0);
return;
}
- if (array && !(current_thd->is_fatal_error)) // If not EOM
+ if (array && !(thd->is_fatal_error)) // If not EOM
{
uint j=0;
for (uint i=1 ; i < arg_count ; i++)
@@ -2048,7 +2065,8 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg)
}
-void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
+void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
+ List<Item> &fields)
{
List_iterator<Item> li(list);
Item *item;
@@ -2057,13 +2075,15 @@ void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
while ((item=li++))
{
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)
{
+ Item **ref= li.ref();
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;
- li.replace(new Item_ref(ref_pointer_array + el, li.ref(), 0, item->name));
+ thd->change_item_tree(ref, new_item);
}
item->update_used_tables();
used_tables_cache|=item->used_tables();