1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00
This commit is contained in:
bell@sanja.is.com.ua
2004-10-05 13:41:51 +03:00
51 changed files with 1292 additions and 259 deletions

View File

@ -1485,10 +1485,65 @@ void st_table_list::calc_md5(char *buffer)
void st_table_list::set_ancestor()
{
if (ancestor->ancestor)
ancestor->set_ancestor();
table= ancestor->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;
}
/*
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();
}
}
}
@ -1513,10 +1568,11 @@ void st_table_list::set_ancestor()
bool st_table_list::setup_ancestor(THD *thd, Item **conds)
{
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;
@ -1524,35 +1580,53 @@ 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))
DBUG_RETURN(1);
for (tbl= ancestor; tbl; tbl= tbl->next_local)
{
if (tbl->ancestor && tbl->setup_ancestor(thd, conds))
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);
}
@ -1568,22 +1642,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)
{
Item_arena *arena= thd->current_arena, backup;
@ -1653,6 +1734,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
@ -1661,6 +1744,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)
{
@ -1727,6 +1819,95 @@ 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 sbelong 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
0 table not found or found only one
1 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 1;
else
*table= tbl;
}
}
else
if (tbl->check_single_table(table, map))
return 1;
}
}
/*
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;
@ -1748,7 +1929,7 @@ Item *Field_iterator_table::item(THD *thd)
const char *Field_iterator_view::name()
{
return (*ptr)->name;
return ptr->name;
}