Skip to content

Commit

Permalink
MDEV-27217 DELETE partition selection doesn't work for history partit…
Browse files Browse the repository at this point in the history
…ions

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.
  • Loading branch information
midenok committed Jan 13, 2022
1 parent f9f6b19 commit 4d5ae2b
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 13 deletions.
3 changes: 2 additions & 1 deletion include/my_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,8 @@ enum ha_base_keytype {
#define HA_ERR_TABLESPACE_MISSING 194 /* Missing Tablespace */
#define HA_ERR_SEQUENCE_INVALID_DATA 195
#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 */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
Expand Down
3 changes: 2 additions & 1 deletion include/my_handler_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ static const char *handler_error_messages[]=
"Foreign key cascade delete/update exceeds max depth",
"Tablespace is missing for a table",
"Sequence has been run out",
"Sequence values are conflicting"
"Sequence values are conflicting",
"Cannot select partitions"
};

#endif /* MYSYS_MY_HANDLER_ERRORS_INCLUDED */
32 changes: 32 additions & 0 deletions mysql-test/suite/versioning/r/partition.result
Original file line number Diff line number Diff line change
Expand Up @@ -767,4 +767,36 @@ alter table t1 add x serial;
alter table t1 add partition (partition p1 history);
alter table t1 add partition (partition p2 history);
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
34 changes: 34 additions & 0 deletions mysql-test/suite/versioning/t/partition.test
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,40 @@ alter table t1 add partition (partition p1 history);
alter table t1 add partition (partition p2 history);
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

--source suite/versioning/common_finish.inc
8 changes: 5 additions & 3 deletions sql/ha_partition.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
only for versioned DML. */
thd->lex->sql_command != SQLCOM_SELECT &&
thd->lex->sql_command != SQLCOM_INSERT_SELECT)
m_part_info->vers_set_hist_part(thd);
thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
(error= m_part_info->vers_set_hist_part(thd)))
goto err_handler;
}
DBUG_RETURN(0);

Expand Down Expand Up @@ -4085,6 +4086,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
/* Add partition to be called in reset(). */
bitmap_set_bit(&m_partitions_to_reset, i);
}
// FIXME: check error?
switch (lock_type)
{
case TL_WRITE_ALLOW_WRITE:
Expand All @@ -4100,7 +4102,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
// TODO: MDEV-20345 (see above)
thd->lex->sql_command != SQLCOM_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:;
}
DBUG_RETURN(error);
Expand Down
2 changes: 2 additions & 0 deletions sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3977,6 +3977,8 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_TABLE_IN_FK_CHECK:
textno= ER_TABLE_IN_FK_CHECK;
break;
case HA_ERR_PARTITION_LIST:
my_error(ER_VERS_NOT_ALLOWED, errflag, table->s->db.str, table->s->table_name.str);
default:
{
/* The error was "unknown" to this function.
Expand Down
1 change: 1 addition & 0 deletions sql/log_event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ static const char *HA_ERR(int i)
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
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_PARTITION_LIST : return "HA_ERR_PARTITION_LIST";
}
return "No Error!";
}
Expand Down
18 changes: 13 additions & 5 deletions sql/partition_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -832,18 +832,25 @@ bool partition_info::has_unique_name(partition_element *element)
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)
{
ha_partition *hp= (ha_partition*)(table->file);
partition_element *next= NULL;
List_iterator<partition_element> it(partitions);
while (next != vers_info->hist_part)
next= it++;
DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
ha_rows records= hp->part_records(next);
while ((next= it++) != vers_info->now_part)
{
DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
ha_rows next_records= hp->part_records(next);
if (next_records == 0)
break;
Expand All @@ -856,13 +863,13 @@ void partition_info::vers_set_hist_part(THD *thd)
goto warn;
vers_info->hist_part= next;
}
return;
return 0;
}

if (vers_info->interval.is_set())
{
if (vers_info->hist_part->range_value > thd->query_start())
return;
return 0;

partition_element *next= NULL;
List_iterator<partition_element> it(partitions);
Expand All @@ -873,14 +880,15 @@ void partition_info::vers_set_hist_part(THD *thd)
{
vers_info->hist_part= next;
if (next->range_value > thd->query_start())
return;
return 0;
}
}
return;
return 0;
warn:
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
table->s->db.str, table->s->table_name.str,
vers_info->hist_part->partition_name);
return 0;
}


Expand Down
2 changes: 1 addition & 1 deletion sql/partition_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ class partition_info : public Sql_alloc
vers_info->limit= 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. */
partition_element *get_partition(uint part_id)
{
Expand Down
4 changes: 2 additions & 2 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6640,8 +6640,8 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
ER_TABLE_IN_FK_CHECK
eng "Table is being used in foreign key check"

ER_UNUSED_1
eng "You should never see it"
ER_VERS_NOT_ALLOWED
eng "Not allowed for system-versioned table %`s.%`s"

ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe"
Expand Down

0 comments on commit 4d5ae2b

Please sign in to comment.