diff options
author | MySQL Build Team <build@mysql.com> | 2009-07-21 20:00:26 +0200 |
---|---|---|
committer | MySQL Build Team <build@mysql.com> | 2009-07-21 20:00:26 +0200 |
commit | 065792924a8c8533825d01cebfff0a6de5e3cb2d (patch) | |
tree | e51b67591ce9cf3c5de8ac763810fce7bb2f32c6 | |
parent | 05a52ac76164cd410cce6cb27321cbdd6b078bee (diff) | |
download | mariadb-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.result | 111 | ||||
-rw-r--r-- | mysql-test/t/view.test | 32 | ||||
-rw-r--r-- | sql/sql_insert.cc | 32 |
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); } |