From c86773f46fa80599c5571b62147dde34135f5851 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 6 Feb 2019 22:26:52 +0300 Subject: MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments [Closes tempesta-tech/mariadb#572] --- mysql-test/suite/versioning/r/partition.result | 19 +++++++++++++++++++ mysql-test/suite/versioning/t/partition.test | 14 ++++++++++++++ sql/partition_info.h | 14 ++++++++++++-- sql/sql_yacc.yy | 7 +------ sql/sql_yacc_ora.yy | 7 +------ 5 files changed, 47 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index 3c33967b780..3fcb59bdb40 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -522,6 +522,25 @@ set timestamp=1523466002.799571; insert into t1 values (11),(12); set timestamp=1523466004.169435; delete from t1 where pk in (11, 12); +# +# MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments +# +create or replace table t1 (pk int) with system versioning +partition by system_time interval 7 second ( +partition ver_p1 history, +partition ver_pn current); +alter table t1 +partition by system_time interval column_get(column_create(7,7), 7 as int) second ( +partition ver_p1 history, +partition ver_pn current); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) DEFAULT NULL +) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING + PARTITION BY SYSTEM_TIME INTERVAL 7 SECOND +(PARTITION `ver_p1` HISTORY ENGINE = DEFAULT_ENGINE, + PARTITION `ver_pn` CURRENT ENGINE = DEFAULT_ENGINE) # Test cleanup drop database test; create database test; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index 88411468516..d5c83b4d3bb 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -475,6 +475,20 @@ insert into t1 values (11),(12); set timestamp=1523466004.169435; delete from t1 where pk in (11, 12); +--echo # +--echo # MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments +--echo # +create or replace table t1 (pk int) with system versioning +partition by system_time interval 7 second ( + partition ver_p1 history, + partition ver_pn current); +alter table t1 +partition by system_time interval column_get(column_create(7,7), 7 as int) second ( + partition ver_p1 history, + partition ver_pn current); +--replace_result $default_engine DEFAULT_ENGINE +show create table t1; + --echo # Test cleanup drop database test; create database test; diff --git a/sql/partition_info.h b/sql/partition_info.h index 5c7dec4c05e..d6a6214c172 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -395,16 +395,26 @@ public: bool field_in_partition_expr(Field *field) const; bool vers_init_info(THD *thd); - bool vers_set_interval(Item *item, interval_type int_type, my_time_t start) + bool vers_set_interval(THD *thd, Item *item, + interval_type int_type, my_time_t start) { DBUG_ASSERT(part_type == VERSIONING_PARTITION); vers_info->interval.type= int_type; vers_info->interval.start= start; - return get_interval_value(item, int_type, &vers_info->interval.step) || + if (item->fix_fields_if_needed_for_scalar(thd, &item)) + return true; + bool error= get_interval_value(item, int_type, &vers_info->interval.step) || vers_info->interval.step.neg || vers_info->interval.step.second_part || !(vers_info->interval.step.year || vers_info->interval.step.month || vers_info->interval.step.day || vers_info->interval.step.hour || vers_info->interval.step.minute || vers_info->interval.step.second); + if (error) + { + my_error(ER_PART_WRONG_VALUE, MYF(0), + thd->lex->create_last_non_select_table->table_name.str, + "INTERVAL"); + } + return error; } bool vers_set_limit(ulonglong limit) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f89984d848f..a333bd79dd3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6064,13 +6064,8 @@ opt_versioning_rotation: | INTERVAL_SYM expr interval opt_versioning_interval_start { partition_info *part_info= Lex->part_info; - if (unlikely(part_info->vers_set_interval($2, $3, $4))) - { - my_error(ER_PART_WRONG_VALUE, MYF(0), - Lex->create_last_non_select_table->table_name.str, - "INTERVAL"); + if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4))) MYSQL_YYABORT; - } } | LIMIT ulonglong_num { diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 6a05423ebc3..7d561e7c34a 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -5910,13 +5910,8 @@ opt_versioning_rotation: | INTERVAL_SYM expr interval opt_versioning_interval_start { partition_info *part_info= Lex->part_info; - if (unlikely(part_info->vers_set_interval($2, $3, $4))) - { - my_error(ER_PART_WRONG_VALUE, MYF(0), - Lex->create_last_non_select_table->table_name.str, - "INTERVAL"); + if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4))) MYSQL_YYABORT; - } } | LIMIT ulonglong_num { -- cgit v1.2.1