summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2012-04-06 16:40:39 -0700
committerIgor Babaev <igor@askmonty.org>2012-04-06 16:40:39 -0700
commitc1feaf8d8a7ac15554e2db6c4b2222517447fe3d (patch)
treed812b6520c67b9ab1618c820c61ef06d474472ab
parent545377ab50c4ae7651d9b6d6882712982f6871dd (diff)
parent4ca9b8eb3af0fbfabd493bf72a0cc0e57f51d935 (diff)
downloadmariadb-git-c1feaf8d8a7ac15554e2db6c4b2222517447fe3d.tar.gz
Merge.
-rw-r--r--mysql-test/r/view.result20
-rw-r--r--mysql-test/t/view.test29
-rw-r--r--sql/item.cc15
-rw-r--r--sql/item.h2
-rw-r--r--sql/sql_base.cc25
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);