Commit 72ed0fc0 authored by unknown's avatar unknown

test of DELETE privilege and cyclic reference added in case of altering view (BUG#5148)

fixed ALTER VIEW syntax
fixed WITH CHECK OPTION clause printing in SHOW CREATE VIEW


mysql-test/r/view.result:
  test of VIEW altering
mysql-test/t/view.test:
  test of VIEW altering
sql/lex.h:
  explicitly mentioned undefined algorithm
sql/sql_show.cc:
  explicitly mentioned undefined algorithm
  added printing WITH CHECK OPTION clause
sql/sql_view.cc:
  test of DELETE privilege and cyclic reference added in case of altering view
  effective and requested WITH CHECK OPTION parameters divided
sql/sql_yacc.yy:
  fixed ALTER VIEW
sql/table.cc:
  effective and requested WITH CHECK OPTION parameters divided
sql/table.h:
  effective and requested WITH CHECK OPTION parameters divided
parent 62ce24cf
......@@ -32,10 +32,10 @@ c
11
show create table v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
show create view v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
show create view t1;
ERROR HY000: 'test.t1' is not VIEW
drop table t1;
......@@ -226,7 +226,11 @@ create table mysqltest.t1 (a int, b int);
create table mysqltest.t2 (a int, b int);
grant select on mysqltest.t1 to mysqltest_1@localhost;
grant create view,select on test.* to mysqltest_1@localhost;
create view v1 as select * from mysqltest.t1;
create view v1 as select * from mysqltest.t1;
alter view v1 as select * from mysqltest.t1;
ERROR 42000: delete command denied to user 'mysqltest_1'@'localhost' for table 'v1'
create or replace view v1 as select * from mysqltest.t1;
ERROR 42000: delete command denied to user 'mysqltest_1'@'localhost' for table 'v1'
create view mysqltest.v2 as select * from mysqltest.t1;
ERROR 42000: create view command denied to user 'mysqltest_1'@'localhost' for table 'v2'
create view v2 as select * from mysqltest.t2;
......@@ -326,7 +330,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
show create view mysqltest.v1;
View Create View
v1 CREATE VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
v1 CREATE ALGORITHM=UNDEFINED VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
explain select c from mysqltest.v2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
......@@ -339,7 +343,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 0 const row not found
show create view mysqltest.v3;
View Create View
v3 CREATE VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
v3 CREATE ALGORITHM=UNDEFINED VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
explain select c from mysqltest.v4;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
......@@ -1054,7 +1058,7 @@ drop table t1;
CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select sql_no_cache connection_id() AS `f1`,pi() AS `f2`,current_user() AS `f3`,version() AS `f4`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache connection_id() AS `f1`,pi() AS `f2`,current_user() AS `f3`,version() AS `f4`
drop view v1;
create table t1 (s1 int);
create table t2 (s2 int);
......@@ -1088,13 +1092,13 @@ create view v1 as select a from t1;
create view v2 as select a from t2 where a in (select a from v1);
show create view v2;
View Create View
v2 CREATE VIEW `test`.`v2` AS select `test`.`t2`.`a` AS `a` from `test`.`t2` where `a` in (select `v1`.`a` AS `a` from `test`.`v1`)
v2 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v2` AS select `test`.`t2`.`a` AS `a` from `test`.`t2` where `a` in (select `v1`.`a` AS `a` from `test`.`v1`)
drop view v2, v1;
drop table t1, t2;
CREATE VIEW `v 1` AS select 5 AS `5`;
show create view `v 1`;
View Create View
v 1 CREATE VIEW `test`.`v 1` AS select 5 AS `5`
v 1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v 1` AS select 5 AS `5`
drop view `v 1`;
create database mysqltest;
create table mysqltest.t1 (a int, b int);
......@@ -1162,14 +1166,14 @@ a b
1 1
show create view v3;
View Create View
v3 CREATE VIEW `test`.`v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from `test`.`v1` join `test`.`v2` where (`v1`.`col1` = `v2`.`col1`)
v3 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from `test`.`v1` join `test`.`v2` where (`v1`.`col1` = `v2`.`col1`)
drop view v3, v2, v1;
drop table t2, t1;
create function `f``1` () returns int return 5;
create view v1 as select test.`f``1` ();
show create view v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select `test`.`f``1`() AS `test.``f````1`` ()`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`f``1`() AS `test.``f````1`` ()`
select * from v1;
test.`f``1` ()
5
......@@ -1186,10 +1190,10 @@ create table t2 (col1 char collate latin1_german2_ci);
create view v2 as select col1 collate latin1_german1_ci from t2;
show create view v2;
View Create View
v2 CREATE VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2`
v2 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2`
show create view v2;
View Create View
v2 CREATE VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2`
v2 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v2` AS select (`test`.`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `test`.`t2`
drop view v2;
drop table t2;
create table t1 (a int);
......@@ -1220,7 +1224,7 @@ drop table t1;
create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1;
show create view v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
drop view v1;
create table t (c char);
create view v as select c from t;
......@@ -1241,7 +1245,7 @@ drop table t1;
create view v1 as select cast(1 as char(3));
show create view v1;
View Create View
v1 CREATE VIEW `test`.`v1` AS select cast(1 as char(3) charset latin1) AS `cast(1 as char(3))`
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select cast(1 as char(3) charset latin1) AS `cast(1 as char(3))`
select * from v1;
cast(1 as char(3))
1
......@@ -1421,3 +1425,35 @@ a
1
drop view v1;
drop table t1;
create table t1 (s1 int);
create view v1 as select * from t1;
create view v2 as select * from v1;
alter view v1 as select * from v2;
ERROR 42S02: Table 'test.v1' doesn't exist
alter view v1 as select * from v1;
ERROR 42000: Not unique table/alias: 'v1'
create or replace view v1 as select * from v2;
ERROR 42S02: Table 'test.v1' doesn't exist
create or replace view v1 as select * from v1;
ERROR 42000: Not unique table/alias: 'v1'
drop view v2,v1;
drop table t1;
create table t1 (a int);
create view v1 as select * from t1;
show create view v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1`
alter algorithm=undefined view v1 as select * from t1 with check option;
show create view v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH LOCAL CHECK OPTION
alter algorithm=merge view v1 as select * from t1 with cascaded check option;
show create view v1;
View Create View
v1 CREATE ALGORITHM=MERGE VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` WITH CASCADED CHECK OPTION
alter algorithm=temptable view v1 as select * from t1;
show create view v1;
View Create View
v1 CREATE ALGORITHM=TEMPTABLE VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1`
drop view v1;
drop table t1;
......@@ -178,7 +178,12 @@ grant create view,select on test.* to mysqltest_1@localhost;
connect (user1,localhost,mysqltest_1,,test);
connection user1;
create view v1 as select * from mysqltest.t1;
create view v1 as select * from mysqltest.t1;
# try to modify view without DELETE privilege on it
-- error 1142
alter view v1 as select * from mysqltest.t1;
-- error 1142
create or replace view v1 as select * from mysqltest.t1;
# no CRETE VIEW privilege
-- error 1142
create view mysqltest.v2 as select * from mysqltest.t1;
......@@ -1384,3 +1389,35 @@ insert ignore into v1 values (1) on duplicate key update a=2;
select * from t1;
drop view v1;
drop table t1;
#
# check cyclic referencing protection on altering view
#
create table t1 (s1 int);
create view v1 as select * from t1;
create view v2 as select * from v1;
-- error 1146
alter view v1 as select * from v2;
-- error 1066
alter view v1 as select * from v1;
-- error 1146
create or replace view v1 as select * from v2;
-- error 1066
create or replace view v1 as select * from v1;
drop view v2,v1;
drop table t1;
#
# check altering differ options
#
create table t1 (a int);
create view v1 as select * from t1;
show create view v1;
alter algorithm=undefined view v1 as select * from t1 with check option;
show create view v1;
alter algorithm=merge view v1 as select * from t1 with cascaded check option;
show create view v1;
alter algorithm=temptable view v1 as select * from t1;
show create view v1;
drop view v1;
drop table t1;
......@@ -479,6 +479,7 @@ static SYMBOL symbols[] = {
{ "TYPE", SYM(TYPE_SYM)},
{ "TYPES", SYM(TYPES_SYM)},
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM)},
{ "UNDEFINED", SYM(UNDEFINED_SYM)},
{ "UNDO", SYM(UNDO_SYM)},
{ "UNICODE", SYM(UNICODE_SYM)},
{ "UNION", SYM(UNION_SYM)},
......
......@@ -1608,14 +1608,23 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
MODE_MAXDB |
MODE_ANSI)) != 0;
buff->append("CREATE ", 7);
if (!foreign_db_mode && (table->algorithm == VIEW_ALGORITHM_MERGE ||
table->algorithm == VIEW_ALGORITHM_TMPTABLE))
if (!foreign_db_mode)
{
buff->append("ALGORITHM=", 10);
if (table->algorithm == VIEW_ALGORITHM_TMPTABLE)
switch(table->algorithm)
{
case VIEW_ALGORITHM_UNDEFINED:
buff->append("UNDEFINED ", 10);
break;
case VIEW_ALGORITHM_TMPTABLE:
buff->append("TEMPTABLE ", 10);
else
break;
case VIEW_ALGORITHM_MERGE:
buff->append("MERGE ", 6);
break;
default:
DBUG_ASSERT(0); // never should happen
}
}
buff->append("VIEW ", 5);
append_identifier(thd, buff, table->view_db.str, table->view_db.length);
......@@ -1623,6 +1632,13 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
append_identifier(thd, buff, table->view_name.str, table->view_name.length);
buff->append(" AS ", 4);
buff->append(table->query.str, table->query.length);
if (table->with_check != VIEW_CHECK_NONE)
{
if (table->with_check == VIEW_CHECK_LOCAL)
buff->append(" WITH LOCAL CHECK OPTION", 24);
else
buff->append(" WITH CASCADED CHECK OPTION", 27);
}
return 0;
}
......
......@@ -83,6 +83,8 @@ int mysql_create_view(THD *thd,
/*
Privilege check for view creation:
- user have CREATE VIEW privilege on view table
- user have DELETE privilege in case of ALTER VIEW or CREATE OR REPLACE
VIEW
- have some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
underlying tables used on top of SELECT list (because it can be
(theoretically) updated, so it is enough to have UPDATE privilege on
......@@ -92,9 +94,13 @@ int mysql_create_view(THD *thd,
checked that we have not more privileges on correspondent column of view
table (i.e. user will not get some privileges by view creation)
*/
if (check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
0, 0) ||
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0))
if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
0, 0) ||
grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) ||
(mode != VIEW_CREATE_NEW &&
(check_access(thd, DELETE_ACL, view->db, &view->grant.privilege,
0, 0) ||
grant_option && check_grant(thd, DELETE_ACL, view, 0, 1, 0))))
DBUG_RETURN(1);
for (sl= select_lex; sl; sl= sl->next_select())
{
......@@ -174,9 +180,13 @@ int mysql_create_view(THD *thd,
if ((res= open_and_lock_tables(thd, tables)))
DBUG_RETURN(res);
/* check that tables are not temporary */
/*
check that tables are not temporary and this VIEW do not used in query
(it is possible with ALTERing VIEW)
*/
for (tbl= tables; tbl; tbl= tbl->next_global)
{
/* is this table temporary and is not view? */
if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view)
{
my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias);
......@@ -184,6 +194,16 @@ int mysql_create_view(THD *thd,
goto err;
}
/* is this table view and the same view which we creates now? */
if (tbl->view &&
strcmp(tbl->view_db.str, view->db) == 0 &&
strcmp(tbl->view_name.str, view->real_name) == 0)
{
my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str);
res= -1;
goto err;
}
/*
Copy the privileges of the underlying VIEWs which were filled by
fill_effective_table_privileges
......@@ -715,6 +735,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check= table->with_check;
table->ancestor= view_tables;
/*
......@@ -745,7 +766,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
lex->select_lex.linkage= DERIVED_TABLE_TYPE;
table->updatable= 0;
table->with_check= VIEW_CHECK_NONE;
table->effective_with_check= VIEW_CHECK_NONE;
/* SELECT tree link */
lex->unit.include_down(table->select_lex);
......
......@@ -425,6 +425,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token UDF_SONAME_SYM
%token FUNCTION_SYM
%token UNCOMMITTED_SYM
%token UNDEFINED_SYM
%token UNDERSCORE_CHARSET
%token UNDO_SYM
%token UNICODE_SYM
......@@ -3210,7 +3211,7 @@ alter:
lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->spname= $3;
}
| ALTER VIEW_SYM table_ident
| ALTER algorithm VIEW_SYM table_ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
......@@ -3218,9 +3219,9 @@ alter:
lex->create_view_mode= VIEW_ALTER;
lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE;
/* first table in list is target VIEW name */
lex->select_lex.add_table_to_list(thd, $3, NULL, 0);
lex->select_lex.add_table_to_list(thd, $4, NULL, 0);
}
opt_view_list AS select_init
opt_view_list AS select_init check_option
{}
;
......@@ -6973,6 +6974,7 @@ keyword:
| TYPES_SYM {}
| FUNCTION_SYM {}
| UNCOMMITTED_SYM {}
| UNDEFINED_SYM {}
| UNICODE_SYM {}
| UNTIL_SYM {}
| USER {}
......@@ -7908,6 +7910,8 @@ or_replace:
algorithm:
/* empty */
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ UNDEFINED_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
| ALGORITHM_SYM EQ MERGE_SYM
{ Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
| ALGORITHM_SYM EQ TEMPTABLE_SYM
......
......@@ -1599,10 +1599,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds)
if (arena)
thd->set_n_backup_item_arena(arena, &backup);
if (with_check)
if (effective_with_check)
{
check_option= where->copy_andor_structure(thd);
if (with_check == VIEW_CHECK_CASCADED)
if (effective_with_check == VIEW_CHECK_CASCADED)
{
check_option= and_conds(check_option, ancestor->check_option);
}
......
......@@ -245,6 +245,11 @@ typedef struct st_table_list
ulonglong revision; /* revision control number */
ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */
ulonglong with_check; /* WITH CHECK OPTION */
/*
effective value of WITH CHECK OPTION (differ for temporary table
algorithm)
*/
uint8 effective_with_check;
uint effective_algorithm; /* which algorithm was really used */
GRANT_INFO grant;
thr_lock_type lock_type;
......
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