summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-01-13 23:35:16 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-01-13 23:35:16 +0300
commit4d5ae2b3258d0d4eb3addd61fdabf49d9a6314e7 (patch)
tree5c211278de35118604bb0650b6e775fed2e37724
parentf9f6b190ccea9c266a541ebbc05b1e2352c84d25 (diff)
downloadmariadb-git-4d5ae2b3258d0d4eb3addd61fdabf49d9a6314e7.tar.gz
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.
-rw-r--r--include/my_base.h3
-rw-r--r--include/my_handler_errors.h3
-rw-r--r--mysql-test/suite/versioning/r/partition.result32
-rw-r--r--mysql-test/suite/versioning/t/partition.test34
-rw-r--r--sql/ha_partition.cc8
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/log_event.cc1
-rw-r--r--sql/partition_info.cc18
-rw-r--r--sql/partition_info.h2
-rw-r--r--sql/share/errmsg-utf8.txt4
10 files changed, 94 insertions, 13 deletions
diff --git a/include/my_base.h b/include/my_base.h
index 4c5b00649cc..8f4efec10bd 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -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)
diff --git a/include/my_handler_errors.h b/include/my_handler_errors.h
index 45614ce221a..946e615aa79 100644
--- a/include/my_handler_errors.h
+++ b/include/my_handler_errors.h
@@ -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 */
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
index df45ae4f00e..d903315414d 100644
--- a/mysql-test/suite/versioning/r/partition.result
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -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
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index f415ea131ba..c5531d3c7f6 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -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
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index bd73642cd0d..33204c03cf1 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -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);
@@ -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:
@@ -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);
diff --git a/sql/handler.cc b/sql/handler.cc
index f8702c27a39..871ba3c4149 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -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.
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 947ee3f7707..fed2b14652f 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -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!";
}
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index a8459438be7..163fb9c214d 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -832,8 +832,13 @@ 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);
@@ -841,9 +846,11 @@ void partition_info::vers_set_hist_part(THD *thd)
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;
@@ -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);
@@ -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;
}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 2aed6cbc5db..9b6a934da51 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -421,7 +421,7 @@ public:
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)
{
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 2313b32dad1..55e6051417c 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -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"