1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-18727 improve DML operation of System Versioning

MDEV-18957 UPDATE with LIMIT clause is wrong for versioned partitioned tables

UPDATE, DELETE: replace linear search of current/historical records
with vers_setup_conds().

Additional DML cases in view.test
This commit is contained in:
Aleksey Midenkov
2019-11-22 14:29:03 +03:00
parent a14544260c
commit 0076dce2c8
19 changed files with 271 additions and 87 deletions

View File

@ -677,6 +677,7 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
{
vers_asof_timestamp_t &in= thd->variables.vers_asof_timestamp;
type= (vers_system_time_t) in.type;
delete_history= false;
start.unit= VERS_TIMESTAMP;
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
{
@ -709,6 +710,7 @@ void vers_select_conds_t::print(String *str, enum_query_type query_type) const
end.print(str, query_type, STRING_WITH_LEN(" AND "));
break;
case SYSTEM_TIME_BEFORE:
case SYSTEM_TIME_HISTORY:
DBUG_ASSERT(0);
break;
case SYSTEM_TIME_ALL:
@ -776,9 +778,22 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
}
bool is_select= false;
switch (thd->lex->sql_command)
{
case SQLCOM_SELECT:
case SQLCOM_INSERT_SELECT:
case SQLCOM_REPLACE_SELECT:
case SQLCOM_DELETE_MULTI:
case SQLCOM_UPDATE_MULTI:
is_select= true;
default:
break;
}
for (table= tables; table; table= table->next_local)
{
if (!table->table || !table->table->versioned())
if (!table->table || table->is_view() || !table->table->versioned())
continue;
vers_select_conds_t &vers_conditions= table->vers_conditions;
@ -808,7 +823,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
}
// propagate system_time from sysvar
if (!vers_conditions.is_set())
if (!vers_conditions.is_set() && is_select)
{
if (vers_conditions.init_from_sysvar(thd))
DBUG_RETURN(-1);
@ -834,7 +849,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
bool timestamps_only= table->table->versioned(VERS_TIMESTAMP);
if (vers_conditions.is_set())
if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY)
{
thd->where= "FOR SYSTEM_TIME";
/* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires
@ -861,10 +876,14 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
switch (vers_conditions.type)
{
case SYSTEM_TIME_UNSPECIFIED:
case SYSTEM_TIME_HISTORY:
thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE);
max_time.second_part= TIME_MAX_SECOND_PART;
curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS);
cond1= newx Item_func_eq(thd, row_end, curr);
if (vers_conditions.type == SYSTEM_TIME_UNSPECIFIED)
cond1= newx Item_func_eq(thd, row_end, curr);
else
cond1= newx Item_func_lt(thd, row_end, curr);
break;
case SYSTEM_TIME_AS_OF:
cond1= newx Item_func_le(thd, row_start, point_in_time1);
@ -896,8 +915,12 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
switch (vers_conditions.type)
{
case SYSTEM_TIME_UNSPECIFIED:
case SYSTEM_TIME_HISTORY:
curr= newx Item_int(thd, ULONGLONG_MAX);
cond1= newx Item_func_eq(thd, row_end, curr);
if (vers_conditions.type == SYSTEM_TIME_UNSPECIFIED)
cond1= newx Item_func_eq(thd, row_end, curr);
else
cond1= newx Item_func_lt(thd, row_end, curr);
break;
case SYSTEM_TIME_AS_OF:
trx_id0= vers_conditions.start.unit == VERS_TIMESTAMP
@ -938,7 +961,19 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
{
cond1= and_items(thd, cond2, cond1);
cond1= and_items(thd, cond3, cond1);
table->on_expr= and_items(thd, table->on_expr, cond1);
if (is_select)
table->on_expr= and_items(thd, table->on_expr, cond1);
else
{
if (join)
{
where= and_items(thd, join->conds, cond1);
join->conds= where;
}
else
where= and_items(thd, where, cond1);
table->where= and_items(thd, table->where, cond1);
}
}
table->vers_conditions.type= SYSTEM_TIME_ALL;