1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge with new VARCHAR code

This commit is contained in:
monty@mysql.com
2004-12-06 19:18:35 +02:00
167 changed files with 3256 additions and 19115 deletions

View File

@ -429,8 +429,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
copy->length-=table->blob_ptr_size;
return copy->length;
}
else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length > 4 ||
type() == FIELD_TYPE_VAR_STRING))
else if (!zero_pack() && (type() == FIELD_TYPE_STRING && copy->length >= 4))
copy->strip=1; /* Remove end space */
else
copy->strip=0;
@ -479,6 +478,26 @@ bool Field::optimize_range(uint idx, uint part)
return test(table->file->index_flags(idx, part, 1) & HA_READ_RANGE);
}
Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table)
{
Field *tmp;
if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
return 0;
if (tmp->table->maybe_null)
tmp->flags&= ~NOT_NULL_FLAG;
tmp->table= new_table;
tmp->key_start.init(0);
tmp->part_of_key.init(0);
tmp->part_of_sortkey.init(0);
tmp->unireg_check=Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
tmp->reset_fields();
return tmp;
}
/****************************************************************************
Field_null, a field that always return NULL
****************************************************************************/
@ -4432,7 +4451,7 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a_ptr, field_length,
(const uchar*) b_ptr,
field_length);
field_length, 0);
}
if (field_charset->mbmaxlen != 1)
{
@ -4461,20 +4480,22 @@ void Field_string::sql_type(String &res) const
{
THD *thd= table->in_use;
CHARSET_INFO *cs=res.charset();
ulong length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
(field_length > 3 &&
(table->db_options_in_use &
HA_OPTION_PACK_RECORD) ?
(has_charset() ? "varchar" : "varbinary") :
ulong length;
length= cs->cset->snprintf(cs,(char*) res.ptr(),
res.alloced_length(), "%s(%d)",
((type() == MYSQL_TYPE_VAR_STRING &&
!thd->variables.new_mode) ?
(has_charset() ? "varchar" : "varbinary") :
(has_charset() ? "char" : "binary")),
(int) field_length / charset()->mbmaxlen);
(int) field_length / charset()->mbmaxlen);
res.length(length);
if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
has_charset() && (charset()->state & MY_CS_BINSORT))
res.append(" binary");
}
char *Field_string::pack(char *to, const char *from, uint max_length)
{
uint length= min(field_length,max_length);
@ -4508,10 +4529,27 @@ const char *Field_string::unpack(char *to, const char *from)
}
int Field_string::pack_cmp(const char *a, const char *b, uint length)
/*
Compare two packed keys
SYNOPSIS
pack_cmp()
a New key
b Original key
length Key length
insert_or_update 1 if this is an insert or update
RETURN
< 0 a < b
0 a = b
> 0 a > b
*/
int Field_string::pack_cmp(const char *a, const char *b, uint length,
my_bool insert_or_update)
{
uint a_length, b_length;
if (field_length > 255)
if (length > 255)
{
a_length= uint2korr(a);
b_length= uint2korr(b);
@ -4523,29 +4561,51 @@ int Field_string::pack_cmp(const char *a, const char *b, uint length)
a_length= (uint) (uchar) *a++;
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar*)a,a_length,
(const uchar*)b,b_length);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length,
insert_or_update);
}
int Field_string::pack_cmp(const char *b, uint length)
/*
Compare a packed key against row
SYNOPSIS
pack_cmp()
key Original key
length Key length. (May be less than field length)
insert_or_update 1 if this is an insert or update
RETURN
< 0 row < key
0 row = key
> 0 row > key
*/
int Field_string::pack_cmp(const char *key, uint length,
my_bool insert_or_update)
{
uint b_length;
if (field_length > 255)
uint row_length, key_length;
char *end;
if (length > 255)
{
b_length= uint2korr(b);
b+= 2;
key_length= uint2korr(key);
key+= 2;
}
else
b_length= (uint) (uchar) *b++;
char *end= ptr + field_length;
key_length= (uint) (uchar) *key++;
/* Only use 'length' of key, not field_length */
end= ptr + length;
while (end > ptr && end[-1] == ' ')
end--;
uint a_length = (uint) (end - ptr);
return my_strnncoll(field_charset,
(const uchar*)ptr,a_length,
(const uchar*)b, b_length);
row_length= (uint) (end - ptr);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) ptr, row_length,
(const uchar*) key, key_length,
insert_or_update);
}
@ -4553,16 +4613,31 @@ uint Field_string::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
return uint2korr(data_ptr)+2;
else
return (uint) ((uchar) *data_ptr)+1;
return (uint) ((uchar) *data_ptr)+1;
}
uint Field_string::max_packed_col_length(uint max_length)
{
return (max_length > 255 ? 2 : 1)+max_length;
}
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
{
if (type() != MYSQL_TYPE_VAR_STRING || table == new_table)
return Field::new_field(root, new_table);
/*
Old VARCHAR field which should be modified to a VARCHAR on copy
This is done to ensure that ALTER TABLE will convert old VARCHAR fields
to now VARCHAR fields.
*/
return new Field_varstring(field_length, maybe_null(),
field_name, new_table,
charset());
}
/****************************************************************************
** VARCHAR type (Not available for the end user yet)
****************************************************************************/
@ -4571,7 +4646,7 @@ uint Field_string::max_packed_col_length(uint max_length)
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
{
int error= 0;
uint32 not_used;
uint32 not_used, copy_length;
char buff[80];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
@ -4585,15 +4660,21 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
if (conv_errors)
error= 1;
}
if (length > field_length)
{
length=field_length;
/*
Make sure we don't break a multibyte sequence
as well as don't copy a malformed data.
*/
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length,
field_length/
field_charset->mbmaxlen);
memcpy(ptr + HA_KEY_BLOB_LENGTH, from, copy_length);
int2store(ptr, copy_length);
if (copy_length < length)
error= 1;
}
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
memcpy(ptr+HA_KEY_BLOB_LENGTH,from,length);
int2store(ptr, length);
return error;
}
@ -4640,17 +4721,49 @@ int Field_varstring::cmp(const char *a_ptr, const char *b_ptr)
uint a_length=uint2korr(a_ptr);
uint b_length=uint2korr(b_ptr);
int diff;
diff= my_strnncoll(field_charset,
(const uchar*) a_ptr+HA_KEY_BLOB_LENGTH,
min(a_length,b_length),
(const uchar*) b_ptr+HA_KEY_BLOB_LENGTH,
min(a_length,b_length));
return diff ? diff : (int) (a_length - b_length);
diff= field_charset->coll->strnncollsp(field_charset,
(const uchar*) a_ptr+
HA_KEY_BLOB_LENGTH,
a_length,
(const uchar*) b_ptr+
HA_KEY_BLOB_LENGTH,
b_length,0);
return diff;
}
int Field_varstring::key_cmp(const byte *key_ptr, uint max_key_length)
{
char *blob1;
uint length= uint2korr(ptr);
CHARSET_INFO *cs= charset();
uint char_length= max_key_length / cs->mbmaxlen;
char_length= my_charpos(cs, ptr + HA_KEY_BLOB_LENGTH,
ptr + HA_KEY_BLOB_LENGTH + length, char_length);
set_if_smaller(length, char_length);
return cs->coll->strnncollsp(cs,
(const uchar*) ptr+2, length,
(const uchar*) key_ptr+HA_KEY_BLOB_LENGTH,
uint2korr(key_ptr), 0);
}
int Field_varstring::key_cmp(const byte *a,const byte *b)
{
CHARSET_INFO *cs= charset();
return cs->coll->strnncollsp(cs,
(const uchar*) a + HA_KEY_BLOB_LENGTH,
uint2korr(a),
(const uchar*) b + HA_KEY_BLOB_LENGTH,
uint2korr(b),
0);
}
void Field_varstring::sort_string(char *to,uint length)
{
uint tot_length=uint2korr(ptr);
uint tot_length= uint2korr(ptr);
tot_length= my_strnxfrm(field_charset,
(uchar*) to, length,
(uchar*) ptr+HA_KEY_BLOB_LENGTH,
@ -4670,9 +4783,11 @@ void Field_varstring::sql_type(String &res) const
res.length(length);
}
char *Field_varstring::pack(char *to, const char *from, uint max_length)
{
uint length=uint2korr(from);
set_if_smaller(max_length, field_length);
if (length > max_length)
length=max_length;
*to++= (char) (length & 255);
@ -4687,12 +4802,14 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length)
char *Field_varstring::pack_key(char *to, const char *from, uint max_length)
{
uint length=uint2korr(from);
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
from+=HA_KEY_BLOB_LENGTH;
uint char_length= ((field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length);
from+= HA_KEY_BLOB_LENGTH;
if (length > char_length)
{
char_length= my_charpos(field_charset, from, from+length, char_length);
set_if_smaller(length, char_length);
set_if_smaller(length, char_length);
}
*to++= (char) (length & 255);
if (max_length > 255)
*to++= (char) (length >> 8);
@ -4705,16 +4822,16 @@ char *Field_varstring::pack_key(char *to, const char *from, uint max_length)
const char *Field_varstring::unpack(char *to, const char *from)
{
uint length;
if (field_length > 255)
if (field_length <= 255)
{
length= (uint) (uchar) (*to= *from++);
to[1]=0;
}
else
{
length=uint2korr(from);
to[0] = *from++;
to[1] = *from++;
length= uint2korr(from);
to[0]= *from++;
to[1]= *from++;
}
if (length)
memcpy(to+HA_KEY_BLOB_LENGTH, from, length);
@ -4722,77 +4839,122 @@ const char *Field_varstring::unpack(char *to, const char *from)
}
int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length)
int Field_varstring::pack_cmp(const char *a, const char *b, uint key_length,
my_bool insert_or_update)
{
uint a_length;
uint b_length;
if (key_length > 255)
{
a_length=uint2korr(a); a+= 2;
b_length=uint2korr(b); b+= 2;
a_length=uint2korr(a); a+= HA_KEY_BLOB_LENGTH;
b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
}
else
{
a_length= (uint) (uchar) *a++;
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length,
insert_or_update);
}
int Field_varstring::pack_cmp(const char *b, uint key_length)
int Field_varstring::pack_cmp(const char *b, uint key_length,
my_bool insert_or_update)
{
char *a= ptr+HA_KEY_BLOB_LENGTH;
uint a_length= uint2korr(ptr);
uint b_length;
uint char_length= ((field_charset->mbmaxlen > 1) ?
key_length / field_charset->mbmaxlen : key_length);
if (key_length > 255)
{
b_length=uint2korr(b); b+= 2;
b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
}
else
{
b_length= (uint) (uchar) *b++;
if (a_length > char_length)
{
char_length= my_charpos(field_charset, a, a+a_length, char_length);
set_if_smaller(a_length, char_length);
}
return my_strnncoll(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a,
a_length,
(const uchar*) b, b_length,
insert_or_update);
}
uint Field_varstring::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
return uint2korr(data_ptr)+HA_KEY_BLOB_LENGTH;
else
return (uint) ((uchar) *data_ptr)+1;
return (uint) ((uchar) *data_ptr)+1;
}
uint Field_varstring::max_packed_col_length(uint max_length)
{
return (max_length > 255 ? 2 : 1)+max_length;
}
void Field_varstring::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
void Field_varstring::get_key_image(char *buff, uint length, imagetype type)
{
uint f_length=uint2korr(ptr);
if (f_length > length)
f_length= length;
int2store(buff,length);
memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, length);
#ifdef HAVE_purify
uint f_length= uint2korr(ptr);
uint char_length= length / field_charset->mbmaxlen;
char_length= my_charpos(field_charset, ptr, ptr + HA_KEY_BLOB_LENGTH,
char_length);
set_if_smaller(f_length, char_length);
int2store(buff,f_length);
memcpy(buff+HA_KEY_BLOB_LENGTH, ptr+HA_KEY_BLOB_LENGTH, f_length);
if (f_length < length)
{
/*
Must clear this as we do a memcmp in opt_range.cc to detect
identical keys
*/
bzero(buff+HA_KEY_BLOB_LENGTH+f_length, (length-f_length));
#endif
}
}
void Field_varstring::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
void Field_varstring::set_key_image(char *buff,uint length)
{
length=uint2korr(buff); // Real length is here
(void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
(void) Field_varstring::store(buff+HA_KEY_BLOB_LENGTH, length,
field_charset);
}
int Field_varstring::cmp_binary_offset(uint row_offset)
{
return cmp_binary(ptr, ptr+row_offset);
}
int Field_varstring::cmp_binary(const char *a_ptr, const char *b_ptr,
uint32 max_length)
{
char *a,*b;
uint diff;
uint32 a_length,b_length;
a_length= uint2korr(a_ptr);
b_length= uint2korr(b_ptr);
set_if_smaller(a_length, max_length);
set_if_smaller(b_length, max_length);
if (a_length != b_length)
return 1;
return memcmp(a_ptr+2, b_ptr+2, a_length);
}
/****************************************************************************
** blob type
@ -5030,10 +5192,10 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
int Field_blob::cmp(const char *a,uint32 a_length, const char *b,
uint32 b_length)
{
return field_charset->coll->strnncoll(field_charset,
(const uchar*)a, a_length,
(const uchar*)b, b_length,
0);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*)a, a_length,
(const uchar*)b, b_length,
0);
}
@ -5080,8 +5242,7 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
/* The following is used only when comparing a key */
void Field_blob::get_key_image(char *buff,uint length,
CHARSET_INFO *cs, imagetype type)
void Field_blob::get_key_image(char *buff, uint length, imagetype type)
{
uint32 blob_length= get_length(ptr);
char *blob;
@ -5116,8 +5277,9 @@ void Field_blob::get_key_image(char *buff,uint length,
#endif /*HAVE_SPATIAL*/
get_ptr(&blob);
uint char_length= length / cs->mbmaxlen;
char_length= my_charpos(cs, blob, blob + blob_length, char_length);
uint char_length= length / field_charset->mbmaxlen;
char_length= my_charpos(field_charset, blob, blob + blob_length,
char_length);
set_if_smaller(blob_length, char_length);
if ((uint32) length > blob_length)
@ -5133,10 +5295,11 @@ void Field_blob::get_key_image(char *buff,uint length,
memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
}
void Field_blob::set_key_image(char *buff,uint length, CHARSET_INFO *cs)
void Field_blob::set_key_image(char *buff,uint length)
{
length= uint2korr(buff);
(void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, cs);
(void) Field_blob::store(buff+HA_KEY_BLOB_LENGTH, length, field_charset);
}
@ -5149,7 +5312,7 @@ int Field_blob::key_cmp(const byte *key_ptr, uint max_key_length)
uint char_length= max_key_length / cs->mbmaxlen;
char_length= my_charpos(cs, blob1, blob1+blob_length, char_length);
set_if_smaller(blob_length, char_length);
return Field_blob::cmp(blob1,min(blob_length, max_key_length),
return Field_blob::cmp(blob1, blob_length,
(char*) key_ptr+HA_KEY_BLOB_LENGTH,
uint2korr(key_ptr));
}
@ -5241,7 +5404,8 @@ const char *Field_blob::unpack(char *to, const char *from)
/* Keys for blobs are like keys on varchars */
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length,
my_bool insert_or_update)
{
uint a_length;
uint b_length;
@ -5255,13 +5419,15 @@ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
a_length= (uint) (uchar) *a++;
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length,
insert_or_update);
}
int Field_blob::pack_cmp(const char *b, uint key_length)
int Field_blob::pack_cmp(const char *b, uint key_length,
my_bool insert_or_update)
{
char *a;
memcpy_fixed(&a,ptr+packlength,sizeof(char*));
@ -5275,12 +5441,11 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
b_length=uint2korr(b); b+=2;
}
else
{
b_length= (uint) (uchar) *b++;
}
return my_strnncoll(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length);
return field_charset->coll->strnncollsp(field_charset,
(const uchar*) a, a_length,
(const uchar*) b, b_length,
insert_or_update);
}
/* Create a packed key that will be used for storage from a MySQL row */
@ -5290,8 +5455,8 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
char *save=ptr;
ptr=(char*) from;
uint32 length=get_length(); // Length of from string
uint char_length= (field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length;
uint char_length= ((field_charset->mbmaxlen > 1) ?
max_length/field_charset->mbmaxlen : max_length);
if (length)
get_ptr((char**) &from);
if (length > char_length)
@ -5365,14 +5530,15 @@ char *Field_blob::pack_key_from_key_image(char *to, const char *from,
return to+length;
}
uint Field_blob::packed_col_length(const char *data_ptr, uint length)
{
if (length > 255)
return uint2korr(data_ptr)+2;
else
return (uint) ((uchar) *data_ptr)+1;
return (uint) ((uchar) *data_ptr)+1;
}
uint Field_blob::max_packed_col_length(uint max_length)
{
return (max_length > 255 ? 2 : 1)+max_length;
@ -5381,8 +5547,7 @@ uint Field_blob::max_packed_col_length(uint max_length)
#ifdef HAVE_SPATIAL
void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
imagetype type)
void Field_geom::get_key_image(char *buff, uint length, imagetype type)
{
char *blob;
const char *dummy;
@ -5411,11 +5576,6 @@ void Field_geom::get_key_image(char *buff, uint length, CHARSET_INFO *cs,
}
void Field_geom::set_key_image(char *buff, uint length, CHARSET_INFO *cs)
{
Field_blob::set_key_image(buff, length, cs);
}
void Field_geom::sql_type(String &res) const
{
CHARSET_INFO *cs= &my_charset_latin1;
@ -5864,7 +6024,7 @@ bool Field_num::eq_def(Field *field)
/*****************************************************************************
** Handling of field and create_field
Handling of field and create_field
*****************************************************************************/
void create_field::create_length_to_internal_length(void)
@ -5876,9 +6036,10 @@ void create_field::create_length_to_internal_length(void)
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VARCHAR:
length*= charset->mbmaxlen;
pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ?
FIELD_TYPE_STRING : sql_type, length);
key_length*= charset->mbmaxlen;
pack_length= calc_pack_length(sql_type, length);
break;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
@ -5890,6 +6051,22 @@ void create_field::create_length_to_internal_length(void)
}
}
enum_field_types get_blob_type_from_length(ulong length)
{
enum_field_types type;
if (length < 256)
type= FIELD_TYPE_TINY_BLOB;
else if (length < 65536)
type= FIELD_TYPE_BLOB;
else if (length < 256L*256L*256L)
type= FIELD_TYPE_MEDIUM_BLOB;
else
type= FIELD_TYPE_LONG_BLOB;
return type;
}
/*
Make a field from the .frm file info
*/
@ -5897,9 +6074,10 @@ void create_field::create_length_to_internal_length(void)
uint32 calc_pack_length(enum_field_types type,uint32 length)
{
switch (type) {
case MYSQL_TYPE_VAR_STRING:
case FIELD_TYPE_STRING:
case FIELD_TYPE_DECIMAL: return (length);
case FIELD_TYPE_VAR_STRING: return (length+HA_KEY_BLOB_LENGTH);
case FIELD_TYPE_DECIMAL: return (length);
case MYSQL_TYPE_VARCHAR: return (length+HA_KEY_BLOB_LENGTH);
case FIELD_TYPE_YEAR:
case FIELD_TYPE_TINY : return 1;
case FIELD_TYPE_SHORT : return 2;
@ -5972,12 +6150,16 @@ Field *make_field(char *ptr, uint32 field_length,
{
if (!f_is_packed(pack_flag))
{
if (field_type == FIELD_TYPE_STRING ||
if (field_type == MYSQL_TYPE_STRING ||
field_type == FIELD_TYPE_DECIMAL || // 3.23 or 4.0 string
field_type == FIELD_TYPE_VAR_STRING)
field_type == MYSQL_TYPE_VAR_STRING)
return new Field_string(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
field_charset);
if (field_type == MYSQL_TYPE_VARCHAR)
return new Field_varstring(ptr,field_length,null_pos,null_bit,
unireg_check, field_name, table,
field_charset);
return 0; // Error
}
@ -6090,44 +6272,51 @@ create_field::create_field(Field *old_field,Field *orig_field)
flags= old_field->flags;
unireg_check=old_field->unireg_check;
pack_length=old_field->pack_length();
key_length= old_field->key_length();
sql_type= old_field->real_type();
charset= old_field->charset(); // May be NULL ptr
comment= old_field->comment;
decimals= old_field->decimals();
/* Fix if the original table had 4 byte pointer blobs */
if (flags & BLOB_FLAG)
pack_length= (pack_length- old_field->table->blob_ptr_size +
portable_sizeof_char_ptr);
switch (sql_type)
{
case FIELD_TYPE_BLOB:
switch (pack_length - portable_sizeof_char_ptr)
{
case 1: sql_type= FIELD_TYPE_TINY_BLOB; break;
case 2: sql_type= FIELD_TYPE_BLOB; break;
case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break;
default: sql_type= FIELD_TYPE_LONG_BLOB; break;
}
length=(length+charset->mbmaxlen-1)/charset->mbmaxlen; // QQ: Probably not needed
break;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case FIELD_TYPE_STRING:
case FIELD_TYPE_VAR_STRING:
length=(length+charset->mbmaxlen-1)/charset->mbmaxlen;
break;
default:
break;
switch (sql_type) {
case FIELD_TYPE_BLOB:
switch (pack_length - portable_sizeof_char_ptr) {
case 1: sql_type= FIELD_TYPE_TINY_BLOB; break;
case 2: sql_type= FIELD_TYPE_BLOB; break;
case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break;
default: sql_type= FIELD_TYPE_LONG_BLOB; break;
}
length=(length+charset->mbmaxlen-1) / charset->mbmaxlen;
key_length/= charset->mbmaxlen;
break;
case FIELD_TYPE_STRING:
/* Change CHAR -> VARCHAR if dynamic record length */
if (old_field->type() == MYSQL_TYPE_VAR_STRING)
sql_type= MYSQL_TYPE_VARCHAR;
/* fall through */
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
/* These are corrected in create_length_to_internal_length */
length= (length+charset->mbmaxlen-1) / charset->mbmaxlen;
key_length/= charset->mbmaxlen;
break;
#ifdef HAVE_SPATIAL
case FIELD_TYPE_GEOMETRY:
geom_type= ((Field_geom*)old_field)->geom_type;
break;
#endif
default:
break;
}
decimals= old_field->decimals();
if (sql_type == FIELD_TYPE_STRING)
{
/* Change CHAR -> VARCHAR if dynamic record length */
sql_type=old_field->type();
decimals=0;
}
if (flags & (ENUM_FLAG | SET_FLAG))
interval= ((Field_enum*) old_field)->typelib;
else
@ -6152,12 +6341,6 @@ create_field::create_field(Field *old_field,Field *orig_field)
def= new Item_string(pos, tmp.length(), charset);
}
}
#ifdef HAVE_SPATIAL
if (sql_type == FIELD_TYPE_GEOMETRY)
{
geom_type= ((Field_geom*)old_field)->geom_type;
}
#endif
}