1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
This commit is contained in:
bell@sanja.is.com.ua
2004-11-21 20:08:12 +02:00
52 changed files with 1333 additions and 306 deletions

View File

@ -1517,11 +1517,68 @@ void st_table_list::calc_md5(char *buffer)
void st_table_list::set_ancestor()
{
if (ancestor->ancestor)
ancestor->set_ancestor();
table= ancestor->table;
schema_table= ancestor->schema_table;
ancestor->table->grant= grant;
/* process all tables of view */
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->ancestor)
ancestor->set_ancestor();
tbl->table->grant= grant;
}
/* if view contain only one table, substitute TABLE of it */
if (!ancestor->next_local)
{
table= ancestor->table;
schema_table= ancestor->schema_table;
}
}
/*
Save old want_privilege and clear want_privilege
SYNOPSIS
save_and_clear_want_privilege()
*/
void st_table_list::save_and_clear_want_privilege()
{
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->table)
{
privilege_backup= tbl->table->grant.want_privilege;
tbl->table->grant.want_privilege= 0;
}
else
{
DBUG_ASSERT(tbl->view && tbl->ancestor &&
tbl->ancestor->next_local);
tbl->save_and_clear_want_privilege();
}
}
}
/*
restore want_privilege saved by save_and_clear_want_privilege
SYNOPSIS
restore_want_privilege()
*/
void st_table_list::restore_want_privilege()
{
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->table)
tbl->table->grant.want_privilege= privilege_backup;
else
{
DBUG_ASSERT(tbl->view && tbl->ancestor &&
tbl->ancestor->next_local);
tbl->restore_want_privilege();
}
}
}
@ -1551,10 +1608,11 @@ void st_table_list::set_ancestor()
bool st_table_list::setup_ancestor(THD *thd, Item **conds,
uint8 check_opt_type)
{
Item **transl;
Field_translator *transl;
SELECT_LEX *select= &view->select_lex;
SELECT_LEX *current_select_save= thd->lex->current_select;
Item *item;
TABLE_LIST *tbl;
List_iterator_fast<Item> it(select->item_list);
uint i= 0;
bool save_set_query_id= thd->set_query_id;
@ -1562,38 +1620,57 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
bool save_allow_sum_func= thd->allow_sum_func;
DBUG_ENTER("st_table_list::setup_ancestor");
if (ancestor->ancestor &&
ancestor->setup_ancestor(thd, conds,
(check_opt_type == VIEW_CHECK_CASCADED ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
DBUG_RETURN(1);
for (tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->ancestor &&
tbl->setup_ancestor(thd, conds,
(check_opt_type == VIEW_CHECK_CASCADED ?
VIEW_CHECK_CASCADED :
VIEW_CHECK_NONE)))
DBUG_RETURN(1);
}
if (field_translation)
{
/* prevent look up in SELECTs tree */
thd->lex->current_select= &thd->lex->select_lex;
thd->lex->select_lex.no_wrap_view_item= 1;
thd->set_query_id= 1;
/* this view was prepared already on previous PS/SP execution */
Item **end= field_translation + select->item_list.elements;
for (Item **item= field_translation; item < end; item++)
Field_translator *end= field_translation + select->item_list.elements;
/* real rights will be checked in VIEW field */
save_and_clear_want_privilege();
/* aggregate function are allowed */
thd->allow_sum_func= 1;
for (transl= field_translation; transl < end; transl++)
{
/* TODO: fix for several tables in VIEW */
uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
if (!(*item)->fixed && (*item)->fix_fields(thd, ancestor, item))
if (!transl->item->fixed &&
transl->item->fix_fields(thd, ancestor, &transl->item))
goto err;
ancestor->table->grant.want_privilege= want_privilege;
}
for (tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->on_expr && !tbl->on_expr->fixed &&
tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr))
goto err;
}
if (where && !where->fixed && where->fix_fields(thd, ancestor, &where))
goto err;
restore_want_privilege();
/* WHERE/ON resolved => we can rename fields */
for (transl= field_translation; transl < end; transl++)
{
transl->item->rename((char *)transl->name);
}
goto ok;
}
/* view fields translation table */
if (!(transl=
(Item**)(thd->current_arena->alloc(select->item_list.elements * sizeof(Item*)))))
(Field_translator*)(thd->current_arena->
alloc(select->item_list.elements *
sizeof(Field_translator)))))
{
DBUG_RETURN(1);
}
@ -1609,22 +1686,29 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
used fields correctly.
*/
thd->set_query_id= 1;
/* real rights will be checked in VIEW field */
save_and_clear_want_privilege();
/* aggregate function are allowed */
thd->allow_sum_func= 1;
while ((item= it++))
{
/* TODO: fix for several tables in VIEW */
uint want_privilege= ancestor->table->grant.want_privilege;
/* real rights will be checked in VIEW field */
ancestor->table->grant.want_privilege= 0;
/* aggregate function are allowed */
thd->allow_sum_func= 1;
/* save original name of view column */
char *name= item->name;
if (!item->fixed && item->fix_fields(thd, ancestor, &item))
goto err;
ancestor->table->grant.want_privilege= want_privilege;
transl[i++]= item;
/* set new item get in fix fields and original column name */
transl[i].name= name;
transl[i++].item= item;
}
field_translation= transl;
/* TODO: sort this list? Use hash for big number of fields */
for (tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->on_expr && !tbl->on_expr->fixed &&
tbl->on_expr->fix_fields(thd, ancestor, &tbl->on_expr))
goto err;
}
if (where ||
(check_opt_type == VIEW_CHECK_CASCADED &&
ancestor->check_option))
@ -1697,6 +1781,8 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
if (arena)
thd->restore_backup_item_arena(arena, &backup);
}
restore_want_privilege();
/*
fix_fields do not need tables, because new are only AND operation and we
just need recollect statistics
@ -1705,6 +1791,15 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
check_option->fix_fields(thd, 0, &check_option))
goto err;
/* WHERE/ON resolved => we can rename fields */
{
Field_translator *end= field_translation + select->item_list.elements;
for (transl= field_translation; transl < end; transl++)
{
transl->item->rename((char *)transl->name);
}
}
/* full text function moving to current select */
if (view->select_lex.ftfunc_list->elements)
{
@ -1749,9 +1844,10 @@ void st_table_list::cleanup_items()
if (!field_translation)
return;
Item **end= field_translation + view->select_lex.item_list.elements;
for (Item **item= field_translation; item < end; item++)
(*item)->walk(&Item::cleanup_processor, 0);
Field_translator *end= (field_translation +
view->select_lex.item_list.elements);
for (Field_translator *transl= field_translation; transl < end; transl++)
transl->item->walk(&Item::cleanup_processor, 0);
}
@ -1789,6 +1885,96 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure)
}
/*
Find table in underlaying tables by mask and check that only this
table belong to given mask
SYNOPSIS
st_table_list::check_single_table()
table reference on variable where to store found table
(should be 0 on call, to find table, or point to table for
unique test)
map bit mask of tables
RETURN
FALSE table not found or found only one
TRUE found several tables
*/
bool st_table_list::check_single_table(st_table_list **table, table_map map)
{
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->table)
{
if (tbl->table->map & map)
{
if (*table)
return TRUE;
else
*table= tbl;
}
}
else
if (tbl->check_single_table(table, map))
return TRUE;
}
return FALSE;
}
/*
Set insert_values buffer
SYNOPSIS
set_insert_values()
mem_root memory pool for allocating
RETURN
FALSE - OK
TRUE - out of memory
*/
bool st_table_list::set_insert_values(MEM_ROOT *mem_root)
{
if (table)
{
if (!table->insert_values &&
!(table->insert_values= (byte *)alloc_root(mem_root,
table->rec_buff_length)))
return TRUE;
}
else
{
DBUG_ASSERT(view && ancestor && ancestor->next_local);
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
if (tbl->set_insert_values(mem_root))
return TRUE;
}
return FALSE;
}
/*
clear insert_values reference
SYNOPSIS
clear_insert_values()
*/
void st_table_list::clear_insert_values()
{
if (table)
table->insert_values= 0;
else
{
DBUG_ASSERT(view && ancestor && ancestor->next_local);
for (TABLE_LIST *tbl= ancestor; tbl; tbl= tbl->next_local)
tbl->clear_insert_values();
}
}
void Field_iterator_view::set(TABLE_LIST *table)
{
ptr= table->field_translation;
@ -1810,7 +1996,7 @@ Item *Field_iterator_table::item(THD *thd)
const char *Field_iterator_view::name()
{
return (*ptr)->name;
return ptr->name;
}