Commit fa08b280 authored by unknown's avatar unknown

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.

(This is a backport of the original patch for 5.1)


mysql-test/r/view.result:
  Fix result file.
mysql-test/r/view_grant.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.
mysql-test/t/view_grant.test:
  Fix order-dependency.
sql/sql_view.cc:
  Report an error if we're going to work with a table.
parent d34f8384
...@@ -3618,4 +3618,23 @@ ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default val ...@@ -3618,4 +3618,23 @@ ERROR HY000: Field of view 'test.v1' underlying table doesn't have a default val
set @@sql_mode=@old_mode; set @@sql_mode=@old_mode;
drop view v1; drop view v1;
drop table t1; drop table t1;
End of 5.0 tests. # -----------------------------------------------------------------
# -- Bug#34337: Server crash when Altering a view using a table name.
# -----------------------------------------------------------------
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(c1 INT);
SELECT * FROM t1;
c1
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.0 tests.
# -----------------------------------------------------------------
...@@ -467,6 +467,7 @@ use test; ...@@ -467,6 +467,7 @@ use test;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
drop database mysqltest; drop database mysqltest;
drop view if exists v1; drop view if exists v1;
drop table if exists t1;
create table t1 as select * from mysql.user where user=''; create table t1 as select * from mysql.user where user='';
delete from mysql.user where user=''; delete from mysql.user where user='';
flush privileges; flush privileges;
......
...@@ -3470,5 +3470,39 @@ insert into v1 values(1); ...@@ -3470,5 +3470,39 @@ insert into v1 values(1);
set @@sql_mode=@old_mode; set @@sql_mode=@old_mode;
drop view v1; drop view v1;
drop table t1; drop table t1;
--echo End of 5.0 tests.
###########################################################################
--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
SELECT * FROM t1;
--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.0 tests.
--echo # -----------------------------------------------------------------
...@@ -608,6 +608,7 @@ drop database mysqltest; ...@@ -608,6 +608,7 @@ drop database mysqltest;
# #
--disable_warnings --disable_warnings
drop view if exists v1; drop view if exists v1;
drop table if exists t1;
--enable_warnings --enable_warnings
# Backup anonymous users and remove them. (They get in the way of # Backup anonymous users and remove them. (They get in the way of
......
...@@ -182,10 +182,33 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) ...@@ -182,10 +182,33 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
TABLE_LIST decoy; TABLE_LIST decoy;
memcpy (&decoy, view, sizeof (TABLE_LIST)); memcpy (&decoy, view, sizeof (TABLE_LIST));
if (!open_table(thd, &decoy, thd->mem_root, &not_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, &not_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; return TRUE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment