mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-34931 MDEV-31466 name resolution fails in --view
Fix for MDEV-31466 - add optional derived table column names. Column names within a SELECT_LEX structure can be left in a non-reparsable state (as printed out from *::print) after JOIN::prepare. This caused an incorrect view definition to be written into the .FRM file. Fixed by resetting item list names in SELECT_LEX structures representing derived tables before writing out the view definition. Reviewed by Igor Babaev (igor@mariadb.com)
This commit is contained in:
parent
10008b3d3e
commit
e90aab7acc
6 changed files with 77 additions and 15 deletions
|
@ -2084,6 +2084,15 @@ union
|
|||
select c1, c2, sum(c3) as s from t2 group by c1, c2 having s > 3
|
||||
)
|
||||
as d2 (f1, f2, f3);
|
||||
create view v6 as select a1 from
|
||||
(
|
||||
select * from t1 union select * from t2 order by c1
|
||||
) as d3 (a1, a2, a3);
|
||||
create view v7 (b1) as select a1 from (select c1 from t1) dt (a1);
|
||||
create view v8 (b1, b2, b3) as select a1, a2, a3 from
|
||||
(
|
||||
select * from t1 union select * from t2 order by c1
|
||||
) as d3 (a1, a2, a3);
|
||||
# test parent query mergability
|
||||
explain format=json select a1 from v1;
|
||||
EXPLAIN
|
||||
|
@ -2156,6 +2165,31 @@ select * from v4 where e3 < 10;
|
|||
e1 e2 e3
|
||||
1 2 3
|
||||
4 5 6
|
||||
select * from v6;
|
||||
a1
|
||||
1
|
||||
4
|
||||
7
|
||||
10
|
||||
show create view v6;
|
||||
View Create View character_set_client collation_connection
|
||||
v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v6` AS select `d3`.`a1` AS `a1` from (select `t1`.`c1` AS `a1`,`t1`.`c2` AS `a2`,`t1`.`c3` AS `a3` from `t1` union select `t2`.`c1` AS `c1`,`t2`.`c2` AS `c2`,`t2`.`c3` AS `c3` from `t2` order by `c1`) `d3`(`a1`,`a2`,`a3`) latin1 latin1_swedish_ci
|
||||
select * from v7;
|
||||
b1
|
||||
1
|
||||
4
|
||||
show create view v7;
|
||||
View Create View character_set_client collation_connection
|
||||
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v7` AS select `dt`.`a1` AS `b1` from (select `t1`.`c1` AS `a1` from `t1`) `dt`(`a1`) latin1 latin1_swedish_ci
|
||||
select * from v8;
|
||||
b1 b2 b3
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
10 11 12
|
||||
show create view v8;
|
||||
View Create View character_set_client collation_connection
|
||||
v8 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v8` AS select `d3`.`a1` AS `b1`,`d3`.`a2` AS `b2`,`d3`.`a3` AS `b3` from (select `t1`.`c1` AS `a1`,`t1`.`c2` AS `a2`,`t1`.`c3` AS `a3` from `t1` union select `t2`.`c1` AS `c1`,`t2`.`c2` AS `c2`,`t2`.`c3` AS `c3` from `t2` order by `c1`) `d3`(`a1`,`a2`,`a3`) latin1 latin1_swedish_ci
|
||||
# show materialization and condition pushdown into having
|
||||
explain format=json select * from v4 where e3 < 10;
|
||||
EXPLAIN
|
||||
|
@ -3169,9 +3203,9 @@ EXPLAIN
|
|||
}
|
||||
# pushdown through GROUP BY
|
||||
create function f1(a int) returns int DETERMINISTIC return (a+1);
|
||||
create view v6 as select * from
|
||||
create view v9 as select * from
|
||||
(select c1, f1(c2), sum(c3) from t1 group by c1, f1(c2)) as f (c1, c2, c3);
|
||||
explain format=json select * from v6 where (c3+1) > 10 and c1 > 1 and c2 > 123;
|
||||
explain format=json select * from v9 where (c3+1) > 10 and c1 > 1 and c2 > 123;
|
||||
EXPLAIN
|
||||
{
|
||||
"query_block": {
|
||||
|
@ -5124,7 +5158,7 @@ where c1=d2 limit 1)
|
|||
alter table t1 rename column c1 to cc1;
|
||||
select * from v1;
|
||||
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
|
||||
drop view v1, v2, v3, v4, v5, v6;
|
||||
drop view v1, v2, v3, v4, v5, v6, v7, v8, v9;
|
||||
drop table t1, t2, t3;
|
||||
create table t10 (a int);
|
||||
create table t20 (b int);
|
||||
|
@ -5148,14 +5182,14 @@ select * from v20;
|
|||
c x u1 y1 b2
|
||||
1 X U Y 1
|
||||
3 NULL NULL NULL NULL
|
||||
select * from v20 limit 9;
|
||||
select * from v20 order by c limit 9;
|
||||
c x u1 y1 b2
|
||||
1 X U Y 1
|
||||
3 NULL NULL NULL NULL
|
||||
select * from v21;
|
||||
select * from v21 order by c;
|
||||
c x u1 b1
|
||||
3 NULL NULL NULL
|
||||
1 X U 1
|
||||
3 NULL NULL NULL
|
||||
drop view v10, v20, v11, v21;
|
||||
drop table t10, t20, t30;
|
||||
#
|
||||
|
|
|
@ -1640,6 +1640,15 @@ create view v5 as select * from
|
|||
select c1, c2, sum(c3) as s from t2 group by c1, c2 having s > 3
|
||||
)
|
||||
as d2 (f1, f2, f3);
|
||||
create view v6 as select a1 from
|
||||
(
|
||||
select * from t1 union select * from t2 order by c1
|
||||
) as d3 (a1, a2, a3);
|
||||
create view v7 (b1) as select a1 from (select c1 from t1) dt (a1);
|
||||
create view v8 (b1, b2, b3) as select a1, a2, a3 from
|
||||
(
|
||||
select * from t1 union select * from t2 order by c1
|
||||
) as d3 (a1, a2, a3);
|
||||
|
||||
--echo # test parent query mergability
|
||||
--source include/explain-no-costs.inc
|
||||
|
@ -1655,6 +1664,12 @@ select a1, a2 from v1 union select b1, b2 from v2;
|
|||
select * from v1 union select * from v2;
|
||||
select * from v3 intersect select * from v2 union select * from v1;
|
||||
select * from v4 where e3 < 10;
|
||||
select * from v6;
|
||||
show create view v6;
|
||||
select * from v7;
|
||||
show create view v7;
|
||||
select * from v8;
|
||||
show create view v8;
|
||||
--echo # show materialization and condition pushdown into having
|
||||
--source include/explain-no-costs.inc
|
||||
explain format=json select * from v4 where e3 < 10;
|
||||
|
@ -1814,9 +1829,9 @@ explain format=json select * from v1 where if( a1 regexp 'def', 'foo', a2 )
|
|||
|
||||
--echo # pushdown through GROUP BY
|
||||
create function f1(a int) returns int DETERMINISTIC return (a+1);
|
||||
create view v6 as select * from
|
||||
create view v9 as select * from
|
||||
(select c1, f1(c2), sum(c3) from t1 group by c1, f1(c2)) as f (c1, c2, c3);
|
||||
explain format=json select * from v6 where (c3+1) > 10 and c1 > 1 and c2 > 123;
|
||||
explain format=json select * from v9 where (c3+1) > 10 and c1 > 1 and c2 > 123;
|
||||
drop function f1;
|
||||
|
||||
--echo # name resolution for multi select units
|
||||
|
@ -2057,7 +2072,7 @@ alter table t1 rename column c1 to cc1;
|
|||
--error ER_VIEW_INVALID
|
||||
select * from v1;
|
||||
|
||||
drop view v1, v2, v3, v4, v5, v6;
|
||||
drop view v1, v2, v3, v4, v5, v6, v7, v8, v9;
|
||||
drop table t1, t2, t3;
|
||||
|
||||
# test derived embedded in views
|
||||
|
@ -2080,8 +2095,8 @@ create view v21 as select * from t30
|
|||
left join (select 'X' as x, v11.u, v11.b1 from v11) dt2 (x, u1, b1)
|
||||
on t30.c=dt2.b1 order by x;
|
||||
select * from v20;
|
||||
select * from v20 limit 9;
|
||||
select * from v21;
|
||||
select * from v20 order by c limit 9;
|
||||
select * from v21 order by c;
|
||||
drop view v10, v20, v11, v21;
|
||||
drop table t10, t20, t30;
|
||||
|
||||
|
|
|
@ -1354,7 +1354,7 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived)
|
|||
derived->get_unit()));
|
||||
st_select_lex_unit *unit= derived->get_unit();
|
||||
|
||||
if (derived->original_names_are_saved)
|
||||
if (derived->original_names_source)
|
||||
unit->first_select()->set_item_list_names(derived->original_names);
|
||||
|
||||
// reset item names to that saved after wildcard expansion in JOIN::prepare
|
||||
|
|
|
@ -662,6 +662,19 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Reset item list names within derived tables so that when reparsed in the
|
||||
view, references elsewhere within this select_lex can be correctly resolved
|
||||
*/
|
||||
for (SELECT_LEX *sl= lex->all_selects_list; sl; sl= sl->next_select_in_list())
|
||||
{
|
||||
for (TABLE_LIST *tl= sl->get_table_list(); tl && !res; tl= tl->next_local)
|
||||
{
|
||||
if (tl->original_names_source)
|
||||
tl->original_names_source->set_item_list_names(tl->original_names);
|
||||
}
|
||||
}
|
||||
|
||||
res= mysql_register_view(thd, &ddl_log_state, view, mode, backup_file_name);
|
||||
|
||||
/*
|
||||
|
|
|
@ -10336,7 +10336,7 @@ bool TABLE_LIST::save_original_names(st_select_lex *derived)
|
|||
{
|
||||
if (unlikely(derived->with_wild))
|
||||
return false;
|
||||
if (original_names_are_saved)
|
||||
if (original_names_source)
|
||||
return false;
|
||||
|
||||
// these elements allocated in LEX::parsed_derived_table
|
||||
|
@ -10356,7 +10356,7 @@ bool TABLE_LIST::save_original_names(st_select_lex *derived)
|
|||
(original_name= overwrite_iterator++))
|
||||
lex_string_set( original_name, item_list_element->name.str);
|
||||
|
||||
original_names_are_saved= true;
|
||||
original_names_source= derived;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2640,7 +2640,7 @@ struct TABLE_LIST
|
|||
With_element *with; /* With element defining this table (if any) */
|
||||
List<Lex_ident_sys> *column_names; /* list of correlation column names */
|
||||
List<Lex_ident_sys> *original_names;/* list of original column names */
|
||||
bool original_names_are_saved:1;
|
||||
st_select_lex *original_names_source;
|
||||
bool save_original_names(st_select_lex *derived);
|
||||
|
||||
/* Bitmap of the defining with element */
|
||||
|
|
Loading…
Reference in a new issue