Commit 4ca9b8eb authored by Igor Babaev's avatar Igor Babaev

Fixed bug #915222.

This bug happened because the function find_field_in_view formed
autogenerated names of view columns without a possibility to roll
them back. In some situation it could cause memory misuses reported
by valgrind or even crashes.
parent 2149a429
...@@ -4433,6 +4433,26 @@ NULL NULL 1 0 ...@@ -4433,6 +4433,26 @@ NULL NULL 1 0
NULL NULL 1 0 NULL NULL 1 0
DROP VIEW v2; DROP VIEW v2;
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
#
# BUG#915222: Valgrind complains or crashes with INSERT SELECT
# within a trigger that uses a view
#
CREATE TABLE t1 (a char(1));
CREATE TABLE t2 (d int, e char(1));
INSERT INTO t2 VALUES (13,'z');
CREATE TRIGGER tr AFTER UPDATE ON t2
FOR EACH ROW
REPLACE INTO t3
SELECT f, a AS alias FROM t3, v;
CREATE TABLE t3 (f int, g char(8));
CREATE VIEW v AS SELECT a, e FROM t2, t1;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
DROP TRIGGER tr;
DROP VIEW v;
DROP TABLE t1,t2,t3;
# ----------------------------------------------------------------- # -----------------------------------------------------------------
# -- End of 5.3 tests. # -- End of 5.3 tests.
# ----------------------------------------------------------------- # -----------------------------------------------------------------
......
...@@ -4365,6 +4365,35 @@ SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM ...@@ -4365,6 +4365,35 @@ SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM
DROP VIEW v2; DROP VIEW v2;
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
--echo #
--echo # BUG#915222: Valgrind complains or crashes with INSERT SELECT
--echo # within a trigger that uses a view
--echo #
CREATE TABLE t1 (a char(1));
CREATE TABLE t2 (d int, e char(1));
INSERT INTO t2 VALUES (13,'z');
CREATE TRIGGER tr AFTER UPDATE ON t2
FOR EACH ROW
REPLACE INTO t3
SELECT f, a AS alias FROM t3, v;
CREATE TABLE t3 (f int, g char(8));
CREATE VIEW v AS SELECT a, e FROM t2, t1;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
UPDATE t2 SET d=7;
DROP TRIGGER tr;
DROP VIEW v;
DROP TABLE t1,t2,t3;
--echo # ----------------------------------------------------------------- --echo # -----------------------------------------------------------------
--echo # -- End of 5.3 tests. --echo # -- End of 5.3 tests.
--echo # ----------------------------------------------------------------- --echo # -----------------------------------------------------------------
......
...@@ -951,6 +951,21 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) ...@@ -951,6 +951,21 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs)
} }
void Item::set_name_for_rollback(THD *thd, const char *str, uint length,
CHARSET_INFO *cs)
{
char *old_name, *new_name;
old_name= name;
set_name(str, length, cs);
new_name= name;
if (old_name != new_name)
{
name= old_name;
thd->change_item_tree((Item **) &name, (Item *) new_name);
}
}
/** /**
@details @details
This function is called when: This function is called when:
......
...@@ -620,6 +620,8 @@ public: ...@@ -620,6 +620,8 @@ public:
#endif #endif
} /*lint -e1509 */ } /*lint -e1509 */
void set_name(const char *str, uint length, CHARSET_INFO *cs); void set_name(const char *str, uint length, CHARSET_INFO *cs);
void set_name_for_rollback(THD *thd, const char *str, uint length,
CHARSET_INFO *cs);
void rename(char *new_name); void rename(char *new_name);
void init_make_field(Send_field *tmp_field,enum enum_field_types type); void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup(); virtual void cleanup();
......
...@@ -5988,15 +5988,22 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, ...@@ -5988,15 +5988,22 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
*/ */
if (*ref && !(*ref)->is_autogenerated_name) if (*ref && !(*ref)->is_autogenerated_name)
{ {
if (register_tree_change && if (register_tree_change)
thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute()) {
arena= thd->activate_stmt_arena_if_needed(&backup); item->set_name_for_rollback(thd, (*ref)->name,
item->set_name((*ref)->name, (*ref)->name_length, (*ref)->name_length,
system_charset_info); system_charset_info);
item->real_item()->set_name((*ref)->name, (*ref)->name_length, item->real_item()->set_name_for_rollback(thd, (*ref)->name,
system_charset_info); (*ref)->name_length,
if (arena) system_charset_info);
thd->restore_active_arena(arena, &backup); }
else
{
item->set_name((*ref)->name, (*ref)->name_length,
system_charset_info);
item->real_item()->set_name((*ref)->name, (*ref)->name_length,
system_charset_info);
}
} }
if (register_tree_change) if (register_tree_change)
thd->change_item_tree(ref, item); thd->change_item_tree(ref, item);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment