Commit 964955b1 authored by unknown's avatar unknown

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
parent c688b7b8
......@@ -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;
......@@ -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;
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment