summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-08-24 19:50:16 +0300
committerunknown <bell@sanja.is.com.ua>2004-08-24 19:50:16 +0300
commit964955b1c0c85c460efa4bbd757848d5e042b37d (patch)
tree2e3066ebe1e79d7dfc14dc57bf3b6dca1ee0f72e
parentc688b7b882e9eda4e19c8db0715184a802446756 (diff)
downloadmariadb-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.result20
-rw-r--r--mysql-test/t/view.test14
-rw-r--r--sql/sql_view.cc106
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);