mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
merge
This commit is contained in:
237
sql/table.cc
237
sql/table.cc
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user