mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Parser, SQL: table-specific FOR SYSTEM_TIME [closes #116]
* Syntax sugar: query-global QUERY FOR SYSTEM_TIME
This commit is contained in:
@@ -25,7 +25,7 @@ a b
|
||||
3 NULL
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select count(*) from t group by b for system_time as of timestamp now(6);
|
||||
select count(*) from t group by b query for system_time as of timestamp now(6);
|
||||
count(*)
|
||||
2
|
||||
Warnings:
|
||||
@@ -42,23 +42,23 @@ a b
|
||||
3 NULL
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select * from t group by a having a=2 for system_time as of timestamp now(6);
|
||||
select * from t group by a having a=2 query for system_time as of timestamp now(6);
|
||||
a b
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select * from t group by b having b=2 for system_time as of timestamp now(6);
|
||||
select * from t group by b having b=2 query for system_time as of timestamp now(6);
|
||||
a b
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select a from t where b=2 for system_time as of timestamp now(6);
|
||||
select a from t where b=2 query for system_time as of timestamp now(6);
|
||||
a
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select a from t where b=NULL for system_time as of timestamp now(6);
|
||||
select a from t where b=NULL query for system_time as of timestamp now(6);
|
||||
a
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
select count(*), b from t group by b having b=NULL for system_time as of timestamp now(6);
|
||||
select count(*), b from t group by b having b=NULL query for system_time as of timestamp now(6);
|
||||
count(*) b
|
||||
Warnings:
|
||||
Warning 4075 Attempt to read unversioned field `b` in historical query
|
||||
|
@@ -95,11 +95,11 @@ select t1.x as RJ1_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
end~~
|
||||
|
@@ -23,7 +23,7 @@ x
|
||||
create or replace view vt1 as select * from 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 `t1`.`x` AS `x` from `t1` where `t1`.`sys_trx_end` = 18446744073709551615 for system_time all latin1 latin1_swedish_ci
|
||||
vt1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vt1` AS select `t1`.`x` AS `x` from `t1` where `t1`.`sys_trx_end` = 18446744073709551615 query for system_time all latin1 latin1_swedish_ci
|
||||
drop view vt1;
|
||||
drop view vt2;
|
||||
drop table t1;
|
||||
|
@@ -9,14 +9,14 @@ select * from t;
|
||||
select a from t for system_time as of timestamp now(6);
|
||||
select a, b, b+0 from t for system_time as of timestamp now(6);
|
||||
select * from t for system_time as of timestamp now(6);
|
||||
select count(*) from t group by b for system_time as of timestamp now(6);
|
||||
select count(*) from t group by b query for system_time as of timestamp now(6);
|
||||
select * from t for system_time as of timestamp now(6) order by b asc;
|
||||
select * from t for system_time as of timestamp now(6) order by b desc;
|
||||
select * from t group by a having a=2 for system_time as of timestamp now(6);
|
||||
select * from t group by b having b=2 for system_time as of timestamp now(6);
|
||||
select a from t where b=2 for system_time as of timestamp now(6);
|
||||
select a from t where b=NULL for system_time as of timestamp now(6);
|
||||
select count(*), b from t group by b having b=NULL for system_time as of timestamp now(6);
|
||||
select * from t group by a having a=2 query for system_time as of timestamp now(6);
|
||||
select * from t group by b having b=2 query for system_time as of timestamp now(6);
|
||||
select a from t where b=2 query for system_time as of timestamp now(6);
|
||||
select a from t where b=NULL query for system_time as of timestamp now(6);
|
||||
select count(*), b from t group by b having b=NULL query for system_time as of timestamp now(6);
|
||||
select a, b from t;
|
||||
|
||||
drop table t;
|
||||
|
@@ -91,11 +91,11 @@ begin
|
||||
delete from t2;
|
||||
|
||||
select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x
|
||||
for system_time as of timestamp @t0;
|
||||
query for system_time as of timestamp @t0;
|
||||
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
@@ -2762,8 +2762,10 @@ void Item_field::set_field(Field *field_par)
|
||||
|
||||
field->force_null= false;
|
||||
if (field->flags & VERS_OPTIMIZED_UPDATE_FLAG && context &&
|
||||
context->select_lex &&
|
||||
context->select_lex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
((field->table->pos_in_table_list &&
|
||||
field->table->pos_in_table_list->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED) ||
|
||||
(context->select_lex &&
|
||||
context->select_lex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)))
|
||||
{
|
||||
field->force_null= true;
|
||||
push_warning_printf(
|
||||
|
@@ -766,6 +766,8 @@ void LEX::start(THD *thd_arg)
|
||||
frame_bottom_bound= NULL;
|
||||
win_spec= NULL;
|
||||
|
||||
vers_conditions.empty();
|
||||
|
||||
is_lex_started= TRUE;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@@ -1366,6 +1368,19 @@ int MYSQLlex(YYSTYPE *yylval, THD *thd)
|
||||
return FOR_SYM;
|
||||
}
|
||||
break;
|
||||
case QUERY_SYM:
|
||||
token= lex_one_token(yylval, thd);
|
||||
lip->add_digest_token(token, yylval);
|
||||
switch(token) {
|
||||
case FOR_SYM:
|
||||
return QUERY_FOR_SYM;
|
||||
default:
|
||||
lip->lookahead_yylval= lip->yylval;
|
||||
lip->yylval= NULL;
|
||||
lip->lookahead_token= token;
|
||||
return QUERY_SYM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -2920,6 +2920,9 @@ public:
|
||||
Window_frame_bound *frame_bottom_bound;
|
||||
Window_spec *win_spec;
|
||||
|
||||
/* System Versioning */
|
||||
vers_select_conds_t vers_conditions;
|
||||
|
||||
inline void free_set_stmt_mem_root()
|
||||
{
|
||||
DBUG_ASSERT(!is_arena_for_set_stmt());
|
||||
|
@@ -688,13 +688,16 @@ 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)
|
||||
{
|
||||
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query");
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
|
||||
vers_range_type_t query_type= slex->vers_conditions.type;
|
||||
|
||||
if (versioned_tables == 0)
|
||||
{
|
||||
if (query_type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
if (slex->vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
{
|
||||
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`FOR SYSTEM_TIME` query");
|
||||
DBUG_RETURN(-1);
|
||||
@@ -702,30 +705,6 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
if (query_type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
{
|
||||
switch (slex->lock_type)
|
||||
{
|
||||
case TL_WRITE_ALLOW_WRITE:
|
||||
case TL_WRITE_CONCURRENT_INSERT:
|
||||
case TL_WRITE_DELAYED:
|
||||
case TL_WRITE_DEFAULT:
|
||||
case TL_WRITE_LOW_PRIORITY:
|
||||
case TL_WRITE:
|
||||
case TL_WRITE_ONLY:
|
||||
my_error(ER_VERS_WRONG_PARAMS, MYF(0), "FOR SYSTEM_TIME query", "write-locking of historic rows");
|
||||
DBUG_RETURN(-1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (query_type == FOR_SYSTEM_TIME_ALL)
|
||||
{
|
||||
slex->vers_conditions.unwrapped= true;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* For prepared statements we create items on statement arena,
|
||||
because they must outlive execution phase for multiple executions. */
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
@@ -779,6 +758,36 @@ 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;
|
||||
|
||||
if (vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
{
|
||||
switch (slex->lock_type)
|
||||
{
|
||||
case TL_WRITE_ALLOW_WRITE:
|
||||
case TL_WRITE_CONCURRENT_INSERT:
|
||||
case TL_WRITE_DELAYED:
|
||||
case TL_WRITE_DEFAULT:
|
||||
case TL_WRITE_LOW_PRIORITY:
|
||||
case TL_WRITE:
|
||||
case TL_WRITE_ONLY:
|
||||
my_error(ER_VERS_WRONG_PARAMS, MYF(0), "FOR SYSTEM_TIME query", "write-locking of historic rows");
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
DBUG_RETURN(-1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (vers_conditions.type == FOR_SYSTEM_TIME_ALL)
|
||||
{
|
||||
vers_conditions.unwrapped= true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
COND** dst_cond= where_expr;
|
||||
if (table->on_expr)
|
||||
{
|
||||
@@ -798,14 +807,14 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
|
||||
if (table->table->versioned_by_sql())
|
||||
{
|
||||
if (slex->vers_conditions.unit == UNIT_TRX_ID)
|
||||
if (vers_conditions.unit == UNIT_TRX_ID)
|
||||
{
|
||||
my_error(ER_VERS_ENGINE_UNSUPPORTED, MYF(0), table->table_name);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
else if (vers_simple_select && slex->vers_conditions.unit == UNIT_TIMESTAMP
|
||||
&& query_type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
else if (vers_simple_select && vers_conditions.unit == UNIT_TIMESTAMP
|
||||
&& vers_conditions.type != FOR_SYSTEM_TIME_UNSPECIFIED)
|
||||
{
|
||||
DBUG_ASSERT(table->table->s && table->table->s->db_plugin);
|
||||
handlerton *hton= plugin_hton(table->table->s->db_plugin);
|
||||
@@ -826,7 +835,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
Item *cond1= 0, *cond2= 0, *curr= 0;
|
||||
if (table->table->versioned_by_sql() || vers_simple_select)
|
||||
{
|
||||
switch (query_type)
|
||||
switch (vers_conditions.type)
|
||||
{
|
||||
case FOR_SYSTEM_TIME_UNSPECIFIED:
|
||||
if (table->table->versioned_by_sql())
|
||||
@@ -844,21 +853,21 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
break;
|
||||
case FOR_SYSTEM_TIME_AS_OF:
|
||||
cond1= newx Item_func_le(thd, row_start,
|
||||
slex->vers_conditions.start);
|
||||
vers_conditions.start);
|
||||
cond2= newx Item_func_gt(thd, row_end,
|
||||
slex->vers_conditions.start);
|
||||
vers_conditions.start);
|
||||
break;
|
||||
case FOR_SYSTEM_TIME_FROM_TO:
|
||||
cond1= newx Item_func_lt(thd, row_start,
|
||||
slex->vers_conditions.end);
|
||||
vers_conditions.end);
|
||||
cond2= newx Item_func_ge(thd, row_end,
|
||||
slex->vers_conditions.start);
|
||||
vers_conditions.start);
|
||||
break;
|
||||
case FOR_SYSTEM_TIME_BETWEEN:
|
||||
cond1= newx Item_func_le(thd, row_start,
|
||||
slex->vers_conditions.end);
|
||||
vers_conditions.end);
|
||||
cond2= newx Item_func_ge(thd, row_end,
|
||||
slex->vers_conditions.start);
|
||||
vers_conditions.start);
|
||||
break;
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
@@ -872,33 +881,33 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
|
||||
Item *trx_id0, *trx_id1;
|
||||
|
||||
switch (query_type)
|
||||
switch (vers_conditions.type)
|
||||
{
|
||||
case FOR_SYSTEM_TIME_UNSPECIFIED:
|
||||
curr= newx Item_int(thd, ULONGLONG_MAX);
|
||||
cond1= newx Item_func_eq(thd, row_end2, curr);
|
||||
break;
|
||||
case FOR_SYSTEM_TIME_AS_OF:
|
||||
trx_id0= slex->vers_conditions.unit == UNIT_TIMESTAMP ?
|
||||
newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID) :
|
||||
slex->vers_conditions.start;
|
||||
trx_id0= vers_conditions.unit == UNIT_TIMESTAMP ?
|
||||
newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID) :
|
||||
vers_conditions.start;
|
||||
cond1= newx Item_func_vtq_trx_sees_eq(thd, trx_id0, row_start);
|
||||
cond2= newx Item_func_vtq_trx_sees(thd, row_end, trx_id0);
|
||||
break;
|
||||
case FOR_SYSTEM_TIME_FROM_TO:
|
||||
case FOR_SYSTEM_TIME_BETWEEN:
|
||||
if (slex->vers_conditions.unit == UNIT_TIMESTAMP)
|
||||
if (vers_conditions.unit == UNIT_TIMESTAMP)
|
||||
{
|
||||
trx_id0= newx Item_func_vtq_id(thd, slex->vers_conditions.start, VTQ_TRX_ID, true);
|
||||
trx_id1= newx Item_func_vtq_id(thd, slex->vers_conditions.end, VTQ_TRX_ID, false);
|
||||
trx_id0= newx Item_func_vtq_id(thd, vers_conditions.start, VTQ_TRX_ID, true);
|
||||
trx_id1= newx Item_func_vtq_id(thd, vers_conditions.end, VTQ_TRX_ID, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
trx_id0= slex->vers_conditions.start;
|
||||
trx_id1= slex->vers_conditions.end;
|
||||
trx_id0= vers_conditions.start;
|
||||
trx_id1= vers_conditions.end;
|
||||
}
|
||||
|
||||
cond1= query_type == FOR_SYSTEM_TIME_FROM_TO ?
|
||||
cond1= vers_conditions.type == FOR_SYSTEM_TIME_FROM_TO ?
|
||||
newx Item_func_vtq_trx_sees(thd, trx_id1, row_start) :
|
||||
newx Item_func_vtq_trx_sees_eq(thd, trx_id1, row_start);
|
||||
cond2= newx Item_func_vtq_trx_sees_eq(thd, row_end, trx_id0);
|
||||
@@ -925,9 +934,7 @@ int vers_setup_select(THD *thd, TABLE_LIST *tables, COND **where_expr,
|
||||
} // for (table= tables; ...)
|
||||
|
||||
if (arena)
|
||||
{
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
}
|
||||
|
||||
slex->vers_conditions.unwrapped= true;
|
||||
|
||||
@@ -25554,7 +25561,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
|
||||
if (vers_conditions.unwrapped)
|
||||
{
|
||||
// versioning conditions are already unwrapped to WHERE clause
|
||||
str->append(STRING_WITH_LEN(" for system_time all "));
|
||||
str->append(STRING_WITH_LEN(" query for system_time all "));
|
||||
}
|
||||
|
||||
if (order_list.elements)
|
||||
|
@@ -751,6 +751,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
|
||||
|
||||
%}
|
||||
%union {
|
||||
bool BOOL;
|
||||
int num;
|
||||
ulong ulong_num;
|
||||
ulonglong ulonglong_number;
|
||||
@@ -1352,6 +1353,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token PURGE
|
||||
%token QUARTER_SYM
|
||||
%token QUERY_SYM
|
||||
%token QUERY_FOR_SYM /* INTERNAL */
|
||||
%token QUICK
|
||||
%token RAISE_SYM /* Oracle-PLSQL-R */
|
||||
%token RANGE_SYM /* SQL-2003-R */
|
||||
@@ -1970,6 +1972,7 @@ END_OF_INPUT
|
||||
%type <lex_str_list> opt_with_column_list
|
||||
|
||||
%type <vers_range_unit> trans_or_timestamp
|
||||
%type <BOOL> opt_for_system_time_clause
|
||||
|
||||
%%
|
||||
|
||||
@@ -8762,7 +8765,7 @@ table_expression:
|
||||
opt_group_clause
|
||||
opt_having_clause
|
||||
opt_window_clause
|
||||
opt_for_system_time_clause
|
||||
opt_query_for_system_time_clause
|
||||
;
|
||||
|
||||
opt_table_expression:
|
||||
@@ -8808,75 +8811,74 @@ trans_or_timestamp:
|
||||
}
|
||||
;
|
||||
|
||||
opt_for_system_time_clause:
|
||||
opt_query_for_system_time_clause:
|
||||
/* empty */
|
||||
{}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
AS OF_SYM
|
||||
trans_or_timestamp simple_expr
|
||||
| QUERY_FOR_SYM SYSTEM_TIME_SYM for_system_time_expr
|
||||
{
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, $4, $5);
|
||||
DBUG_ASSERT(Select);
|
||||
Select->vers_conditions= Lex->vers_conditions;
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
AS OF_SYM
|
||||
NOW_SYM
|
||||
;
|
||||
|
||||
opt_for_system_time_clause:
|
||||
/* empty */
|
||||
{
|
||||
$$= false;
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM for_system_time_expr
|
||||
{
|
||||
$$= true;
|
||||
}
|
||||
;
|
||||
|
||||
for_system_time_expr:
|
||||
AS OF_SYM trans_or_timestamp simple_expr
|
||||
{
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, $3, $4);
|
||||
}
|
||||
| AS OF_SYM NOW_SYM
|
||||
{
|
||||
Item *item= new (thd->mem_root) Item_func_now_local(thd, 6);
|
||||
if (item == NULL)
|
||||
MYSQL_YYABORT;
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, UNIT_TIMESTAMP, item);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_AS_OF, UNIT_TIMESTAMP, item);
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM ALL
|
||||
| ALL
|
||||
{
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_ALL, UNIT_TIMESTAMP);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_ALL, UNIT_TIMESTAMP);
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
FROM
|
||||
trans_or_timestamp
|
||||
simple_expr
|
||||
TO_SYM
|
||||
trans_or_timestamp
|
||||
simple_expr
|
||||
| FROM trans_or_timestamp simple_expr
|
||||
TO_SYM trans_or_timestamp simple_expr
|
||||
{
|
||||
if ($3 != $6)
|
||||
if ($2 != $5)
|
||||
{
|
||||
Lex->parse_error(ER_VERS_RANGE_UNITS_MISMATCH);
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $3, $4, $7);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $2, $3, $6);
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
trans_or_timestamp
|
||||
FROM
|
||||
simple_expr
|
||||
TO_SYM
|
||||
simple_expr
|
||||
| trans_or_timestamp
|
||||
FROM simple_expr
|
||||
TO_SYM simple_expr
|
||||
{
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $2, $4, $6);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_FROM_TO, $1, $3, $5);
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
BETWEEN_SYM
|
||||
trans_or_timestamp
|
||||
simple_expr
|
||||
AND_SYM
|
||||
trans_or_timestamp
|
||||
simple_expr
|
||||
| BETWEEN_SYM trans_or_timestamp simple_expr
|
||||
AND_SYM trans_or_timestamp simple_expr
|
||||
{
|
||||
if ($3 != $6)
|
||||
if ($2 != $5)
|
||||
{
|
||||
Lex->parse_error(ER_VERS_RANGE_UNITS_MISMATCH);
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $3, $4, $7);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $2, $3, $6);
|
||||
}
|
||||
| FOR_SYSTEM_TIME_SYM
|
||||
trans_or_timestamp
|
||||
BETWEEN_SYM
|
||||
simple_expr
|
||||
AND_SYM
|
||||
simple_expr
|
||||
| trans_or_timestamp
|
||||
BETWEEN_SYM simple_expr
|
||||
AND_SYM simple_expr
|
||||
{
|
||||
Lex->current_select->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $2, $4, $6);
|
||||
Lex->vers_conditions.init(FOR_SYSTEM_TIME_BETWEEN, $1, $3, $5);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -11284,10 +11286,11 @@ table_factor:
|
||||
|
||||
table_primary_ident:
|
||||
{
|
||||
DBUG_ASSERT(Select);
|
||||
SELECT_LEX *sel= Select;
|
||||
sel->table_join_options= 0;
|
||||
}
|
||||
table_ident opt_use_partition opt_table_alias opt_key_definition
|
||||
table_ident opt_use_partition opt_table_alias opt_key_definition opt_for_system_time_clause
|
||||
{
|
||||
if (!($$= Select->add_table_to_list(thd, $2, $4,
|
||||
Select->get_table_join_options(),
|
||||
@@ -11297,6 +11300,8 @@ table_primary_ident:
|
||||
$3)))
|
||||
MYSQL_YYABORT;
|
||||
Select->add_joined_table($$);
|
||||
if ($6)
|
||||
$$->vers_conditions= Lex->vers_conditions;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -13007,6 +13012,8 @@ truncate:
|
||||
lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
|
||||
if (lex->m_sql_cmd == NULL)
|
||||
MYSQL_YYABORT;
|
||||
if ($5)
|
||||
Select->vers_conditions= Lex->vers_conditions;
|
||||
}
|
||||
;
|
||||
|
||||
|
@@ -1856,7 +1856,7 @@ enum vers_range_unit_t
|
||||
UNIT_TRX_ID
|
||||
};
|
||||
|
||||
/** System versioning support. */
|
||||
/** last_leaf_for_name_resolutioning support. */
|
||||
struct vers_select_conds_t
|
||||
{
|
||||
vers_range_type_t type;
|
||||
@@ -2344,6 +2344,9 @@ struct TABLE_LIST
|
||||
TABLE_LIST *first_leaf_for_name_resolution();
|
||||
TABLE_LIST *last_leaf_for_name_resolution();
|
||||
|
||||
/* System Versioning */
|
||||
vers_select_conds_t vers_conditions;
|
||||
|
||||
/**
|
||||
@brief
|
||||
Find the bottom in the chain of embedded table VIEWs.
|
||||
|
Reference in New Issue
Block a user