Commit 9b53e541 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-13788 Server crash when issuing bad SQL partition syntax

parent c44ece73
--echo #
--echo # MDEV-13788 Server crash when issuing bad SQL partition syntax
--echo #
--eval CREATE TABLE t1 (id int, d date) ENGINE=$engine PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE))
SHOW CREATE TABLE t1;
--error ER_PARTITION_REQUIRES_VALUES_ERROR
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
DROP TABLE t1;
--eval CREATE TABLE t1 (id int, d date) ENGINE=$engine PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3))
SHOW CREATE TABLE t1;
--error ER_PARTITION_REQUIRES_VALUES_ERROR
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES IN (4,5,6)
);
DROP TABLE t1;
#
# MDEV-13788 Server crash when issuing bad SQL partition syntax
#
CREATE TABLE t1 (id int, d date) ENGINE=InnoDB PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
DROP TABLE t1;
CREATE TABLE t1 (id int, d date) ENGINE=InnoDB PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY LIST (id)
(PARTITION p1 VALUES IN (1,2,3) ENGINE = InnoDB) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
...@@ -16,3 +16,38 @@ select * from t1; ...@@ -16,3 +16,38 @@ select * from t1;
pk dt pk dt
1 2017-09-28 15:12:00 1 2017-09-28 15:12:00
drop table t1; drop table t1;
#
# MDEV-13788 Server crash when issuing bad SQL partition syntax
#
CREATE TABLE t1 (id int, d date) ENGINE=Aria PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN (MAXVALUE) ENGINE = Aria) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
DROP TABLE t1;
CREATE TABLE t1 (id int, d date) ENGINE=Aria PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1
/*!50100 PARTITION BY LIST (id)
(PARTITION p1 VALUES IN (1,2,3) ENGINE = Aria) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
#
# MDEV-13788 Server crash when issuing bad SQL partition syntax
#
CREATE TABLE t1 (id int, d date) ENGINE=MyISAM PARTITION BY RANGE COLUMNS(d) (PARTITION p1 VALUES LESS THAN (MAXVALUE));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE COLUMNS(d)
(PARTITION p1 VALUES LESS THAN (MAXVALUE) ENGINE = MyISAM) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
ERROR HY000: Syntax error: RANGE PARTITIONING requires definition of VALUES LESS THAN for each partition
DROP TABLE t1;
CREATE TABLE t1 (id int, d date) ENGINE=MyISAM PARTITION BY LIST (id) (PARTITION p1 VALUES IN (1,2,3));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL,
`d` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
/*!50100 PARTITION BY LIST (id)
(PARTITION p1 VALUES IN (1,2,3) ENGINE = MyISAM) */
ALTER TABLE t1 REORGANIZE PARTITION p1 INTO
(
PARTITION p2, /* Notice no values */
PARTITION p3 VALUES IN (4,5,6)
);
ERROR HY000: Syntax error: LIST PARTITIONING requires definition of VALUES IN for each partition
DROP TABLE t1;
--source include/have_innodb.inc
--source include/have_partition.inc
--let $engine=InnoDB
--source inc/part_alter_values.inc
...@@ -16,3 +16,6 @@ select * from t1; ...@@ -16,3 +16,6 @@ select * from t1;
alter table t1 drop partition p20181231; alter table t1 drop partition p20181231;
select * from t1; select * from t1;
drop table t1; drop table t1;
--let $engine=Aria
--source inc/part_alter_values.inc
--source include/have_partition.inc
--let $engine=MyISAM
--source inc/part_alter_values.inc
...@@ -2132,6 +2132,24 @@ bool partition_info::fix_column_value_functions(THD *thd, ...@@ -2132,6 +2132,24 @@ bool partition_info::fix_column_value_functions(THD *thd,
DBUG_RETURN(result); DBUG_RETURN(result);
} }
bool partition_info::error_if_requires_values() const
{
switch (part_type) {
case NOT_A_PARTITION:
case HASH_PARTITION:
break;
case RANGE_PARTITION:
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "RANGE", "LESS THAN");
return true;
case LIST_PARTITION:
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN");
return true;
}
return false;
}
/* /*
The parser generates generic data structures, we need to set them up The parser generates generic data structures, we need to set them up
as the rest of the code expects to find them. This is in reality part as the rest of the code expects to find them. This is in reality part
...@@ -2221,6 +2239,8 @@ int partition_info::fix_parser_data(THD *thd) ...@@ -2221,6 +2239,8 @@ int partition_info::fix_parser_data(THD *thd)
part_elem= it++; part_elem= it++;
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list); List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
num_elements= part_elem->list_val_list.elements; num_elements= part_elem->list_val_list.elements;
if (!num_elements && error_if_requires_values())
DBUG_RETURN(true);
DBUG_ASSERT(part_type == RANGE_PARTITION ? DBUG_ASSERT(part_type == RANGE_PARTITION ?
num_elements == 1U : TRUE); num_elements == 1U : TRUE);
for (j= 0; j < num_elements; j++) for (j= 0; j < num_elements; j++)
......
...@@ -313,6 +313,7 @@ class partition_info : public Sql_alloc ...@@ -313,6 +313,7 @@ class partition_info : public Sql_alloc
void set_show_version_string(String *packet); void set_show_version_string(String *packet);
void report_part_expr_error(bool use_subpart_expr); void report_part_expr_error(bool use_subpart_expr);
bool has_same_partitioning(partition_info *new_part_info); bool has_same_partitioning(partition_info *new_part_info);
bool error_if_requires_values() const;
private: private:
static int list_part_cmp(const void* a, const void* b); static int list_part_cmp(const void* a, const void* b);
bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,
......
...@@ -4770,16 +4770,11 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, ...@@ -4770,16 +4770,11 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"LIST", "IN"); "LIST", "IN");
} }
else if (tab_part_info->part_type == RANGE_PARTITION)
{
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"RANGE", "LESS THAN");
}
else else
{ {
DBUG_ASSERT(tab_part_info->part_type == LIST_PARTITION); DBUG_ASSERT(tab_part_info->part_type == RANGE_PARTITION ||
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), tab_part_info->part_type == LIST_PARTITION);
"LIST", "IN"); (void) tab_part_info->error_if_requires_values();
} }
goto err; goto err;
} }
......
...@@ -4679,18 +4679,8 @@ opt_part_values: ...@@ -4679,18 +4679,8 @@ opt_part_values:
partition_info *part_info= lex->part_info; partition_info *part_info= lex->part_info;
if (! lex->is_partition_management()) if (! lex->is_partition_management())
{ {
if (part_info->part_type == RANGE_PARTITION) if (part_info->error_if_requires_values())
{ MYSQL_YYABORT;
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"RANGE", "LESS THAN");
MYSQL_YYABORT;
}
if (part_info->part_type == LIST_PARTITION)
{
my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
"LIST", "IN");
MYSQL_YYABORT;
}
} }
else else
part_info->part_type= HASH_PARTITION; part_info->part_type= HASH_PARTITION;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment