Commit 115bf436 authored by unknown's avatar unknown
Browse files

BUG#14139: When handling "CREATE TABLE(field_X type_spec,...) SELECT smth AS field_X, ...."

avoid multiplying length of field_X by charset->mbmaxlen twice when calculating space 
required for field_X in the new table.


mysql-test/r/create.result:
  Testcase for BUG#14139
mysql-test/t/create.test:
  Testcase for BUG#14139
sql/field.cc:
  BUG#14139: Make create_length_to_internal_length() save length-in-characters in 
  create_field::chars_length.
sql/field.h:
  BUG#14139: Add create_length::chars_length where we save length-in-characters, added comments.
sql/sql_table.cc:
  BUG#14139: When handling "CREATE TABLE(field_X type_spec,...) SELECT smth AS field_X, ...."
  we get two instances of create_field: (1) is occurence of field_X in create list, and (2) is
  in select list. If we figure they both refer to the same field, we "join" them according to
  some rule that is not explicitly specified anywhere.
  When we do this "join", create_field::length already contains length-in-bytes for both, so
  when we transfer field length (in characters) from (1) to (2), use length-in-characters that
  we have saved in create_length::chars_length.
parent 1c9783e8
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -621,3 +621,14 @@ create table if not exists t1 (a int);
Warnings:
Note	1050	Table 't1' already exists
drop table t1;
create table t1 (
a varchar(112) charset utf8 collate utf8_bin not null,
primary key (a)
) select 'test' as a ;
show create table t1;
Table	Create Table
t1	CREATE TABLE `t1` (
  `a` varchar(112) character set utf8 collate utf8_bin NOT NULL default '',
  PRIMARY KEY  (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
+8 −0
Original line number Diff line number Diff line
@@ -526,4 +526,12 @@ create table t1 (a int);
create table if not exists t1 (a int);
drop table t1;

# BUG#14139
create table t1 (
  a varchar(112) charset utf8 collate utf8_bin not null,
  primary key (a)
) select 'test' as a ;
show create table t1;
drop table t1;

# End of 4.1 tests
+12 −0
Original line number Diff line number Diff line
@@ -6511,8 +6511,20 @@ bool Field_num::eq_def(Field *field)
** Handling of field and create_field
*****************************************************************************/

/*
  Convert create_field::length from number of characters to number of bytes

  SYNOPSIS
    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.
*/

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:
+8 −0
Original line number Diff line number Diff line
@@ -1180,7 +1180,15 @@ class create_field :public Sql_alloc {
  LEX_STRING comment;			// Comment for field
  Item	*def;				// Default value
  enum	enum_field_types sql_type;
  /*
    At various stages in execution this can be length of field in bytes or
    max number of characters. 
  */
  uint32 length;
  /*
    The value of 'length' before a call to create_length_to_internal_length
  */
  uint32 chars_length;
  uint decimals,flags,pack_length;
  Field::utype unireg_check;
  TYPELIB *interval;			// Which interval to use
+2 −2
Original line number Diff line number Diff line
@@ -643,7 +643,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
	  sql_field->charset=		(dup_field->charset ?
					 dup_field->charset :
					 create_info->default_table_charset);
	  sql_field->length=		dup_field->length;
	  sql_field->length=		dup_field->chars_length;
          sql_field->pack_length=	dup_field->pack_length;
	  sql_field->create_length_to_internal_length();
	  sql_field->decimals=		dup_field->decimals;