mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-27217 DELETE partition selection doesn't work for history partitions
LIMIT history switching requires the number of history partitions to be marked for read: from first to last non-empty plus one empty. The least we can do is to fail with error message if the needed partition was not marked for read. As this is handler interface we require new handler error code to display user-friendly error message. Switching by INTERVAL works out-of-the-box with ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET error.
This commit is contained in:
@ -522,7 +522,8 @@ enum ha_base_keytype {
|
|||||||
#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */
|
#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */
|
||||||
#define HA_ERR_SEQUENCE_INVALID_DATA 195
|
#define HA_ERR_SEQUENCE_INVALID_DATA 195
|
||||||
#define HA_ERR_SEQUENCE_RUN_OUT 196
|
#define HA_ERR_SEQUENCE_RUN_OUT 196
|
||||||
#define HA_ERR_LAST 196 /* Copy of last error nr * */
|
#define HA_ERR_PARTITION_LIST 197
|
||||||
|
#define HA_ERR_LAST 197 /* Copy of last error nr * */
|
||||||
|
|
||||||
/* Number of different errors */
|
/* Number of different errors */
|
||||||
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
|
||||||
|
@ -107,7 +107,8 @@ static const char *handler_error_messages[]=
|
|||||||
"Foreign key cascade delete/update exceeds max depth",
|
"Foreign key cascade delete/update exceeds max depth",
|
||||||
"Tablespace is missing for a table",
|
"Tablespace is missing for a table",
|
||||||
"Sequence has been run out",
|
"Sequence has been run out",
|
||||||
"Sequence values are conflicting"
|
"Sequence values are conflicting",
|
||||||
|
"Cannot select partitions"
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
|
#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
|
||||||
|
@ -767,4 +767,36 @@ alter table t1 add x serial;
|
|||||||
alter table t1 add partition (partition p1 history);
|
alter table t1 add partition (partition p1 history);
|
||||||
alter table t1 add partition (partition p2 history);
|
alter table t1 add partition (partition p2 history);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-27217 DELETE partition selection doesn't work for history partitions
|
||||||
|
#
|
||||||
|
create table t1 (f char) with system versioning
|
||||||
|
partition by system_time limit 10 (
|
||||||
|
partition p0 history,
|
||||||
|
partition p1 history,
|
||||||
|
partition p2 history,
|
||||||
|
partition pn current);
|
||||||
|
delete from t1 partition (p1);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
delete from t1 partition (p0, pn);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
delete from t1 partition (p0, p1);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
delete from t1 partition (p0, p1, pn);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
drop table t1;
|
||||||
|
set timestamp=unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
create or replace table t1 (i int) with system versioning
|
||||||
|
partition by system_time interval 1 day (
|
||||||
|
partition p0 history,
|
||||||
|
partition p1 history,
|
||||||
|
partition pn current);
|
||||||
|
set timestamp=unix_timestamp('2000-01-02 00:00:00');
|
||||||
|
insert t1 values (1);
|
||||||
|
delete from t1 partition (p0, pn);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
delete from t1 partition (p0, p1, pn);
|
||||||
|
ERROR HY000: Not allowed for system-versioned table `test`.`t1`
|
||||||
|
drop table t1;
|
||||||
|
set timestamp= default;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
|
@ -748,6 +748,40 @@ alter table t1 add partition (partition p1 history);
|
|||||||
alter table t1 add partition (partition p2 history);
|
alter table t1 add partition (partition p2 history);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-27217 DELETE partition selection doesn't work for history partitions
|
||||||
|
--echo #
|
||||||
|
create table t1 (f char) with system versioning
|
||||||
|
partition by system_time limit 10 (
|
||||||
|
partition p0 history,
|
||||||
|
partition p1 history,
|
||||||
|
partition p2 history,
|
||||||
|
partition pn current);
|
||||||
|
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p1);
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p0, pn);
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p0, p1);
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p0, p1, pn);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
set timestamp=unix_timestamp('2000-01-01 00:00:00');
|
||||||
|
create or replace table t1 (i int) with system versioning
|
||||||
|
partition by system_time interval 1 day (
|
||||||
|
partition p0 history,
|
||||||
|
partition p1 history,
|
||||||
|
partition pn current);
|
||||||
|
set timestamp=unix_timestamp('2000-01-02 00:00:00');
|
||||||
|
insert t1 values (1);
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p0, pn);
|
||||||
|
--error ER_VERS_NOT_ALLOWED
|
||||||
|
delete from t1 partition (p0, p1, pn);
|
||||||
|
drop table t1;
|
||||||
|
set timestamp= default;
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@ -3943,8 +3943,9 @@ int ha_partition::external_lock(THD *thd, int lock_type)
|
|||||||
These commands may be excluded because working history partition is needed
|
These commands may be excluded because working history partition is needed
|
||||||
only for versioned DML. */
|
only for versioned DML. */
|
||||||
thd->lex->sql_command != SQLCOM_SELECT &&
|
thd->lex->sql_command != SQLCOM_SELECT &&
|
||||||
thd->lex->sql_command != SQLCOM_INSERT_SELECT)
|
thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
|
||||||
m_part_info->vers_set_hist_part(thd);
|
(error= m_part_info->vers_set_hist_part(thd)))
|
||||||
|
goto err_handler;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
@ -4085,6 +4086,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
/* Add partition to be called in reset(). */
|
/* Add partition to be called in reset(). */
|
||||||
bitmap_set_bit(&m_partitions_to_reset, i);
|
bitmap_set_bit(&m_partitions_to_reset, i);
|
||||||
}
|
}
|
||||||
|
// FIXME: check error?
|
||||||
switch (lock_type)
|
switch (lock_type)
|
||||||
{
|
{
|
||||||
case TL_WRITE_ALLOW_WRITE:
|
case TL_WRITE_ALLOW_WRITE:
|
||||||
@ -4100,7 +4102,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
|
|||||||
// TODO: MDEV-20345 (see above)
|
// TODO: MDEV-20345 (see above)
|
||||||
thd->lex->sql_command != SQLCOM_SELECT &&
|
thd->lex->sql_command != SQLCOM_SELECT &&
|
||||||
thd->lex->sql_command != SQLCOM_INSERT_SELECT)
|
thd->lex->sql_command != SQLCOM_INSERT_SELECT)
|
||||||
m_part_info->vers_set_hist_part(thd);
|
error= m_part_info->vers_set_hist_part(thd);
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
|
@ -3977,6 +3977,8 @@ void handler::print_error(int error, myf errflag)
|
|||||||
case HA_ERR_TABLE_IN_FK_CHECK:
|
case HA_ERR_TABLE_IN_FK_CHECK:
|
||||||
textno= ER_TABLE_IN_FK_CHECK;
|
textno= ER_TABLE_IN_FK_CHECK;
|
||||||
break;
|
break;
|
||||||
|
case HA_ERR_PARTITION_LIST:
|
||||||
|
my_error(ER_VERS_NOT_ALLOWED, errflag, table->s->db.str, table->s->table_name.str);
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* The error was "unknown" to this function.
|
/* The error was "unknown" to this function.
|
||||||
|
@ -174,6 +174,7 @@ static const char *HA_ERR(int i)
|
|||||||
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
|
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
|
||||||
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
|
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
|
||||||
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
|
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
|
||||||
|
case HA_ERR_PARTITION_LIST : return "HA_ERR_PARTITION_LIST";
|
||||||
}
|
}
|
||||||
return "No Error!";
|
return "No Error!";
|
||||||
}
|
}
|
||||||
|
@ -832,8 +832,13 @@ bool partition_info::has_unique_name(partition_element *element)
|
|||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void partition_info::vers_set_hist_part(THD *thd)
|
int partition_info::vers_set_hist_part(THD *thd)
|
||||||
{
|
{
|
||||||
|
if (table->pos_in_table_list &&
|
||||||
|
table->pos_in_table_list->partition_names)
|
||||||
|
{
|
||||||
|
return HA_ERR_PARTITION_LIST;
|
||||||
|
}
|
||||||
if (vers_info->limit)
|
if (vers_info->limit)
|
||||||
{
|
{
|
||||||
ha_partition *hp= (ha_partition*)(table->file);
|
ha_partition *hp= (ha_partition*)(table->file);
|
||||||
@ -841,9 +846,11 @@ void partition_info::vers_set_hist_part(THD *thd)
|
|||||||
List_iterator<partition_element> it(partitions);
|
List_iterator<partition_element> it(partitions);
|
||||||
while (next != vers_info->hist_part)
|
while (next != vers_info->hist_part)
|
||||||
next= it++;
|
next= it++;
|
||||||
|
DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
|
||||||
ha_rows records= hp->part_records(next);
|
ha_rows records= hp->part_records(next);
|
||||||
while ((next= it++) != vers_info->now_part)
|
while ((next= it++) != vers_info->now_part)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
|
||||||
ha_rows next_records= hp->part_records(next);
|
ha_rows next_records= hp->part_records(next);
|
||||||
if (next_records == 0)
|
if (next_records == 0)
|
||||||
break;
|
break;
|
||||||
@ -856,13 +863,13 @@ void partition_info::vers_set_hist_part(THD *thd)
|
|||||||
goto warn;
|
goto warn;
|
||||||
vers_info->hist_part= next;
|
vers_info->hist_part= next;
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vers_info->interval.is_set())
|
if (vers_info->interval.is_set())
|
||||||
{
|
{
|
||||||
if (vers_info->hist_part->range_value > thd->query_start())
|
if (vers_info->hist_part->range_value > thd->query_start())
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
partition_element *next= NULL;
|
partition_element *next= NULL;
|
||||||
List_iterator<partition_element> it(partitions);
|
List_iterator<partition_element> it(partitions);
|
||||||
@ -873,14 +880,15 @@ void partition_info::vers_set_hist_part(THD *thd)
|
|||||||
{
|
{
|
||||||
vers_info->hist_part= next;
|
vers_info->hist_part= next;
|
||||||
if (next->range_value > thd->query_start())
|
if (next->range_value > thd->query_start())
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
warn:
|
warn:
|
||||||
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
|
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
|
||||||
table->s->db.str, table->s->table_name.str,
|
table->s->db.str, table->s->table_name.str,
|
||||||
vers_info->hist_part->partition_name);
|
vers_info->hist_part->partition_name);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ public:
|
|||||||
vers_info->limit= limit;
|
vers_info->limit= limit;
|
||||||
return !limit;
|
return !limit;
|
||||||
}
|
}
|
||||||
void vers_set_hist_part(THD *thd);
|
int vers_set_hist_part(THD *thd);
|
||||||
bool vers_setup_expression(THD *thd, uint32 alter_add= 0); /* Stage 1. */
|
bool vers_setup_expression(THD *thd, uint32 alter_add= 0); /* Stage 1. */
|
||||||
partition_element *get_partition(uint part_id)
|
partition_element *get_partition(uint part_id)
|
||||||
{
|
{
|
||||||
|
@ -6640,8 +6640,8 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
|
|||||||
ER_TABLE_IN_FK_CHECK
|
ER_TABLE_IN_FK_CHECK
|
||||||
eng "Table is being used in foreign key check"
|
eng "Table is being used in foreign key check"
|
||||||
|
|
||||||
ER_UNUSED_1
|
ER_VERS_NOT_ALLOWED
|
||||||
eng "You should never see it"
|
eng "Not allowed for system-versioned table %`s.%`s"
|
||||||
|
|
||||||
ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
|
ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
|
||||||
eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe"
|
eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe"
|
||||||
|
Reference in New Issue
Block a user