diff options
author | unknown <bell@sanja.is.com.ua> | 2004-08-24 19:50:16 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2004-08-24 19:50:16 +0300 |
commit | 964955b1c0c85c460efa4bbd757848d5e042b37d (patch) | |
tree | 2e3066ebe1e79d7dfc14dc57bf3b6dca1ee0f72e | |
parent | c688b7b882e9eda4e19c8db0715184a802446756 (diff) | |
download | mariadb-git-964955b1c0c85c460efa4bbd757848d5e042b37d.tar.gz |
Fixed UNION support in view creation (BUG#4664)
mysql-test/r/view.result:
added removing of table t2
test of view built over union
mysql-test/t/view.test:
added removing of table t2
test of view built over union
sql/sql_view.cc:
Fixed UNION support in view creation
-rw-r--r-- | mysql-test/r/view.result | 20 | ||||
-rw-r--r-- | mysql-test/t/view.test | 14 | ||||
-rw-r--r-- | sql/sql_view.cc | 106 |
3 files changed, 85 insertions, 55 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index ac19dbe4ffa..059b8d4cf70 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -830,7 +830,7 @@ a b c 30 4 -60 50 6 -100 40 5 NULL -drop table t1; +drop table t1, t2; drop view v1,v2,v3,v4,v5; create database mysqltest; create table mysqltest.t1 (a int, b int, primary key(a)); @@ -1040,7 +1040,6 @@ CREATE VIEW v02 AS SELECT * FROM DUAL; ERROR HY000: No tables used SHOW TABLES; Tables_in_test table_type -t2 BASE TABLE v4 VIEW CREATE VIEW v1 AS SELECT EXISTS (SELECT 1 UNION SELECT 2); select * from v1; @@ -1058,3 +1057,20 @@ SHOW CREATE VIEW v1; Table Create Table v1 CREATE 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); +insert into t1 values (1), (2); +insert into t2 values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +s1 s2 +1 2 +2 2 +1 3 +2 3 +1 2 +2 2 +1 3 +2 3 +drop view v1; +drop tables t1, t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index dc92d7936eb..805d033c525 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -693,7 +693,7 @@ insert into v1 select c, b, a from t2; insert into v1 (z,y,x) select a+20,b+2,-100 from t2; insert into v2 select b+1, a+10 from t2; select * from t1; -drop table t1; +drop table t1, t2; drop view v1,v2,v3,v4,v5; # @@ -1004,3 +1004,15 @@ drop table t1; CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version(); SHOW CREATE VIEW v1; drop view v1; + +# +# VIEW built over UNION +# +create table t1 (s1 int); +create table t2 (s2 int); +insert into t1 values (1), (2); +insert into t2 values (2), (3); +create view v1 as select * from t1,t2 union all select * from t1,t2; +select * from v1; +drop view v1; +drop tables t1, t2; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 78fcac4ddcf..f531f2c94f5 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -54,7 +54,7 @@ int mysql_create_view(THD *thd, TABLE_LIST *view= lex->unlink_first_table(&link_to_local); TABLE_LIST *tables= lex->query_tables; TABLE_LIST *tbl; - SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *select_lex= &lex->select_lex, *sl; SELECT_LEX_UNIT *unit= &lex->unit; int res= 0; DBUG_ENTER("mysql_create_view"); @@ -74,56 +74,59 @@ int mysql_create_view(THD *thd, 0, 0) || grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) DBUG_RETURN(1); - for (tbl= tables; tbl; tbl= tbl->next_local) + for (sl= select_lex; sl; sl= sl->next_select()) { - /* - Ensure that we have some privilage on this table, more strict check - will be done on column level after preparation, - - SELECT_ACL will be checked for sure for all fields because it is - listed first (if we have not rights to SELECT from whole table this - right will be written as tbl->grant.want_privilege and will be checked - later (except fields which need any privilege and can be updated). - */ - if ((check_access(thd, SELECT_ACL, tbl->db, - &tbl->grant.privilege, 0, 1) || - grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 1)) && - (check_access(thd, INSERT_ACL, tbl->db, - &tbl->grant.privilege, 0, 1) || - grant_option && check_grant(thd, INSERT_ACL, tbl, 0, 1, 1)) && - (check_access(thd, DELETE_ACL, tbl->db, - &tbl->grant.privilege, 0, 1) || - grant_option && check_grant(thd, DELETE_ACL, tbl, 0, 1, 1)) && - (check_access(thd, UPDATE_ACL, tbl->db, - &tbl->grant.privilege, 0, 1) || - grant_option && check_grant(thd, UPDATE_ACL, tbl, 0, 1, 1)) - ) + for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) { - my_printf_error(ER_TABLEACCESS_DENIED_ERROR, - ER(ER_TABLEACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - tbl->real_name); - DBUG_RETURN(-1); - } - /* mark this table as table which will be checked after preparation */ - tbl->table_in_first_from_clause= 1; + /* + Ensure that we have some privilage on this table, more strict check + will be done on column level after preparation, - /* - We need to check only SELECT_ACL for all normal fields, fields - where we need any privilege will be pmarked later - */ - tbl->grant.want_privilege= SELECT_ACL; - /* - Make sure that all rights are loaded to table 'grant' field. + SELECT_ACL will be checked for sure for all fields because it is + listed first (if we have not rights to SELECT from whole table this + right will be written as tbl->grant.want_privilege and will be checked + later (except fields which need any privilege and can be updated). + */ + if ((check_access(thd, SELECT_ACL, tbl->db, + &tbl->grant.privilege, 0, 1) || + grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 1)) && + (check_access(thd, INSERT_ACL, tbl->db, + &tbl->grant.privilege, 0, 1) || + grant_option && check_grant(thd, INSERT_ACL, tbl, 0, 1, 1)) && + (check_access(thd, DELETE_ACL, tbl->db, + &tbl->grant.privilege, 0, 1) || + grant_option && check_grant(thd, DELETE_ACL, tbl, 0, 1, 1)) && + (check_access(thd, UPDATE_ACL, tbl->db, + &tbl->grant.privilege, 0, 1) || + grant_option && check_grant(thd, UPDATE_ACL, tbl, 0, 1, 1)) + ) + { + my_printf_error(ER_TABLEACCESS_DENIED_ERROR, + ER(ER_TABLEACCESS_DENIED_ERROR), + MYF(0), + "ANY", + thd->priv_user, + thd->host_or_ip, + tbl->real_name); + DBUG_RETURN(-1); + } + /* mark this table as table which will be checked after preparation */ + tbl->table_in_first_from_clause= 1; - tbl->real_name will be correct name of table because VIEWs are - not opened yet. - */ - fill_effective_table_privileges(thd, &tbl->grant, tbl->db, - tbl->real_name); + /* + We need to check only SELECT_ACL for all normal fields, fields + where we need any privilege will be pmarked later + */ + tbl->grant.want_privilege= SELECT_ACL; + /* + Make sure that all rights are loaded to table 'grant' field. + + tbl->real_name will be correct name of table because VIEWs are + not opened yet. + */ + fill_effective_table_privileges(thd, &tbl->grant, tbl->db, + tbl->real_name); + } } if (&lex->select_lex != lex->all_selects_list) @@ -145,12 +148,10 @@ int mysql_create_view(THD *thd, } /* Mark fields for special privilege check (any privilege) - - 'if' should be changed if we made updateable UNION. */ - if (lex->select_lex.next_select() == 0) + for (sl= select_lex; sl; sl= sl->next_select()) { - List_iterator_fast<Item> it(lex->select_lex.item_list); + List_iterator_fast<Item> it(sl->item_list); Item *item; while ((item= it++)) { @@ -235,9 +236,10 @@ int mysql_create_view(THD *thd, /* Compare/check grants on view with grants of underlaying tables */ + for (sl= select_lex; sl; sl= sl->next_select()) { char *db= view->db ? view->db : thd->db; - List_iterator_fast<Item> it(select_lex->item_list); + List_iterator_fast<Item> it(sl->item_list); Item *item; fill_effective_table_privileges(thd, &view->grant, db, view->real_name); |