1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Name resolution context added (BUG#6443)

This commit is contained in:
bell@sanja.is.com.ua
2005-07-01 07:05:42 +03:00
parent d8cb0cbc3f
commit d3905f3d0e
55 changed files with 1688 additions and 1069 deletions

View File

@ -828,10 +828,23 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check= (uint8)table->with_check;
table->ancestor= view_tables;
table->effective_with_check=
old_lex->get_effective_with_check(table);
/* prepare view context */
lex->select_lex.context.resolve_in_table_list_only(table->ancestor=
view_tables);
lex->select_lex.context.outer_context= 0;
lex->select_lex.context.select_lex= table->select_lex;
/* do not check privileges & hide errors for view underlyings */
for (SELECT_LEX *sl= lex->all_selects_list;
sl;
sl= sl->next_select_in_list())
{
sl->context.check_privileges= FALSE;
sl->context.error_processor= &view_error_processor;
sl->context.error_processor_data= (void *)table;
}
/*
Tables of the main select of the view should be marked as belonging
to the same select as original view (again we can use LEX::select_lex
@ -866,13 +879,12 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
table->where= view_select->where;
/*
Add subqueries units to SELECT into which we merging current view.
unit(->next)* chain starts with subqueries that are used by this
view and continues with subqueries that are used by other views.
We must not add any subquery twice (otherwise we'll form a loop),
to do this we remember in end_unit the first subquery that has
to do this we remember in end_unit the first subquery that has
been already added.
NOTE: we do not support UNION here, so we take only one select
*/
SELECT_LEX_NODE *end_unit= table->select_lex->slave;
@ -1058,9 +1070,9 @@ frm_type_enum mysql_frm_type(char *path)
bool check_key_in_view(THD *thd, TABLE_LIST *view)
{
TABLE *table;
Field_translator *trans;
Field_translator *trans, *end_of_trans;
KEY *key_info, *key_info_end;
uint i, elements_in_view;
uint i;
DBUG_ENTER("check_key_in_view");
/*
@ -1077,9 +1089,24 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
trans= view->field_translation;
key_info_end= (key_info= table->key_info)+ table->s->keys;
elements_in_view= view->view->select_lex.item_list.elements;
end_of_trans= view->field_translation_end;
DBUG_ASSERT(table != 0 && view->field_translation != 0);
{
/*
We should be sure that all fields are ready to get keys from them, but
this operation should not have influence on Field::query_id, to avoid
marking as used fields which are not used
*/
bool save_set_query_id= thd->set_query_id;
thd->set_query_id= 0;
for (Field_translator *fld= trans; fld < end_of_trans; fld++)
{
if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
return TRUE;
}
thd->set_query_id= save_set_query_id;
}
/* Loop over all keys to see if a unique-not-null key is used */
for (;key_info != key_info_end ; key_info++)
{
@ -1091,15 +1118,15 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
/* check that all key parts are used */
for (;;)
{
uint k;
for (k= 0; k < elements_in_view; k++)
Field_translator *k;
for (k= trans; k < end_of_trans; k++)
{
Item_field *field;
if ((field= trans[k].item->filed_for_view_update()) &&
if ((field= k->item->filed_for_view_update()) &&
field->field == key_part->field)
break;
}
if (k == elements_in_view)
if (k == end_of_trans)
break; // Key is not possible
if (++key_part == key_part_end)
DBUG_RETURN(FALSE); // Found usable key
@ -1111,19 +1138,20 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
/* check all fields presence */
{
Field **field_ptr;
Field_translator *fld;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
for (i= 0; i < elements_in_view; i++)
for (fld= trans; fld < end_of_trans; fld++)
{
Item_field *field;
if ((field= trans[i].item->filed_for_view_update()) &&
if ((field= fld->item->filed_for_view_update()) &&
field->field == *field_ptr)
break;
}
if (i == elements_in_view) // If field didn't exists
if (fld == end_of_trans) // If field didn't exists
{
/*
Keys or all fields of underlying tables are not foud => we have
Keys or all fields of underlying tables are not found => we have
to check variable updatable_views_with_limit to decide should we
issue an error or just a warning
*/
@ -1148,6 +1176,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
SYNOPSIS
insert_view_fields()
thd thread handler
list list for insertion
view view for processing
@ -1156,19 +1185,22 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
TRUE error (is not sent to cliet)
*/
bool insert_view_fields(List<Item> *list, TABLE_LIST *view)
bool insert_view_fields(THD *thd, List<Item> *list, TABLE_LIST *view)
{
uint elements_in_view= view->view->select_lex.item_list.elements;
Field_translator *trans_end;
Field_translator *trans;
DBUG_ENTER("insert_view_fields");
if (!(trans= view->field_translation))
DBUG_RETURN(FALSE);
trans_end= view->field_translation_end;
for (uint i= 0; i < elements_in_view; i++)
for (Field_translator *entry= trans; entry < trans_end; entry++)
{
Item_field *fld;
if ((fld= trans[i].item->filed_for_view_update()))
if (!entry->item->fixed && entry->item->fix_fields(thd, &entry->item))
DBUG_RETURN(TRUE);
if ((fld= entry->item->filed_for_view_update()))
list->push_back(fld);
else
{