diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 2a593f7c6df..5f399b816ac 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -977,9 +977,19 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) drop view v1; create view v1 (a,a) as select 'a','a'; ERROR 42S21: Duplicate column name 'a' -create procedure p11 () begin declare v int; create view v1 as select v; end;// +create procedure p1 () begin declare v int; create view v1 as select v; end;// Warnings: Warning 1310 Referring to uninitialized variable v -call p11(); +call p1(); ERROR HY000: View's SELECT contains a variable or parameter -drop procedure p11; +drop procedure p1; +create table t1 (col1 int,col2 char(22)); +insert into t1 values(5,'Hello, world of views'); +create view v1 as select * from t1; +create view v2 as select * from v1; +update v2 set col2='Hello, view world'; +select * from t1; +col1 col2 +5 Hello, view world +drop view v2, v1; +drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 33ffa114c28..30016b38b16 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -905,8 +905,20 @@ create view v1 (a,a) as select 'a','a'; # SP variables inside view test # delimiter //; -create procedure p11 () begin declare v int; create view v1 as select v; end;// +create procedure p1 () begin declare v int; create view v1 as select v; end;// delimiter ;// -- error 1350 -call p11(); -drop procedure p11; +call p1(); +drop procedure p1; + +# +# updateablity should be transitive +# +create table t1 (col1 int,col2 char(22)); +insert into t1 values(5,'Hello, world of views'); +create view v1 as select * from t1; +create view v2 as select * from v1; +update v2 set col2='Hello, view world'; +select * from t1; +drop view v2, v1; +drop table t1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 71bdd84e2ac..41c629e5c12 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3856,19 +3856,19 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, /* db privileges */ grant->privilege|= acl_get(thd->host, thd->ip, thd->priv_user, db, 0); /* table privileges */ - rw_rdlock(&LOCK_grant); if (grant->version != grant_version) { + rw_rdlock(&LOCK_grant); grant->grant_table= table_hash_search(thd->host, thd->ip, db, thd->priv_user, table, 0); /* purecov: inspected */ grant->version= grant_version; /* purecov: inspected */ + rw_unlock(&LOCK_grant); } if (grant->grant_table != 0) { grant->privilege|= grant->grant_table->privs; } - rw_unlock(&LOCK_grant); } #endif diff --git a/sql/sql_view.cc b/sql/sql_view.cc index eebf5a20795..339e14d9333 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -330,7 +330,7 @@ static File_option view_parameters[]= FILE_OPTIONS_STRING}, {{view_field_names[1], 3}, offsetof(TABLE_LIST, md5), FILE_OPTIONS_STRING}, - {{view_field_names[2], 9}, offsetof(TABLE_LIST, updatable), + {{view_field_names[2], 9}, offsetof(TABLE_LIST, updatable_view), FILE_OPTIONS_ULONGLONG}, {{view_field_names[3], 9}, offsetof(TABLE_LIST, algorithm), FILE_OPTIONS_ULONGLONG}, @@ -472,17 +472,17 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, thd->lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } view->algorithm= thd->lex->create_view_algorithm; - if ((view->updatable= (can_be_merged && - view->algorithm != VIEW_ALGORITHM_TMEPTABLE))) + if ((view->updatable_view= (can_be_merged && + view->algorithm != VIEW_ALGORITHM_TMEPTABLE))) { // TODO: change here when we will support UNIONs for (TABLE_LIST *tbl= (TABLE_LIST *)thd->lex->select_lex.table_list.first; tbl; tbl= tbl->next_local) { - if (tbl->view != 0 && !tbl->updatable) + if (tbl->view != 0 && !tbl->updatable_view) { - view->updatable= 0; + view->updatable_view= 0; break; } } @@ -663,6 +663,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) DBUG_ASSERT(view_table != 0); table->effective_algorithm= VIEW_ALGORITHM_MERGE; + table->updatable= (table->updatable_view != 0); if (old_next) { @@ -692,12 +693,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) table->effective_algorithm= VIEW_ALGORITHM_TMEPTABLE; lex->select_lex.linkage= DERIVED_TABLE_TYPE; - if (table->updatable) - { - //TOTO: warning: can't be updateable, .frm edited by hand. version - //downgrade? - table->updatable= 0; - } + table->updatable= 0; /* SELECT tree link */ lex->unit.include_down(table->select_lex); diff --git a/sql/table.h b/sql/table.h index 166cea84b53..75d54d9d069 100644 --- a/sql/table.h +++ b/sql/table.h @@ -215,8 +215,8 @@ typedef struct st_table_list LEX_STRING view_name; /* save view name */ LEX_STRING timestamp; /* GMT time stamp of last operation */ ulonglong file_version; /* version of file's field set */ + ulonglong updatable_view; /* VIEW can be updated */ ulonglong revision; /* revision control number */ - ulonglong updatable; /* Is VIEW updateable */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ uint effective_algorithm; /* which algorithm was really used */ GRANT_INFO grant; @@ -224,6 +224,7 @@ typedef struct st_table_list uint outer_join; /* Which join type */ uint shared; /* Used in multi-upd */ uint32 db_length, real_name_length; + bool updatable; /* VIEW/TABLE can be updated now */ bool straight; /* optimize with prev table */ bool updating; /* for replicate-do/ignore table */ bool force_index; /* prefer index over table scan */