diff options
author | Igor Babaev <igor@askmonty.org> | 2012-04-06 16:40:39 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2012-04-06 16:40:39 -0700 |
commit | c1feaf8d8a7ac15554e2db6c4b2222517447fe3d (patch) | |
tree | d812b6520c67b9ab1618c820c61ef06d474472ab | |
parent | 545377ab50c4ae7651d9b6d6882712982f6871dd (diff) | |
parent | 4ca9b8eb3af0fbfabd493bf72a0cc0e57f51d935 (diff) | |
download | mariadb-git-c1feaf8d8a7ac15554e2db6c4b2222517447fe3d.tar.gz |
Merge.
-rw-r--r-- | mysql-test/r/view.result | 20 | ||||
-rw-r--r-- | mysql-test/t/view.test | 29 | ||||
-rw-r--r-- | sql/item.cc | 15 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 25 |
5 files changed, 82 insertions, 9 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 15ef0c088b1..b4e6f194058 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4433,6 +4433,26 @@ NULL NULL 1 0 NULL NULL 1 0 DROP VIEW v2; 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. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 2a9bfd89f3b..4820e0ac173 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -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 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 # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/item.cc b/sql/item.cc index 60d01c19b8c..70c5798eb6c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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 This function is called when: diff --git a/sql/item.h b/sql/item.h index aeae1b1faf2..69aa28dfadd 100644 --- a/sql/item.h +++ b/sql/item.h @@ -620,6 +620,8 @@ public: #endif } /*lint -e1509 */ 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 init_make_field(Send_field *tmp_field,enum enum_field_types type); virtual void cleanup(); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2e085ece93d..3a5b6ac635f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -5988,15 +5988,22 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, */ if (*ref && !(*ref)->is_autogenerated_name) { - 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((*ref)->name, (*ref)->name_length, - system_charset_info); - item->real_item()->set_name((*ref)->name, (*ref)->name_length, - system_charset_info); - if (arena) - thd->restore_active_arena(arena, &backup); + if (register_tree_change) + { + item->set_name_for_rollback(thd, (*ref)->name, + (*ref)->name_length, + system_charset_info); + item->real_item()->set_name_for_rollback(thd, (*ref)->name, + (*ref)->name_length, + system_charset_info); + } + 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) thd->change_item_tree(ref, item); |