mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
Merge
This commit is contained in:
commit
8fb46a3d13
15 changed files with 356 additions and 77 deletions
|
@ -136,7 +136,7 @@ connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
|
|||
connection user3;
|
||||
select "user3";
|
||||
--replace_result 127.0.0.1 localhost
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
select * from t1;
|
||||
select a from t1;
|
||||
--replace_result 127.0.0.1 localhost
|
||||
|
|
|
@ -434,7 +434,7 @@ USE db1;
|
|||
SELECT c FROM t2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
|
||||
SELECT * FROM t2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for table 't2'
|
||||
SELECT * FROM t1 JOIN t2 USING (b);
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest1'@'localhost' for column 'c' in table 't2'
|
||||
DROP TABLE db1.t1, db1.t2;
|
||||
|
|
|
@ -155,7 +155,7 @@ select "user3";
|
|||
user3
|
||||
user3
|
||||
select * from t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'b' in table 't1'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
|
||||
select a from t1;
|
||||
a
|
||||
1
|
||||
|
|
|
@ -155,7 +155,7 @@ select "user3";
|
|||
user3
|
||||
user3
|
||||
select * from t1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'b' in table 't1'
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't1'
|
||||
select a from t1;
|
||||
a
|
||||
1
|
||||
|
|
|
@ -957,3 +957,35 @@ Warning 1356 View 'test.v1' references invalid table(s) or column(s) or function
|
|||
DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests.
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
USE mysqltest1;
|
||||
CREATE TABLE t1 ( a INT, b INT );
|
||||
CREATE TABLE t2 ( a INT, b INT );
|
||||
CREATE VIEW v1 AS SELECT a, b FROM t1;
|
||||
GRANT SELECT( a ) ON v1 TO mysqluser1@localhost;
|
||||
GRANT UPDATE( b ) ON t2 TO mysqluser1@localhost;
|
||||
SELECT * FROM mysqltest1.v1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
|
||||
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t2;
|
||||
ERROR 42000: ANY command denied to user 'mysqluser1'@'localhost' for table 't2'
|
||||
DROP TABLE t1, t2;
|
||||
DROP VIEW v1;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP USER mysqluser1@localhost;
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
USE mysqltest1;
|
||||
CREATE VIEW v1 AS SELECT * FROM information_schema.tables LIMIT 1;
|
||||
CREATE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT 1 AS A;
|
||||
GRANT SELECT ON mysqltest1.* to mysqluser1@localhost;
|
||||
PREPARE stmt_v1 FROM "SELECT * FROM mysqltest1.v1";
|
||||
PREPARE stmt_v2 FROM "SELECT * FROM mysqltest1.v2";
|
||||
REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost;
|
||||
EXECUTE stmt_v1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1'
|
||||
EXECUTE stmt_v2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v2'
|
||||
DROP VIEW v1, v2;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP USER mysqluser1@localhost;
|
||||
|
|
|
@ -605,7 +605,7 @@ connection conn1;
|
|||
USE db1;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
SELECT c FROM t2;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT * FROM t2;
|
||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||
SELECT * FROM t1 JOIN t2 USING (b);
|
||||
|
|
|
@ -1219,3 +1219,71 @@ DROP VIEW v1;
|
|||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests.
|
||||
|
||||
#
|
||||
# Bug#36086: SELECT * from views don't check column grants
|
||||
#
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
|
||||
USE mysqltest1;
|
||||
|
||||
CREATE TABLE t1 ( a INT, b INT );
|
||||
CREATE TABLE t2 ( a INT, b INT );
|
||||
|
||||
CREATE VIEW v1 AS SELECT a, b FROM t1;
|
||||
|
||||
GRANT SELECT( a ) ON v1 TO mysqluser1@localhost;
|
||||
GRANT UPDATE( b ) ON t2 TO mysqluser1@localhost;
|
||||
|
||||
--connect (connection1, localhost, mysqluser1, , test)
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT * FROM mysqltest1.v1;
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t2;
|
||||
|
||||
--disconnect connection1
|
||||
|
||||
--connection default
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
DROP VIEW v1;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP USER mysqluser1@localhost;
|
||||
|
||||
#
|
||||
# Bug#35600: Security breach via view, I_S table and prepared
|
||||
# statement/stored procedure
|
||||
#
|
||||
CREATE USER mysqluser1@localhost;
|
||||
CREATE DATABASE mysqltest1;
|
||||
|
||||
USE mysqltest1;
|
||||
|
||||
CREATE VIEW v1 AS SELECT * FROM information_schema.tables LIMIT 1;
|
||||
CREATE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT 1 AS A;
|
||||
|
||||
--connection default
|
||||
GRANT SELECT ON mysqltest1.* to mysqluser1@localhost;
|
||||
|
||||
--connect (connection1, localhost, mysqluser1, , test)
|
||||
PREPARE stmt_v1 FROM "SELECT * FROM mysqltest1.v1";
|
||||
PREPARE stmt_v2 FROM "SELECT * FROM mysqltest1.v2";
|
||||
|
||||
--connection default
|
||||
REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost;
|
||||
|
||||
--connection connection1
|
||||
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
EXECUTE stmt_v1;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
EXECUTE stmt_v2;
|
||||
|
||||
--disconnect connection1
|
||||
--connection default
|
||||
DROP VIEW v1, v2;
|
||||
DROP DATABASE mysqltest1;
|
||||
DROP USER mysqluser1@localhost;
|
||||
|
|
12
sql/item.cc
12
sql/item.cc
|
@ -4120,16 +4120,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||
if (any_privileges)
|
||||
{
|
||||
char *db, *tab;
|
||||
if (cached_table->view)
|
||||
{
|
||||
db= cached_table->view_db.str;
|
||||
tab= cached_table->view_name.str;
|
||||
}
|
||||
else
|
||||
{
|
||||
db= cached_table->db;
|
||||
tab= cached_table->table_name;
|
||||
}
|
||||
db= cached_table->get_db_name();
|
||||
tab= cached_table->get_table_name();
|
||||
if (!(have_privileges= (get_column_grant(thd, &field->table->grant,
|
||||
db, tab, field_name) &
|
||||
VIEW_ANY_ACL)))
|
||||
|
|
|
@ -3092,12 +3092,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
|
|||
continue; // Add next user
|
||||
}
|
||||
|
||||
db_name= (table_list->view_db.length ?
|
||||
table_list->view_db.str :
|
||||
table_list->db);
|
||||
table_name= (table_list->view_name.length ?
|
||||
table_list->view_name.str :
|
||||
table_list->table_name);
|
||||
db_name= table_list->get_db_name();
|
||||
table_name= table_list->get_table_name();
|
||||
|
||||
/* Find/create cached table grant */
|
||||
grant_table= table_hash_search(Str->host.str, NullS, db_name,
|
||||
|
@ -3907,8 +3903,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||
if (!want_access)
|
||||
continue; // ok
|
||||
|
||||
if (!(~table->grant.privilege & want_access) ||
|
||||
table->derived || table->schema_table)
|
||||
if (!(~table->grant.privilege & want_access) ||
|
||||
table->is_anonymous_derived_table() || table->schema_table)
|
||||
{
|
||||
/*
|
||||
It is subquery in the FROM clause. VIEW set table->derived after
|
||||
|
@ -3926,8 +3922,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
|
|||
continue;
|
||||
}
|
||||
if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
|
||||
table->db, sctx->priv_user,
|
||||
table->table_name,0)))
|
||||
table->get_db_name(), sctx->priv_user,
|
||||
table->get_table_name(), FALSE)))
|
||||
{
|
||||
want_access &= ~table->grant.privilege;
|
||||
goto err; // No grants
|
||||
|
@ -3963,7 +3959,7 @@ err:
|
|||
command,
|
||||
sctx->priv_user,
|
||||
sctx->host_or_ip,
|
||||
table ? table->table_name : "unknown");
|
||||
table ? table->get_table_name() : "unknown");
|
||||
}
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -4118,7 +4114,7 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref,
|
|||
@retval 1 Falure
|
||||
@details This function walks over the columns of a table reference
|
||||
The columns may originate from different tables, depending on the kind of
|
||||
table reference, e.g. join.
|
||||
table reference, e.g. join, view.
|
||||
For each table it will retrieve the grant information and will use it
|
||||
to check the required access privileges for the fields requested from it.
|
||||
*/
|
||||
|
@ -4133,6 +4129,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
|
|||
GRANT_INFO *grant;
|
||||
/* Initialized only to make gcc happy */
|
||||
GRANT_TABLE *grant_table= NULL;
|
||||
/*
|
||||
Flag that gets set if privilege checking has to be performed on column
|
||||
level.
|
||||
*/
|
||||
bool using_column_privileges= FALSE;
|
||||
|
||||
rw_rdlock(&LOCK_grant);
|
||||
|
||||
|
@ -4140,10 +4141,10 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
|
|||
{
|
||||
const char *field_name= fields->name();
|
||||
|
||||
if (table_name != fields->table_name())
|
||||
if (table_name != fields->get_table_name())
|
||||
{
|
||||
table_name= fields->table_name();
|
||||
db_name= fields->db_name();
|
||||
table_name= fields->get_table_name();
|
||||
db_name= fields->get_db_name();
|
||||
grant= fields->grant();
|
||||
/* get a fresh one for each table */
|
||||
want_access= want_access_arg & ~grant->privilege;
|
||||
|
@ -4169,6 +4170,8 @@ bool check_grant_all_columns(THD *thd, ulong want_access_arg,
|
|||
GRANT_COLUMN *grant_column=
|
||||
column_hash_search(grant_table, field_name,
|
||||
(uint) strlen(field_name));
|
||||
if (grant_column)
|
||||
using_column_privileges= TRUE;
|
||||
if (!grant_column || (~grant_column->rights & want_access))
|
||||
goto err;
|
||||
}
|
||||
|
@ -4181,12 +4184,21 @@ err:
|
|||
|
||||
char command[128];
|
||||
get_privilege_desc(command, sizeof(command), want_access);
|
||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
||||
command,
|
||||
sctx->priv_user,
|
||||
sctx->host_or_ip,
|
||||
fields->name(),
|
||||
table_name);
|
||||
/*
|
||||
Do not give an error message listing a column name unless the user has
|
||||
privilege to see all columns.
|
||||
*/
|
||||
if (using_column_privileges)
|
||||
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
|
||||
command, sctx->priv_user,
|
||||
sctx->host_or_ip, table_name);
|
||||
else
|
||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
|
||||
command,
|
||||
sctx->priv_user,
|
||||
sctx->host_or_ip,
|
||||
fields->name(),
|
||||
table_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -7620,9 +7620,34 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
|||
continue;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* Ensure that we have access rights to all fields to be inserted. */
|
||||
if (!((table && (table->grant.privilege & SELECT_ACL) ||
|
||||
tables->view && (tables->grant.privilege & SELECT_ACL))) &&
|
||||
/*
|
||||
Ensure that we have access rights to all fields to be inserted. Under
|
||||
some circumstances, this check may be skipped.
|
||||
|
||||
- If any_privileges is true, skip the check.
|
||||
|
||||
- If the SELECT privilege has been found as fulfilled already for both
|
||||
the TABLE and TABLE_LIST objects (and both of these exist, of
|
||||
course), the check is skipped.
|
||||
|
||||
- If the SELECT privilege has been found fulfilled for the TABLE object
|
||||
and the TABLE_LIST represents a derived table other than a view (see
|
||||
below), the check is skipped.
|
||||
|
||||
- If the TABLE_LIST object represents a view, we may skip checking if
|
||||
the SELECT privilege has been found fulfilled for it, regardless of
|
||||
the TABLE object.
|
||||
|
||||
- If there is no TABLE object, the test is skipped if either
|
||||
* the TABLE_LIST does not represent a view, or
|
||||
* the SELECT privilege has been found fulfilled.
|
||||
|
||||
A TABLE_LIST that is not a view may be a subquery, an
|
||||
information_schema table, or a nested table reference. See the comment
|
||||
for TABLE_LIST.
|
||||
*/
|
||||
if (!(table && !tables->view && (table->grant.privilege & SELECT_ACL) ||
|
||||
tables->view && (tables->grant.privilege & SELECT_ACL)) &&
|
||||
!any_privileges)
|
||||
{
|
||||
field_iterator.set(tables);
|
||||
|
@ -7676,19 +7701,19 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
|||
tables->is_natural_join);
|
||||
DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
|
||||
Item_field *fld= (Item_field*) item;
|
||||
const char *field_table_name= field_iterator.table_name();
|
||||
const char *field_table_name= field_iterator.get_table_name();
|
||||
|
||||
if (!tables->schema_table &&
|
||||
!(fld->have_privileges=
|
||||
(get_column_grant(thd, field_iterator.grant(),
|
||||
field_iterator.db_name(),
|
||||
field_iterator.get_db_name(),
|
||||
field_table_name, fld->field_name) &
|
||||
VIEW_ANY_ACL)))
|
||||
{
|
||||
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), "ANY",
|
||||
my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "ANY",
|
||||
thd->security_ctx->priv_user,
|
||||
thd->security_ctx->host_or_ip,
|
||||
fld->field_name, field_table_name);
|
||||
field_table_name);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2633,7 +2633,7 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
|
|||
tables_used;
|
||||
tables_used= tables_used->next_global, n++, block_table++)
|
||||
{
|
||||
if (tables_used->derived && !tables_used->view)
|
||||
if (tables_used->is_anonymous_derived_table())
|
||||
{
|
||||
DBUG_PRINT("qcache", ("derived table skipped"));
|
||||
n--;
|
||||
|
|
|
@ -73,29 +73,59 @@ out:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Create temporary table structure (but do not fill it)
|
||||
/**
|
||||
@brief Create temporary table structure (but do not fill it).
|
||||
|
||||
SYNOPSIS
|
||||
mysql_derived_prepare()
|
||||
thd Thread handle
|
||||
lex LEX for this thread
|
||||
orig_table_list TABLE_LIST for the upper SELECT
|
||||
@param thd Thread handle
|
||||
@param lex LEX for this thread
|
||||
@param orig_table_list TABLE_LIST for the upper SELECT
|
||||
|
||||
IMPLEMENTATION
|
||||
Derived table is resolved with temporary table.
|
||||
@details
|
||||
|
||||
After table creation, the above TABLE_LIST is updated with a new table.
|
||||
This function is called before any command containing derived tables is
|
||||
executed. Currently the function is used for derived tables, i.e.
|
||||
|
||||
This function is called before any command containing derived table
|
||||
is executed.
|
||||
- Anonymous derived tables, or
|
||||
- Named derived tables (aka views) with the @c TEMPTABLE algorithm.
|
||||
|
||||
The table reference, contained in @c orig_table_list, is updated with the
|
||||
fields of a new temporary table.
|
||||
|
||||
Derived tables is stored in thd->derived_tables and freed in
|
||||
close_thread_tables()
|
||||
Derived tables are stored in @c thd->derived_tables and closed by
|
||||
close_thread_tables().
|
||||
|
||||
RETURN
|
||||
FALSE OK
|
||||
TRUE Error
|
||||
This function is part of the procedure that starts in
|
||||
open_and_lock_tables(), a procedure that - among other things - introduces
|
||||
new table and table reference objects (to represent derived tables) that
|
||||
don't exist in the privilege database. This means that normal privilege
|
||||
checking cannot handle them. Hence this function does some extra tricks in
|
||||
order to bypass normal privilege checking, by exploiting the fact that the
|
||||
current state of privilege verification is attached as GRANT_INFO structures
|
||||
on the relevant TABLE and TABLE_REF objects.
|
||||
|
||||
For table references, the current state of accrued access is stored inside
|
||||
TABLE_LIST::grant. Hence this function must update the state of fulfilled
|
||||
privileges for the new TABLE_LIST, an operation which is normally performed
|
||||
exclusively by the table and database access checking functions,
|
||||
check_access() and check_grant(), respectively. This modification is done
|
||||
for both views and anonymous derived tables: The @c SELECT privilege is set
|
||||
as fulfilled by the user. However, if a view is referenced and the table
|
||||
reference is queried against directly (see TABLE_LIST::referencing_view),
|
||||
the state of privilege checking (GRANT_INFO struct) is copied as-is to the
|
||||
temporary table.
|
||||
|
||||
This function implements a signature called "derived table processor", and
|
||||
is passed as a function pointer to mysql_handle_derived().
|
||||
|
||||
@note This function sets @c SELECT_ACL for @c TEMPTABLE views as well as
|
||||
anonymous derived tables, but this is ok since later access checking will
|
||||
distinguish between them.
|
||||
|
||||
@see mysql_handle_derived(), mysql_derived_filling(), GRANT_INFO
|
||||
|
||||
@return
|
||||
false OK
|
||||
true Error
|
||||
*/
|
||||
|
||||
bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
|
||||
|
|
|
@ -4872,6 +4872,8 @@ bool check_single_table_access(THD *thd, ulong privilege,
|
|||
/* Show only 1 table for check_grant */
|
||||
if (!(all_tables->belong_to_view &&
|
||||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
|
||||
!(all_tables->view &&
|
||||
all_tables->effective_algorithm == VIEW_ALGORITHM_TMPTABLE) &&
|
||||
check_grant(thd, privilege, all_tables, 0, 1, no_errors))
|
||||
goto deny;
|
||||
|
||||
|
@ -5184,7 +5186,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tables->derived ||
|
||||
if (tables->is_anonymous_derived_table() ||
|
||||
(tables->table && (int)tables->table->s->tmp_table))
|
||||
continue;
|
||||
thd->security_ctx= sctx;
|
||||
|
|
31
sql/table.cc
31
sql/table.cc
|
@ -2993,16 +2993,27 @@ void TABLE_LIST::calc_md5(char *buffer)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
set underlying TABLE for table place holder of VIEW
|
||||
/**
|
||||
@brief Set underlying table for table place holder of view.
|
||||
|
||||
DESCRIPTION
|
||||
Replace all views that only uses one table with the table itself.
|
||||
This allows us to treat the view as a simple table and even update
|
||||
it (it is a kind of optimisation)
|
||||
@details
|
||||
|
||||
SYNOPSIS
|
||||
TABLE_LIST::set_underlying_merge()
|
||||
Replace all views that only use one table with the table itself. This
|
||||
allows us to treat the view as a simple table and even update it (it is a
|
||||
kind of optimization).
|
||||
|
||||
@note
|
||||
|
||||
This optimization is potentially dangerous as it makes views
|
||||
masquerade as base tables: Views don't have the pointer TABLE_LIST::table
|
||||
set to non-@c NULL.
|
||||
|
||||
We may have the case where a view accesses tables not normally accessible
|
||||
in the current Security_context (only in the definer's
|
||||
Security_context). According to the table's GRANT_INFO (TABLE::grant),
|
||||
access is fulfilled, but this is implicitly meant in the definer's security
|
||||
context. Hence we must never look at only a TABLE's GRANT_INFO without
|
||||
looking at the one of the referring TABLE_LIST.
|
||||
*/
|
||||
|
||||
void TABLE_LIST::set_underlying_merge()
|
||||
|
@ -4082,7 +4093,7 @@ void Field_iterator_table_ref::next()
|
|||
}
|
||||
|
||||
|
||||
const char *Field_iterator_table_ref::table_name()
|
||||
const char *Field_iterator_table_ref::get_table_name()
|
||||
{
|
||||
if (table_ref->view)
|
||||
return table_ref->view_name.str;
|
||||
|
@ -4095,7 +4106,7 @@ const char *Field_iterator_table_ref::table_name()
|
|||
}
|
||||
|
||||
|
||||
const char *Field_iterator_table_ref::db_name()
|
||||
const char *Field_iterator_table_ref::get_db_name()
|
||||
{
|
||||
if (table_ref->view)
|
||||
return table_ref->view_db.str;
|
||||
|
|
117
sql/table.h
117
sql/table.h
|
@ -66,13 +66,63 @@ typedef struct st_order {
|
|||
table_map used, depend_map;
|
||||
} ORDER;
|
||||
|
||||
/**
|
||||
@brief The current state of the privilege checking process for the current
|
||||
user, SQL statement and SQL object.
|
||||
|
||||
@details The privilege checking process is divided into phases depending on
|
||||
the level of the privilege to be checked and the type of object to be
|
||||
accessed. Due to the mentioned scattering of privilege checking
|
||||
functionality, it is necessary to keep track of the state of the
|
||||
process. This information is stored in privilege, want_privilege, and
|
||||
orig_want_privilege.
|
||||
|
||||
A GRANT_INFO also serves as a cache of the privilege hash tables. Relevant
|
||||
members are grant_table and version.
|
||||
*/
|
||||
typedef struct st_grant_info
|
||||
{
|
||||
/**
|
||||
@brief A copy of the privilege information regarding the current host,
|
||||
database, object and user.
|
||||
|
||||
@details The version of this copy is found in GRANT_INFO::version.
|
||||
*/
|
||||
GRANT_TABLE *grant_table;
|
||||
/**
|
||||
@brief Used for cache invalidation when caching privilege information.
|
||||
|
||||
@details The privilege information is stored on disk, with dedicated
|
||||
caches residing in memory: table-level and column-level privileges,
|
||||
respectively, have their own dedicated caches.
|
||||
|
||||
The GRANT_INFO works as a level 1 cache with this member updated to the
|
||||
current value of the global variable @c grant_version (@c static variable
|
||||
in sql_acl.cc). It is updated Whenever the GRANT_INFO is refreshed from
|
||||
the level 2 cache. The level 2 cache is the @c column_priv_hash structure
|
||||
(@c static variable in sql_acl.cc)
|
||||
|
||||
@see grant_version
|
||||
*/
|
||||
uint version;
|
||||
/**
|
||||
@brief The set of privileges that the current user has fulfilled for a
|
||||
certain host, database, and object.
|
||||
|
||||
@details This field is continually updated throughout the access checking
|
||||
process. In each step the "wanted privilege" is checked against the
|
||||
fulfilled privileges. When/if the intersection of these sets is empty,
|
||||
access is granted.
|
||||
|
||||
The set is implemented as a bitmap, with the bits defined in sql_acl.h.
|
||||
*/
|
||||
ulong privilege;
|
||||
/**
|
||||
@brief the set of privileges that the current user needs to fulfil in
|
||||
order to carry out the requested operation.
|
||||
*/
|
||||
ulong want_privilege;
|
||||
/*
|
||||
/**
|
||||
Stores the requested access acl of top level tables list. Is used to
|
||||
check access rights to the underlying tables of a view.
|
||||
*/
|
||||
|
@ -1104,6 +1154,27 @@ struct TABLE_LIST
|
|||
can see this lists can't be merged)
|
||||
*/
|
||||
TABLE_LIST *correspondent_table;
|
||||
/**
|
||||
@brief Normally, this field is non-null for anonymous derived tables only.
|
||||
|
||||
@details This field is set to non-null for
|
||||
|
||||
- Anonymous derived tables, In this case it points to the SELECT_LEX_UNIT
|
||||
representing the derived table. E.g. for a query
|
||||
|
||||
@verbatim SELECT * FROM (SELECT a FROM t1) b @endverbatim
|
||||
|
||||
For the @c TABLE_LIST representing the derived table @c b, @c derived
|
||||
points to the SELECT_LEX_UNIT representing the result of the query within
|
||||
parenteses.
|
||||
|
||||
- Views. This is set for views with @verbatim ALGORITHM = TEMPTABLE
|
||||
@endverbatim by mysql_make_view().
|
||||
|
||||
@note Inside views, a subquery in the @c FROM clause is not allowed.
|
||||
@note Do not use this field to separate views/base tables/anonymous
|
||||
derived tables. Use TABLE_LIST::is_anonymous_derived_table().
|
||||
*/
|
||||
st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */
|
||||
ST_SCHEMA_TABLE *schema_table; /* Information_schema table */
|
||||
st_select_lex *schema_select_lex;
|
||||
|
@ -1169,7 +1240,15 @@ struct TABLE_LIST
|
|||
ulonglong file_version; /* version of file's field set */
|
||||
ulonglong updatable_view; /* VIEW can be updated */
|
||||
ulonglong revision; /* revision control number */
|
||||
ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */
|
||||
/**
|
||||
@brief The declared algorithm, if this is a view.
|
||||
@details One of
|
||||
- VIEW_ALGORITHM_UNDEFINED
|
||||
- VIEW_ALGORITHM_TMPTABLE
|
||||
- VIEW_ALGORITHM_MERGE
|
||||
@to do Replace with an enum
|
||||
*/
|
||||
ulonglong algorithm;
|
||||
ulonglong view_suid; /* view is suid (TRUE dy default) */
|
||||
ulonglong with_check; /* WITH CHECK OPTION */
|
||||
/*
|
||||
|
@ -1177,7 +1256,15 @@ struct TABLE_LIST
|
|||
algorithm)
|
||||
*/
|
||||
uint8 effective_with_check;
|
||||
uint8 effective_algorithm; /* which algorithm was really used */
|
||||
/**
|
||||
@brief The view algorithm that is actually used, if this is a view.
|
||||
@details One of
|
||||
- VIEW_ALGORITHM_UNDEFINED
|
||||
- VIEW_ALGORITHM_TMPTABLE
|
||||
- VIEW_ALGORITHM_MERGE
|
||||
@to do Replace with an enum
|
||||
*/
|
||||
uint8 effective_algorithm;
|
||||
GRANT_INFO grant;
|
||||
/* data need by some engines in query cache*/
|
||||
ulonglong engine_data;
|
||||
|
@ -1362,6 +1449,26 @@ struct TABLE_LIST
|
|||
m_table_ref_version= s->get_table_ref_version();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief True if this TABLE_LIST represents an anonymous derived table,
|
||||
i.e. the result of a subquery.
|
||||
*/
|
||||
bool is_anonymous_derived_table() const { return derived && !view; }
|
||||
|
||||
/**
|
||||
@brief Returns the name of the database that the referenced table belongs
|
||||
to.
|
||||
*/
|
||||
char *get_db_name() { return view != NULL ? view_db.str : db; }
|
||||
|
||||
/**
|
||||
@brief Returns the name of the table that this TABLE_LIST represents.
|
||||
|
||||
@details The unqualified table name or view name for a table or view,
|
||||
respectively.
|
||||
*/
|
||||
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
|
||||
|
||||
private:
|
||||
bool prep_check_option(THD *thd, uint8 check_opt_type);
|
||||
bool prep_where(THD *thd, Item **conds, bool no_where_clause);
|
||||
|
@ -1491,8 +1598,8 @@ public:
|
|||
bool end_of_fields()
|
||||
{ return (table_ref == last_leaf && field_it->end_of_fields()); }
|
||||
const char *name() { return field_it->name(); }
|
||||
const char *table_name();
|
||||
const char *db_name();
|
||||
const char *get_table_name();
|
||||
const char *get_db_name();
|
||||
GRANT_INFO *grant();
|
||||
Item *create_item(THD *thd) { return field_it->create_item(thd); }
|
||||
Field *field() { return field_it->field(); }
|
||||
|
|
Loading…
Reference in a new issue