diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index af277e5ce40..fb991ef5fcc 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -1,4 +1,28 @@ drop table if exists t1; +create table t1 (a varchar(5)) +engine=memory +partition by range column_list(a) +( partition p0 values less than (column_list('m')), +partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; +create table t1 (a varchar(5)) +engine=myisam +partition by range column_list(a) +( partition p0 values less than (column_list('m')), +partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; +create table t1 (a varchar(5)) +engine=innodb +partition by range column_list(a) +( partition p0 values less than (column_list('m')), +partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; CREATE TABLE t1 (id INT PRIMARY KEY, data INT) ENGINE = InnoDB PARTITION BY RANGE(id) ( PARTITION p0 VALUES LESS THAN (5), diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index c6bf0af0b6f..a8758525342 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -5,6 +5,36 @@ drop table if exists t1; --enable_warnings +# +# BUG#47776, Failed to update for MEMORY engine, crash for InnoDB and success for MyISAM +# +create table t1 (a varchar(5)) +engine=memory +partition by range column_list(a) +( partition p0 values less than (column_list('m')), + partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; + +create table t1 (a varchar(5)) +engine=myisam +partition by range column_list(a) +( partition p0 values less than (column_list('m')), + partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; + +create table t1 (a varchar(5)) +engine=innodb +partition by range column_list(a) +( partition p0 values less than (column_list('m')), + partition p1 values less than (column_list('za'))); +insert into t1 values ('j'); +update t1 set a = 'z' where (a >= 'j'); +drop table t1; + # # Bug#40595: Non-matching rows not released with READ-COMMITTED on tables # with partitions diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 898cf8f07cd..5e7fdb6c981 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1404,15 +1404,21 @@ static void set_up_partition_func_pointers(partition_info *part_info) if (part_info->is_sub_partitioned()) { DBUG_ASSERT(part_info->get_part_partition_id); - part_info->get_part_partition_id_charset= - part_info->get_part_partition_id; - part_info->get_part_partition_id= get_part_id_charset_func_part; + if (!part_info->column_list) + { + part_info->get_part_partition_id= + part_info->get_part_partition_id_charset; + part_info->get_part_partition_id= get_part_id_charset_func_part; + } } else { DBUG_ASSERT(part_info->get_partition_id); - part_info->get_part_partition_id_charset= part_info->get_partition_id; - part_info->get_partition_id= get_part_id_charset_func_part; + if (!part_info->column_list) + { + part_info->get_part_partition_id_charset= part_info->get_partition_id; + part_info->get_part_partition_id= get_part_id_charset_func_part; + } } } if (part_info->subpart_charset_field_array) @@ -1715,7 +1721,8 @@ bool fix_partition_func(THD *thd, TABLE *table, } if (((part_info->part_type != HASH_PARTITION || part_info->list_of_part_fields == FALSE) && - check_part_func_fields(part_info->part_field_array, TRUE)) || + (!part_info->column_list && + check_part_func_fields(part_info->part_field_array, TRUE))) || (part_info->list_of_part_fields == FALSE && part_info->is_sub_partitioned() && check_part_func_fields(part_info->subpart_field_array, TRUE))) @@ -2603,7 +2610,8 @@ static void copy_to_part_field_buffers(Field **ptr, if (!field->maybe_null() || !field->is_null()) { CHARSET_INFO *cs= ((Field_str*)field)->charset(); - uint len= field->pack_length(); + uint max_len= field->pack_length(); + uint data_len= field->data_length(); uchar *field_buf= *field_bufs; /* We only use the field buffer for VARCHAR and CHAR strings @@ -2615,17 +2623,17 @@ static void copy_to_part_field_buffers(Field **ptr, if (field->type() == MYSQL_TYPE_VARCHAR) { uint len_bytes= ((Field_varstring*)field)->length_bytes; - my_strnxfrm(cs, field_buf + len_bytes, (len - len_bytes), - field->ptr + len_bytes, field->field_length); + my_strnxfrm(cs, field_buf + len_bytes, max_len, + field->ptr + len_bytes, data_len); if (len_bytes == 1) - *field_buf= (uchar) field->field_length; + *field_buf= (uchar) data_len; else - int2store(field_buf, field->field_length); + int2store(field_buf, data_len); } else { - my_strnxfrm(cs, field_buf, len, - field->ptr, field->field_length); + my_strnxfrm(cs, field_buf, max_len, + field->ptr, max_len); } field->ptr= field_buf; }