From 985e9523479fb1143ac60e1644613d34e126ef58 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Feb 2008 22:23:39 +0300 Subject: [PATCH] Fix for Bug#34337: Server crash when Altering a view using a table name. The problem was that fill_defined_view_parts() did not return an error if a table is going to be altered. That happened if the table was already in the table cache. In that case, open_table() returned non-NULL value (valid TABLE-instance from the cache). The fix is to ensure that an error is thrown even if the table is in the cache. mysql-test/r/view.result: Fix result file. mysql-test/t/view.test: Add a test case for Bug#34337: Server crash when Altering a view using a table name. sql/sql_view.cc: Report an error if we're going to work with a table. --- mysql-test/r/view.result | 15 +++++++++++++++ mysql-test/t/view.test | 28 ++++++++++++++++++++++++++++ sql/sql_view.cc | 29 ++++++++++++++++++++++++++--- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 3f8ed1b4e56..e5c20a2c26f 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3720,6 +3720,21 @@ DROP VIEW v1; # -- End of test case for Bug#32538. +# ----------------------------------------------------------------- +# -- Bug#34337: Server crash when Altering a view using a table name. +# ----------------------------------------------------------------- + +DROP TABLE IF EXISTS t1; + +CREATE TABLE t1(c1 INT); + +ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1); +ERROR HY000: 'test.t1' is not VIEW + +DROP TABLE t1; + +# -- End of test case for Bug#34337. + # ----------------------------------------------------------------- # -- End of 5.1 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3f10bc62289..d350dd102d7 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3603,6 +3603,34 @@ DROP VIEW v1; ########################################################################### +--echo # ----------------------------------------------------------------- +--echo # -- Bug#34337: Server crash when Altering a view using a table name. +--echo # ----------------------------------------------------------------- +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo + +CREATE TABLE t1(c1 INT); + +--echo + +--error ER_WRONG_OBJECT +ALTER ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW t1 (c2) AS SELECT (1); + +--echo + +DROP TABLE t1; + +--echo +--echo # -- End of test case for Bug#34337. +--echo + +########################################################################### + --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 0b0763afb84..0642a2d2e17 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -182,10 +182,33 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) TABLE_LIST decoy; memcpy (&decoy, view, sizeof (TABLE_LIST)); - if (!open_table(thd, &decoy, thd->mem_root, ¬_used, OPEN_VIEW_NO_PARSE) && - !decoy.view) + + /* + Let's reset decoy.view before calling open_table(): when we start + supporting ALTER VIEW in PS/SP that may save us from a crash. + */ + + decoy.view= NULL; + + /* + open_table() will return NULL if 'decoy' is idenitifying a view *and* + there is no TABLE object for that view in the table cache. However, + decoy.view will be set to 1. + + If there is a TABLE-instance for the oject identified by 'decoy', + open_table() will return that instance no matter if it is a table or + a view. + + Thus, there is no need to check for the return value of open_table(), + since the return value itself does not mean anything. + */ + + open_table(thd, &decoy, thd->mem_root, ¬_used, OPEN_VIEW_NO_PARSE); + + if (!decoy.view) { - /* It's a table */ + /* It's a table. */ + my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW"); return TRUE; }