summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMySQL Build Team <build@mysql.com>2009-07-21 20:00:26 +0200
committerMySQL Build Team <build@mysql.com>2009-07-21 20:00:26 +0200
commit065792924a8c8533825d01cebfff0a6de5e3cb2d (patch)
treee51b67591ce9cf3c5de8ac763810fce7bb2f32c6
parent05a52ac76164cd410cce6cb27321cbdd6b078bee (diff)
downloadmariadb-git-065792924a8c8533825d01cebfff0a6de5e3cb2d.tar.gz
Backport into build-200907211706-5.0.82sp1mysql-5.0.82sp1
> ------------------------------------------------------------ > revno: 2792 > revision-id: sergey.glukhov@sun.com-20090703083500-jq8vhw0tqr37j7te > parent: bernt.johnsen@sun.com-20090703083610-o7l4s8syz05rc4w0 > committer: Sergey Glukhov <Sergey.Glukhov@sun.com> > branch nick: mysql-5.0-bugteam > timestamp: Fri 2009-07-03 13:35:00 +0500 > message: > 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.
-rw-r--r--mysql-test/r/view.result111
-rw-r--r--mysql-test/t/view.test32
-rw-r--r--sql/sql_insert.cc32
3 files changed, 172 insertions, 3 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 58aa614c508..e8971e8d16b 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -3659,6 +3659,117 @@ DROP TABLE t1;
# -- End of test case for Bug#34337.
+#
+# 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
+REPLACE INTO v1(a) SELECT 3 FROM t1,t1 AS c;
+SELECT * FROM v1;
+a
+1
+2
+3
+1
+2
+3
+1
+2
+3
+DELETE FROM t1 WHERE a=3;
+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
+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 v2;
+a
+1
+2
+1
+2
+1
+2
+1
+2
+REPLACE INTO v2(a) SELECT 3 FROM t1,t1 AS c;
+SELECT * FROM v2;
+a
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+INSERT INTO v2(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v2`.`a`= 1;
+SELECT * FROM v2;
+a
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+1
+2
+3
+DROP VIEW v1;
+DROP VIEW v2;
+DROP TABLE t1;
+# -- End of test case for Bug#45806
# -----------------------------------------------------------------
# -- Bug#35193 VIEW query is rewritten without "FROM DUAL",
# -- causing syntax error
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 6437e546697..0e8f17d9497 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3680,6 +3680,38 @@ SELECT * FROM v1 IGNORE INDEX (c2) WHERE c2=2;
DROP VIEW v1;
DROP TABLE t1;
+--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;
+REPLACE INTO v1(a) SELECT 3 FROM t1,t1 AS c;
+SELECT * FROM v1;
+DELETE FROM t1 WHERE a=3;
+INSERT INTO v1(a) SELECT 1 FROM t1,t1 AS c
+ON DUPLICATE KEY UPDATE `v1`.`a`= 1;
+SELECT * FROM v1;
+
+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 v2;
+REPLACE INTO v2(a) SELECT 3 FROM t1,t1 AS c;
+SELECT * FROM v2;
+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 # -----------------------------------------------------------------
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index d9027e3f5b9..2f03b43de4d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1148,6 +1148,33 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
/*
+ Get extra info for tables we insert into
+
+ @param table table(TABLE object) we insert into,
+ might be NULL in case of view
+ @param table(TABLE_LIST object) or view we insert into
+*/
+
+static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
+{
+ if (table)
+ {
+ if(table->reginfo.lock_type != TL_WRITE_DELAYED)
+ table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
+ return;
+ }
+
+ DBUG_ASSERT(tables->view);
+ List_iterator<TABLE_LIST> it(*tables->view_tables);
+ TABLE_LIST *tbl;
+ while ((tbl= it++))
+ prepare_for_positional_update(tbl->table, tbl);
+
+ return;
+}
+
+
+/*
Prepare items in INSERT statement
SYNOPSIS
@@ -1297,9 +1324,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
Only call extra() handler method if we are not performing a DELAYED
operation. It will instead be executed by delayed insert thread.
*/
- if ((duplic == DUP_UPDATE || duplic == DUP_REPLACE) &&
- (table->reginfo.lock_type != TL_WRITE_DELAYED))
- table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
+ if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
+ prepare_for_positional_update(table, table_list);
DBUG_RETURN(FALSE);
}