Merge buzz.(none):/home/davi/mysql-5.0-runtime
into buzz.(none):/home/davi/mysql-5.1-runtime mysql-test/r/ps.result: Auto merged mysql-test/t/ps.test: Auto merged sql/sql_view.h: Auto merged sql/item.h: Manual merge sql/sql_prepare.cc: Manual merge sql/sql_view.cc: Manual merge
This commit is contained in:
commit
955b3e3d0b
@ -1733,6 +1733,158 @@ a b
|
||||
9999999999999999 14632475938453979136
|
||||
deallocate prepare stmt;
|
||||
drop table t1;
|
||||
drop view if exists v1;
|
||||
drop table if exists t1;
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (1,1), (2,2), (3,3);
|
||||
insert into t1 values (3,1), (1,2), (2,3);
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
execute stmt;
|
||||
drop table t1;
|
||||
create table t1 (a int, b int);
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1`
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 (c,d) as select a,b from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1`
|
||||
select * from v1;
|
||||
c d
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d` from `t1`
|
||||
select * from v1;
|
||||
c d
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 (c) as select b+1 from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
|
||||
select * from v1;
|
||||
c
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
|
||||
select * from v1;
|
||||
c
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1`
|
||||
select * from v1;
|
||||
c d e f
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `c`,`t1`.`b` AS `d`,`t1`.`a` in (select (`t1`.`a` + 2) AS `a+2` from `t1`) AS `e`,`t1`.`a` = all (select `t1`.`a` AS `a` from `t1`) AS `f` from `t1`
|
||||
select * from v1;
|
||||
c d e f
|
||||
drop view v1;
|
||||
prepare stmt from "create or replace view v1 as select 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
|
||||
select * from v1;
|
||||
1
|
||||
1
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
|
||||
select * from v1;
|
||||
1
|
||||
1
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 as select 1, 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1`
|
||||
select * from v1;
|
||||
1 My_exp_1
|
||||
1 1
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`,1 AS `My_exp_1`
|
||||
select * from v1;
|
||||
1 My_exp_1
|
||||
1 1
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1)
|
||||
select * from v1;
|
||||
x
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `x` from `t1` where (`t1`.`a` > 1)
|
||||
select * from v1;
|
||||
x
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 as select * from `t1` `b`";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b`
|
||||
select * from v1;
|
||||
a b
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
View Create View
|
||||
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `b`.`a` AS `a`,`b`.`b` AS `b` from `t1` `b`
|
||||
select * from v1;
|
||||
a b
|
||||
drop view v1;
|
||||
prepare stmt from "create view v1 (a,b,c) as select * from t1";
|
||||
execute stmt;
|
||||
ERROR HY000: View's SELECT and view's field list have different column counts
|
||||
execute stmt;
|
||||
ERROR HY000: View's SELECT and view's field list have different column counts
|
||||
deallocate prepare stmt;
|
||||
drop table t1;
|
||||
create temporary table t1 (a int, b int);
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
execute stmt;
|
||||
ERROR HY000: View's SELECT refers to a temporary table 't1'
|
||||
execute stmt;
|
||||
ERROR HY000: View's SELECT refers to a temporary table 't1'
|
||||
deallocate prepare stmt;
|
||||
drop table t1;
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
prepare stmt from "create view v1 as select * from `t1` `b`";
|
||||
ERROR 42S02: Table 'test.t1' doesn't exist
|
||||
End of 5.0 tests.
|
||||
create procedure proc_1() reset query cache;
|
||||
call proc_1();
|
||||
|
@ -1838,6 +1838,129 @@ select * from t1 where a = @a and b = @b;
|
||||
deallocate prepare stmt;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#32890 Crash after repeated create and drop of tables and views
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop view if exists v1;
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 values (1,1), (2,2), (3,3);
|
||||
insert into t1 values (3,1), (1,2), (2,3);
|
||||
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
execute stmt;
|
||||
drop table t1;
|
||||
create table t1 (a int, b int);
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 (c,d) as select a,b from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 (c) as select b+1 from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 (c,d,e,f) as select a,b,a in (select a+2 from t1), a = all (select a from t1) from t1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create or replace view v1 as select 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 as select 1, 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 (x) as select a from t1 where a > 1";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 as select * from `t1` `b`";
|
||||
execute stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
show create view v1;
|
||||
select * from v1;
|
||||
drop view v1;
|
||||
|
||||
prepare stmt from "create view v1 (a,b,c) as select * from t1";
|
||||
--error ER_VIEW_WRONG_LIST
|
||||
execute stmt;
|
||||
--error ER_VIEW_WRONG_LIST
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
|
||||
drop table t1;
|
||||
create temporary table t1 (a int, b int);
|
||||
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
--error ER_VIEW_SELECT_TMPTABLE
|
||||
execute stmt;
|
||||
--error ER_VIEW_SELECT_TMPTABLE
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
|
||||
drop table t1;
|
||||
|
||||
--error ER_NO_SUCH_TABLE
|
||||
prepare stmt from "create view v1 as select * from t1";
|
||||
--error ER_NO_SUCH_TABLE
|
||||
prepare stmt from "create view v1 as select * from `t1` `b`";
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
#
|
||||
|
45
sql/item.h
45
sql/item.h
@ -1010,6 +1010,23 @@ public:
|
||||
class sp_head;
|
||||
|
||||
|
||||
class Item_basic_constant :public Item
|
||||
{
|
||||
public:
|
||||
/* to prevent drop fixed flag (no need parent cleanup call) */
|
||||
void cleanup()
|
||||
{
|
||||
/*
|
||||
Restore the original field name as it might not have been allocated
|
||||
in the statement memory. If the name is auto generated, it must be
|
||||
done again between subsequent executions of a prepared statement.
|
||||
*/
|
||||
if (orig_name)
|
||||
name= orig_name;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
The class is a base class for representation of stored routine variables in
|
||||
the Item-hierarchy. There are the following kinds of SP-vars:
|
||||
@ -1292,7 +1309,7 @@ bool agg_item_charsets(DTCollation &c, const char *name,
|
||||
Item **items, uint nitems, uint flags, int item_sep);
|
||||
|
||||
|
||||
class Item_num: public Item
|
||||
class Item_num: public Item_basic_constant
|
||||
{
|
||||
public:
|
||||
Item_num() {} /* Remove gcc warning */
|
||||
@ -1484,7 +1501,7 @@ public:
|
||||
friend class st_select_lex_unit;
|
||||
};
|
||||
|
||||
class Item_null :public Item
|
||||
class Item_null :public Item_basic_constant
|
||||
{
|
||||
public:
|
||||
Item_null(char *name_par=0)
|
||||
@ -1506,8 +1523,6 @@ public:
|
||||
bool send(Protocol *protocol, String *str);
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
|
||||
/* to prevent drop fixed flag (no need parent cleanup call) */
|
||||
void cleanup() {}
|
||||
bool basic_const_item() const { return 1; }
|
||||
Item *clone_item() { return new Item_null(name); }
|
||||
bool is_null() { return 1; }
|
||||
@ -1701,8 +1716,6 @@ public:
|
||||
int save_in_field(Field *field, bool no_conversions);
|
||||
bool basic_const_item() const { return 1; }
|
||||
Item *clone_item() { return new Item_int(name,value,max_length); }
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
void print(String *str);
|
||||
Item_num *neg() { value= -value; return this; }
|
||||
uint decimal_precision() const
|
||||
@ -1757,8 +1770,6 @@ public:
|
||||
{
|
||||
return new Item_decimal(name, &decimal_value, decimals, max_length);
|
||||
}
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
void print(String *str);
|
||||
Item_num *neg()
|
||||
{
|
||||
@ -1813,8 +1824,6 @@ public:
|
||||
String *val_str(String*);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
bool basic_const_item() const { return 1; }
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
Item *clone_item()
|
||||
{ return new Item_float(name, value, decimals, max_length); }
|
||||
Item_num *neg() { value= -value; return this; }
|
||||
@ -1836,7 +1845,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Item_string :public Item
|
||||
class Item_string :public Item_basic_constant
|
||||
{
|
||||
public:
|
||||
Item_string(const char *str,uint length,
|
||||
@ -1923,8 +1932,6 @@ public:
|
||||
max_length= str_value.numchars() * collation.collation->mbmaxlen;
|
||||
}
|
||||
void print(String *str);
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
|
||||
|
||||
/**
|
||||
@ -1968,6 +1975,8 @@ public:
|
||||
|
||||
private:
|
||||
bool m_cs_specified;
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
};
|
||||
|
||||
|
||||
@ -2050,10 +2059,10 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Item_hex_string: public Item
|
||||
class Item_hex_string: public Item_basic_constant
|
||||
{
|
||||
public:
|
||||
Item_hex_string(): Item() {}
|
||||
Item_hex_string() {}
|
||||
Item_hex_string(const char *str,uint str_length);
|
||||
enum Type type() const { return VARBIN_ITEM; }
|
||||
double val_real()
|
||||
@ -2069,8 +2078,6 @@ public:
|
||||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum Item_result cast_to_int_type() const { return INT_RESULT; }
|
||||
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
void print(String *str);
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
|
||||
@ -2662,7 +2669,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class Item_cache: public Item
|
||||
class Item_cache: public Item_basic_constant
|
||||
{
|
||||
protected:
|
||||
Item *example;
|
||||
@ -2709,8 +2716,6 @@ public:
|
||||
static Item_cache* get_cache(const Item *item);
|
||||
table_map used_tables() const { return used_table_map; }
|
||||
virtual void keep_array() {}
|
||||
// to prevent drop fixed flag (no need parent cleanup call)
|
||||
void cleanup() {}
|
||||
void print(String *str);
|
||||
bool eq_def(Field *field)
|
||||
{
|
||||
|
@ -1524,6 +1524,44 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
|
||||
|
||||
|
||||
/**
|
||||
@brief Validate and prepare for execution CREATE VIEW statement
|
||||
|
||||
@param stmt prepared statement
|
||||
|
||||
@note This function handles create view commands.
|
||||
|
||||
@retval FALSE Operation was a success.
|
||||
@retval TRUE An error occured.
|
||||
*/
|
||||
|
||||
static bool mysql_test_create_view(Prepared_statement *stmt)
|
||||
{
|
||||
DBUG_ENTER("mysql_test_create_view");
|
||||
THD *thd= stmt->thd;
|
||||
LEX *lex= stmt->lex;
|
||||
bool res= TRUE;
|
||||
/* Skip first table, which is the view we are creating */
|
||||
bool link_to_local;
|
||||
TABLE_LIST *view= lex->unlink_first_table(&link_to_local);
|
||||
TABLE_LIST *tables= lex->query_tables;
|
||||
|
||||
if (create_view_precheck(thd, tables, view, lex->create_view_mode))
|
||||
goto err;
|
||||
|
||||
if (open_normal_and_derived_tables(thd, tables, 0))
|
||||
goto err;
|
||||
|
||||
lex->view_prepare_mode= 1;
|
||||
res= select_like_stmt_test(stmt, 0, 0);
|
||||
|
||||
err:
|
||||
/* put view back for PS rexecuting */
|
||||
lex->link_first_table_back(view, link_to_local);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Validate and prepare for execution a multi update statement.
|
||||
|
||||
@param stmt prepared statement
|
||||
@ -1735,6 +1773,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
|
||||
my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0));
|
||||
goto error;
|
||||
}
|
||||
res= mysql_test_create_view(stmt);
|
||||
break;
|
||||
case SQLCOM_DO:
|
||||
res= mysql_test_do_fields(stmt, tables, lex->insert_list);
|
||||
|
247
sql/sql_view.cc
247
sql/sql_view.cc
@ -227,9 +227,146 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
|
||||
/**
|
||||
Creating/altering VIEW procedure
|
||||
@brief CREATE VIEW privileges pre-check.
|
||||
|
||||
@param thd thread handler
|
||||
@param tables tables used in the view
|
||||
@param views views to create
|
||||
@param mode VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
|
||||
|
||||
@retval FALSE Operation was a success.
|
||||
@retval TRUE An error occured.
|
||||
*/
|
||||
|
||||
bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
|
||||
enum_view_create_mode mode)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
/* first table in list is target VIEW name => cut off it */
|
||||
TABLE_LIST *tbl;
|
||||
SELECT_LEX *select_lex= &lex->select_lex;
|
||||
SELECT_LEX *sl;
|
||||
bool res= TRUE;
|
||||
DBUG_ENTER("create_view_precheck");
|
||||
|
||||
/*
|
||||
Privilege check for view creation:
|
||||
- user has CREATE VIEW privilege on view table
|
||||
- user has DROP privilege in case of ALTER VIEW or CREATE OR REPLACE
|
||||
VIEW
|
||||
- user has some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
|
||||
underlying tables used on top of SELECT list (because it can be
|
||||
(theoretically) updated, so it is enough to have UPDATE privilege on
|
||||
them, for example)
|
||||
- user has SELECT privilege on columns used in expressions of VIEW select
|
||||
- for columns of underly tables used on top of SELECT list also will be
|
||||
checked that we have not more privileges on correspondent column of view
|
||||
table (i.e. user will not get some privileges by view creation)
|
||||
*/
|
||||
if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
|
||||
0, 0, is_schema_db(view->db)) ||
|
||||
check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) ||
|
||||
(mode != VIEW_CREATE_NEW &&
|
||||
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
|
||||
0, 0, is_schema_db(view->db)) ||
|
||||
check_grant(thd, DROP_ACL, view, 0, 1, 0))))
|
||||
goto err;
|
||||
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
|
||||
{
|
||||
/*
|
||||
Ensure that we have some privileges on this table, more strict check
|
||||
will be done on column level after preparation,
|
||||
*/
|
||||
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
|
||||
{
|
||||
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
|
||||
"ANY", thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host, tbl->table_name);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
Mark this table as a table which will be checked after the prepare
|
||||
phase
|
||||
*/
|
||||
tbl->table_in_first_from_clause= 1;
|
||||
|
||||
/*
|
||||
We need to check only SELECT_ACL for all normal fields, fields for
|
||||
which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be
|
||||
checked later
|
||||
*/
|
||||
tbl->grant.want_privilege= SELECT_ACL;
|
||||
/*
|
||||
Make sure that all rights are loaded to the TABLE::grant field.
|
||||
|
||||
tbl->table_name will be correct name of table because VIEWs are
|
||||
not opened yet.
|
||||
*/
|
||||
fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
|
||||
tbl->table_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (&lex->select_lex != lex->all_selects_list)
|
||||
{
|
||||
/* check tables of subqueries */
|
||||
for (tbl= tables; tbl; tbl= tbl->next_global)
|
||||
{
|
||||
if (!tbl->table_in_first_from_clause)
|
||||
{
|
||||
if (check_access(thd, SELECT_ACL, tbl->db,
|
||||
&tbl->grant.privilege, 0, 0, test(tbl->schema_table)) ||
|
||||
check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Mark fields for special privilege check ("any" privilege)
|
||||
*/
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
List_iterator_fast<Item> it(sl->item_list);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
Item_field *field;
|
||||
if ((field= item->filed_for_view_update()))
|
||||
{
|
||||
/*
|
||||
any_privileges may be reset later by the Item_field::set_field
|
||||
method in case of a system temporary table.
|
||||
*/
|
||||
field->any_privileges= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res= FALSE;
|
||||
|
||||
err:
|
||||
DBUG_RETURN(res || thd->net.report_error);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
|
||||
enum_view_create_mode mode)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
@brief Creating/altering VIEW procedure
|
||||
|
||||
@param thd thread handler
|
||||
@param views views to create
|
||||
@ -241,7 +378,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
|
||||
@retval TRUE An error occured.
|
||||
*/
|
||||
|
||||
bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
enum_view_create_mode mode)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
@ -260,7 +397,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
|
||||
/* This is ensured in the parser. */
|
||||
DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
|
||||
!lex->param_list.elements);
|
||||
!lex->param_list.elements && !lex->derived_tables);
|
||||
|
||||
if (mode != VIEW_CREATE_NEW)
|
||||
{
|
||||
@ -325,109 +462,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Privilege check for view creation:
|
||||
- user has CREATE VIEW privilege on view table
|
||||
- user has DROP privilege in case of ALTER VIEW or CREATE OR REPLACE
|
||||
VIEW
|
||||
- user has some (SELECT/UPDATE/INSERT/DELETE) privileges on columns of
|
||||
underlying tables used on top of SELECT list (because it can be
|
||||
(theoretically) updated, so it is enough to have UPDATE privilege on
|
||||
them, for example)
|
||||
- user has SELECT privilege on columns used in expressions of VIEW select
|
||||
- for columns of underly tables used on top of SELECT list also will be
|
||||
checked that we have not more privileges on correspondent column of view
|
||||
table (i.e. user will not get some privileges by view creation)
|
||||
*/
|
||||
if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege,
|
||||
0, 0, is_schema_db(view->db)) ||
|
||||
check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) ||
|
||||
(mode != VIEW_CREATE_NEW &&
|
||||
(check_access(thd, DROP_ACL, view->db, &view->grant.privilege,
|
||||
0, 0, is_schema_db(view->db)) ||
|
||||
check_grant(thd, DROP_ACL, view, 0, 1, 0))))
|
||||
{
|
||||
res= TRUE;
|
||||
goto err;
|
||||
}
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local)
|
||||
{
|
||||
/*
|
||||
Ensure that we have some privileges on this table, more strict check
|
||||
will be done on column level after preparation,
|
||||
*/
|
||||
if (check_some_access(thd, VIEW_ANY_ACL, tbl))
|
||||
{
|
||||
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
|
||||
"ANY", thd->security_ctx->priv_user,
|
||||
thd->security_ctx->priv_host, tbl->table_name);
|
||||
res= TRUE;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
Mark this table as a table which will be checked after the prepare
|
||||
phase
|
||||
*/
|
||||
tbl->table_in_first_from_clause= 1;
|
||||
|
||||
/*
|
||||
We need to check only SELECT_ACL for all normal fields, fields for
|
||||
which we need "any" (SELECT/UPDATE/INSERT/DELETE) privilege will be
|
||||
checked later
|
||||
*/
|
||||
tbl->grant.want_privilege= SELECT_ACL;
|
||||
/*
|
||||
Make sure that all rights are loaded to the TABLE::grant field.
|
||||
|
||||
tbl->table_name will be correct name of table because VIEWs are
|
||||
not opened yet.
|
||||
*/
|
||||
fill_effective_table_privileges(thd, &tbl->grant, tbl->db,
|
||||
tbl->table_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (&lex->select_lex != lex->all_selects_list)
|
||||
{
|
||||
/* check tables of subqueries */
|
||||
for (tbl= tables; tbl; tbl= tbl->next_global)
|
||||
{
|
||||
if (!tbl->table_in_first_from_clause)
|
||||
{
|
||||
if (check_access(thd, SELECT_ACL, tbl->db,
|
||||
&tbl->grant.privilege, 0, 0, test(tbl->schema_table)) ||
|
||||
check_grant(thd, SELECT_ACL, tbl, 0, 1, 0))
|
||||
{
|
||||
res= TRUE;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Mark fields for special privilege check ("any" privilege)
|
||||
*/
|
||||
for (sl= select_lex; sl; sl= sl->next_select())
|
||||
{
|
||||
List_iterator_fast<Item> it(sl->item_list);
|
||||
Item *item;
|
||||
while ((item= it++))
|
||||
{
|
||||
Item_field *field;
|
||||
if ((field= item->filed_for_view_update()))
|
||||
{
|
||||
/*
|
||||
any_privileges may be reset later by the Item_field::set_field
|
||||
method in case of a system temporary table.
|
||||
*/
|
||||
field->any_privileges= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((res= create_view_precheck(thd, tables, view, mode)))
|
||||
goto err;
|
||||
|
||||
if (open_and_lock_tables(thd, tables))
|
||||
{
|
||||
res= TRUE;
|
||||
|
@ -15,6 +15,9 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
|
||||
enum_view_create_mode mode);
|
||||
|
||||
bool mysql_create_view(THD *thd, TABLE_LIST *view,
|
||||
enum_view_create_mode mode);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user