From a809813b0dd1856b275d61a1d4bb7a829c50e681 Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Fri, 8 Jun 2007 14:42:08 +0500 Subject: [PATCH 1/3] Bug#18660 Can't grant any privileges on single table in database with underscore char In case of database level grant the database name may be a pattern, in case of table|column level grant the database name can not be a pattern. We use 'dont_check_global_grants' as a flag to determine if it's database level grant command (see SQLCOM_GRANT case, mysql_execute_command() function) and set db_is_pattern according to 'dont_check_global_grants' value. --- mysql-test/r/grant2.result | 18 ++++++++++++++++++ mysql-test/t/grant2.test | 30 ++++++++++++++++++++++++++++++ sql/sql_parse.cc | 12 +++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 93098e68070..6de9a83aeed 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -403,4 +403,22 @@ use test; drop database mysqltest_1; drop database mysqltest_2; drop user mysqltest_u1@localhost; +grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option; +grant usage on *.* to mysqltest_2@localhost; +create database mysqltest_1; +use mysqltest_1; +create table t1 (f1 int); +grant create on `mysqltest\_1`.* to mysqltest_2@localhost; +grant select on mysqltest_1.t1 to mysqltest_2@localhost; +create database mysqltest_3; +ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysqltest_3' +use mysqltest_1; +create table t2(f1 int); +select * from t1; +f1 +drop database mysqltest_1; +revoke all privileges, grant option from mysqltest_1@localhost; +revoke all privileges, grant option from mysqltest_2@localhost; +drop user mysqltest_1@localhost; +drop user mysqltest_2@localhost; End of 5.0 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 4a3324b1833..a3a8e2d5d53 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -555,5 +555,35 @@ drop database mysqltest_1; drop database mysqltest_2; drop user mysqltest_u1@localhost; +# +# Bug#18660 Can't grant any privileges on single table in database +# with underscore char +# +grant all on `mysqltest\_%`.* to mysqltest_1@localhost with grant option; +grant usage on *.* to mysqltest_2@localhost; +connect (con18600_1,localhost,mysqltest_1,,); + +create database mysqltest_1; +use mysqltest_1; +create table t1 (f1 int); + +grant create on `mysqltest\_1`.* to mysqltest_2@localhost; +grant select on mysqltest_1.t1 to mysqltest_2@localhost; +connect (con3,localhost,mysqltest_2,,); +connection con3; +--error 1044 +create database mysqltest_3; +use mysqltest_1; +create table t2(f1 int); +select * from t1; +connection default; +drop database mysqltest_1; + +revoke all privileges, grant option from mysqltest_1@localhost; +revoke all privileges, grant option from mysqltest_2@localhost; +drop user mysqltest_1@localhost; +drop user mysqltest_2@localhost; + + --echo End of 5.0 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6277a6c0c10..77525b49fdf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5252,7 +5252,17 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, Security_context *sctx= thd->security_ctx; #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; - bool db_is_pattern= test(want_access & GRANT_ACL); + /* + GRANT command: + In case of database level grant the database name may be a pattern, + in case of table|column level grant the database name can not be a pattern. + We use 'dont_check_global_grants' as a flag to determine + if it's database level grant command + (see SQLCOM_GRANT case, mysql_execute_command() function) and + set db_is_pattern according to 'dont_check_global_grants' value. + */ + bool db_is_pattern= (test(want_access & GRANT_ACL) && + dont_check_global_grants); #endif ulong dummy; DBUG_ENTER("check_access"); From d12fbdd8d0c3037168c1d2850f37db49ed77dc4f Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@magare.gmz" <> Date: Fri, 8 Jun 2007 13:42:10 +0300 Subject: [PATCH 2/3] Bug #28754: RPM builds differ from tar.gz in "ALTER ... RENAME" on views When constructing the path to the original .frm file ALTER .. RENAME was unnecessary (and incorrectly) lowercasing the whole path when not on a case-insensitive filesystem. This path should not be modified because of lower_case_table_names as it is already in the correct case according to that setting. Fixed by removing the lowercasing. Unfortunately testing this would require running the tests on a case sensitive filesystem in a directory that has uppercase letters. This cannot be guaranteed in all setups so no test case added. --- sql/sql_table.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 29ecf43a531..a44b087202b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3101,8 +3101,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, alter_info->tablespace_op)); sprintf(new_name_buff,"%s/%s/%s%s",mysql_data_home, db, table_name, reg_ext); unpack_filename(new_name_buff, new_name_buff); - if (lower_case_table_names != 2) - my_casedn_str(files_charset_info, new_name_buff); frm_type= mysql_frm_type(thd, new_name_buff, &table_type); /* Rename a view */ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) From 47ecabe91507e72d2a184d1649862e50526fa2cb Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Sat, 9 Jun 2007 16:52:37 +0500 Subject: [PATCH 3/3] Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong IS_UPDATABLE flag is set to 'yes' when the view has at least one updatable column and the algorithm is not 'temporary'. --- mysql-test/r/information_schema.result | 11 ++++++++++ mysql-test/r/view.result | 13 +++++++++++ mysql-test/t/information_schema.test | 15 +++++++++++++ mysql-test/t/view.test | 4 ++++ sql/sql_show.cc | 30 +++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index db703df1f52..4947fd7aecc 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1315,3 +1315,14 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 TRIGGERS information_schema.TRIGGERS 1 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 VIEWS information_schema.VIEWS 1 +create table t1(f1 int); +create view v1 as select f1+1 as a from t1; +create table t2 (f1 int, f2 int); +create view v2 as select f1+1 as a, f2 as b from t2; +select table_name, is_updatable from information_schema.views; +table_name is_updatable +v1 NO +v2 YES +delete from v1; +drop view v1,v2; +drop table t1,t2; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 43e147724c8..3757c5fd451 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -23,6 +23,9 @@ c 5 6 11 +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +NO create temporary table t1 (a int, b int); select * from t1; a b @@ -322,6 +325,12 @@ create table t1 (a int, b int, primary key(a)); insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10); create view v1 (a,c) as select a, b+1 from t1; create algorithm=temptable view v2 (a,c) as select a, b+1 from t1; +select is_updatable from information_schema.views where table_name='v2'; +is_updatable +NO +select is_updatable from information_schema.views where table_name='v1'; +is_updatable +YES update v1 set c=a+c; ERROR HY000: Column 'c' is not updatable update v2 set a=a+c; @@ -604,6 +613,10 @@ 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 is_updatable from information_schema.views; +is_updatable +YES +YES select * from t1; col1 col2 5 Hello, view world diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index f8922317eb3..1d368ac6075 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1023,4 +1023,19 @@ where t.table_schema = 'information_schema' and group by c2.column_type order by num limit 1) group by t.table_name order by num1, t.table_name; +# +# Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong +# +create table t1(f1 int); +create view v1 as select f1+1 as a from t1; +create table t2 (f1 int, f2 int); +create view v2 as select f1+1 as a, f2 as b from t2; +select table_name, is_updatable from information_schema.views; +# +# Note: we can perform 'delete' for non updatable view. +# +delete from v1; +drop view v1,v2; +drop table t1,t2; + # End of 5.0 tests. diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index f574451af08..3c370da4139 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -32,6 +32,7 @@ create view v1 (c,d) as select a,b from t1 # simple view create view v1 (c) as select b+1 from t1; select c from v1; +select is_updatable from information_schema.views where table_name='v1'; # temporary table should not hide table of view create temporary table t1 (a int, b int); @@ -228,6 +229,8 @@ create table t1 (a int, b int, primary key(a)); insert into t1 values (10,2), (20,3), (30,4), (40,5), (50,10); create view v1 (a,c) as select a, b+1 from t1; create algorithm=temptable view v2 (a,c) as select a, b+1 from t1; +select is_updatable from information_schema.views where table_name='v2'; +select is_updatable from information_schema.views where table_name='v1'; # try to update expression -- error 1348 update v1 set c=a+c; @@ -497,6 +500,7 @@ 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 is_updatable from information_schema.views; select * from t1; drop view v2, v1; drop table t1; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 16ed20cd479..a0db458be78 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3158,6 +3158,7 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, DBUG_ENTER("get_schema_views_record"); char definer[USER_HOST_BUFF_SIZE]; uint definer_len; + bool updatable_view; if (tables->view) { @@ -3195,7 +3196,34 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, else table->field[4]->store(STRING_WITH_LEN("NONE"), cs); - if (tables->updatable_view) + updatable_view= 0; + if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE) + { + /* + We should use tables->view->select_lex.item_list here and + can not use Field_iterator_view because the view always uses + temporary algorithm during opening for I_S and + TABLE_LIST fields 'field_translation' & 'field_translation_end' + are uninitialized is this case. + */ + List *fields= &tables->view->select_lex.item_list; + List_iterator it(*fields); + Item *item; + Item_field *field; + /* + chech that at least one coulmn in view is updatable + */ + while ((item= it++)) + { + if ((field= item->filed_for_view_update()) && field->field && + !field->field->table->pos_in_table_list->schema_table) + { + updatable_view= 1; + break; + } + } + } + if (updatable_view) table->field[5]->store(STRING_WITH_LEN("YES"), cs); else table->field[5]->store(STRING_WITH_LEN("NO"), cs);