1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
ON conditions from JOIN expression were ignored at CHECK OPTION
check when updating a multi-table view with CHECK OPTION.

The st_table_list::prep_check_option function has been
modified to to take into account ON conditions at CHECK OPTION check
It was also changed to build the check option condition only once
for any update used in PS/SP.
This commit is contained in:
gshchepa/uchum@gleb.loc
2007-06-01 02:15:40 +05:00
parent 559063177f
commit cab4ca9c33
4 changed files with 177 additions and 17 deletions

View File

@ -1985,6 +1985,47 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
}
/*
Merge ON expressions for a view
SYNOPSIS
merge_on_conds()
thd thread handle
table table for the VIEW
is_cascaded TRUE <=> merge ON expressions from underlying views
DESCRIPTION
This function returns the result of ANDing the ON expressions
of the given view and all underlying views. The ON expressions
of the underlying views are added only if is_cascaded is TRUE.
RETURN
Pointer to the built expression if there is any.
Otherwise and in the case of a failure NULL is returned.
*/
static Item *
merge_on_conds(THD *thd, TABLE_LIST *table, bool is_cascaded)
{
DBUG_ENTER("merge_on_conds");
Item *cond= NULL;
DBUG_PRINT("info", ("alias: %s", table->alias));
if (table->on_expr)
cond= table->on_expr->copy_andor_structure(thd);
if (!table->nested_join)
DBUG_RETURN(cond);
List_iterator<TABLE_LIST> li(table->nested_join->join_list);
while (TABLE_LIST *tbl= li++)
{
if (tbl->view && !is_cascaded)
continue;
cond= and_conds(cond, merge_on_conds(thd, tbl, is_cascaded));
}
DBUG_RETURN(cond);
}
/*
Prepare check option expression of table
@ -2001,8 +2042,8 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
VIEW_CHECK_LOCAL option.
NOTE
This method build check options for every call
(usual execution or every SP/PS call)
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)
@ -2014,38 +2055,42 @@ bool st_table_list::prep_where(THD *thd, Item **conds,
bool st_table_list::prep_check_option(THD *thd, uint8 check_opt_type)
{
DBUG_ENTER("st_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)
{
/* see comment of check_opt_type parameter */
if (tbl->view &&
tbl->prep_check_option(thd,
((check_opt_type == VIEW_CHECK_CASCADED) ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
{
if (tbl->view && tbl->prep_check_option(thd, (is_cascaded ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
DBUG_RETURN(TRUE);
}
}
if (check_opt_type)
if (check_opt_type && !check_option_processed)
{
Item *item= 0;
Query_arena *arena= thd->stmt_arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
if (where)
{
DBUG_ASSERT(where->fixed);
item= where->copy_andor_structure(thd);
check_option= where->copy_andor_structure(thd);
}
if (check_opt_type == VIEW_CHECK_CASCADED)
if (is_cascaded)
{
for (TABLE_LIST *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
{
if (tbl->check_option)
item= and_conds(item, tbl->check_option);
check_option= and_conds(check_option, tbl->check_option);
}
}
if (item)
thd->change_item_tree(&check_option, item);
check_option= and_conds(check_option,
merge_on_conds(thd, this, is_cascaded));
if (arena)
thd->restore_active_arena(arena, &backup);
check_option_processed= TRUE;
}
if (check_option)
@ -2150,7 +2195,7 @@ void st_table_list::cleanup_items()
check CHECK OPTION condition
SYNOPSIS
check_option()
st_table_list::view_check_option()
ignore_failure ignore check option fail
RETURN