Below is the list of changes that have just been committed into a local
5.0 repository of tomash. When tomash does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-08-16 20:58:03+04:00, kroki@stripped +8 -0
BUG#21166: Prepared statement causes signal 11 on second execution
Changes in an item tree done by optimizer weren't properly
registered and went unnoticed, which resulted in preliminary freeing
of used memory.
TO THE REVIEWER:
The original bug was triggered in Item_row::transform(). I fixed
all transform methods (hope this is correct), but test case covers only
original case, because it's difficult to figure out how to trigger
particular transform.
mysql-test/r/ps.result@stripped, 2006-08-16 20:57:58+04:00, kroki@stripped +15 -0
Add result for bug#21166: Prepared statement causes signal 11
on second execution.
mysql-test/t/ps.test@stripped, 2006-08-16 20:57:58+04:00, kroki@stripped +30 -1
Add test case for bug#21166: Prepared statement causes signal 11
on second execution.
sql/item.cc@stripped, 2006-08-16 20:57:58+04:00, kroki@stripped +15 -0
Move Item_default_value::transform() from item.h here and use
THD::change_item_tree() instead of plain assignment.
sql/item.h@stripped, 2006-08-16 20:57:59+04:00, kroki@stripped +1 -12
Move definition of Item_default_value::transform() to item.cc.
sql/item_cmpfunc.cc@stripped, 2006-08-16 20:57:59+04:00, kroki@stripped +2 -2
Use THD::change_item_tree() instead of plain assignment.
sql/item_row.cc@stripped, 2006-08-16 20:57:59+04:00, kroki@stripped +2 -1
Use THD::change_item_tree() instead of plain assignment.
sql/item_strfunc.cc@stripped, 2006-08-16 20:57:59+04:00, kroki@stripped +11 -0
Move Item_func_make_set::transform() from item_strfunc.h here and use
THD::change_item_tree() instead of plain assignment.
sql/item_strfunc.h@stripped, 2006-08-16 20:57:59+04:00, kroki@stripped +1 -8
Move definition of Item_func_make_set::transform() to item_strfunc.cc.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: kroki
# Host: moonlight.intranet
# Root: /home/tomash/src/mysql_ab/mysql-5.0-bug21166
--- 1.230/sql/item.cc 2006-08-16 20:58:11 +04:00
+++ 1.231/sql/item.cc 2006-08-16 20:58:11 +04:00
@@ -5294,6 +5294,21 @@ int Item_default_value::save_in_field(Fi
}
+/*
+ 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)
+{
+ Item *new_item= arg->transform(transformer, args);
+ if (!new_item)
+ return 0;
+ 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 &&
--- 1.205/sql/item.h 2006-08-16 20:58:11 +04:00
+++ 1.206/sql/item.h 2006-08-16 20:58:11 +04:00
@@ -2116,18 +2116,7 @@ public:
(this->*processor)(args);
}
- /*
- This method like the walk method traverses the item tree, but
- at the same time it can replace some nodes in the tree
- */
- Item *transform(Item_transformer transformer, byte *args)
- {
- Item *new_item= arg->transform(transformer, args);
- if (!new_item)
- return 0;
- arg= new_item;
- return (this->*transformer)(args);
- }
+ Item *transform(Item_transformer transformer, byte *args);
};
/*
--- 1.213/sql/item_cmpfunc.cc 2006-08-16 20:58:11 +04:00
+++ 1.214/sql/item_cmpfunc.cc 2006-08-16 20:58:11 +04:00
@@ -2761,7 +2761,7 @@ Item *Item_cond::transform(Item_transfor
if (!new_item)
return 0;
if (new_item != item)
- li.replace(new_item);
+ current_thd->change_item_tree(li.ref(), new_item);
}
return Item_func::transform(transformer, arg);
}
@@ -4014,7 +4014,7 @@ Item *Item_equal::transform(Item_transfo
if (!new_item)
return 0;
if (new_item != item)
- it.replace((Item_field *) new_item);
+ current_thd->change_item_tree((Item **) it.ref(), new_item);
}
return Item_func::transform(transformer, arg);
}
--- 1.279/sql/item_strfunc.cc 2006-08-16 20:58:11 +04:00
+++ 1.280/sql/item_strfunc.cc 2006-08-16 20:58:11 +04:00
@@ -2051,6 +2051,17 @@ String *Item_func_make_set::val_str(Stri
}
+Item *Item_func_make_set::transform(Item_transformer transformer, byte *arg)
+{
+ Item *new_item= item->transform(transformer, arg);
+ if (!new_item)
+ return 0;
+ if (item != new_item)
+ current_thd->change_item_tree(&item, new_item);
+ return Item_str_func::transform(transformer, arg);
+}
+
+
void Item_func_make_set::print(String *str)
{
str->append(STRING_WITH_LEN("make_set("));
--- 1.112/sql/item_strfunc.h 2006-08-16 20:58:11 +04:00
+++ 1.113/sql/item_strfunc.h 2006-08-16 20:58:11 +04:00
@@ -475,14 +475,7 @@ public:
return item->walk(processor, arg) ||
Item_str_func::walk(processor, arg);
}
- Item *transform(Item_transformer transformer, byte *arg)
- {
- Item *new_item= item->transform(transformer, arg);
- if (!new_item)
- return 0;
- item= new_item;
- return Item_str_func::transform(transformer, arg);
- }
+ Item *transform(Item_transformer transformer, byte *arg);
void print(String *str);
};
--- 1.32/sql/item_row.cc 2006-08-16 20:58:11 +04:00
+++ 1.33/sql/item_row.cc 2006-08-16 20:58:11 +04:00
@@ -159,7 +159,8 @@ Item *Item_row::transform(Item_transform
Item *new_item= items[i]->transform(transformer, arg);
if (!new_item)
return 0;
- items[i]= new_item;
+ if (items[i] != new_item)
+ current_thd->change_item_tree(&items[i], new_item);
}
return (this->*transformer)(arg);
}
--- 1.71/mysql-test/r/ps.result 2006-08-16 20:58:11 +04:00
+++ 1.72/mysql-test/r/ps.result 2006-08-16 20:58:11 +04:00
@@ -1297,3 +1297,18 @@ ERROR 3D000: No database selected
create temporary table t1 (i int);
ERROR 3D000: No database selected
use test;
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 (i BIGINT, j BIGINT);
+CREATE TABLE t2 (i BIGINT);
+CREATE TABLE t3 (i BIGINT, j BIGINT);
+PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i)
+ LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j))
+ WHERE t1.i = ?";
+SET @a= 1;
+EXECUTE stmt USING @a;
+i j i i j
+EXECUTE stmt USING @a;
+i j i i j
+DEALLOCATE PREPARE stmt;
+DROP TABLE IF EXISTS t1, t2, t3;
+End of 5.0 tests.
--- 1.68/mysql-test/t/ps.test 2006-08-16 20:58:11 +04:00
+++ 1.69/mysql-test/t/ps.test 2006-08-16 20:58:11 +04:00
@@ -1329,4 +1329,33 @@ create temporary table t1 (i int);
# Restore the old environemnt
#
use test;
-# End of 5.0 tests
+
+
+#
+# BUG#21166: Prepared statement causes signal 11 on second execution
+#
+# Changes in an item tree done by optimizer weren't properly
+# registered and went unnoticed, which resulted in preliminary freeing
+# of used memory.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 (i BIGINT, j BIGINT);
+CREATE TABLE t2 (i BIGINT);
+CREATE TABLE t3 (i BIGINT, j BIGINT);
+
+PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i)
+ LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j))
+ WHERE t1.i = ?";
+
+SET @a= 1;
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE IF EXISTS t1, t2, t3;
+
+
+--echo End of 5.0 tests.
| Thread |
|---|
| • bk commit into 5.0 tree (kroki:1.2235) BUG#21166 | kroki | 16 Aug |