summaryrefslogtreecommitdiff
path: root/sql/sql_view.cc
diff options
context:
space:
mode:
authorbell@sanja.is.com.ua <>2004-09-14 19:28:29 +0300
committerbell@sanja.is.com.ua <>2004-09-14 19:28:29 +0300
commitf797298fc564c70accf5b227fcfe72f12869762b (patch)
tree44ca229eb83d0543674b391c46f4d3a77539bfb7 /sql/sql_view.cc
parent31379fbebe149392550d3d3e2387785d55a230d5 (diff)
downloadmariadb-git-f797298fc564c70accf5b227fcfe72f12869762b.tar.gz
fixed merged view fields names (BUG#5147)
support of merged VIEW over several tables added (WL#1809)
Diffstat (limited to 'sql/sql_view.cc')
-rw-r--r--sql/sql_view.cc91
1 files changed, 65 insertions, 26 deletions
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 2364be228f8..12923af0ecf 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -465,15 +465,20 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
if ((view->updatable_view= (can_be_merged &&
view->algorithm != VIEW_ALGORITHM_TMPTABLE)))
{
- // 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)
+ if (thd->lex->select_lex.table_list.elements > 1)
+ view->updatable_view= 0;
+ else
{
- if (tbl->view && !tbl->updatable_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)
{
- view->updatable_view= 0;
- break;
+ if (tbl->view && !tbl->updatable_view)
+ {
+ view->updatable_view= 0;
+ break;
+ }
}
}
}
@@ -516,6 +521,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;
/*
@@ -558,7 +564,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;
@@ -601,6 +608,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)
{
@@ -655,7 +663,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;
/*
@@ -704,20 +712,51 @@ 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)
+ {
+ table->updatable= 0;
+ /* 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
@@ -730,12 +769,12 @@ 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;
/* 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;
}
@@ -746,7 +785,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;
@@ -875,7 +914,7 @@ 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");
@@ -903,8 +942,8 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
uint k;
for (k= 0; k < elements_in_view; k++)
{
- if (trans[k]->type() == Item::FIELD_ITEM &&
- ((Item_field *)trans[k])->field == key_part->field)
+ if (trans[k].item->type() == Item::FIELD_ITEM &&
+ ((Item_field *)trans[k].item)->field == key_part->field)
break;
}
if (k == elements_in_view)
@@ -923,8 +962,8 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
{
for (i= 0; i < elements_in_view; i++)
{
- if (trans[i]->type() == Item::FIELD_ITEM &&
- ((Item_field *)trans[i])->field == *field_ptr)
+ if (trans[i].item->type() == Item::FIELD_ITEM &&
+ ((Item_field *)trans[i].item)->field == *field_ptr)
break;
}
if (i == elements_in_view) // If field didn't exists
@@ -968,7 +1007,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
void 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))
@@ -976,8 +1015,8 @@ void insert_view_fields(List<Item> *list, TABLE_LIST *view)
for (uint i= 0; i < elements_in_view; i++)
{
- if (trans[i]->type() == Item::FIELD_ITEM)
- list->push_back(trans[i]);
+ if (trans[i].item->type() == Item::FIELD_ITEM)
+ list->push_back(trans[i].item);
}
DBUG_VOID_RETURN;
}