Commit 9cf3f255 authored by unknown's avatar unknown
Browse files

A fix and a test case for Bug#13134 "Length of VARCHAR() utf8

column is increasing when table is recreated with PS/SP":
make use of create_field::char_length more consistent in the code.
Reinit create_field::length from create_field::char_length
for every execution of a prepared statement (actually fixes the 
bug).


mysql-test/r/ps.result:
  Test results fixed (Bug#13134)
mysql-test/t/ps.test:
  A test case for Bug#13134 "Length of VARCHAR() utf8 column is 
  increasing when table is recreated with PS/SP"
sql/field.cc:
  Move initialization of create_field::char_length to the constructor
  of create_field.
sql/field.h:
  Rename chars_length to char_length (to be consistent with
  how this term is used throughout the rest of the code).
sql/sql_parse.cc:
  Initialize char_length in add_field_to_list. This function
  effectively works as another create_field constructor.
sql/sql_table.cc:
  Reinit length from char_length for every field in 
  mysql_prepare_table. This is not needed if we're executing
  a statement for the first time, however, at subsequent executions
  length contains the number of bytes, not characters (as it's expected 
  to).
parent 1e686ae7
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -733,3 +733,20 @@ count(*)
5
deallocate prepare stmt;
drop table t1;
drop table if exists t1;
Warnings:
Note	1051	Unknown table 't1'
prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
execute stmt;
insert into t1 (a) values (repeat('a', 20));
select length(a) from t1;
length(a)
10
drop table t1;
execute stmt;
insert into t1 (a) values (repeat('a', 20));
select length(a) from t1;
length(a)
10
drop table t1;
deallocate prepare stmt;
+23 −1
Original line number Diff line number Diff line
@@ -763,5 +763,27 @@ execute stmt using @like;
deallocate prepare stmt;
drop table t1;

# End of 4.1 tests

#
# Bug#13134 "Length of VARCHAR() utf8 column is increasing when table is
# recreated with PS/SP"
#

drop table if exists t1;
prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
execute stmt;
--disable_warnings
insert into t1 (a) values (repeat('a', 20));
--enable_warnings
select length(a) from t1;
drop table t1;
execute stmt;
--disable_warnings
insert into t1 (a) values (repeat('a', 20));
--enable_warnings
# Check that the data is truncated to the same length
select length(a) from t1;
drop table t1;
deallocate prepare stmt;

# End of 4.1 tests
+2 −3
Original line number Diff line number Diff line
@@ -6516,13 +6516,11 @@ bool Field_num::eq_def(Field *field)
    create_field::create_length_to_internal_length()
  
  DESCRIPTION
    Convert create_field::length from number of characters to number of bytes,
    save original value in chars_length.
    Convert create_field::length from number of characters to number of bytes.
*/

void create_field::create_length_to_internal_length(void)
{
  chars_length= length;
  switch (sql_type) {
  case MYSQL_TYPE_TINY_BLOB:
  case MYSQL_TYPE_MEDIUM_BLOB:
@@ -6775,6 +6773,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
      break;
  }

  char_length= length;
  decimals= old_field->decimals();
  if (sql_type == FIELD_TYPE_STRING)
  {
+1 −1
Original line number Diff line number Diff line
@@ -1188,7 +1188,7 @@ class create_field :public Sql_alloc {
  /*
    The value of 'length' before a call to create_length_to_internal_length
  */
  uint32 chars_length;
  uint32 char_length;
  uint decimals,flags,pack_length;
  Field::utype unireg_check;
  TYPELIB *interval;			// Which interval to use
+2 −0
Original line number Diff line number Diff line
@@ -4480,6 +4480,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
						  NOT_FIXED_DEC-1) : 0;
  new_field->sql_type=type;
  new_field->length=0;
  new_field->char_length= 0;
  new_field->change=change;
  new_field->interval=0;
  new_field->pack_length=0;
@@ -4750,6 +4751,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
					    FIELD_TYPE_STRING :
					    new_field->sql_type,
					    new_field->length);
  new_field->char_length= new_field->length;
  lex->create_list.push_back(new_field);
  lex->last_field=new_field;
  DBUG_RETURN(0);
Loading