#At file:///home/gluh/MySQL/mysql-5.0-bug-45806/ based on revid:staale.smedseng@stripped
2789 Sergey Glukhov 2009-07-01
Bug#45806 crash when replacing into a view with a join!
The crash happend because for views which are joins
we have table_list->table == 0 and
table_list->table->'any method' call leads to crash.
The fix is to perform table_list->table->file->extra()
method for all tables belonging to view.
@ mysql-test/r/view.result
test result
@ mysql-test/t/view.test
test case
@ sql/sql_insert.cc
added update_info_for_insert() function which
updates extra info about primary key for tables
belonging to view.
modified:
mysql-test/r/view.result
mysql-test/t/view.test
sql/sql_insert.cc
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2009-05-18 18:43:06 +0000
+++ b/mysql-test/r/view.result 2009-07-01 09:47:02 +0000
@@ -3723,6 +3723,53 @@ DROP TABLE t1;
# -- End of test case for Bug#40825
+#
+# Bug #45806 crash when replacing into a view with a join!
+#
+CREATE TABLE t1(a INT UNIQUE);
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a;
+INSERT INTO t1 VALUES (1), (2);
+REPLACE INTO v1(a) SELECT 1 FROM t1,t1 AS c;
+SELECT * FROM v1;
+a
+1
+2
+1
+2
+INSERT INTO v1(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v1`.`a`= 1;
+SELECT * FROM v1;
+a
+1
+2
+1
+2
+DROP VIEW v1;
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a;
+CREATE VIEW v2 AS SELECT t1.a FROM t1, v1 AS a;
+REPLACE INTO v2(a) SELECT 1 FROM t1,t1 AS c;
+SELECT * FROM v1;
+a
+1
+2
+1
+2
+INSERT INTO v2(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v2`.`a`= 1;
+SELECT * FROM v2;
+a
+1
+2
+1
+2
+1
+2
+1
+2
+DROP VIEW v1;
+DROP VIEW v2;
+DROP TABLE t1;
+# -- End of test case for Bug#45806
# -----------------------------------------------------------------
# -- End of 5.0 tests.
# -----------------------------------------------------------------
=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test 2009-05-18 18:43:06 +0000
+++ b/mysql-test/t/view.test 2009-07-01 09:47:02 +0000
@@ -3703,6 +3703,38 @@ DROP TABLE t1;
--echo # -- End of test case for Bug#40825
--echo
+--echo #
+--echo # Bug #45806 crash when replacing into a view with a join!
+--echo #
+CREATE TABLE t1(a INT UNIQUE);
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a;
+INSERT INTO t1 VALUES (1), (2);
+
+REPLACE INTO v1(a) SELECT 1 FROM t1,t1 AS c;
+SELECT * FROM v1;
+
+INSERT INTO v1(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v1`.`a`= 1;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+
+CREATE VIEW v1 AS SELECT t1.a FROM t1, t1 AS a;
+CREATE VIEW v2 AS SELECT t1.a FROM t1, v1 AS a;
+
+REPLACE INTO v2(a) SELECT 1 FROM t1,t1 AS c;
+SELECT * FROM v1;
+
+INSERT INTO v2(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v2`.`a`= 1;
+SELECT * FROM v2;
+
+DROP VIEW v1;
+DROP VIEW v2;
+DROP TABLE t1;
+
+--echo # -- End of test case for Bug#45806
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.0 tests.
--echo # -----------------------------------------------------------------
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2009-06-17 13:54:01 +0000
+++ b/sql/sql_insert.cc 2009-07-01 09:47:02 +0000
@@ -1149,6 +1149,26 @@ static bool mysql_prepare_insert_check_t
/*
+ Get extra info for tables belonging to a view
+*/
+static void update_info_for_insert(List<TABLE_LIST>* tables,
+ enum_duplicates duplic)
+{
+ List_iterator<TABLE_LIST> it(*tables);
+ TABLE_LIST *tbl;
+ while ((tbl= it++))
+ {
+ if (tbl->view && !tbl->table)
+ update_info_for_insert(tbl->view_tables, duplic);
+ else
+ if ((duplic == DUP_UPDATE || duplic == DUP_REPLACE) &&
+ (tbl->table->reginfo.lock_type != TL_WRITE_DELAYED))
+ tbl->table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
+ }
+}
+
+
+/*
Prepare items in INSERT statement
SYNOPSIS
@@ -1294,6 +1314,14 @@ bool mysql_prepare_insert(THD *thd, TABL
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
select_lex->first_execution= 0;
}
+
+ if (!table)
+ {
+ DBUG_ASSERT(insert_into_view);
+ update_info_for_insert(table_list->view_tables, duplic);
+ DBUG_RETURN(FALSE);
+ }
+
/*
Only call extra() handler method if we are not performing a DELAYED
operation. It will instead be executed by delayed insert thread.
Attachment: [text/bzr-bundle] bzr/sergey.glukhov@sun.com-20090701094702-ltszbk0ulp3wxgsu.bundle
| Thread |
|---|
| • bzr commit into mysql-5.0-bugteam branch (Sergey.Glukhov:2789)Bug#45806 | Sergey Glukhov | 1 Jul |