summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2019-02-06 22:26:52 +0300
committerAlexander Barkov <bar@mariadb.com>2019-05-20 15:28:20 +0400
commitc86773f46fa80599c5571b62147dde34135f5851 (patch)
tree6cc56aa15743caf3417285af0ded5549b6b6959d
parent6473641b9a04d65b7480831e926aa4150571a617 (diff)
downloadmariadb-git-c86773f46fa80599c5571b62147dde34135f5851.tar.gz
MDEV-18136 Server crashes in Item_func_dyncol_create::prepare_arguments
[Closes tempesta-tech/mariadb#572]
-rw-r--r--mysql-test/suite/versioning/r/partition.result19
-rw-r--r--mysql-test/suite/versioning/t/partition.test14
-rw-r--r--sql/partition_info.h14
-rw-r--r--sql/sql_yacc.yy7
-rw-r--r--sql/sql_yacc_ora.yy7
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
{