mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Better emulation correct SELECT tree for fields expressions of merging view during name resolving (BUG#6394)
mysql-test/r/view.result: added test with subquery in the FROM clause mysql-test/t/view.test: added test with subquery in the FROM clause sql/table.cc: use SELECT in which view is merging as main SELECT for nameresolving to make correct support for subqueries in the view.
This commit is contained in:
@ -1744,6 +1744,9 @@ c1
|
|||||||
select * from v2;
|
select * from v2;
|
||||||
c1
|
c1
|
||||||
1
|
1
|
||||||
|
select * from (select c1 from v2) X;
|
||||||
|
c1
|
||||||
|
1
|
||||||
drop view v2, v1;
|
drop view v2, v1;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
CREATE TABLE t1 (C1 INT, C2 INT);
|
CREATE TABLE t1 (C1 INT, C2 INT);
|
||||||
|
@ -1680,6 +1680,7 @@ create view v1 as SELECT c1 FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
|
|||||||
create view v2 as SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
|
create view v2 as SELECT c1 FROM t1 WHERE EXISTS (SELECT c2 FROM t2 WHERE c2 = c1);
|
||||||
select * from v1;
|
select * from v1;
|
||||||
select * from v2;
|
select * from v2;
|
||||||
|
select * from (select c1 from v2) X;
|
||||||
drop view v2, v1;
|
drop view v2, v1;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
|
41
sql/table.cc
41
sql/table.cc
@ -1699,13 +1699,15 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
|
|||||||
Field_translator *transl;
|
Field_translator *transl;
|
||||||
SELECT_LEX *select= &view->select_lex;
|
SELECT_LEX *select= &view->select_lex;
|
||||||
SELECT_LEX *current_select_save= thd->lex->current_select;
|
SELECT_LEX *current_select_save= thd->lex->current_select;
|
||||||
byte *main_table_list_save= thd->lex->select_lex.table_list.first;
|
byte *main_table_list_save= select_lex->table_list.first;
|
||||||
Item *item;
|
Item *item;
|
||||||
TABLE_LIST *tbl;
|
TABLE_LIST *tbl;
|
||||||
List_iterator_fast<Item> it(select->item_list);
|
List_iterator_fast<Item> it(select->item_list);
|
||||||
uint i= 0;
|
uint i= 0;
|
||||||
|
enum sub_select_type linkage_save=
|
||||||
|
select_lex->master_unit()->first_select()->linkage;
|
||||||
bool save_set_query_id= thd->set_query_id;
|
bool save_set_query_id= thd->set_query_id;
|
||||||
bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
|
bool save_wrapper= select_lex->no_wrap_view_item;
|
||||||
bool save_allow_sum_func= thd->allow_sum_func;
|
bool save_allow_sum_func= thd->allow_sum_func;
|
||||||
DBUG_ENTER("st_table_list::setup_ancestor");
|
DBUG_ENTER("st_table_list::setup_ancestor");
|
||||||
|
|
||||||
@ -1723,13 +1725,16 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
|
|||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("there are already translation table"));
|
DBUG_PRINT("info", ("there are already translation table"));
|
||||||
/*
|
/*
|
||||||
prevent look up in SELECTs tree, and emulate main table list by
|
Prevent look up in SELECTs tree (DERIVED_TABLE_TYPE is barrier for name
|
||||||
ancestor table list for subquery processing
|
lookup) and emulate main table list by ancestor table list for
|
||||||
|
subquery processing
|
||||||
*/
|
*/
|
||||||
thd->lex->current_select= &thd->lex->select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
thd->lex->select_lex.table_list.first= (byte *)ancestor;
|
select_lex->table_list.first= (byte *)ancestor;
|
||||||
|
select_lex->master_unit()->first_select()->linkage= DERIVED_TABLE_TYPE;
|
||||||
|
|
||||||
|
select_lex->no_wrap_view_item= 1;
|
||||||
|
|
||||||
thd->lex->select_lex.no_wrap_view_item= 1;
|
|
||||||
thd->set_query_id= 1;
|
thd->set_query_id= 1;
|
||||||
/* this view was prepared already on previous PS/SP execution */
|
/* this view was prepared already on previous PS/SP execution */
|
||||||
Field_translator *end= field_translation + select->item_list.elements;
|
Field_translator *end= field_translation + select->item_list.elements;
|
||||||
@ -1774,13 +1779,15 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
prevent look up in SELECTs tree, and emulate main table list by ancestor
|
Prevent look up in SELECTs tree (DERIVED_TABLE_TYPE is barrier for name
|
||||||
table list for subquery processing
|
lookup) and emulate main table list by ancestor table list for
|
||||||
|
subquery processing
|
||||||
*/
|
*/
|
||||||
thd->lex->current_select= &thd->lex->select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
thd->lex->select_lex.table_list.first= (byte *)ancestor;
|
select_lex->table_list.first= (byte *)ancestor;
|
||||||
|
select_lex->master_unit()->first_select()->linkage= DERIVED_TABLE_TYPE;
|
||||||
|
|
||||||
thd->lex->select_lex.no_wrap_view_item= 1;
|
select_lex->no_wrap_view_item= 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Resolve all view items against ancestor table.
|
Resolve all view items against ancestor table.
|
||||||
@ -1922,9 +1929,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ok:
|
ok:
|
||||||
thd->lex->select_lex.no_wrap_view_item= save_wrapper;
|
select_lex->no_wrap_view_item= save_wrapper;
|
||||||
thd->lex->current_select= current_select_save;
|
thd->lex->current_select= current_select_save;
|
||||||
thd->lex->select_lex.table_list.first= main_table_list_save;
|
select_lex->table_list.first= main_table_list_save;
|
||||||
|
select_lex->master_unit()->first_select()->linkage= linkage_save;
|
||||||
thd->set_query_id= save_set_query_id;
|
thd->set_query_id= save_set_query_id;
|
||||||
thd->allow_sum_func= save_allow_sum_func;
|
thd->allow_sum_func= save_allow_sum_func;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -1937,9 +1945,10 @@ err:
|
|||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str);
|
my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str);
|
||||||
}
|
}
|
||||||
thd->lex->select_lex.no_wrap_view_item= save_wrapper;
|
select_lex->no_wrap_view_item= save_wrapper;
|
||||||
thd->lex->current_select= current_select_save;
|
thd->lex->current_select= current_select_save;
|
||||||
thd->lex->select_lex.table_list.first= main_table_list_save;
|
select_lex->table_list.first= main_table_list_save;
|
||||||
|
select_lex->master_unit()->first_select()->linkage= linkage_save;
|
||||||
thd->set_query_id= save_set_query_id;
|
thd->set_query_id= save_set_query_id;
|
||||||
thd->allow_sum_func= save_allow_sum_func;
|
thd->allow_sum_func= save_allow_sum_func;
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
Reference in New Issue
Block a user