Commit de264164 authored by unknown's avatar unknown
Browse files

Bug#14367 Partitions: crash if utf8 column

  use part_info->item_free_list instead of thd->free_list during partition function parsing


mysql-test/r/partition.result:
  Bug#14367 Partitions: crash if utf8 column
    test case
mysql-test/t/partition.test:
  Bug#14367 Partitions: crash if utf8 column
    test case
sql/item.cc:
  Bug#14367 Partitions: crash if utf8 column
    create copy of string in current mem_root to avoid memory leak
parent f9dd31ca
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -557,4 +557,9 @@ t2 CREATE TABLE `t2` (
  PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='no comment' PARTITION BY KEY (a) 
drop table t2;
create table t1 (s1 char(2) character set utf8)
partition by list (case when s1 > 'cz' then 1 else 2 end)
(partition p1 values in (1),
partition p2 values in (2));
drop table t1;
End of 5.1 tests
+9 −0
Original line number Diff line number Diff line
@@ -714,4 +714,13 @@ show create table t2;

drop table t2;

#
# Bug#14367: Partitions: crash if utf8 column
#
create table t1 (s1 char(2) character set utf8)
partition by list (case when s1 > 'cz' then 1 else 2 end)
(partition p1 values in (1),
 partition p2 values in (2));
drop table t1;

--echo End of 5.1 tests
+4 −1
Original line number Diff line number Diff line
@@ -647,6 +647,7 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
{
  Item_string *conv;
  uint conv_errors;
  char *ptr;
  String tmp, cstr, *ostr= val_str(&tmp);
  cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
  if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
@@ -661,7 +662,9 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
    */
    return NULL;
  }
  conv->str_value.copy();
  if (!(ptr= current_thd->memdup(cstr.ptr(), cstr.length() + 1 )))
    return NULL;
  conv->str_value.set(ptr, cstr.length(), cstr.charset());
  /* Ensure that no one is going to change the result string */
  conv->str_value.mark_as_const();
  return conv;
+3 −0
Original line number Diff line number Diff line
@@ -1710,6 +1710,7 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
  char* db_name;
  partition_info *part_info= table->part_info;
  ulong save_set_query_id= thd->set_query_id;
  Item *thd_free_list= thd->free_list;
  DBUG_ENTER("fix_partition_func");

  if (part_info->fixed)
@@ -1744,6 +1745,7 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
      DBUG_RETURN(TRUE);
    }
  }
  thd->free_list= part_info->item_free_list;
  if (part_info->is_sub_partitioned())
  {
    DBUG_ASSERT(part_info->subpart_type == HASH_PARTITION);
@@ -1853,6 +1855,7 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
  set_up_range_analysis_info(part_info);
  result= FALSE;
end:
  thd->free_list= thd_free_list;
  thd->set_query_id= save_set_query_id;
  DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
  DBUG_RETURN(result);