1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge bodhi.(none):/opt/local/work/mysql-5.0-runtime

into  bodhi.(none):/opt/local/work/mysql-5.1-runtime
This commit is contained in:
kostja@bodhi.(none)
2007-07-16 23:31:36 +04:00
36 changed files with 1784 additions and 269 deletions

View File

@ -2849,15 +2849,144 @@ void st_table::reset_item_list(List<Item> *item_list) const
}
}
/**
Set the initial purpose of this TABLE_LIST object in the list of
used tables. We need to track this information on table-by-
table basis, since when this table becomes an element of the
pre-locked list, it's impossible to identify which SQL
sub-statement it has been originally used in.
E.g.:
User request: SELECT * FROM t1 WHERE f1();
FUNCTION f1(): DELETE FROM t2; RETURN 1;
BEFORE DELETE trigger on t2: INSERT INTO t3 VALUES (old.a);
For this user request, the pre-locked list will contain t1, t2, t3
table elements, each needed for different DML.
This method is called immediately after parsing for tables
of the table list of the top-level select lex.
The trigger event map is updated to reflect INSERT, UPDATE, DELETE,
REPLACE, LOAD DATA, CREATE TABLE .. SELECT, CREATE TABLE ..
REPLACE SELECT statements, and additionally ON DUPLICATE KEY UPDATE
clause.
*/
void
TABLE_LIST::set_trg_event_type(const st_lex *lex)
{
enum trg_event_type trg_event;
/*
Some auxiliary operations
(e.g. GRANT processing) create TABLE_LIST instances outside
the parser. Additionally, some commands (e.g. OPTIMIZE) change
the lock type for a table only after parsing is done. Luckily,
these do not fire triggers and do not need to pre-load them.
For these TABLE_LISTs set_trg_event_type is never called, and
trg_event_map is always empty. That means that the pre-locking
algorithm will ignore triggers defined on these tables, if
any, and the execution will either fail with an assert in
sql_trigger.cc or with an error that a used table was not
pre-locked, in case of a production build.
TODO: this usage pattern creates unnecessary module dependencies
and should be rewritten to go through the parser.
Table list instances created outside the parser in most cases
refer to mysql.* system tables. It is not allowed to have
a trigger on a system table, but keeping track of
initialization provides extra safety in case this limitation
is circumvented.
*/
/*
This is a fast check to filter out statements that do
not change data, or tables on the right side, in case of
INSERT .. SELECT, CREATE TABLE .. SELECT and so on.
Here we also filter out OPTIMIZE statement and non-updateable
views, for which lock_type is TL_UNLOCK or TL_READ after
parsing.
*/
if (static_cast<int>(lock_type) < static_cast<int>(TL_WRITE_ALLOW_WRITE))
return;
switch (lex->sql_command) {
/*
Basic INSERT. If there is an additional ON DUPLIATE KEY UPDATE
clause, it will be handled later in this method.
*/
case SQLCOM_INSERT: /* fall through */
case SQLCOM_INSERT_SELECT:
/*
LOAD DATA ... INFILE is expected to fire BEFORE/AFTER INSERT
triggers.
If the statement also has REPLACE clause, it will be
handled later in this method.
*/
case SQLCOM_LOAD: /* fall through */
/*
REPLACE is semantically equivalent to INSERT. In case
of a primary or unique key conflict, it deletes the old
record and inserts a new one. So we also may need to
fire ON DELETE triggers. This functionality is handled
later in this method.
*/
case SQLCOM_REPLACE: /* fall through */
case SQLCOM_REPLACE_SELECT:
/*
CREATE TABLE ... SELECT defaults to INSERT if the table or
view already exists. REPLACE option of CREATE TABLE ...
REPLACE SELECT is handled later in this method.
*/
case SQLCOM_CREATE_TABLE:
trg_event= TRG_EVENT_INSERT;
break;
/* Basic update and multi-update */
case SQLCOM_UPDATE: /* fall through */
case SQLCOM_UPDATE_MULTI:
trg_event= TRG_EVENT_UPDATE;
break;
/* Basic delete and multi-delete */
case SQLCOM_DELETE: /* fall through */
case SQLCOM_DELETE_MULTI:
trg_event= TRG_EVENT_DELETE;
break;
default:
/*
OK to return, since value of 'duplicates' is irrelevant
for non-updating commands.
*/
return;
}
trg_event_map|= static_cast<uint8>(1 << static_cast<int>(trg_event));
switch (lex->duplicates) {
case DUP_UPDATE:
trg_event= TRG_EVENT_UPDATE;
break;
case DUP_REPLACE:
trg_event= TRG_EVENT_DELETE;
break;
case DUP_ERROR:
default:
return;
}
trg_event_map|= static_cast<uint8>(1 << static_cast<int>(trg_event));
}
/*
calculate md5 of query
SYNOPSIS
st_table_list::calc_md5()
TABLE_LIST::calc_md5()
buffer buffer for md5 writing
*/
void st_table_list::calc_md5(char *buffer)
void TABLE_LIST::calc_md5(char *buffer)
{
my_MD5_CTX context;
uchar digest[16];
@ -2882,10 +3011,10 @@ void st_table_list::calc_md5(char *buffer)
it (it is a kind of optimisation)
SYNOPSIS
st_table_list::set_underlying_merge()
TABLE_LIST::set_underlying_merge()
*/
void st_table_list::set_underlying_merge()
void TABLE_LIST::set_underlying_merge()
{
TABLE_LIST *tbl;
@ -2920,7 +3049,7 @@ void st_table_list::set_underlying_merge()
setup fields of placeholder of merged VIEW
SYNOPSIS
st_table_list::setup_underlying()
TABLE_LIST::setup_underlying()
thd - thread handler
DESCRIPTION
@ -2933,9 +3062,9 @@ void st_table_list::set_underlying_merge()
TRUE - error
*/
bool st_table_list::setup_underlying(THD *thd)
bool TABLE_LIST::setup_underlying(THD *thd)
{
DBUG_ENTER("st_table_list::setup_underlying");
DBUG_ENTER("TABLE_LIST::setup_underlying");
if (!field_translation && merge_underlying_list)
{
@ -2998,7 +3127,7 @@ bool st_table_list::setup_underlying(THD *thd)
Prepare where expression of view
SYNOPSIS
st_table_list::prep_where()
TABLE_LIST::prep_where()
thd - thread handler
conds - condition of this JOIN
no_where_clause - do not build WHERE or ON outer qwery do not need it
@ -3012,10 +3141,10 @@ bool st_table_list::setup_underlying(THD *thd)
TRUE - error
*/
bool st_table_list::prep_where(THD *thd, Item **conds,
bool TABLE_LIST::prep_where(THD *thd, Item **conds,
bool no_where_clause)
{
DBUG_ENTER("st_table_list::prep_where");
DBUG_ENTER("TABLE_LIST::prep_where");
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
@ -3115,7 +3244,7 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
Prepare check option expression of table
SYNOPSIS
st_table_list::prep_check_option()
TABLE_LIST::prep_check_option()
thd - thread handler
check_opt_type - WITH CHECK OPTION type (VIEW_CHECK_NONE,
VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED)
@ -3130,16 +3259,16 @@ merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
This method builds check option condition to use it later on
every call (usual execution or every SP/PS call).
This method have to be called after WHERE preparation
(st_table_list::prep_where)
(TABLE_LIST::prep_where)
RETURN
FALSE - OK
TRUE - error
*/
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
{
DBUG_ENTER("st_table_list::prep_check_option");
DBUG_ENTER("TABLE_LIST::prep_check_option");
bool is_cascaded= check_opt_type == VIEW_CHECK_CASCADED;
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
@ -3198,12 +3327,12 @@ bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
Hide errors which show view underlying table information
SYNOPSIS
st_table_list::hide_view_error()
TABLE_LIST::hide_view_error()
thd thread handler
*/
void st_table_list::hide_view_error(THD *thd)
void TABLE_LIST::hide_view_error(THD *thd)
{
/* Hide "Unknown column" or "Unknown function" error */
if (thd->net.last_errno == ER_BAD_FIELD_ERROR ||
@ -3234,7 +3363,7 @@ void st_table_list::hide_view_error(THD *thd)
table_to_find (TABLE)
SYNOPSIS
st_table_list::find_underlying_table()
TABLE_LIST::find_underlying_table()
table_to_find table to find
RETURN
@ -3242,7 +3371,7 @@ void st_table_list::hide_view_error(THD *thd)
found table reference
*/
st_table_list *st_table_list::find_underlying_table(TABLE *table_to_find)
TABLE_LIST *TABLE_LIST::find_underlying_table(TABLE *table_to_find)
{
/* is this real table and table which we are looking for? */
if (table == table_to_find && merge_underlying_list == 0)
@ -3261,10 +3390,10 @@ st_table_list *st_table_list::find_underlying_table(TABLE *table_to_find)
cleunup items belonged to view fields translation table
SYNOPSIS
st_table_list::cleanup_items()
TABLE_LIST::cleanup_items()
*/
void st_table_list::cleanup_items()
void TABLE_LIST::cleanup_items()
{
if (!field_translation)
return;
@ -3280,7 +3409,7 @@ void st_table_list::cleanup_items()
check CHECK OPTION condition
SYNOPSIS
st_table_list::view_check_option()
TABLE_LIST::view_check_option()
ignore_failure ignore check option fail
RETURN
@ -3289,7 +3418,7 @@ void st_table_list::cleanup_items()
VIEW_CHECK_SKIP FAILED, but continue
*/
int st_table_list::view_check_option(THD *thd, bool ignore_failure)
int TABLE_LIST::view_check_option(THD *thd, bool ignore_failure)
{
if (check_option && check_option->val_int() == 0)
{
@ -3314,7 +3443,7 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure)
table belong to given mask
SYNOPSIS
st_table_list::check_single_table()
TABLE_LIST::check_single_table()
table_arg reference on variable where to store found table
(should be 0 on call, to find table, or point to table for
unique test)
@ -3326,9 +3455,9 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure)
TRUE found several tables
*/
bool st_table_list::check_single_table(st_table_list **table_arg,
bool TABLE_LIST::check_single_table(TABLE_LIST **table_arg,
table_map map,
st_table_list *view_arg)
TABLE_LIST *view_arg)
{
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
@ -3361,7 +3490,7 @@ bool st_table_list::check_single_table(st_table_list **table_arg,
TRUE - out of memory
*/
bool st_table_list::set_insert_values(MEM_ROOT *mem_root)
bool TABLE_LIST::set_insert_values(MEM_ROOT *mem_root)
{
if (table)
{
@ -3385,7 +3514,7 @@ bool st_table_list::set_insert_values(MEM_ROOT *mem_root)
Test if this is a leaf with respect to name resolution.
SYNOPSIS
st_table_list::is_leaf_for_name_resolution()
TABLE_LIST::is_leaf_for_name_resolution()
DESCRIPTION
A table reference is a leaf with respect to name resolution if
@ -3397,7 +3526,7 @@ bool st_table_list::set_insert_values(MEM_ROOT *mem_root)
RETURN
TRUE if a leaf, FALSE otherwise.
*/
bool st_table_list::is_leaf_for_name_resolution()
bool TABLE_LIST::is_leaf_for_name_resolution()
{
return (view || is_natural_join || is_join_columns_complete ||
!nested_join);
@ -3409,7 +3538,7 @@ bool st_table_list::is_leaf_for_name_resolution()
respect to name resolution.
SYNOPSIS
st_table_list::first_leaf_for_name_resolution()
TABLE_LIST::first_leaf_for_name_resolution()
DESCRIPTION
Given that 'this' is a nested table reference, recursively walk
@ -3427,7 +3556,7 @@ bool st_table_list::is_leaf_for_name_resolution()
else return 'this'
*/
TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
TABLE_LIST *TABLE_LIST::first_leaf_for_name_resolution()
{
TABLE_LIST *cur_table_ref;
NESTED_JOIN *cur_nested_join;
@ -3467,7 +3596,7 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
respect to name resolution.
SYNOPSIS
st_table_list::last_leaf_for_name_resolution()
TABLE_LIST::last_leaf_for_name_resolution()
DESCRIPTION
Given that 'this' is a nested table reference, recursively walk
@ -3485,7 +3614,7 @@ TABLE_LIST *st_table_list::first_leaf_for_name_resolution()
- else - 'this'
*/
TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
TABLE_LIST *TABLE_LIST::last_leaf_for_name_resolution()
{
TABLE_LIST *cur_table_ref= this;
NESTED_JOIN *cur_nested_join;
@ -3527,7 +3656,7 @@ TABLE_LIST *st_table_list::last_leaf_for_name_resolution()
want_access Acess which we require
*/
void st_table_list::register_want_access(ulong want_access)
void TABLE_LIST::register_want_access(ulong want_access)
{
/* Remove SHOW_VIEW_ACL, because it will be checked during making view */
want_access&= ~SHOW_VIEW_ACL;
@ -3546,7 +3675,7 @@ void st_table_list::register_want_access(ulong want_access)
Load security context information for this view
SYNOPSIS
st_table_list::prepare_view_securety_context()
TABLE_LIST::prepare_view_securety_context()
thd [in] thread handler
RETURN
@ -3555,9 +3684,9 @@ void st_table_list::register_want_access(ulong want_access)
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool st_table_list::prepare_view_securety_context(THD *thd)
bool TABLE_LIST::prepare_view_securety_context(THD *thd)
{
DBUG_ENTER("st_table_list::prepare_view_securety_context");
DBUG_ENTER("TABLE_LIST::prepare_view_securety_context");
DBUG_PRINT("enter", ("table: %s", alias));
DBUG_ASSERT(!prelocking_placeholder && view);
@ -3606,17 +3735,17 @@ bool st_table_list::prepare_view_securety_context(THD *thd)
Find security context of current view
SYNOPSIS
st_table_list::find_view_security_context()
TABLE_LIST::find_view_security_context()
thd [in] thread handler
*/
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *st_table_list::find_view_security_context(THD *thd)
Security_context *TABLE_LIST::find_view_security_context(THD *thd)
{
Security_context *sctx;
TABLE_LIST *upper_view= this;
DBUG_ENTER("st_table_list::find_view_security_context");
DBUG_ENTER("TABLE_LIST::find_view_security_context");
DBUG_ASSERT(view);
while (upper_view && !upper_view->view_suid)
@ -3645,7 +3774,7 @@ Security_context *st_table_list::find_view_security_context(THD *thd)
Prepare security context and load underlying tables priveleges for view
SYNOPSIS
st_table_list::prepare_security()
TABLE_LIST::prepare_security()
thd [in] thread handler
RETURN
@ -3653,11 +3782,11 @@ Security_context *st_table_list::find_view_security_context(THD *thd)
TRUE Error
*/
bool st_table_list::prepare_security(THD *thd)
bool TABLE_LIST::prepare_security(THD *thd)
{
List_iterator_fast<TABLE_LIST> tb(*view_tables);
TABLE_LIST *tbl;
DBUG_ENTER("st_table_list::prepare_security");
DBUG_ENTER("TABLE_LIST::prepare_security");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context *save_security_ctx= thd->security_ctx;
@ -4406,10 +4535,10 @@ void st_table::mark_columns_needed_for_insert()
Cleanup this table for re-execution.
SYNOPSIS
st_table_list::reinit_before_use()
TABLE_LIST::reinit_before_use()
*/
void st_table_list::reinit_before_use(THD *thd)
void TABLE_LIST::reinit_before_use(THD *thd)
{
/*
Reset old pointers to TABLEs: they are not valid since the tables
@ -4436,7 +4565,7 @@ void st_table_list::reinit_before_use(THD *thd)
Return subselect that contains the FROM list this table is taken from
SYNOPSIS
st_table_list::containing_subselect()
TABLE_LIST::containing_subselect()
RETURN
Subselect item for the subquery that contains the FROM list
@ -4445,7 +4574,7 @@ void st_table_list::reinit_before_use(THD *thd)
*/
Item_subselect *st_table_list::containing_subselect()
Item_subselect *TABLE_LIST::containing_subselect()
{
return (select_lex ? select_lex->master_unit()->item : 0);
}