From 9962acb15110d997cfed9971871a26242c0773e8 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 29 May 2026 13:19:50 +1000 Subject: [PATCH 1/3] MDEV-39789 Fix compiling without perfschema --- extra/mariadb_migrate_config_file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extra/mariadb_migrate_config_file.c b/extra/mariadb_migrate_config_file.c index a69e8fdfa4196..f24c1e5ee859b 100644 --- a/extra/mariadb_migrate_config_file.c +++ b/extra/mariadb_migrate_config_file.c @@ -135,7 +135,9 @@ static size_t global_copied_lines=0, global_unsupported_lines= 0; static size_t global_mariadbd_additions= 0; static PSI_memory_key key_memory_upgrade_config; +#ifdef HAVE_PSI_FILE_INTERFACE static PSI_file_key key_file_cnf; +#endif static size_t global_update_count= 0; static my_bool give_error_for_missing_files= 0; static my_bool opt_mariadbd_testing; From 5a0b74a31c146969b1012082d62fb3efc4edf5a2 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 25 May 2026 14:16:21 +1000 Subject: [PATCH 2/3] MDEV-15621 [refactor] Partitioning cleanup change p_column_list_val::fixed to a bool remove redundant end label in partition_info::fix_column_value_functions --- sql/partition_element.h | 2 +- sql/partition_info.cc | 19 +++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/sql/partition_element.h b/sql/partition_element.h index 795a7a1d56fb2..205df4344b7bf 100644 --- a/sql/partition_element.h +++ b/sql/partition_element.h @@ -69,7 +69,7 @@ typedef struct p_column_list_val uint partition_id; bool max_value; // MAXVALUE for RANGE type or DEFAULT value for LIST type bool null_value; - char fixed; + bool fixed; } part_column_list_val; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 7666997dc5eca..a6320dc489dd9 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -2166,7 +2166,7 @@ int partition_info::fix_partition_values(THD *thd, } part_elem->range_value= val->value; } - col_val->fixed= 2; + col_val->fixed= TRUE; DBUG_RETURN(FALSE); } @@ -2219,12 +2219,11 @@ bool partition_info::fix_column_value_functions(THD *thd, uint part_id) { uint n_columns= part_field_list.elements; - bool result= FALSE; uint i; part_column_list_val *col_val= val->col_val_array; DBUG_ENTER("partition_info::fix_column_value_functions"); - if (col_val->fixed > 1) + if (col_val->fixed) { DBUG_RETURN(FALSE); } @@ -2247,8 +2246,7 @@ bool partition_info::fix_column_value_functions(THD *thd, if (!(column_item= get_column_item(column_item, field))) { - result= TRUE; - goto end; + DBUG_RETURN(TRUE); } Sql_mode_instant_set sms(thd, 0); save_got_warning= thd->got_warning; @@ -2257,22 +2255,19 @@ bool partition_info::fix_column_value_functions(THD *thd, thd->got_warning) { my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0)); - result= TRUE; - goto end; + DBUG_RETURN(TRUE); } thd->got_warning= save_got_warning; if (!(val_ptr= (uchar*) thd->memdup(field->ptr, len))) { - result= TRUE; - goto end; + DBUG_RETURN(TRUE); } col_val->column_value= val_ptr; } } - col_val->fixed= 2; + col_val->fixed= TRUE; } -end: - DBUG_RETURN(result); + DBUG_RETURN(FALSE); } From d11539dc5b41daa58342d901dd4a91576a048f16 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 29 May 2026 18:11:23 +1000 Subject: [PATCH 3/3] MDEV-15621 Auto add RANGE COLUMNS partitions by interval Allow auto partitioning by interval in PARTITION BY RANGE COLUMNS PARTITION BY RANGE COLUMNS (col_name) INTERVAL interval [AUTO] ( PARTITION partition_name VALUES LESS THAN (value) [, PARTITION partition_name VALUES LESS THAN (value) ... ] ) where - col_name is the name of one column of type DATE or DATETIME or TIMESTAMP - at least one partition is supplied, and the highest partition cannot have MAXVALUE range - INTERVAL interval is a positive time interval. it can be mariadb format or oracle NUMTODSINTERVAL/NUMTOYMINTERVAL format. Like versioning, the smallest unit is second, i.e. no subsecond like microsecond. - DATE column cannot have interval with values less than a day When performing DML on such a table, it will first add partitions by the specified interval until the partition covers the current time. Partition addition will not cause an implicit commit like DDL normally does. The partitions are named pN. Otherwise the table behaves exactly the same as a normal RANGE COLUMNS partitioned table. Note that TIMESTAMP is not allowed as a type for PARTITION BY RANGE COLUMNS otherwise. --- .../main/partition_range_interval.result | 1711 +++++++++++++++++ mysql-test/main/partition_range_interval.test | 588 ++++++ sql/lex.h | 2 + sql/partition_info.cc | 221 ++- sql/partition_info.h | 33 +- sql/share/errmsg-utf8.txt | 6 + sql/sql_base.cc | 118 +- sql/sql_base.h | 4 +- sql/sql_partition.cc | 174 +- sql/sql_yacc.yy | 60 +- sql/table.h | 2 + 11 files changed, 2902 insertions(+), 17 deletions(-) create mode 100644 mysql-test/main/partition_range_interval.result create mode 100644 mysql-test/main/partition_range_interval.test diff --git a/mysql-test/main/partition_range_interval.result b/mysql-test/main/partition_range_interval.result new file mode 100644 index 0000000000000..e13dfa766557d --- /dev/null +++ b/mysql-test/main/partition_range_interval.result @@ -0,0 +1,1711 @@ +# simple case with DATETIME column showing partitions added in INSERT +set timestamp= unix_timestamp('2026-05-02 00:00:00'); +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-21 00:00:00') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-22 00:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-23 00:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-24 00:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-25 00:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-26 00:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-27 00:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-20' 0 +p1 RANGE COLUMNS `c` '2026-04-21 00:00:00' 0 +p2 RANGE COLUMNS `c` '2026-04-22 00:00:00' 0 +p3 RANGE COLUMNS `c` '2026-04-23 00:00:00' 0 +p4 RANGE COLUMNS `c` '2026-04-24 00:00:00' 0 +p5 RANGE COLUMNS `c` '2026-04-25 00:00:00' 0 +p6 RANGE COLUMNS `c` '2026-04-26 00:00:00' 0 +p7 RANGE COLUMNS `c` '2026-04-27 00:00:00' 0 +p8 RANGE COLUMNS `c` '2026-04-28 00:00:00' 0 +p9 RANGE COLUMNS `c` '2026-04-29 00:00:00' 0 +p10 RANGE COLUMNS `c` '2026-04-30 00:00:00' 0 +p11 RANGE COLUMNS `c` '2026-05-01 00:00:00' 0 +p12 RANGE COLUMNS `c` '2026-05-02 00:00:00' 1 +p13 RANGE COLUMNS `c` '2026-05-03 00:00:00' 0 +set timestamp= unix_timestamp('2026-05-06 00:00:00'); +insert into t1 values ('2026-05-04'); +select * from t1; +c +2026-05-01 00:00:00 +2026-05-04 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-21 00:00:00') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-22 00:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-23 00:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-24 00:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-25 00:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-26 00:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-27 00:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-04 00:00:00') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05 00:00:00') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-20' 0 +p1 RANGE COLUMNS `c` '2026-04-21 00:00:00' 0 +p2 RANGE COLUMNS `c` '2026-04-22 00:00:00' 0 +p3 RANGE COLUMNS `c` '2026-04-23 00:00:00' 0 +p4 RANGE COLUMNS `c` '2026-04-24 00:00:00' 0 +p5 RANGE COLUMNS `c` '2026-04-25 00:00:00' 0 +p6 RANGE COLUMNS `c` '2026-04-26 00:00:00' 0 +p7 RANGE COLUMNS `c` '2026-04-27 00:00:00' 0 +p8 RANGE COLUMNS `c` '2026-04-28 00:00:00' 0 +p9 RANGE COLUMNS `c` '2026-04-29 00:00:00' 0 +p10 RANGE COLUMNS `c` '2026-04-30 00:00:00' 0 +p11 RANGE COLUMNS `c` '2026-05-01 00:00:00' 0 +p12 RANGE COLUMNS `c` '2026-05-02 00:00:00' 1 +p13 RANGE COLUMNS `c` '2026-05-03 00:00:00' 0 +p14 RANGE COLUMNS `c` '2026-05-04 00:00:00' 0 +p15 RANGE COLUMNS `c` '2026-05-05 00:00:00' 1 +p16 RANGE COLUMNS `c` '2026-05-06 00:00:00' 0 +p17 RANGE COLUMNS `c` '2026-05-07 00:00:00' 0 +drop table t1; +# simple case with DATE column +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 DAY AUTO +( +PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-30' 0 +p1 RANGE COLUMNS `c` '2026-05-01' 0 +p2 RANGE COLUMNS `c` '2026-05-02' 1 +p3 RANGE COLUMNS `c` '2026-05-03' 0 +p4 RANGE COLUMNS `c` '2026-05-04' 0 +p5 RANGE COLUMNS `c` '2026-05-05' 0 +p6 RANGE COLUMNS `c` '2026-05-06' 0 +p7 RANGE COLUMNS `c` '2026-05-07' 0 +drop table t1; +# oracle interval syntax +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTODSINTERVAL(1, 'DAY')) +( +PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-30' 0 +p1 RANGE COLUMNS `c` '2026-05-01' 0 +p2 RANGE COLUMNS `c` '2026-05-02' 1 +p3 RANGE COLUMNS `c` '2026-05-03' 0 +p4 RANGE COLUMNS `c` '2026-05-04' 0 +p5 RANGE COLUMNS `c` '2026-05-05' 0 +p6 RANGE COLUMNS `c` '2026-05-06' 0 +p7 RANGE COLUMNS `c` '2026-05-07' 0 +drop table t1; +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) +( +PARTITION p0 VALUES LESS THAN ('2025-04-30') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 MONTH +(PARTITION `p0` VALUES LESS THAN ('2025-04-30') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 MONTH +(PARTITION `p0` VALUES LESS THAN ('2025-04-30') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2025-05-30') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2025-06-30') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2025-07-30') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2025-08-30') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2025-09-30') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2025-10-30') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2025-11-30') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2025-12-30') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-01-30') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-02-28') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-03-28') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-28') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2025-04-30' 0 +p1 RANGE COLUMNS `c` '2025-05-30' 0 +p2 RANGE COLUMNS `c` '2025-06-30' 0 +p3 RANGE COLUMNS `c` '2025-07-30' 0 +p4 RANGE COLUMNS `c` '2025-08-30' 0 +p5 RANGE COLUMNS `c` '2025-09-30' 0 +p6 RANGE COLUMNS `c` '2025-10-30' 0 +p7 RANGE COLUMNS `c` '2025-11-30' 0 +p8 RANGE COLUMNS `c` '2025-12-30' 0 +p9 RANGE COLUMNS `c` '2026-01-30' 0 +p10 RANGE COLUMNS `c` '2026-02-28' 0 +p11 RANGE COLUMNS `c` '2026-03-28' 0 +p12 RANGE COLUMNS `c` '2026-04-28' 0 +p13 RANGE COLUMNS `c` '2026-05-28' 1 +drop table t1; +## NUMTODSINTERVAL takes only DAY, HOUR, MINUTE or SECOND +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTODSINTERVAL(1, 'YEAR')) +( +PARTITION p0 VALUES LESS THAN ('2024-04-30') +); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +## NUMTOYMINTERVAL takes only YEAR or MONTH +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTOYMINTERVAL(1, 'HOUR')) +( +PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +# 1.5 day interval truncated to +1d, +2d, +1d, +2d, ... +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 36 Hour +( +PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 36 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 36 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-30' 0 +p1 RANGE COLUMNS `c` '2026-05-01' 0 +p2 RANGE COLUMNS `c` '2026-05-03' 1 +p3 RANGE COLUMNS `c` '2026-05-04' 0 +p4 RANGE COLUMNS `c` '2026-05-06' 0 +p5 RANGE COLUMNS `c` '2026-05-07' 0 +drop table t1; +# DATE column with 1 week interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Week +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 7 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 7 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-11') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-20' 0 +p1 RANGE COLUMNS `c` '2026-04-27' 0 +p2 RANGE COLUMNS `c` '2026-05-04' 1 +p3 RANGE COLUMNS `c` '2026-05-11' 0 +drop table t1; +# DATETIME column with 1 hour interval +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( +PARTITION p0 VALUES LESS THAN ('2026-05-05') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB) +insert into t1 values ('2026-05-05 03:00:00'); +select * from t1; +c +2026-05-05 03:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-05 01:00:00') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-05 02:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-05 03:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-05 04:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-05 05:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-05 06:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-05 07:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-05 08:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-05 09:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-05 10:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-05 11:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-05 12:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-05 13:00:00') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-05 14:00:00') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05 15:00:00') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-05 16:00:00') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-05 17:00:00') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-05-05 18:00:00') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-05-05 19:00:00') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-05-05 20:00:00') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-05-05 21:00:00') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-05-05 22:00:00') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-05-05 23:00:00') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-05-06 01:00:00') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-05-05' 0 +p1 RANGE COLUMNS `c` '2026-05-05 01:00:00' 0 +p2 RANGE COLUMNS `c` '2026-05-05 02:00:00' 0 +p3 RANGE COLUMNS `c` '2026-05-05 03:00:00' 0 +p4 RANGE COLUMNS `c` '2026-05-05 04:00:00' 1 +p5 RANGE COLUMNS `c` '2026-05-05 05:00:00' 0 +p6 RANGE COLUMNS `c` '2026-05-05 06:00:00' 0 +p7 RANGE COLUMNS `c` '2026-05-05 07:00:00' 0 +p8 RANGE COLUMNS `c` '2026-05-05 08:00:00' 0 +p9 RANGE COLUMNS `c` '2026-05-05 09:00:00' 0 +p10 RANGE COLUMNS `c` '2026-05-05 10:00:00' 0 +p11 RANGE COLUMNS `c` '2026-05-05 11:00:00' 0 +p12 RANGE COLUMNS `c` '2026-05-05 12:00:00' 0 +p13 RANGE COLUMNS `c` '2026-05-05 13:00:00' 0 +p14 RANGE COLUMNS `c` '2026-05-05 14:00:00' 0 +p15 RANGE COLUMNS `c` '2026-05-05 15:00:00' 0 +p16 RANGE COLUMNS `c` '2026-05-05 16:00:00' 0 +p17 RANGE COLUMNS `c` '2026-05-05 17:00:00' 0 +p18 RANGE COLUMNS `c` '2026-05-05 18:00:00' 0 +p19 RANGE COLUMNS `c` '2026-05-05 19:00:00' 0 +p20 RANGE COLUMNS `c` '2026-05-05 20:00:00' 0 +p21 RANGE COLUMNS `c` '2026-05-05 21:00:00' 0 +p22 RANGE COLUMNS `c` '2026-05-05 22:00:00' 0 +p23 RANGE COLUMNS `c` '2026-05-05 23:00:00' 0 +p24 RANGE COLUMNS `c` '2026-05-06 00:00:00' 0 +p25 RANGE COLUMNS `c` '2026-05-06 01:00:00' 0 +drop table t1; +# DATETIME column with some decimal points in partition range value +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( +PARTITION p0 VALUES LESS THAN ('2026-05-05 01:23:45.6789') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-05 01:23:45.6789') ENGINE = InnoDB) +insert into t1 values ('2026-05-05 03:00:00'); +select * from t1; +c +2026-05-05 03:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-05 01:23:45.6789') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-05 02:23:45.6789') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-05 03:23:45.6789') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-05 04:23:45.6789') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-05 05:23:45.6789') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-05 06:23:45.6789') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-05 07:23:45.6789') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-05 08:23:45.6789') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-05 09:23:45.6789') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-05 10:23:45.6789') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-05 11:23:45.6789') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-05 12:23:45.6789') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-05 13:23:45.6789') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-05 14:23:45.6789') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-05 15:23:45.6789') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05 16:23:45.6789') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-05 17:23:45.6789') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-05 18:23:45.6789') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-05-05 19:23:45.6789') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-05-05 20:23:45.6789') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-05-05 21:23:45.6789') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-05-05 22:23:45.6789') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-05-05 23:23:45.6789') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-05-06 00:23:45.6789') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-05-05 01:23:45.6789' 0 +p1 RANGE COLUMNS `c` '2026-05-05 02:23:45.6789' 0 +p2 RANGE COLUMNS `c` '2026-05-05 03:23:45.6789' 1 +p3 RANGE COLUMNS `c` '2026-05-05 04:23:45.6789' 0 +p4 RANGE COLUMNS `c` '2026-05-05 05:23:45.6789' 0 +p5 RANGE COLUMNS `c` '2026-05-05 06:23:45.6789' 0 +p6 RANGE COLUMNS `c` '2026-05-05 07:23:45.6789' 0 +p7 RANGE COLUMNS `c` '2026-05-05 08:23:45.6789' 0 +p8 RANGE COLUMNS `c` '2026-05-05 09:23:45.6789' 0 +p9 RANGE COLUMNS `c` '2026-05-05 10:23:45.6789' 0 +p10 RANGE COLUMNS `c` '2026-05-05 11:23:45.6789' 0 +p11 RANGE COLUMNS `c` '2026-05-05 12:23:45.6789' 0 +p12 RANGE COLUMNS `c` '2026-05-05 13:23:45.6789' 0 +p13 RANGE COLUMNS `c` '2026-05-05 14:23:45.6789' 0 +p14 RANGE COLUMNS `c` '2026-05-05 15:23:45.6789' 0 +p15 RANGE COLUMNS `c` '2026-05-05 16:23:45.6789' 0 +p16 RANGE COLUMNS `c` '2026-05-05 17:23:45.6789' 0 +p17 RANGE COLUMNS `c` '2026-05-05 18:23:45.6789' 0 +p18 RANGE COLUMNS `c` '2026-05-05 19:23:45.6789' 0 +p19 RANGE COLUMNS `c` '2026-05-05 20:23:45.6789' 0 +p20 RANGE COLUMNS `c` '2026-05-05 21:23:45.6789' 0 +p21 RANGE COLUMNS `c` '2026-05-05 22:23:45.6789' 0 +p22 RANGE COLUMNS `c` '2026-05-05 23:23:45.6789' 0 +p23 RANGE COLUMNS `c` '2026-05-06 00:23:45.6789' 0 +drop table t1; +# more than 1 starting partition +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20'), +PARTITION p1 VALUES LESS THAN ('2026-04-25') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-26 00:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-27 00:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-04 00:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-05 00:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +drop table t1; +# no need to create new partition when existing ones are sufficient +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01'), +PARTITION p1 VALUES LESS THAN ('2026-05-06') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +drop table t1; +# find a gap big enough for names of 10 new partition names +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p9 VALUES LESS THAN ('2026-04-01'), +PARTITION p29 VALUES LESS THAN ('2026-04-04'), +PARTITION p19 VALUES LESS THAN ('2026-04-23'), +PARTITION p40 VALUES LESS THAN ('2026-04-27') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p9` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-04') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p40` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 00:00:00 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p9` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-04') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p40` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-04 00:00:00') ENGINE = InnoDB, + PARTITION `p37` VALUES LESS THAN ('2026-05-05 00:00:00') ENGINE = InnoDB, + PARTITION `p38` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p39` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +drop table t1; +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p40 VALUES LESS THAN ('2026-04-27') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p40` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +select * from t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p40` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p0` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +drop table t1; +# CREATE TABLE ... SELECT +# does not work probably because of MDEV-29769 +select to_days('2026-04-01') = 740072; +to_days('2026-04-01') = 740072 +1 +select to_days('2026-05-01') = 740102; +to_days('2026-05-01') = 740102 +1 +# somehow ps protocol has different results +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +) +select from_days(seq) as c from seq_740073_to_740102; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +NULL NULL NULL NULL 30 +drop table t1; +# INSERT ... SELECT +select to_days('2026-04-01') = 740072; +to_days('2026-04-01') = 740072 +1 +select to_days('2026-05-01') = 740102; +to_days('2026-05-01') = 740102 +1 +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +insert into t1 select from_days(seq) from seq_740073_to_740102; +select * from t1; +c +2026-04-02 +2026-04-03 +2026-04-04 +2026-04-05 +2026-04-06 +2026-04-07 +2026-04-08 +2026-04-09 +2026-04-10 +2026-04-11 +2026-04-12 +2026-04-13 +2026-04-14 +2026-04-15 +2026-04-16 +2026-04-17 +2026-04-18 +2026-04-19 +2026-04-20 +2026-04-21 +2026-04-22 +2026-04-23 +2026-04-24 +2026-04-25 +2026-04-26 +2026-04-27 +2026-04-28 +2026-04-29 +2026-04-30 +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-02') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-03') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-04') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-05') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-06') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-07') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-08') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-09') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-10') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-11') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-04-12') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-13') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-04-14') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-04-15') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-04-16') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-04-17') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-04-18') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-04-19') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-01' 0 +p1 RANGE COLUMNS `c` '2026-04-02' 0 +p2 RANGE COLUMNS `c` '2026-04-03' 1 +p3 RANGE COLUMNS `c` '2026-04-04' 1 +p4 RANGE COLUMNS `c` '2026-04-05' 1 +p5 RANGE COLUMNS `c` '2026-04-06' 1 +p6 RANGE COLUMNS `c` '2026-04-07' 1 +p7 RANGE COLUMNS `c` '2026-04-08' 1 +p8 RANGE COLUMNS `c` '2026-04-09' 1 +p9 RANGE COLUMNS `c` '2026-04-10' 1 +p10 RANGE COLUMNS `c` '2026-04-11' 1 +p11 RANGE COLUMNS `c` '2026-04-12' 1 +p12 RANGE COLUMNS `c` '2026-04-13' 1 +p13 RANGE COLUMNS `c` '2026-04-14' 1 +p14 RANGE COLUMNS `c` '2026-04-15' 1 +p15 RANGE COLUMNS `c` '2026-04-16' 1 +p16 RANGE COLUMNS `c` '2026-04-17' 1 +p17 RANGE COLUMNS `c` '2026-04-18' 1 +p18 RANGE COLUMNS `c` '2026-04-19' 1 +p19 RANGE COLUMNS `c` '2026-04-20' 1 +p20 RANGE COLUMNS `c` '2026-04-21' 1 +p21 RANGE COLUMNS `c` '2026-04-22' 1 +p22 RANGE COLUMNS `c` '2026-04-23' 1 +p23 RANGE COLUMNS `c` '2026-04-24' 1 +p24 RANGE COLUMNS `c` '2026-04-25' 1 +p25 RANGE COLUMNS `c` '2026-04-26' 1 +p26 RANGE COLUMNS `c` '2026-04-27' 1 +p27 RANGE COLUMNS `c` '2026-04-28' 1 +p28 RANGE COLUMNS `c` '2026-04-29' 1 +p29 RANGE COLUMNS `c` '2026-04-30' 1 +p30 RANGE COLUMNS `c` '2026-05-01' 1 +p31 RANGE COLUMNS `c` '2026-05-02' 1 +p32 RANGE COLUMNS `c` '2026-05-03' 0 +p33 RANGE COLUMNS `c` '2026-05-04' 0 +p34 RANGE COLUMNS `c` '2026-05-05' 0 +p35 RANGE COLUMNS `c` '2026-05-06' 0 +p36 RANGE COLUMNS `c` '2026-05-07' 0 +drop table t1; +select to_days('2026-05-01') = 740102; +to_days('2026-05-01') = 740102 +1 +select to_days('2026-05-08') = 740109; +to_days('2026-05-08') = 740109 +1 +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +insert into t1 select from_days(seq) from seq_740102_to_740109; +ERROR HY000: Table has no partition for value from column_list +select * from t1; +c +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-02') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-03') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-04') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-05') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-06') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-07') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-08') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-09') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-10') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-11') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-04-12') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-13') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-04-14') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-04-15') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-04-16') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-04-17') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-04-18') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-04-19') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +drop table t1; +# LOAD DATA INFILE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +load data infile 'load.data' into table t1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p12 RANGE COLUMNS `c` '2026-05-02' 1 +p13 RANGE COLUMNS `c` '2026-05-03' 1 +p14 RANGE COLUMNS `c` '2026-05-04' 1 +p15 RANGE COLUMNS `c` '2026-05-05' 1 +p16 RANGE COLUMNS `c` '2026-05-06' 1 +drop table t1; +# LOAD DATA INFILE failure for future dates +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +load data infile 'load.data' into table t1; +ERROR HY000: Table has no partition for value from column_list +select * from t1; +c +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +drop table t1; +# LOAD DATA INFILE IGNORE for future dates +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +load data infile 'load.data' ignore into table t1; +Warnings: +Warning 1526 Table has no partition for value from column_list +Warning 1526 Table has no partition for value from column_list +select * from t1; +c +2026-05-05 +2026-05-06 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p16 RANGE COLUMNS `c` '2026-05-06' 1 +p17 RANGE COLUMNS `c` '2026-05-07' 1 +drop table t1; +# UPDATE +set timestamp= unix_timestamp('2026-05-02 00:00:00'); +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 values ('2026-04-28'), ('2026-04-29'), ('2026-04-30'); +select * from t1; +c +2026-04-28 +2026-04-29 +2026-04-30 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p4 RANGE COLUMNS `c` '2026-04-29' 1 +p5 RANGE COLUMNS `c` '2026-04-30' 1 +p6 RANGE COLUMNS `c` '2026-05-01' 1 +set timestamp= unix_timestamp('2026-05-06 00:00:00'); +update t1 set c = date_add(c, interval 6 day); +select * from t1; +c +2026-05-04 +2026-05-05 +2026-05-06 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p10 RANGE COLUMNS `c` '2026-05-05' 1 +p11 RANGE COLUMNS `c` '2026-05-06' 1 +p12 RANGE COLUMNS `c` '2026-05-07' 1 +set timestamp= unix_timestamp('2026-05-08 00:00:00'); +update t1 set c = date_add(c, interval 3 day); +ERROR HY000: Table has no partition for value from column_list +select * from t1; +c +2026-05-04 +2026-05-05 +2026-05-06 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-08') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-09') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p10 RANGE COLUMNS `c` '2026-05-05' 1 +p11 RANGE COLUMNS `c` '2026-05-06' 1 +p12 RANGE COLUMNS `c` '2026-05-07' 1 +set timestamp= unix_timestamp('2026-05-06 00:00:00'); +drop table t1; +# ALTER TABLE, no interval => have interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 values ('2026-05-01'); +ERROR HY000: Table has no partition for value from column_list +ALTER TABLE t1 PARTITION BY RANGE COLUMNS (c) INTERVAL 1 DAY +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 values ('2026-05-01'); +SELECT * FROM t1; +c +2026-05-01 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name partition_method partition_expression partition_description table_rows +p7 RANGE COLUMNS `c` '2026-05-02' 1 +drop table t1; +# ALTER TABLE, have interval => no interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 DAY +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB) +alter table t1 +PARTITION BY RANGE COLUMNS (c) +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`) +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +ERROR HY000: Table has no partition for value from column_list +drop table t1; +# ALTER TABLE, adding a partition to a RANGE COLUMNS INTERVAL +# partitioned table +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 3 DAY +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN ('2026-04-27')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 3 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB) +insert into t1 values ('2026-05-01'); +ALTER TABLE t1 ADD PARTITION (PARTITION p6 VALUES LESS THAN ('2026-05-02')); +ERROR HY000: VALUES LESS THAN value must be strictly increasing for each partition +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 3 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-09') ENGINE = InnoDB) +ALTER TABLE t1 ADD PARTITION (PARTITION p7 VALUES LESS THAN ('2026-05-10')); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 3 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-09') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-10') ENGINE = InnoDB) +ALTER TABLE t1 ADD PARTITION (PARTITION p8 VALUES LESS THAN MAXVALUE); +ERROR HY000: MAXVALUE is not allowed in range partitioning with interval +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 3 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-09') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-10') ENGINE = InnoDB) +drop table t1; +# with subpartitions. +# note that only [LINEAR] KEY and [LINEAR] HASH are allowed +# subpartitioning methods +select to_days('2026-04-20') = 740091; +to_days('2026-04-20') = 740091 +1 +select to_days('2026-05-01') = 740102; +to_days('2026-05-01') = 740102 +1 +create table t1 (c date, d int) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 3 DAY +SUBPARTITION BY KEY ALGORITHM=XXH3 (d) SUBPARTITIONS 2 +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 select from_days(seq), seq from seq_740091_to_740102; +select * from t1; +c d +2026-04-21 740092 +2026-04-23 740094 +2026-04-24 740095 +2026-04-20 740091 +2026-04-22 740093 +2026-04-25 740096 +2026-04-27 740098 +2026-04-26 740097 +2026-04-30 740101 +2026-04-28 740099 +2026-04-29 740100 +2026-05-01 740102 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL, + `d` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 3 DAY +SUBPARTITION BY KEY ALGORITHM = XXH3 (`d`) +SUBPARTITIONS 2 +(PARTITION `p0` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +select partition_name, subpartition_name, partition_method, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +partition_name subpartition_name partition_method partition_description table_rows +p0 p0sp0 RANGE COLUMNS '2026-04-25' 3 +p0 p0sp1 RANGE COLUMNS '2026-04-25' 2 +p1 p1sp0 RANGE COLUMNS '2026-04-28' 2 +p1 p1sp1 RANGE COLUMNS '2026-04-28' 1 +p2 p2sp0 RANGE COLUMNS '2026-05-01' 1 +p2 p2sp1 RANGE COLUMNS '2026-05-01' 2 +p3 p3sp0 RANGE COLUMNS '2026-05-04' 1 +drop table t1; +# failing insertion of dates in the future +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB) +insert into t1 values ('2026-05-07'); +ERROR HY000: Table has no partition for value from column_list +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-02 00:00:00') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-03 00:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-04 00:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-05 00:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-06 00:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-07 00:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-08 00:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-09 00:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-10 00:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-11 00:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-04-12 00:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-13 00:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-04-14 00:00:00') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-04-15 00:00:00') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-04-16 00:00:00') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-04-17 00:00:00') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-04-18 00:00:00') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-04-19 00:00:00') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-20 00:00:00') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-04-21 00:00:00') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-04-22 00:00:00') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-04-23 00:00:00') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-04-24 00:00:00') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-04-25 00:00:00') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-04-26 00:00:00') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-04-27 00:00:00') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-04 00:00:00') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05 00:00:00') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +drop table t1; +# passthrough behaviour +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB) +begin; +insert into t1 values ('2026-05-01'); +insert into t1 values ('2026-05-02'); +select * from t1; +c +2026-05-01 00:00:00 +2026-05-02 00:00:00 +rollback; +select * from t1; +c +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` datetime DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-02 00:00:00') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-03 00:00:00') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-04 00:00:00') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-05 00:00:00') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-06 00:00:00') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-07 00:00:00') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-08 00:00:00') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-09 00:00:00') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-10 00:00:00') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-11 00:00:00') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-04-12 00:00:00') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-13 00:00:00') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-04-14 00:00:00') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-04-15 00:00:00') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-04-16 00:00:00') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-04-17 00:00:00') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-04-18 00:00:00') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-04-19 00:00:00') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-20 00:00:00') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-04-21 00:00:00') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-04-22 00:00:00') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-04-23 00:00:00') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-04-24 00:00:00') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-04-25 00:00:00') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-04-26 00:00:00') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-04-27 00:00:00') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-04-28 00:00:00') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-04-29 00:00:00') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-30 00:00:00') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-01 00:00:00') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-02 00:00:00') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-03 00:00:00') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-04 00:00:00') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05 00:00:00') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-06 00:00:00') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-07 00:00:00') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-04-01' 0 +p1 RANGE COLUMNS `c` '2026-04-02 00:00:00' 0 +p2 RANGE COLUMNS `c` '2026-04-03 00:00:00' 0 +p3 RANGE COLUMNS `c` '2026-04-04 00:00:00' 0 +p4 RANGE COLUMNS `c` '2026-04-05 00:00:00' 0 +p5 RANGE COLUMNS `c` '2026-04-06 00:00:00' 0 +p6 RANGE COLUMNS `c` '2026-04-07 00:00:00' 0 +p7 RANGE COLUMNS `c` '2026-04-08 00:00:00' 0 +p8 RANGE COLUMNS `c` '2026-04-09 00:00:00' 0 +p9 RANGE COLUMNS `c` '2026-04-10 00:00:00' 0 +p10 RANGE COLUMNS `c` '2026-04-11 00:00:00' 0 +p11 RANGE COLUMNS `c` '2026-04-12 00:00:00' 0 +p12 RANGE COLUMNS `c` '2026-04-13 00:00:00' 0 +p13 RANGE COLUMNS `c` '2026-04-14 00:00:00' 0 +p14 RANGE COLUMNS `c` '2026-04-15 00:00:00' 0 +p15 RANGE COLUMNS `c` '2026-04-16 00:00:00' 0 +p16 RANGE COLUMNS `c` '2026-04-17 00:00:00' 0 +p17 RANGE COLUMNS `c` '2026-04-18 00:00:00' 0 +p18 RANGE COLUMNS `c` '2026-04-19 00:00:00' 0 +p19 RANGE COLUMNS `c` '2026-04-20 00:00:00' 0 +p20 RANGE COLUMNS `c` '2026-04-21 00:00:00' 0 +p21 RANGE COLUMNS `c` '2026-04-22 00:00:00' 0 +p22 RANGE COLUMNS `c` '2026-04-23 00:00:00' 0 +p23 RANGE COLUMNS `c` '2026-04-24 00:00:00' 0 +p24 RANGE COLUMNS `c` '2026-04-25 00:00:00' 0 +p25 RANGE COLUMNS `c` '2026-04-26 00:00:00' 0 +p26 RANGE COLUMNS `c` '2026-04-27 00:00:00' 0 +p27 RANGE COLUMNS `c` '2026-04-28 00:00:00' 0 +p28 RANGE COLUMNS `c` '2026-04-29 00:00:00' 0 +p29 RANGE COLUMNS `c` '2026-04-30 00:00:00' 0 +p30 RANGE COLUMNS `c` '2026-05-01 00:00:00' 0 +p31 RANGE COLUMNS `c` '2026-05-02 00:00:00' 0 +p32 RANGE COLUMNS `c` '2026-05-03 00:00:00' 0 +p33 RANGE COLUMNS `c` '2026-05-04 00:00:00' 0 +p34 RANGE COLUMNS `c` '2026-05-05 00:00:00' 0 +p35 RANGE COLUMNS `c` '2026-05-06 00:00:00' 0 +p36 RANGE COLUMNS `c` '2026-05-07 00:00:00' 0 +drop table t1; +select to_days('2026-04-01') = 740072; +to_days('2026-04-01') = 740072 +1 +select to_days('2026-05-01') = 740102; +to_days('2026-05-01') = 740102 +1 +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +begin; +insert into t1 select from_days(seq) from seq_740073_to_740102; +select * from t1; +c +2026-04-02 +2026-04-03 +2026-04-04 +2026-04-05 +2026-04-06 +2026-04-07 +2026-04-08 +2026-04-09 +2026-04-10 +2026-04-11 +2026-04-12 +2026-04-13 +2026-04-14 +2026-04-15 +2026-04-16 +2026-04-17 +2026-04-18 +2026-04-19 +2026-04-20 +2026-04-21 +2026-04-22 +2026-04-23 +2026-04-24 +2026-04-25 +2026-04-26 +2026-04-27 +2026-04-28 +2026-04-29 +2026-04-30 +2026-05-01 +rollback; +select * from t1; +c +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` date DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 DAY +(PARTITION `p0` VALUES LESS THAN ('2026-04-01') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-04-02') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-04-03') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-04-04') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-04-05') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-04-06') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-04-07') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-04-08') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-04-09') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-04-10') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-04-11') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-04-12') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-04-13') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-04-14') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-04-15') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-04-16') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-04-17') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-04-18') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-04-19') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-04-20') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-04-21') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-04-22') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-04-23') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-04-24') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-04-25') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-04-26') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-04-27') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-04-28') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-04-29') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-04-30') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-01') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-02') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-03') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-04') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-06') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-07') ENGINE = InnoDB) +drop table t1; +# failures +create table t1 (c1 datetime, c2 datetime) +PARTITION BY RANGE COLUMNS (c1, c2) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-01', '2026-04-01') +); +ERROR HY000: Too many fields in 'range interval partition fields' +create table t1 (c datetime) +PARTITION BY LIST COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES IN ('2026-04-01') +); +ERROR HY000: LIST partition type does not support INTERVAL +create table t1 (c int) +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p0 VALUES LESS THAN (740072) +); +ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning +# timestamp +create table t1 (c timestamp) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( +PARTITION p0 VALUES LESS THAN ('2026-05-04 12:34:56.789') +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` timestamp NULL DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-04 12:34:56.789') ENGINE = InnoDB) +insert into t1 values ('2026-05-05 10:00:00.123456'); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` timestamp NULL DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + PARTITION BY RANGE COLUMNS(`c`)INTERVAL 1 HOUR +(PARTITION `p0` VALUES LESS THAN ('2026-05-04 12:34:56.789') ENGINE = InnoDB, + PARTITION `p1` VALUES LESS THAN ('2026-05-04 13:34:56.789') ENGINE = InnoDB, + PARTITION `p2` VALUES LESS THAN ('2026-05-04 14:34:56.789') ENGINE = InnoDB, + PARTITION `p3` VALUES LESS THAN ('2026-05-04 15:34:56.789') ENGINE = InnoDB, + PARTITION `p4` VALUES LESS THAN ('2026-05-04 16:34:56.789') ENGINE = InnoDB, + PARTITION `p5` VALUES LESS THAN ('2026-05-04 17:34:56.789') ENGINE = InnoDB, + PARTITION `p6` VALUES LESS THAN ('2026-05-04 18:34:56.789') ENGINE = InnoDB, + PARTITION `p7` VALUES LESS THAN ('2026-05-04 19:34:56.789') ENGINE = InnoDB, + PARTITION `p8` VALUES LESS THAN ('2026-05-04 20:34:56.789') ENGINE = InnoDB, + PARTITION `p9` VALUES LESS THAN ('2026-05-04 21:34:56.789') ENGINE = InnoDB, + PARTITION `p10` VALUES LESS THAN ('2026-05-04 22:34:56.789') ENGINE = InnoDB, + PARTITION `p11` VALUES LESS THAN ('2026-05-04 23:34:56.789') ENGINE = InnoDB, + PARTITION `p12` VALUES LESS THAN ('2026-05-05 00:34:56.789') ENGINE = InnoDB, + PARTITION `p13` VALUES LESS THAN ('2026-05-05 01:34:56.789') ENGINE = InnoDB, + PARTITION `p14` VALUES LESS THAN ('2026-05-05 02:34:56.789') ENGINE = InnoDB, + PARTITION `p15` VALUES LESS THAN ('2026-05-05 03:34:56.789') ENGINE = InnoDB, + PARTITION `p16` VALUES LESS THAN ('2026-05-05 04:34:56.789') ENGINE = InnoDB, + PARTITION `p17` VALUES LESS THAN ('2026-05-05 05:34:56.789') ENGINE = InnoDB, + PARTITION `p18` VALUES LESS THAN ('2026-05-05 06:34:56.789') ENGINE = InnoDB, + PARTITION `p19` VALUES LESS THAN ('2026-05-05 07:34:56.789') ENGINE = InnoDB, + PARTITION `p20` VALUES LESS THAN ('2026-05-05 08:34:56.789') ENGINE = InnoDB, + PARTITION `p21` VALUES LESS THAN ('2026-05-05 09:34:56.789') ENGINE = InnoDB, + PARTITION `p22` VALUES LESS THAN ('2026-05-05 10:34:56.789') ENGINE = InnoDB, + PARTITION `p23` VALUES LESS THAN ('2026-05-05 11:34:56.789') ENGINE = InnoDB, + PARTITION `p24` VALUES LESS THAN ('2026-05-05 12:34:56.789') ENGINE = InnoDB, + PARTITION `p25` VALUES LESS THAN ('2026-05-05 13:34:56.789') ENGINE = InnoDB, + PARTITION `p26` VALUES LESS THAN ('2026-05-05 14:34:56.789') ENGINE = InnoDB, + PARTITION `p27` VALUES LESS THAN ('2026-05-05 15:34:56.789') ENGINE = InnoDB, + PARTITION `p28` VALUES LESS THAN ('2026-05-05 16:34:56.789') ENGINE = InnoDB, + PARTITION `p29` VALUES LESS THAN ('2026-05-05 17:34:56.789') ENGINE = InnoDB, + PARTITION `p30` VALUES LESS THAN ('2026-05-05 18:34:56.789') ENGINE = InnoDB, + PARTITION `p31` VALUES LESS THAN ('2026-05-05 19:34:56.789') ENGINE = InnoDB, + PARTITION `p32` VALUES LESS THAN ('2026-05-05 20:34:56.789') ENGINE = InnoDB, + PARTITION `p33` VALUES LESS THAN ('2026-05-05 21:34:56.789') ENGINE = InnoDB, + PARTITION `p34` VALUES LESS THAN ('2026-05-05 22:34:56.789') ENGINE = InnoDB, + PARTITION `p35` VALUES LESS THAN ('2026-05-05 23:34:56.789') ENGINE = InnoDB, + PARTITION `p36` VALUES LESS THAN ('2026-05-06 00:34:56.789') ENGINE = InnoDB) +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +partition_name partition_method partition_expression partition_description table_rows +p0 RANGE COLUMNS `c` '2026-05-04 12:34:56.789' 0 +p1 RANGE COLUMNS `c` '2026-05-04 13:34:56.789' 0 +p2 RANGE COLUMNS `c` '2026-05-04 14:34:56.789' 0 +p3 RANGE COLUMNS `c` '2026-05-04 15:34:56.789' 0 +p4 RANGE COLUMNS `c` '2026-05-04 16:34:56.789' 0 +p5 RANGE COLUMNS `c` '2026-05-04 17:34:56.789' 0 +p6 RANGE COLUMNS `c` '2026-05-04 18:34:56.789' 0 +p7 RANGE COLUMNS `c` '2026-05-04 19:34:56.789' 0 +p8 RANGE COLUMNS `c` '2026-05-04 20:34:56.789' 0 +p9 RANGE COLUMNS `c` '2026-05-04 21:34:56.789' 0 +p10 RANGE COLUMNS `c` '2026-05-04 22:34:56.789' 0 +p11 RANGE COLUMNS `c` '2026-05-04 23:34:56.789' 0 +p12 RANGE COLUMNS `c` '2026-05-05 00:34:56.789' 0 +p13 RANGE COLUMNS `c` '2026-05-05 01:34:56.789' 0 +p14 RANGE COLUMNS `c` '2026-05-05 02:34:56.789' 0 +p15 RANGE COLUMNS `c` '2026-05-05 03:34:56.789' 0 +p16 RANGE COLUMNS `c` '2026-05-05 04:34:56.789' 0 +p17 RANGE COLUMNS `c` '2026-05-05 05:34:56.789' 0 +p18 RANGE COLUMNS `c` '2026-05-05 06:34:56.789' 0 +p19 RANGE COLUMNS `c` '2026-05-05 07:34:56.789' 0 +p20 RANGE COLUMNS `c` '2026-05-05 08:34:56.789' 0 +p21 RANGE COLUMNS `c` '2026-05-05 09:34:56.789' 0 +p22 RANGE COLUMNS `c` '2026-05-05 10:34:56.789' 1 +p23 RANGE COLUMNS `c` '2026-05-05 11:34:56.789' 0 +p24 RANGE COLUMNS `c` '2026-05-05 12:34:56.789' 0 +p25 RANGE COLUMNS `c` '2026-05-05 13:34:56.789' 0 +p26 RANGE COLUMNS `c` '2026-05-05 14:34:56.789' 0 +p27 RANGE COLUMNS `c` '2026-05-05 15:34:56.789' 0 +p28 RANGE COLUMNS `c` '2026-05-05 16:34:56.789' 0 +p29 RANGE COLUMNS `c` '2026-05-05 17:34:56.789' 0 +p30 RANGE COLUMNS `c` '2026-05-05 18:34:56.789' 0 +p31 RANGE COLUMNS `c` '2026-05-05 19:34:56.789' 0 +p32 RANGE COLUMNS `c` '2026-05-05 20:34:56.789' 0 +p33 RANGE COLUMNS `c` '2026-05-05 21:34:56.789' 0 +p34 RANGE COLUMNS `c` '2026-05-05 22:34:56.789' 0 +p35 RANGE COLUMNS `c` '2026-05-05 23:34:56.789' 0 +p36 RANGE COLUMNS `c` '2026-05-06 00:34:56.789' 0 +drop table t1; +# year is not allowed in range column partitioning +create table t1 (c year) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 minute +( +PARTITION p0 VALUES LESS THAN ('2025') +); +ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning +# interval less than a day for date column +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 23.59 HOUR_MINUTE +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +ERROR HY000: RANGE COLUMN partition by a DATE with INTERVAL smaller than date +# bad interval values +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL -1 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 0 Day +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1.1 SECOND_MICROSECOND +( +PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +ERROR HY000: Wrong parameters for partitioned `t1`: wrong value for 'INTERVAL' +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( +PARTITION p1 VALUES LESS THAN ('2026-04-01'), +PARTITION p0 VALUES LESS THAN MAXVALUE +); +ERROR HY000: MAXVALUE is not allowed in range partitioning with interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day; +ERROR HY000: For RANGE partitions each partition must be defined +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Second +( +PARTITION p1 VALUES LESS THAN ('2026-04-01') +); +insert into t1 values ('2026-01-01'); +ERROR HY000: Too many partitions (including subpartitions) were defined +drop table t1; +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 999999999 DAY +( +PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +ERROR 22008: Datetime function: datetime field overflow diff --git a/mysql-test/main/partition_range_interval.test b/mysql-test/main/partition_range_interval.test new file mode 100644 index 0000000000000..974c654e948fb --- /dev/null +++ b/mysql-test/main/partition_range_interval.test @@ -0,0 +1,588 @@ +--source include/have_partition.inc +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # simple case with DATETIME column showing partitions added in INSERT +set timestamp= unix_timestamp('2026-05-02 00:00:00'); + +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; + +set timestamp= unix_timestamp('2026-05-06 00:00:00'); + +insert into t1 values ('2026-05-04'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; + +drop table t1; + +--echo # simple case with DATE column +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 DAY AUTO +( + PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # oracle interval syntax +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTODSINTERVAL(1, 'DAY')) +( + PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTOYMINTERVAL(1, 'MONTH')) +( + PARTITION p0 VALUES LESS THAN ('2025-04-30') +); +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo ## NUMTODSINTERVAL takes only DAY, HOUR, MINUTE or SECOND +--error ER_PART_WRONG_VALUE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTODSINTERVAL(1, 'YEAR')) +( + PARTITION p0 VALUES LESS THAN ('2024-04-30') +); + +--echo ## NUMTOYMINTERVAL takes only YEAR or MONTH +--error ER_PART_WRONG_VALUE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL (NUMTOYMINTERVAL(1, 'HOUR')) +( + PARTITION p0 VALUES LESS THAN ('2026-04-30') +); + +--echo # 1.5 day interval truncated to +1d, +2d, +1d, +2d, ... +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 36 Hour +( + PARTITION p0 VALUES LESS THAN ('2026-04-30') +); +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # DATE column with 1 week interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Week +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # DATETIME column with 1 hour interval +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( + PARTITION p0 VALUES LESS THAN ('2026-05-05') +); +show create table t1; +insert into t1 values ('2026-05-05 03:00:00'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # DATETIME column with some decimal points in partition range value +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( + PARTITION p0 VALUES LESS THAN ('2026-05-05 01:23:45.6789') +); +show create table t1; +insert into t1 values ('2026-05-05 03:00:00'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # more than 1 starting partition +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20'), + PARTITION p1 VALUES LESS THAN ('2026-04-25') +); + +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +drop table t1; + +--echo # no need to create new partition when existing ones are sufficient +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01'), + PARTITION p1 VALUES LESS THAN ('2026-05-06') +); + +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +drop table t1; + +--echo # find a gap big enough for names of 10 new partition names +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p9 VALUES LESS THAN ('2026-04-01'), + PARTITION p29 VALUES LESS THAN ('2026-04-04'), + PARTITION p19 VALUES LESS THAN ('2026-04-23'), + PARTITION p40 VALUES LESS THAN ('2026-04-27') +); + +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +drop table t1; + +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p40 VALUES LESS THAN ('2026-04-27') +); + +show create table t1; +insert into t1 values ('2026-05-01'); +select * from t1; +show create table t1; +drop table t1; + +--echo # CREATE TABLE ... SELECT +--echo # does not work probably because of MDEV-29769 +select to_days('2026-04-01') = 740072; +select to_days('2026-05-01') = 740102; + +--echo # somehow ps protocol has different results +--disable_ps_protocol +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +) +select from_days(seq) as c from seq_740073_to_740102; +--enable_ps_protocol +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # INSERT ... SELECT +select to_days('2026-04-01') = 740072; +select to_days('2026-05-01') = 740102; + +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +insert into t1 select from_days(seq) from seq_740073_to_740102; +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +select to_days('2026-05-01') = 740102; +select to_days('2026-05-08') = 740109; + +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +insert into t1 select from_days(seq) from seq_740102_to_740109; +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # LOAD DATA INFILE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--let $mysqld_datadir= `select @@datadir` +--write_file $mysqld_datadir/test/load.data +2026-05-01 +2026-05-02 +2026-05-03 +2026-05-04 +2026-05-05 +EOF +load data infile 'load.data' into table t1; +--remove_file $mysqld_datadir/test/load.data +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # LOAD DATA INFILE failure for future dates +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--let $mysqld_datadir= `select @@datadir` +--write_file $mysqld_datadir/test/load.data +2026-05-05 +2026-05-06 +2026-05-07 +2026-05-08 +EOF +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +load data infile 'load.data' into table t1; +--remove_file $mysqld_datadir/test/load.data +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # LOAD DATA INFILE IGNORE for future dates +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--let $mysqld_datadir= `select @@datadir` +--write_file $mysqld_datadir/test/load.data +2026-05-05 +2026-05-06 +2026-05-07 +2026-05-08 +EOF +load data infile 'load.data' ignore into table t1; +--remove_file $mysqld_datadir/test/load.data +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # UPDATE +set timestamp= unix_timestamp('2026-05-02 00:00:00'); +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); + +insert into t1 values ('2026-04-28'), ('2026-04-29'), ('2026-04-30'); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +set timestamp= unix_timestamp('2026-05-06 00:00:00'); +update t1 set c = date_add(c, interval 6 day); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +set timestamp= unix_timestamp('2026-05-08 00:00:00'); +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +update t1 set c = date_add(c, interval 3 day); +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +set timestamp= unix_timestamp('2026-05-06 00:00:00'); +drop table t1; + +--echo # ALTER TABLE, no interval => have interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +insert into t1 values ('2026-05-01'); +ALTER TABLE t1 PARTITION BY RANGE COLUMNS (c) INTERVAL 1 DAY +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 values ('2026-05-01'); +SELECT * FROM t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # ALTER TABLE, have interval => no interval +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 DAY +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +show create table t1; +alter table t1 +PARTITION BY RANGE COLUMNS (c) +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +show create table t1; +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +insert into t1 values ('2026-05-01'); +drop table t1; + +--echo # ALTER TABLE, adding a partition to a RANGE COLUMNS INTERVAL +--echo # partitioned table +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 3 DAY +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +ALTER TABLE t1 ADD PARTITION (PARTITION p1 VALUES LESS THAN ('2026-04-27')); +show create table t1; +insert into t1 values ('2026-05-01'); +--error ER_RANGE_NOT_INCREASING_ERROR +ALTER TABLE t1 ADD PARTITION (PARTITION p6 VALUES LESS THAN ('2026-05-02')); +show create table t1; +ALTER TABLE t1 ADD PARTITION (PARTITION p7 VALUES LESS THAN ('2026-05-10')); +show create table t1; +--error ER_PARTITION_INTERVAL_MAXVALUE +ALTER TABLE t1 ADD PARTITION (PARTITION p8 VALUES LESS THAN MAXVALUE); +show create table t1; +drop table t1; + +--echo # with subpartitions. +--echo # note that only [LINEAR] KEY and [LINEAR] HASH are allowed +--echo # subpartitioning methods +select to_days('2026-04-20') = 740091; +select to_days('2026-05-01') = 740102; + +create table t1 (c date, d int) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 3 DAY + SUBPARTITION BY KEY ALGORITHM=XXH3 (d) SUBPARTITIONS 2 +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); +insert into t1 select from_days(seq), seq from seq_740091_to_740102; +select * from t1; +show create table t1; +select partition_name, subpartition_name, partition_method, partition_description, table_rows from information_schema.partitions where table_name='t1' and table_rows > 0; +drop table t1; + +--echo # failing insertion of dates in the future +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +); + +show create table t1; +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +insert into t1 values ('2026-05-07'); +show create table t1; +drop table t1; + +--echo # passthrough behaviour +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +show create table t1; +begin; +insert into t1 values ('2026-05-01'); +insert into t1 values ('2026-05-02'); +select * from t1; +rollback; +select * from t1; +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +select to_days('2026-04-01') = 740072; +select to_days('2026-05-01') = 740102; + +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01') +); +begin; +insert into t1 select from_days(seq) from seq_740073_to_740102; +select * from t1; +rollback; +select * from t1; +show create table t1; +drop table t1; + +--echo # failures + +--error ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR +create table t1 (c1 datetime, c2 datetime) +PARTITION BY RANGE COLUMNS (c1, c2) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-01', '2026-04-01') +); + +--error ER_PARTITION_INTERVAL_NOT_LIST +create table t1 (c datetime) +PARTITION BY LIST COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES IN ('2026-04-01') +); + +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD +create table t1 (c int) +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p0 VALUES LESS THAN (740072) +); + +--echo # timestamp +create table t1 (c timestamp) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 hour +( + PARTITION p0 VALUES LESS THAN ('2026-05-04 12:34:56.789') +); +show create table t1; +insert into t1 values ('2026-05-05 10:00:00.123456'); +show create table t1; +select partition_name, partition_method, partition_expression, partition_description, table_rows from information_schema.partitions where table_name='t1'; +drop table t1; + +--echo # year is not allowed in range column partitioning +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD +create table t1 (c year) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 minute +( + PARTITION p0 VALUES LESS THAN ('2025') +); + +# TODO: somehow 23.59.59 HOUR_SECOND causes parsing error +--echo # interval less than a day for date column +--error ER_PARTITION_INTERVAL_FINER_THAN_DATE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 23.59 HOUR_MINUTE +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--echo # bad interval values +--error ER_PART_WRONG_VALUE +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL -1 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--error ER_PART_WRONG_VALUE +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 0 Day +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--error ER_PART_WRONG_VALUE +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1.1 SECOND_MICROSECOND +( + PARTITION p0 VALUES LESS THAN ('2026-04-20') +); + +--error ER_PARTITION_INTERVAL_MAXVALUE +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day +( + PARTITION p1 VALUES LESS THAN ('2026-04-01'), + PARTITION p0 VALUES LESS THAN MAXVALUE +); + +--error ER_PARTITIONS_MUST_BE_DEFINED_ERROR +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Day; + +create table t1 (c datetime) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 1 Second +( + PARTITION p1 VALUES LESS THAN ('2026-04-01') +); +--error ER_TOO_MANY_PARTITIONS_ERROR +insert into t1 values ('2026-01-01'); +drop table t1; + +--error ER_DATETIME_FUNCTION_OVERFLOW +create table t1 (c date) engine=innodb +PARTITION BY RANGE COLUMNS (c) +INTERVAL 999999999 DAY +( + PARTITION p0 VALUES LESS THAN ('2026-04-25') +); diff --git a/sql/lex.h b/sql/lex.h index 079633536c0fc..15bc1d2cf693c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -778,6 +778,8 @@ SYMBOL sql_functions[] = { { "NOW", SYM(NOW_SYM)}, { "NTH_VALUE", SYM(NTH_VALUE_SYM)}, { "NTILE", SYM(NTILE_SYM)}, + { "NUMTODSINTERVAL", SYM(NUMTODSINTERVAL_SYM)}, + { "NUMTOYMINTERVAL", SYM(NUMTOYMINTERVAL_SYM)}, { "POSITION", SYM(POSITION_SYM)}, { "PERCENT_RANK", SYM(PERCENT_RANK_SYM)}, { "PERCENTILE_CONT", SYM(PERCENTILE_CONT_SYM)}, diff --git a/sql/partition_info.cc b/sql/partition_info.cc index a6320dc489dd9..57f022b7b9415 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -400,7 +400,7 @@ bool partition_info::set_up_default_partitions(THD *thd, handler *file, num_parts= 2; use_default_num_partitions= false; } - else if (part_type != HASH_PARTITION) + else if (part_type != HASH_PARTITION && !is_range_interval()) { const char *error_string; if (part_type == RANGE_PARTITION) @@ -891,6 +891,36 @@ bool partition_info::vers_set_hist_part(THD *thd, uint *create_count) return false; } +/* + Determine the number of range interval partitions to create, like + partition_info::vers_set_hist_part. +*/ +bool partition_info::range_interval_set_count(THD* thd, uint *create_count) +{ + /* At least one range partition is defined */ + DBUG_ASSERT(partitions.elements > 0); + partition_element *el= partitions.elem(partitions.elements - 1); + Item *item= el->get_col_val(0).item_expression; + MYSQL_TIME cur_time, end_time; + thd->variables.time_zone->gmt_sec_to_TIME(&end_time, thd->query_start()); + longlong cur= item->val_datetime_packed(thd); + unpack_time(cur, &cur_time, MYSQL_TIMESTAMP_DATETIME); + longlong end= pack_time(&end_time); + *create_count= 0; + while (cur <= end) + { + if (date_add_interval(thd, &cur_time, int_type, interval)) + return true; + cur= pack_time(&cur_time); + ++*create_count; + if (partitions.elements + *create_count > MAX_PARTITIONS) + { + my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0)); + return true; + } + } + return false; +} /** @brief Run fast_alter_partition_table() to add new history partitions @@ -1014,6 +1044,103 @@ bool vers_create_partitions(THD *thd, TABLE_LIST* tl, uint num_parts) return result; } +/* + Similar to vers_create_partitions, create range interval partitions +*/ +bool range_interval_create_partitions(THD* thd, TABLE_LIST* tl, uint num_parts) +{ + bool result= true; + Table_specification_st create_info; + Alter_info alter_info; + TABLE *table= tl->table; + partition_info *save_part_info= thd->work_part_info; + /* TODO: this may still trigger MSAN unitialised? */ + bool save_no_write_to_binlog= thd->lex->no_write_to_binlog; + thd->lex->no_write_to_binlog= true; + + DBUG_ASSERT(!thd->is_error()); + DBUG_ASSERT(num_parts); + + { + alter_info.reset(); + alter_info.partition_flags= ALTER_PARTITION_ADD; + create_info.init(); + create_info.alter_info= &alter_info; + Alter_table_ctx alter_ctx(thd, tl, 1, &table->s->db, &table->s->table_name); + + MDL_REQUEST_INIT(&tl->mdl_request, MDL_key::TABLE, tl->db.str, + tl->table_name.str, MDL_SHARED_NO_WRITE, MDL_TRANSACTION); + if (thd->mdl_context.acquire_lock(&tl->mdl_request, + thd->variables.lock_wait_timeout)) + goto exit; + table->mdl_ticket= tl->mdl_request.ticket; + + create_info.db_type= table->s->db_type(); + DBUG_ASSERT(create_info.db_type); + + partition_info *part_info= new partition_info(); + if (unlikely(!part_info)) + { + my_error(ER_OUT_OF_RESOURCES, MYF(0)); + goto exit; + } + part_info->use_default_num_partitions= false; + part_info->use_default_num_subpartitions= false; + part_info->num_parts= num_parts; + part_info->num_subparts= table->part_info->num_subparts; + part_info->subpart_type= table->part_info->subpart_type; + part_info->num_columns= table->part_info->num_columns; + part_info->part_type= RANGE_PARTITION; + /* for partition_info::fix_parser_data to exit early */ + part_info->int_type= table->part_info->int_type; + + thd->work_part_info= part_info; + bool partition_changed= false; + bool fast_alter_partition= false; + if (prep_alter_part_table(thd, table, &alter_info, &create_info, + &partition_changed, &fast_alter_partition)) + { + my_error(ER_INTERNAL_ERROR, MYF(ME_WARNING), + tl->db.str, tl->table_name.str); + goto exit; + } + if (!fast_alter_partition) + { + my_error(ER_INTERNAL_ERROR, MYF(ME_WARNING), + tl->db.str, tl->table_name.str); + goto exit; + } + DBUG_ASSERT(partition_changed); + if (mysql_prepare_alter_table(thd, table, &create_info, &alter_info, + &alter_ctx)) + { + my_error(ER_INTERNAL_ERROR, MYF(ME_WARNING), + tl->db.str, tl->table_name.str); + goto exit; + } + + alter_info.db= alter_ctx.db; + alter_info.table_name= alter_ctx.table_name; + if (fast_alter_partition_table(thd, table, &alter_info, &alter_ctx, + &create_info, tl)) + { + my_error(ER_INTERNAL_ERROR, MYF(ME_WARNING), + tl->db.str, tl->table_name.str); + goto exit; + } + } + + result= false; + // NOTE: we have to return DA_EMPTY for new command + DBUG_ASSERT(thd->get_stmt_da()->is_ok()); + thd->get_stmt_da()->reset_diagnostics_area(); + thd->variables.option_bits|= OPTION_BINLOG_THIS; + +exit: + thd->lex->no_write_to_binlog= save_no_write_to_binlog; + thd->work_part_info= save_part_info; + return result; +} /** Warn at the end of DML command if the last history partition is out of LIMIT. @@ -2320,6 +2447,7 @@ bool partition_info::fix_parser_data(THD *thd) partition_element *part_elem; uint num_elements; uint i= 0, j, k; + int sql_command= thd_sql_command(thd); DBUG_ENTER("partition_info::fix_parser_data"); if (!(part_type == RANGE_PARTITION || @@ -2334,13 +2462,23 @@ bool partition_info::fix_parser_data(THD *thd) DBUG_RETURN(true); } /* If not set, use DEFAULT = 2 for CREATE and ALTER! */ - if ((thd_sql_command(thd) == SQLCOM_CREATE_TABLE || - thd_sql_command(thd) == SQLCOM_ALTER_TABLE) && + if ((sql_command == SQLCOM_CREATE_TABLE || + sql_command == SQLCOM_ALTER_TABLE) && key_algorithm == KEY_ALGORITHM_NONE) key_algorithm= KEY_ALGORITHM_55; } DBUG_RETURN(FALSE); } + /* + We exit here for range interval partitions because if this is + called from prep_alter_part_table then partition data is not + calculated (in check_range_interval_constants) yet. + */ + if (sql_command != SQLCOM_CREATE_TABLE && + sql_command != SQLCOM_ALTER_TABLE && is_range_interval()) + { + DBUG_RETURN(FALSE); + } if (is_sub_partitioned() && list_of_subpart_fields) { /* KEY subpartitioning, check ALGORITHM = N. Should not pass the parser! */ @@ -2785,6 +2923,83 @@ bool partition_info::vers_init_info(THD * thd) return false; } +/* Check and set interval value for auto interval partitioning */ +bool partition_info::set_range_interval(THD* thd, Item* ival, + interval_type type, + const char *table_name) +{ + bool error= get_interval_value(thd, ival, type, &interval) || + interval.neg || interval.second_part || + !(interval.year || interval.month || interval.day || interval.hour || + interval.minute || interval.second); + if (error) + { + my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "INTERVAL"); + return true; + } + int_type= type; + return false; +} + +/* + Check and set interval value for auto interval partitioning, from + the ORACLE NUMTODSINTERVAL/NUMTOYMINTERVAL format +*/ +bool partition_info::set_range_interval(int num, LEX_CSTRING &type, + bool is_ds, + const char *table_name) +{ + if (num < 0) + goto end; + if (is_ds) + { + if (type.length == 3 && !strncasecmp(type.str, "DAY", 3)) + { + interval.day= num; + int_type= INTERVAL_DAY; + return false; + } + else if (type.length == 4 && !strncasecmp(type.str, "HOUR", 4)) + { + interval.hour= num; + int_type= INTERVAL_HOUR; + return false; + } + else if (type.length == 6) + { + if (!strncasecmp(type.str, "MINUTE", 6)) + { + interval.minute= num; + int_type= INTERVAL_MINUTE; + return false; + } + else if (!strncasecmp(type.str, "SECOND", 6)) + { + interval.second= num; + int_type= INTERVAL_SECOND; + return false; + } + } + } + else + { + if (type.length == 4 && !strncasecmp(type.str, "YEAR", 4)) + { + interval.year= num; + int_type= INTERVAL_YEAR; + return false; + } + else if (type.length == 5 && !strncasecmp(type.str, "MONTH", 5)) + { + interval.month= num; + int_type= INTERVAL_MONTH; + return false; + } + } +end: + my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "INTERVAL"); + return true; +} /** Assign INTERVAL and STARTS for SYSTEM_TIME partitions. diff --git a/sql/partition_info.h b/sql/partition_info.h index e25e27860c966..8bebdbc1b7d80 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -207,6 +207,10 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc part_column_list_val *list_col_array; }; + /* TODO: change to pointer */ + INTERVAL interval; + enum interval_type int_type; + Vers_part_info *vers_info; /******************************************** @@ -319,7 +323,7 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL), part_expr(NULL), subpart_expr(NULL), item_free_list(NULL), bitmaps_are_initialized(FALSE), - list_array(NULL), vers_info(NULL), err_value(0), + list_array(NULL), int_type(INTERVAL_LAST), vers_info(NULL), err_value(0), part_info_string(NULL), curr_part_elem(NULL), current_partition(NULL), curr_list_object(0), num_columns(0), table(NULL), @@ -348,6 +352,9 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc temp_partitions.empty(); part_field_list.empty(); subpart_field_list.empty(); + interval.second_part= interval.second= interval.minute= + interval.hour= interval.day= interval.month= interval.year= 0; + interval.neg= FALSE; } ~partition_info() = default; @@ -417,11 +424,16 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc bool field_in_partition_expr(Field *field) const; bool vers_init_info(THD *thd); + bool set_range_interval(THD* thd, Item* ival, interval_type type, + const char *table_name); + bool set_range_interval(int num, LEX_CSTRING& type, bool is_ds, + const char *table_name); bool vers_set_interval(THD *thd, Item *interval, interval_type int_type, Item *starts, bool auto_part, const char *table_name); bool vers_set_limit(ulonglong limit, bool auto_part, const char *table_name); bool vers_set_hist_part(THD* thd, uint *create_count); + bool range_interval_set_count(THD* thd, uint *create_count); bool vers_require_hist_part(THD *thd) const { return part_type == VERSIONING_PARTITION && @@ -430,6 +442,8 @@ class partition_info : public DDL_LOG_STATE, public Sql_alloc void vers_check_limit(THD *thd); bool vers_fix_field_list(THD *thd); void vers_update_el_ids(); + bool is_range_interval() const + { return int_type != INTERVAL_LAST && part_type == RANGE_PARTITION; } partition_element *get_partition(uint part_id) { List_iterator it(partitions); @@ -452,6 +466,7 @@ void part_type_error(THD *thd, partition_info *work_part_info, uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); bool check_partition_dirs(partition_info *part_info); bool vers_create_partitions(THD* thd, TABLE_LIST* tl, uint num_parts); +bool range_interval_create_partitions(THD* thd, TABLE_LIST* tl, uint num_parts); /* Initialize the iterator to return a single partition with given part_id */ @@ -546,15 +561,25 @@ Lex_ident_partition make_partition_name(char *move_ptr, uint i) #ifdef WITH_PARTITION_STORAGE_ENGINE +/* + Find the first index for naming system time versioning or range + interval auto created partitions. + + For range interval partitions, find the first gap large enough to + fit in all the new partitions. + + TODO(MDEV-15621): consider making this more efficient by using a + hash, possibly like Partition_share::partition_name_hash +*/ inline uint partition_info::next_part_no(uint new_parts) const { - if (part_type != VERSIONING_PARTITION) + if (part_type != VERSIONING_PARTITION && !is_range_interval()) return num_parts; DBUG_ASSERT(new_parts > 0); /* Choose first non-occupied name suffix */ - uint32 suffix= num_parts - 1; - DBUG_ASSERT(suffix > 0); + uint32 suffix= part_type == VERSIONING_PARTITION ? num_parts - 1 : 0; + DBUG_ASSERT(suffix > 0 || part_type != VERSIONING_PARTITION); char part_name[MAX_PART_NAME_SIZE + 1]; List_iterator_fast it(table->part_info->partitions); for (uint cur_part= 0; cur_part < new_parts; ++cur_part, ++suffix) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index ef4fd75fc205b..c75a687bf3198 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -12406,3 +12406,9 @@ ER_WARN_QB_NAME_PATH_VIEW_NOT_FOUND eng "Hint %s is ignored. `%s` required at element #%u of the path is not found in the target query block." ER_WARN_QB_NAME_PATH_NOT_SUPPORTED_INSIDE_VIEW eng "Hint %s is ignored. QB_NAME hints with path are not supported inside view definitions." +ER_PARTITION_INTERVAL_NOT_LIST + eng "LIST partition type does not support INTERVAL" +ER_PARTITION_INTERVAL_FINER_THAN_DATE + eng "RANGE COLUMN partition by a DATE with INTERVAL smaller than date" +ER_PARTITION_INTERVAL_MAXVALUE + eng "MAXVALUE is not allowed in range partitioning with interval" diff --git a/sql/sql_base.cc b/sql/sql_base.cc index d1d876985f81a..354c98f05b2c3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1922,6 +1922,41 @@ bool TABLE::vers_switch_partition(THD *thd, TABLE_LIST *table_list, return false; } + +/* + Similar to vers_switch_partition, find how many partitions to create + and calls oc_ctx->request_backoff_action for actions to take when + failing opening_and_process_table +*/ +bool TABLE::range_interval_check_partition(THD *thd, TABLE_LIST *table_list, + Open_table_context *ot_ctx) +{ + if (!part_info || !part_info->is_range_interval() || + table_list->mdl_request.type == MDL_EXCLUSIVE || + ot_ctx->range_interval_create_count > 0) + return false; + switch (thd->lex->sql_command) + { + case SQLCOM_INSERT_SELECT: + case SQLCOM_INSERT: + case SQLCOM_LOAD: + case SQLCOM_UPDATE: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_UPDATE_MULTI: + break; + default: + return false; + } + if (part_info->range_interval_set_count( + thd, &ot_ctx->range_interval_create_count)) + return true; + if (ot_ctx->range_interval_create_count == 0) + return false; + ot_ctx->request_backoff_action( + Open_table_context::OT_ADD_RANGE_INTERVAL_PARTITION, table_list); + return true; +} #endif /* WITH_PARTITION_STORAGE_ENGINE */ @@ -2348,7 +2383,9 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) #ifdef WITH_PARTITION_STORAGE_ENGINE if (!part_names_error && - table->vers_switch_partition(thd, table_list, ot_ctx)) + (table->vers_switch_partition(thd, table_list, ot_ctx) || + table->range_interval_check_partition(thd, table_list, ot_ctx)) + ) { MYSQL_UNBIND_TABLE(table->file); tc_release_table(table); @@ -3421,7 +3458,7 @@ Open_table_context::Open_table_context(THD *thd, uint flags) m_action(OT_NO_ACTION), m_has_locks(thd->mdl_context.has_locks()), m_has_protection_against_grl(0), - vers_create_count(0) + vers_create_count(0), range_interval_create_count(0) {} @@ -3502,7 +3539,8 @@ request_backoff_action(enum_open_table_action action_arg, if (table) { DBUG_ASSERT(action_arg == OT_DISCOVER || action_arg == OT_REPAIR || - action_arg == OT_ADD_HISTORY_PARTITION); + action_arg == OT_ADD_HISTORY_PARTITION || + action_arg == OT_ADD_RANGE_INTERVAL_PARTITION); m_failed_table= m_thd->alloc(1); if (m_failed_table == NULL) return TRUE; @@ -3570,6 +3608,7 @@ Open_table_context::recover_from_failed_open() break; case OT_DISCOVER: case OT_REPAIR: + case OT_ADD_RANGE_INTERVAL_PARTITION: case OT_ADD_HISTORY_PARTITION: DEBUG_SYNC(m_thd, "add_history_partition"); if (!m_thd->locked_tables_mode) @@ -3611,7 +3650,8 @@ Open_table_context::recover_from_failed_open() We don't need to remove share under OT_ADD_HISTORY_PARTITION. Moreover fast_alter_partition_table() works with TABLE instance. */ - if (m_action != OT_ADD_HISTORY_PARTITION) + if (m_action != OT_ADD_HISTORY_PARTITION && + m_action != OT_ADD_RANGE_INTERVAL_PARTITION) tdc_remove_table(m_thd, m_failed_table->db.str, m_failed_table->table_name.str); @@ -3641,6 +3681,76 @@ Open_table_context::recover_from_failed_open() case OT_REPAIR: result= auto_repair_table(m_thd, m_failed_table); break; + case OT_ADD_RANGE_INTERVAL_PARTITION: +#ifdef WITH_PARTITION_STORAGE_ENGINE + { + result= false; + TABLE *table= open_ltable(m_thd, m_failed_table, TL_WRITE, + MYSQL_OPEN_HAS_MDL_LOCK | MYSQL_OPEN_IGNORE_LOGGING_FORMAT); + if (table == NULL) + { + m_thd->clear_error(); + break; + } + + result= range_interval_create_partitions( + m_thd, m_failed_table, range_interval_create_count); + range_interval_create_count= 0; + if (!m_thd->transaction->stmt.is_empty()) + trans_commit_stmt(m_thd); + DBUG_ASSERT(!result || + !m_thd->locked_tables_mode || + m_thd->lock->lock_count); + if (result) + break; + if (!m_thd->locked_tables_mode) + { + /* + alter_partition_lock_handling() does mysql_lock_remove() but + does not clear thd->lock completely. + */ + DBUG_ASSERT(m_thd->lock->lock_count == 0); + if (!(m_thd->lock->flags & GET_LOCK_ON_THD)) + my_free(m_thd->lock); + m_thd->lock= NULL; + } + /* + TODO(MDEV-15621): here I just copied code from + OT_ADD_HISTORY_PARTITION + */ + else if (m_thd->locked_tables_mode == LTM_PRELOCKED) + { + MYSQL_LOCK *lock; + MYSQL_LOCK *merged_lock; + + /* + In LTM_LOCK_TABLES table was reopened via locked_tables_list, + but not in prelocked environment where we have to reopen + the table manually. + */ + Open_table_context ot_ctx(m_thd, MYSQL_OPEN_REOPEN); + if (open_table(m_thd, m_failed_table, &ot_ctx)) + { + result= true; + break; + } + TABLE *table= m_failed_table->table; + table->reginfo.lock_type= m_thd->update_lock_default; + m_thd->in_lock_tables= 1; + lock= mysql_lock_tables(m_thd, &table, 1, + MYSQL_OPEN_REOPEN | MYSQL_LOCK_USE_MALLOC); + m_thd->in_lock_tables= 0; + if (lock == NULL || + !(merged_lock= mysql_lock_merge(m_thd->lock, lock, m_thd))) + { + result= true; + break; + } + m_thd->lock= merged_lock; + } + break; + } +#endif case OT_ADD_HISTORY_PARTITION: #ifdef WITH_PARTITION_STORAGE_ENGINE { diff --git a/sql/sql_base.h b/sql/sql_base.h index 77d2b17a1fe5d..d428e2bec9e8d 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -569,7 +569,8 @@ class Open_table_context OT_REOPEN_TABLES, OT_DISCOVER, OT_REPAIR, - OT_ADD_HISTORY_PARTITION + OT_ADD_HISTORY_PARTITION, + OT_ADD_RANGE_INTERVAL_PARTITION }; Open_table_context(THD *thd, uint flags); @@ -645,6 +646,7 @@ class Open_table_context public: uint vers_create_count; + uint range_interval_create_count; }; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 85a64936e1f95..9b4108946e150 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1248,6 +1248,114 @@ int partition_info_compare_column_values(const void *first_arg, return 0; } +/* Determine the range of the new RANGE COLUMNS partitions by interval */ +static bool check_range_interval_constants(THD *thd, partition_info *part_info) +{ + List_iterator part_it(part_info->partitions); + partition_element *el; + Item *last_el_item; + uint error, part_id= 0; + int warn; + /* No partition auto-creation in DDL. */ + if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE || + thd_sql_command(thd) == SQLCOM_ALTER_TABLE) + return FALSE; + /* Range interval is only supported in RANGE COLUMNS with one column */ + DBUG_ASSERT(part_info->column_list); + DBUG_ASSERT(part_info->part_field_list.elements == 1); + /* Find the first partition to auto-add */ + while ((el= part_it++) && el->part_state == PART_NORMAL) + part_id++; + /* No partition to auto-add */ + if (!el) + return FALSE; + /* + We are in a DML where partitions need to be created. There + should already be some existing partitions + */ + DBUG_ASSERT(part_id != 0); + last_el_item= + part_info->partitions.elem(part_id - 1)->get_col_val(0).item_expression; + longlong packed= last_el_item->val_datetime_packed(thd); + MYSQL_TIME ltime; + unpack_time(packed, <ime, MYSQL_TIMESTAMP_DATETIME); + enum_field_types ftype= part_info->part_field_array[0]->type(); + decimal_digits_t dec= last_el_item->datetime_precision(thd); + do + { + if (date_add_interval(thd, <ime, + part_info->int_type, part_info->interval)) + { + /* Same error as in check_vers_constants */ + my_error(ER_DATA_OUT_OF_RANGE, MYF(0), + part_info->part_field_array[0]->type_handler()->name().ptr(), + "INTERVAL"); + return TRUE; + } + Datetime dt(thd, &warn, <ime, Datetime::Options(thd), dec); + Date d(static_cast(&dt)); + Timestamp_or_zero_datetime ts(thd, <ime, &error); + Item *column_item; + switch (ftype) + { + case MYSQL_TYPE_DATE: + column_item= new (thd->mem_root) Item_date_literal(thd, &d); + break; + case MYSQL_TYPE_DATETIME: + column_item= new (thd->mem_root) Item_datetime_literal(thd, &dt, dec); + break; + case MYSQL_TYPE_TIMESTAMP: + column_item= new (thd->mem_root) Item_timestamp_literal(thd, ts, dec); + break; + default: + /* Only DATE, DATETIME and TIMESTAMP are allowed */ + DBUG_ASSERT(0); + return TRUE; + } + part_elem_value *range_val= thd->calloc(1); + el->list_val_list.push_back(range_val); + part_column_list_val *col_val= thd->calloc(1); + range_val->col_val_array= col_val; + col_val->item_expression= column_item; + col_val->max_value= false; + col_val->null_value= false; + + /* + Similar to partition_info::fix_column_value_functions, but with a + hack on field->table->write_set to pass the assertion of + marked_for_write_or_computed() in + Field_date_common::store_TIME_with_warning + */ + Field *field= part_info->part_field_array[0]; + col_val->part_info= part_info; + col_val->partition_id= part_id; + uchar *val_ptr; + uint len= field->pack_length(); + + Sql_mode_instant_set sms(thd, 0); + /* Needed to pass assertion on Field::marked_for_write_or_computed() */ + MY_BITMAP *save_write_set= field->table->write_set; + field->table->write_set= &field->table->s->all_set; + bool save_got_warning= thd->got_warning; + thd->got_warning= FALSE; + if (column_item->save_in_field(field, TRUE) || thd->got_warning) + { + field->table->write_set= save_write_set; + my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0)); + return TRUE; + } + thd->got_warning= save_got_warning; + field->table->write_set= save_write_set; + if (!(val_ptr= (uchar*) thd->memdup(field->ptr, len))) + { + return TRUE; + } + col_val->column_value= val_ptr; + col_val->fixed= TRUE; + part_id++; + } while ((el= part_it++)); + return FALSE; +} /* This routine allocates an array for all range constants to achieve a fast @@ -1281,6 +1389,8 @@ static bool check_range_constants(THD *thd, partition_info *part_info) DBUG_PRINT("enter", ("RANGE with %d parts, column_list = %u", part_info->num_parts, part_info->column_list)); + if (part_info->is_range_interval() && check_range_interval_constants(thd, part_info)) + goto end; if (part_info->column_list) { part_column_list_val *loc_range_col_array; @@ -2292,7 +2402,15 @@ static int add_column_list_values(String *str, partition_info *part_info, part_column_list_val *col_val= &list_value->col_val_array[i]; const char *field_name= it++; if (col_val->max_value) + { + /* MAXVALUE is not allowed for range interval auto-partitioning */ + if (part_info->is_range_interval()) + { + my_error(ER_PARTITION_INTERVAL_MAXVALUE, MYF(0)); + return 1; + } err+= str->append(STRING_WITH_LEN("MAXVALUE")); + } else if (col_val->null_value) err+= str->append(NULL_clex_str); else @@ -2324,7 +2442,42 @@ static int add_column_list_values(String *str, partition_info *part_info, return 1; } th= sql_field->type_handler(); - if (th->partition_field_check(sql_field->field_name, item_expr)) + enum_field_types ftype= th->field_type(); + /* + Only allow DATETIME and DATE, and TIMESTAMP for range + interval auto-partitioning. YEAR is already not allowed in + range column partitioning and not very useful for interval + partitioning. + */ + if (part_info->is_range_interval()) + { + if (ftype != MYSQL_TYPE_DATETIME && ftype != MYSQL_TYPE_DATE && + ftype != MYSQL_TYPE_TIMESTAMP) + { + th->partition_field_type_not_allowed(sql_field->field_name); + return 1; + } + /* + Check that the interval is at least one day long when + partitioned by a DATE column + */ + if (ftype == MYSQL_TYPE_DATE) + { + MYSQL_TIME t1= {1, 1, 1, 0, 0, 0, 0, 0, MYSQL_TIMESTAMP_DATE}, + t2= t1; + t1.day++; + if (date_add_interval(current_thd, &t2, part_info->int_type, + part_info->interval)) + return 1; + if (pack_time(&t1) > pack_time(&t2)) + { + my_error(ER_PARTITION_INTERVAL_FINER_THAN_DATE, MYF(0)); + return 1; + } + } + } + else if (th->partition_field_check(sql_field->field_name, + item_expr)) return 1; field_cs= sql_field->explicit_or_derived_charset(&derived_attr); } @@ -2332,7 +2485,14 @@ static int add_column_list_values(String *str, partition_info *part_info, { Field *field= part_info->part_field_array[i]; th= field->type_handler(); - if (th->partition_field_check(field->field_name, item_expr)) + /* + th->partition_field_check(...) has the side effect of + reporting error so we have to rule out TIMESTAMP with + range interval partitioning first + */ + if (likely(!part_info->is_range_interval() || + th->field_type() != MYSQL_TYPE_TIMESTAMP) && + th->partition_field_check(field->field_name, item_expr)) return 1; field_cs= field->charset(); } @@ -2673,6 +2833,13 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info, part_info->part_expr->print_for_table_def(&str); err+= str.append(')'); } + else if (part_info->is_range_interval()) + { + err+= str.append(STRING_WITH_LEN(" COLUMNS")); + err+= add_part_field_list(thd, &str, part_info->part_field_list); + err+= str.append(STRING_WITH_LEN("INTERVAL ")); + err+= append_interval(&str, part_info->int_type, part_info->interval); + } else if (part_info->column_list) { err+= str.append(STRING_WITH_LEN(" COLUMNS")); @@ -5251,7 +5418,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, */ if (thd->lex->no_write_to_binlog && tab_part_info->part_type != HASH_PARTITION && - tab_part_info->part_type != VERSIONING_PARTITION) + tab_part_info->part_type != VERSIONING_PARTITION && + !tab_part_info->is_range_interval()) { my_error(ER_NO_BINLOG_ERROR, MYF(0)); goto err; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index df4395395dcde..88eb290f5377c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1024,6 +1024,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token NOWAIT_SYM %token NUMBER_MARIADB_SYM /* SQL-2003-N */ %token NUMBER_ORACLE_SYM /* Oracle-R, PLSQL-R */ +%token NUMTODSINTERVAL_SYM +%token NUMTOYMINTERVAL_SYM %token NVARCHAR_SYM %token OBJECT_SYM %token OF_SYM /* SQL-1992-R, Oracle-R */ @@ -5111,7 +5113,11 @@ part_type_def: Select->parsing_place= NO_MATTER; } | LIST_SYM part_column_list - { Lex->part_info->part_type= LIST_PARTITION; } + { + Lex->part_info->part_type= LIST_PARTITION; + if (Lex->part_info->int_type != INTERVAL_LAST) + my_yyabort_error((ER_PARTITION_INTERVAL_NOT_LIST, MYF(0))); + } | SYSTEM_TIME_SYM { if (unlikely(Lex->part_info->vers_init_info(thd))) @@ -5179,14 +5185,53 @@ part_field_item: ; part_column_list: - COLUMNS '(' part_field_list ')' + COLUMNS '(' part_field_list ')' opt_part_interval { partition_info *part_info= Lex->part_info; part_info->column_list= TRUE; part_info->list_of_part_fields= TRUE; + if (part_info->int_type != INTERVAL_LAST && + part_info->num_columns > 1) + my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), + "range interval partition fields")); } ; +opt_part_interval: + /* empty */ {} + | INTERVAL_SYM expr interval opt_auto + { + partition_info *part_info= Lex->part_info; + const char *table_name= + Lex->create_last_non_select_table ? + Lex->create_last_non_select_table->table_name.str : ""; + if (unlikely(part_info->set_range_interval(thd, $2, $3, + table_name))) + MYSQL_YYABORT; + } + | INTERVAL_SYM '(' NUMTODSINTERVAL_SYM + '(' NUM ',' TEXT_STRING_sys ')' ')' + { + partition_info *part_info= Lex->part_info; + const char *table_name= + Lex->create_last_non_select_table ? + Lex->create_last_non_select_table->table_name.str : ""; + if (unlikely(part_info->set_range_interval(atoi($5.str), $7, + true, table_name))) + MYSQL_YYABORT; + } + | INTERVAL_SYM '(' NUMTOYMINTERVAL_SYM + '(' NUM ',' TEXT_STRING_sys ')' ')' + { + partition_info *part_info= Lex->part_info; + const char *table_name= + Lex->create_last_non_select_table ? + Lex->create_last_non_select_table->table_name.str : ""; + if (unlikely(part_info->set_range_interval(atoi($5.str), $7, + false, table_name))) + MYSQL_YYABORT; + } + ; part_func: '(' part_func_expr ')' @@ -5448,6 +5493,11 @@ part_func_max: thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); MYSQL_YYABORT; } + else if (part_info->is_range_interval()) + { + my_error(ER_PARTITION_INTERVAL_MAXVALUE, MYF(0)); + MYSQL_YYABORT; + } else part_info->num_columns= 1U; if (unlikely(part_info->init_column_part(thd))) @@ -5757,6 +5807,12 @@ opt_vers_auto_part: $$= 1; } ; + +opt_auto: + /* empty */ {} + | AUTO_SYM {} + ; + /* End of partition parser part */ diff --git a/sql/table.h b/sql/table.h index ba15cf45a1257..6a65d7dfadbba 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2024,6 +2024,8 @@ struct TABLE #ifdef WITH_PARTITION_STORAGE_ENGINE bool vers_switch_partition(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx); + bool range_interval_check_partition(THD *thd, TABLE_LIST *table_list, + Open_table_context *ot_ctx); #endif bool vers_implicit() const;