summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorkostja@bodhi.local <>2006-08-31 12:34:06 +0400
committerkostja@bodhi.local <>2006-08-31 12:34:06 +0400
commitbddfef1e360e8c511d801e084ea6a1b466f5dd90 (patch)
treed4ab6a36efa202b09b1767575c74be071e36aedc /sql/item.cc
parentaa330d19105071ae5e53cd6de06ccac55261b4e4 (diff)
parent3948fcf575a20f2d4b728e0a787cdb02c1be0b59 (diff)
downloadmariadb-git-bddfef1e360e8c511d801e084ea6a1b466f5dd90.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into bodhi.local:/opt/local/work/mysql-5.0-14897
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc72
1 files changed, 70 insertions, 2 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 96b20d0f0bb..34e5e2da165 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -422,6 +422,49 @@ void Item::rename(char *new_name)
}
+/*
+ Traverse item tree possibly transforming it (replacing items).
+
+ SYNOPSIS
+ Item::transform()
+ transformer functor that performs transformation of a subtree
+ arg opaque argument passed to the functor
+
+ DESCRIPTION
+ This function is designed to ease transformation of Item trees.
+
+ Re-execution note: every such transformation is registered for
+ rollback by THD::change_item_tree() and is rolled back at the end
+ of execution by THD::rollback_item_tree_changes().
+
+ Therefore:
+
+ - this function can not be used at prepared statement prepare
+ (in particular, in fix_fields!), as only permanent
+ transformation of Item trees are allowed at prepare.
+
+ - the transformer function shall allocate new Items in execution
+ memory root (thd->mem_root) and not anywhere else: allocated
+ items will be gone in the end of execution.
+
+ If you don't need to transform an item tree, but only traverse
+ it, please use Item::walk() instead.
+
+
+ RETURN VALUE
+ Returns pointer to the new subtree root. THD::change_item_tree()
+ should be called for it if transformation took place, i.e. if a
+ pointer to newly allocated item is returned.
+*/
+
+Item* Item::transform(Item_transformer transformer, byte *arg)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
+ return (this->*transformer)(arg);
+}
+
+
Item_ident::Item_ident(Name_resolution_context *context_arg,
const char *db_name_arg,const char *table_name_arg,
const char *field_name_arg)
@@ -3802,11 +3845,11 @@ Item *Item_field::equal_fields_propagator(byte *arg)
See comments in Arg_comparator::set_compare_func() for details
*/
-Item *Item_field::set_no_const_sub(byte *arg)
+bool Item_field::set_no_const_sub(byte *arg)
{
if (field->charset() != &my_charset_bin)
no_const_subst=1;
- return this;
+ return FALSE;
}
@@ -5308,6 +5351,31 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
}
+/*
+ This method like the walk method traverses the item tree, but at the
+ same time it can replace some nodes in the tree
+*/
+
+Item *Item_default_value::transform(Item_transformer transformer, byte *args)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
+ Item *new_item= arg->transform(transformer, args);
+ if (!new_item)
+ return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
+ if (arg != new_item)
+ current_thd->change_item_tree(&arg, new_item);
+ return (this->*transformer)(args);
+}
+
+
bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == INSERT_VALUE_ITEM &&