mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
merge
This commit is contained in:
106
sql/sql_view.cc
106
sql/sql_view.cc
@ -453,16 +453,25 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
|
||||
{
|
||||
// TODO: change here when we will support UNIONs
|
||||
for (TABLE_LIST *tbl= (TABLE_LIST *)thd->lex->select_lex.table_list.first;
|
||||
tbl;
|
||||
tbl= tbl->next_local)
|
||||
tbl;
|
||||
tbl= tbl->next_local)
|
||||
{
|
||||
if (tbl->view && !tbl->updatable_view)
|
||||
{
|
||||
view->updatable_view= 0;
|
||||
break;
|
||||
view->updatable_view= 0;
|
||||
break;
|
||||
}
|
||||
for (TABLE_LIST *up= tbl; up; up= up->embedding)
|
||||
{
|
||||
if (up->outer_join)
|
||||
{
|
||||
view->updatable_view= 0;
|
||||
goto loop_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loop_out:
|
||||
|
||||
if (view->with_check != VIEW_CHECK_NONE &&
|
||||
!view->updatable_view)
|
||||
@ -510,6 +519,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
SELECT_LEX *end;
|
||||
THD *thd= current_thd;
|
||||
LEX *old_lex= thd->lex, *lex;
|
||||
SELECT_LEX *view_select;
|
||||
int res= 0;
|
||||
|
||||
/*
|
||||
@ -552,7 +562,8 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
*/
|
||||
table->view= lex= thd->lex= (LEX*) new(&thd->mem_root) st_lex_local;
|
||||
mysql_init_query(thd, (uchar*)table->query.str, table->query.length, TRUE);
|
||||
lex->select_lex.select_number= ++thd->select_number;
|
||||
view_select= &lex->select_lex;
|
||||
view_select->select_number= ++thd->select_number;
|
||||
old_lex->derived_tables|= DERIVED_VIEW;
|
||||
{
|
||||
ulong options= thd->options;
|
||||
@ -595,6 +606,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
table);
|
||||
TABLE_LIST *view_tables= lex->query_tables;
|
||||
TABLE_LIST *view_tables_tail= 0;
|
||||
TABLE_LIST *tbl;
|
||||
|
||||
if (lex->spfuns.records)
|
||||
{
|
||||
@ -653,7 +665,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
old_lex->safe_to_cache_query= (old_lex->safe_to_cache_query &&
|
||||
lex->safe_to_cache_query);
|
||||
/* move SQL_CACHE to whole query */
|
||||
if (lex->select_lex.options & OPTION_TO_QUERY_CACHE)
|
||||
if (view_select->options & OPTION_TO_QUERY_CACHE)
|
||||
old_lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
|
||||
|
||||
/*
|
||||
@ -691,9 +703,6 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
old_lex->can_use_merged()) &&
|
||||
!old_lex->can_not_use_merged())
|
||||
{
|
||||
/*
|
||||
TODO: support multi tables substitutions
|
||||
*/
|
||||
/* lex should contain at least one table */
|
||||
DBUG_ASSERT(view_tables != 0);
|
||||
|
||||
@ -702,20 +711,50 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
table->updatable= (table->updatable_view != 0);
|
||||
|
||||
table->ancestor= view_tables;
|
||||
|
||||
/*
|
||||
next table should include SELECT_LEX under this table SELECT_LEX
|
||||
|
||||
TODO: ehere should be loop for multi tables substitution
|
||||
*/
|
||||
table->ancestor->select_lex= table->select_lex;
|
||||
|
||||
/*
|
||||
move lock type (TODO: should we issue error in case of TMPTABLE
|
||||
algorithm and non-read locking)?
|
||||
Process upper level tables of view. As far as we do noy suport union
|
||||
here we can go through local tables of view most upper SELECT
|
||||
*/
|
||||
view_tables->lock_type= table->lock_type;
|
||||
for(tbl= (TABLE_LIST*)view_select->table_list.first;
|
||||
tbl;
|
||||
tbl= tbl->next_local)
|
||||
{
|
||||
/*
|
||||
move lock type (TODO: should we issue error in case of TMPTABLE
|
||||
algorithm and non-read locking)?
|
||||
*/
|
||||
tbl->lock_type= table->lock_type;
|
||||
}
|
||||
|
||||
/* multi table view */
|
||||
if (view_tables->next_local)
|
||||
{
|
||||
/* make nested join structure for view tables */
|
||||
NESTED_JOIN *nested_join;
|
||||
if (!(nested_join= table->nested_join=
|
||||
(NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN))))
|
||||
goto err;
|
||||
nested_join->join_list= view_select->top_join_list;
|
||||
|
||||
/* re-nest tables of VIEW */
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> ti(nested_join->join_list);
|
||||
while(tbl= ti++)
|
||||
{
|
||||
tbl->join_list= &nested_join->join_list;
|
||||
tbl->embedding= table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Store WHERE clause for postprocessing in setup_ancestor */
|
||||
table->where= lex->select_lex.where;
|
||||
table->where= view_select->where;
|
||||
|
||||
/*
|
||||
This SELECT_LEX will be linked in global SELECT_LEX list
|
||||
@ -728,13 +767,13 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
||||
|
||||
table->effective_algorithm= VIEW_ALGORITHM_TMPTABLE;
|
||||
DBUG_PRINT("info", ("algorithm: TEMPORARY TABLE"));
|
||||
lex->select_lex.linkage= DERIVED_TABLE_TYPE;
|
||||
view_select->linkage= DERIVED_TABLE_TYPE;
|
||||
table->updatable= 0;
|
||||
table->with_check= VIEW_CHECK_NONE;
|
||||
|
||||
/* SELECT tree link */
|
||||
lex->unit.include_down(table->select_lex);
|
||||
lex->unit.slave= &lex->select_lex; // fix include_down initialisation
|
||||
lex->unit.slave= view_select; // fix include_down initialisation
|
||||
|
||||
table->derived= &lex->unit;
|
||||
}
|
||||
@ -745,7 +784,7 @@ ok:
|
||||
if (arena)
|
||||
thd->restore_backup_item_arena(arena, &backup);
|
||||
/* global SELECT list linking */
|
||||
end= &lex->select_lex; // primary SELECT_LEX is always last
|
||||
end= view_select; // primary SELECT_LEX is always last
|
||||
end->link_next= old_lex->all_selects_list;
|
||||
old_lex->all_selects_list->link_prev= &end->link_next;
|
||||
old_lex->all_selects_list= lex->all_selects_list;
|
||||
@ -874,19 +913,21 @@ frm_type_enum mysql_frm_type(char *path)
|
||||
bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
{
|
||||
TABLE *table;
|
||||
Item **trans;
|
||||
Field_translator *trans;
|
||||
KEY *key_info, *key_info_end;
|
||||
uint i, elements_in_view;
|
||||
DBUG_ENTER("check_key_in_view");
|
||||
|
||||
if (!view->view)
|
||||
if (!view->view && !view->belong_to_view)
|
||||
DBUG_RETURN(FALSE); /* it is normal table */
|
||||
table= view->table;
|
||||
if (view->belong_to_view)
|
||||
view= view->belong_to_view;
|
||||
trans= view->field_translation;
|
||||
key_info_end= (key_info= table->key_info)+ table->keys;
|
||||
|
||||
elements_in_view= view->view->select_lex.item_list.elements;
|
||||
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
|
||||
DBUG_ASSERT(table != 0 && view->field_translation != 0);
|
||||
|
||||
/* Loop over all keys to see if a unique-not-null key is used */
|
||||
for (;key_info != key_info_end ; key_info++)
|
||||
@ -903,7 +944,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
for (k= 0; k < elements_in_view; k++)
|
||||
{
|
||||
Item_field *field;
|
||||
if ((field= trans[k]->filed_for_view_update()) &&
|
||||
if ((field= trans[k].item->filed_for_view_update()) &&
|
||||
field->field == key_part->field)
|
||||
break;
|
||||
}
|
||||
@ -924,7 +965,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
for (i= 0; i < elements_in_view; i++)
|
||||
{
|
||||
Item_field *field;
|
||||
if ((field= trans[i]->filed_for_view_update()) &&
|
||||
if ((field= trans[i].item->filed_for_view_update()) &&
|
||||
field->field == *field_ptr)
|
||||
break;
|
||||
}
|
||||
@ -964,22 +1005,31 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
|
||||
insert_view_fields()
|
||||
list list for insertion
|
||||
view view for processing
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - error (is not sent to cliet)
|
||||
*/
|
||||
|
||||
void insert_view_fields(List<Item> *list, TABLE_LIST *view)
|
||||
int insert_view_fields(List<Item> *list, TABLE_LIST *view)
|
||||
{
|
||||
uint elements_in_view= view->view->select_lex.item_list.elements;
|
||||
Item **trans;
|
||||
Field_translator *trans;
|
||||
DBUG_ENTER("insert_view_fields");
|
||||
|
||||
if (!(trans= view->field_translation))
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
for (uint i= 0; i < elements_in_view; i++)
|
||||
{
|
||||
Item_field *fld;
|
||||
if ((fld= trans[i]->filed_for_view_update()))
|
||||
if ((fld= trans[i].item->filed_for_view_update()))
|
||||
list->push_back(fld);
|
||||
else
|
||||
{
|
||||
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), view->alias, "INSERT");
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user