diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c8a673e2209..62bf5b30503 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2807,3 +2807,14 @@ yadda yad DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 (x INT, y INT); +CREATE ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x` from `t1` +ALTER VIEW v1 AS SELECT x, y FROM t1; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x`,`t1`.`y` AS `y` from `t1` +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 6399cef9086..5db9030eece 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2667,3 +2667,16 @@ SELECT * FROM v1; DROP VIEW v1; DROP TABLE t1; + +# +#Bug #21080: ALTER VIEW makes user restate SQL SECURITY mode, and ALGORITHM +# +CREATE TABLE t1 (x INT, y INT); +CREATE ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +SHOW CREATE VIEW v1; + +ALTER VIEW v1 AS SELECT x, y FROM t1; +SHOW CREATE VIEW v1; + +DROP VIEW v1; +DROP TABLE t1; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e5b087fc72a..897f6c25190 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -978,7 +978,7 @@ typedef struct st_lex : public Query_tables_list /* view created to be run from definer (standard behaviour) */ - bool create_view_suid; + uint8 create_view_suid; /* Characterstics of trigger being created */ st_trg_chistics trg_chistics; /* diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 1561ade78af..8aa93a7bbeb 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -155,6 +155,54 @@ err: DBUG_RETURN(TRUE); } +/* + Fill defined view parts + + SYNOPSIS + fill_defined_view_parts() + thd current thread. + view view to operate on + + DESCRIPTION + This function will initialize the parts of the view + definition that are not specified in ALTER VIEW + to their values from CREATE VIEW. + The view must be opened to get its definition. + We use a copy of the view when opening because we want + to preserve the original view instance. + + RETURN VALUE + TRUE can't open table + FALSE success +*/ +static bool +fill_defined_view_parts (THD *thd, TABLE_LIST *view) +{ + LEX *lex= thd->lex; + bool not_used; + TABLE_LIST decoy; + + memcpy (&decoy, view, sizeof (TABLE_LIST)); + if (!open_table(thd, &decoy, thd->mem_root, ¬_used, 0) && + !decoy.view) + { + return TRUE; + } + if (!lex->definer) + { + view->definer.host= decoy.definer.host; + view->definer.user= decoy.definer.user; + lex->definer= &view->definer; + } + if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED) + lex->create_view_algorithm= decoy.algorithm; + if (lex->create_view_suid == VIEW_SUID_DEFAULT) + lex->create_view_suid= decoy.view_suid ? + VIEW_SUID_DEFINER : VIEW_SUID_INVOKER; + + return FALSE; +} + /* Creating/altering VIEW procedure @@ -207,7 +255,15 @@ bool mysql_create_view(THD *thd, } if (mode != VIEW_CREATE_NEW) + { + if (mode == VIEW_ALTER && + fill_defined_view_parts(thd, view)) + { + res= TRUE; + goto err; + } sp_cache_invalidate(); + } if (!lex->definer) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 425945f525e..677c327be3e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8997,11 +8997,11 @@ view_algorithm_opt: view_suid: /* empty */ - { Lex->create_view_suid= TRUE; } + { Lex->create_view_suid= VIEW_SUID_DEFAULT; } | SQL_SYM SECURITY_SYM DEFINER_SYM - { Lex->create_view_suid= TRUE; } + { Lex->create_view_suid= VIEW_SUID_DEFINER; } | SQL_SYM SECURITY_SYM INVOKER_SYM - { Lex->create_view_suid= FALSE; } + { Lex->create_view_suid= VIEW_SUID_INVOKER; } ; view_tail: diff --git a/sql/table.h b/sql/table.h index eb34867c390..675439e3662 100644 --- a/sql/table.h +++ b/sql/table.h @@ -360,6 +360,10 @@ typedef struct st_schema_table #define VIEW_ALGORITHM_TMPTABLE 1 #define VIEW_ALGORITHM_MERGE 2 +#define VIEW_SUID_INVOKER 0 +#define VIEW_SUID_DEFINER 1 +#define VIEW_SUID_DEFAULT 2 + /* view WITH CHECK OPTION parameter options */ #define VIEW_CHECK_NONE 0 #define VIEW_CHECK_LOCAL 1