Skip to content

Commit

Permalink
SQL: CREATE VIEW and misc improvements [fixes #183]
Browse files Browse the repository at this point in the history
  • Loading branch information
midenok committed May 5, 2017
1 parent 27a6ef0 commit 1e8a81d
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 82 deletions.
2 changes: 2 additions & 0 deletions mysql-test/suite/versioning/r/select.result
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ x y
1 1
2 1
3 1
select * from t1 for system_time all, t2 for system_time all query for system_time all;
ERROR HY000: Wrong versioned query: unused `QUERY FOR SYSTEM_TIME` clause!
drop view v1;
drop table t1, t2;
call innodb_verify_vtq(27);
Expand Down
46 changes: 24 additions & 22 deletions mysql-test/suite/versioning/r/view.result
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set @vt1= concat("create view vt1 as select * from t1 for system_time as of time
prepare stmt from @vt1;
execute stmt;
drop prepare stmt;
set @vt2= concat("create view vt2 as select * from t1 for system_time as of timestamp '", @t2, "'");
set @vt2= concat("create view vt2 as select *, sys_trx_end from t1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @vt2;
execute stmt;
drop prepare stmt;
Expand Down Expand Up @@ -76,10 +76,6 @@ x
select * from vt1 for system_time all;
x
3
create view error_view as select *, sys_trx_start from t1;
ERROR 42S21: Duplicate column name 'sys_trx_start'
create view error_view as select *, sys_trx_end from t1;
ERROR 42S21: Duplicate column name 'sys_trx_end'
create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
set @t1=now(6);
Expand All @@ -91,27 +87,14 @@ set @tmp= concat("create or replace view vt1 as select * from t1 for system_time
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
set @tmp= concat("create or replace view vvt1 as select * from vt1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
set @tmp= concat("create or replace view vvvt1 as select * from vvt1 for system_time as of timestamp '", @t3, "'");
prepare stmt from @tmp;
execute stmt;
drop prepare stmt;
select * from vt1 for system_time all;
x
1
2
select * from vvt1 for system_time all;
x
1
select * from vvvt1 for system_time all;
x
create or replace table t1 (x int) with system versioning;
create or replace view vt1(c) as select x from t1;
create or replace table t1 (a int) with system versioning;
create or replace table t2 (b int) with system versioning;
create or replace table t1 (a int) with system versioning engine innodb;
create or replace table t2 (b int) with system versioning engine innodb;
insert into t1 values (1);
insert into t2 values (2);
create or replace view vt12 as select * from t1 cross join t2;
Expand All @@ -121,5 +104,24 @@ a b
create or replace view vt12 as select * from t1 for system_time as of timestamp '0-0-0' cross join t2;
select * from vt12;
a b
drop view vt1, vvt1, vvvt1, vt12;
drop table t1, t2;
create or replace view vt1 as select a, t1.sys_trx_start, t2.sys_trx_end from t1, t2;
ERROR HY000: Creating VIEW `vt1` is prohibited: system fields from multiple tables `t1`, `t2` in query!
create or replace view vt1 as select a, t1.sys_trx_end, t2.sys_trx_end from t1, t2;
ERROR HY000: Creating VIEW `vt1` is prohibited: multiple end system fields `t1.sys_trx_end`, `t2.sys_trx_end` in query!
create or replace table t3 (x int);
create or replace view vt1 as select * from t1, t2, t3;
show create view vt1;
View Create View character_set_client collation_connection
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,`t3`.`x` AS `x`,`t1`.`sys_trx_start` AS `sys_trx_start`,`t1`.`sys_trx_end` AS `sys_trx_end` from ((`t1` FOR SYSTEM_TIME ALL join `t2` FOR SYSTEM_TIME ALL) join `t3`) where `t1`.`sys_trx_end` = 18446744073709551615 and `t2`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
create or replace view vt1 as select * from t3, t2, t1;
show create view vt1;
View Create View character_set_client collation_connection
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t3`.`x` AS `x`,`t2`.`b` AS `b`,`t1`.`a` AS `a`,`t2`.`sys_trx_start` AS `sys_trx_start`,`t2`.`sys_trx_end` AS `sys_trx_end` from ((`t3` join `t2` FOR SYSTEM_TIME ALL) join `t1` FOR SYSTEM_TIME ALL) where `t2`.`sys_trx_end` = 18446744073709551615 and `t1`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
create or replace view vt1 as select a, t2.sys_trx_end as endo from t3, t1, t2;
show create view vt1;
View Create View character_set_client collation_connection
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`a` AS `a`,`t2`.`sys_trx_end` AS `endo`,`t2`.`sys_trx_start` AS `sys_trx_start` from ((`t3` join `t1` FOR SYSTEM_TIME ALL) join `t2` FOR SYSTEM_TIME ALL) where `t1`.`sys_trx_end` = 18446744073709551615 and `t2`.`sys_trx_end` = 18446744073709551615 latin1 latin1_swedish_ci
create or replace view vvt1 as select * from t1, t2, vt1;
ERROR HY000: Creating VIEW `vvt1` is prohibited: versioned VIEW `vt1` in query!
drop view vt1, vt12;
drop table t1, t2, t3;
3 changes: 3 additions & 0 deletions mysql-test/suite/versioning/t/select.test
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ delete from t1 where x = 3;
insert into t2 values (1);
select * from t1, t2 query for system_time all;

--error ER_VERS_WRONG_QUERY
select * from t1 for system_time all, t2 for system_time all query for system_time all;

drop view v1;
drop table t1, t2;

Expand Down
37 changes: 21 additions & 16 deletions mysql-test/suite/versioning/t/view.test
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ delete from t1;
set @vt1= concat("create view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
prepare stmt from @vt1; execute stmt; drop prepare stmt;

set @vt2= concat("create view vt2 as select * from t1 for system_time as of timestamp '", @t2, "'");
set @vt2= concat("create view vt2 as select *, sys_trx_end from t1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @vt2; execute stmt; drop prepare stmt;

select * from vt1 for system_time all;
Expand Down Expand Up @@ -46,11 +46,6 @@ select * from vt1;
select * from t1 for system_time all;
select * from vt1 for system_time all;

--error ER_DUP_FIELDNAME
create view error_view as select *, sys_trx_start from t1;
--error ER_DUP_FIELDNAME
create view error_view as select *, sys_trx_end from t1;

create or replace table t1 (x int) with system versioning;
insert into t1 values (1), (2);
set @t1=now(6);
Expand All @@ -61,26 +56,36 @@ set @t3=now(6);

set @tmp= concat("create or replace view vt1 as select * from t1 for system_time as of timestamp '", @t1, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;
set @tmp= concat("create or replace view vvt1 as select * from vt1 for system_time as of timestamp '", @t2, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;
set @tmp= concat("create or replace view vvvt1 as select * from vvt1 for system_time as of timestamp '", @t3, "'");
prepare stmt from @tmp; execute stmt; drop prepare stmt;

select * from vt1 for system_time all;
select * from vvt1 for system_time all;
select * from vvvt1 for system_time all;

create or replace table t1 (x int) with system versioning;
create or replace view vt1(c) as select x from t1;

create or replace table t1 (a int) with system versioning;
create or replace table t2 (b int) with system versioning;
create or replace table t1 (a int) with system versioning engine innodb;
create or replace table t2 (b int) with system versioning engine innodb;
insert into t1 values (1);
insert into t2 values (2);
create or replace view vt12 as select * from t1 cross join t2;
select * from vt12;
create or replace view vt12 as select * from t1 for system_time as of timestamp '0-0-0' cross join t2;
select * from vt12;

drop view vt1, vvt1, vvvt1, vt12;
drop table t1, t2;
--error ER_VERS_VIEW_PROHIBITED
create or replace view vt1 as select a, t1.sys_trx_start, t2.sys_trx_end from t1, t2;
--error ER_VERS_VIEW_PROHIBITED
create or replace view vt1 as select a, t1.sys_trx_end, t2.sys_trx_end from t1, t2;

create or replace table t3 (x int);
create or replace view vt1 as select * from t1, t2, t3;
show create view vt1;
create or replace view vt1 as select * from t3, t2, t1;
show create view vt1;
create or replace view vt1 as select a, t2.sys_trx_end as endo from t3, t1, t2;
show create view vt1;

--error ER_VERS_VIEW_PROHIBITED
create or replace view vvt1 as select * from t1, t2, vt1;

drop view vt1, vt12;
drop table t1, t2, t3;
9 changes: 9 additions & 0 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7535,5 +7535,14 @@ ER_VERS_NOT_ALLOWED
ER_VERS_WRONG_QUERY_TYPE
eng "%`s works only with %`s query type"

ER_VERS_VIEW_PROHIBITED
eng "Creating VIEW %`s is prohibited!"

ER_VERS_WRONG_QUERY
eng "Wrong versioned query: %s"

WARN_VERS_ALIAS_TOO_LONG
eng "Auto generated alias for `%s.%s` is too long; using `%s`."

ER_WRONG_TABLESPACE_NAME 42000
eng "Incorrect tablespace name `%-.192s`"
5 changes: 2 additions & 3 deletions sql/sql_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7582,7 +7582,6 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
if (!(item= field_iterator.create_item(thd)))
DBUG_RETURN(TRUE);

/* This will be deprecated when HIDDEN feature will come to MariaDB. */
if (item->type() == Item::FIELD_ITEM)
{
Item_field *f= static_cast<Item_field *>(item);
Expand All @@ -7597,8 +7596,8 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
tl->vers_conditions.type == FOR_SYSTEM_TIME_UNSPECIFIED ?
slex->vers_conditions.type : tl->vers_conditions.type;

if ((sys_field && vers_hide == VERS_HIDE_FULL &&
thd->lex->sql_command != SQLCOM_CREATE_TABLE) ||
if ((sys_field && (thd->lex->sql_command == SQLCOM_CREATE_VIEW ||
vers_hide == VERS_HIDE_FULL && thd->lex->sql_command != SQLCOM_CREATE_TABLE)) ||
((fl & HIDDEN_FLAG) && (
!sys_field ||
vers_hide == VERS_HIDE_IMPLICIT ||
Expand Down
22 changes: 22 additions & 0 deletions sql/sql_lex.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7044,3 +7044,25 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_STRING &name)
return true;
return false;
}


bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, const char* field_name)
{
char buf[MAX_FIELD_NAME];
Item_field *fld= new (thd->mem_root) Item_field(thd, &context,
table->db, table->alias, field_name);
if (!fld)
return true;

item_list.push_back(fld);

if (thd->lex->view_list.elements)
{
if (LEX_STRING *l= thd->make_lex_string(field_name, strlen(field_name)))
thd->lex->view_list.push_back(l);
else
return true;
}

return false;
}
3 changes: 2 additions & 1 deletion sql/sql_lex.h
Original file line number Diff line number Diff line change
Expand Up @@ -991,8 +991,9 @@ class st_select_lex: public st_select_lex_node
/* it is for correct printing SELECT options */
thr_lock_type lock_type;

/* System Versioning conditions */
/* System Versioning */
vers_select_conds_t vers_conditions;
bool vers_push_field(THD *thd, TABLE_LIST *table, const char* field_name);

void init_query();
void init_select();
Expand Down
29 changes: 18 additions & 11 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,

TABLE_LIST *table;
int versioned_tables= 0;
int slex_conds_used= 0;
Query_arena *arena= 0, backup;

if (!thd->stmt_arena->is_conventional() &&
Expand All @@ -707,7 +708,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
{
if (table->table && table->table->versioned())
versioned_tables++;
else if (table->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
else if (table->vers_conditions)
{
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query");
DBUG_RETURN(-1);
Expand All @@ -716,7 +717,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,

if (versioned_tables == 0)
{
if (slex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
if (slex->vers_conditions)
{
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query");
DBUG_RETURN(-1);
Expand Down Expand Up @@ -775,17 +776,17 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
{
if (table->table && table->table->versioned())
{
vers_select_conds_t &vers_conditions=
table->vers_conditions.type == FOR_SYSTEM_TIME_UNSPECIFIED ?
slex->vers_conditions : table->vers_conditions;
vers_select_conds_t &vers_conditions= !table->vers_conditions?
(++slex_conds_used, slex->vers_conditions) :
table->vers_conditions;

if (vers_conditions.type == FOR_SYSTEM_TIME_UNSPECIFIED)
if (!vers_conditions)
{
if (vers_conditions.init_from_sysvar(thd))
DBUG_RETURN(-1);
}

if (vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
if (vers_conditions)
{
switch (slex->lock_type)
{
Expand All @@ -804,9 +805,9 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
break;
}

if (vers_conditions.type == FOR_SYSTEM_TIME_ALL)
if (vers_conditions == FOR_SYSTEM_TIME_ALL)
continue;
}
} // if (vers_conditions)

COND** dst_cond= where_expr;
if (table->on_expr)
Expand Down Expand Up @@ -979,6 +980,12 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
if (arena)
thd->restore_active_arena(arena, &backup);

if (!slex_conds_used && slex->vers_conditions)
{
my_error(ER_VERS_WRONG_QUERY, MYF(0), "unused `QUERY FOR SYSTEM_TIME` clause!");
DBUG_RETURN(-1);
}

DBUG_RETURN(0);
#undef newx
}
Expand Down Expand Up @@ -16985,8 +16992,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
sys_trx_end->flags|= VERS_SYS_END_FLAG | HIDDEN_FLAG;
share->versioned= true;
share->field= table->field;
share->row_start_field= field_count - 2;
share->row_end_field= field_count - 1;
share->row_start_field= sys_trx_start->field_index;
share->row_end_field= sys_trx_end->field_index;
}

DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
Expand Down
Loading

0 comments on commit 1e8a81d

Please sign in to comment.