1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Change create_field->offset to store offset from start of fields, independent of null bits.

Count null_bits separately from field offsets and adjust them in case of primary key parts.
(Previously a CREATE TABLE with a lot of null fields that was part of a primary key caused MySQL to wrongly count the number of bytes needed to store null bits)
This is a more complete bug fix for #6236


mysql-test/r/alter_table.result:
  More test for bug #6236 (CREATE TABLE didn't properly count not null columns for primary keys)
mysql-test/t/alter_table.test:
  More test for bug #6236 (CREATE TABLE didn't properly count not null columns for primary keys)
sql/handler.h:
  Add counter for null fields
sql/sql_table.cc:
  Change create_field->offset to store offset from start of fields, independent of null bits.
  Count null_bits separately from field offsets and adjust them in case of primary key parts.
sql/unireg.cc:
  Change create_field->offset to store offset from start of fields, independent of null bits.
  Count null_bits separately from field offsets and adjust them in case of primary key parts.
This commit is contained in:
unknown
2005-05-13 11:11:50 +03:00
parent 913e2e12d2
commit 7c441dd115
5 changed files with 98 additions and 56 deletions

View File

@ -363,7 +363,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
create_field *sql_field,*dup_field;
int error= -1;
uint db_options,field,null_fields,blob_columns;
ulong pos;
ulong record_offset;
KEY *key_info,*key_info_buffer;
KEY_PART_INFO *key_part_info;
int auto_increment=0;
@ -418,10 +418,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
it2.rewind();
}
/* If fixed row records, we need one bit to check for deleted rows */
if (!(db_options & HA_OPTION_PACK_RECORD))
null_fields++;
pos=(null_fields+7)/8;
/* record_offset will be increased with 'length-of-null-bits' later */
record_offset= 0;
it.rewind();
while ((sql_field=it++))
@ -478,10 +477,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
}
if (!(sql_field->flags & NOT_NULL_FLAG))
sql_field->pack_flag|=FIELDFLAG_MAYBE_NULL;
sql_field->offset= pos;
sql_field->offset= record_offset;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
pos+=sql_field->pack_length;
record_offset+= sql_field->pack_length;
}
if (auto_increment > 1)
{
@ -578,11 +577,12 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
column->field_name);
DBUG_RETURN(-1);
}
/* for fulltext keys keyseg length is 1 for blobs (it's ignored in
ft code anyway, and 0 (set to column width later) for char's.
it has to be correct col width for char's, as char data are not
prefixed with length (unlike blobs, where ft code takes data length
from a data prefix, ignoring column->length).
/*
for fulltext keys keyseg length is 1 for blobs (it's ignored in
ft code anyway, and 0 (set to column width later) for char's.
it has to be correct col width for char's, as char data are not
prefixed with length (unlike blobs, where ft code takes data length
from a data prefix, ignoring column->length).
*/
if (key->type == Key::FULLTEXT)
column->length=test(f_is_blob(sql_field->pack_flag));
@ -609,6 +609,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* Implicitly set primary key fields to NOT NULL for ISO conf. */
sql_field->flags|= NOT_NULL_FLAG;
sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
null_fields--;
}
else
key_info->flags|= HA_NULL_PART_KEY;
@ -765,6 +766,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (thd->sql_mode & MODE_NO_DIR_IN_CREATE)
create_info->data_file_name= create_info->index_file_name= 0;
create_info->table_options=db_options;
create_info->null_bits= null_fields;
if (rea_create_table(path, create_info, fields, key_count,
key_info_buffer))
@ -1829,17 +1831,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
cfield->pack_length <= key_part_length))
key_part_length=0; // Use whole field
}
if (!(cfield->flags & NOT_NULL_FLAG))
{
if (key_type == Key::PRIMARY)
{
/* Implicitly set primary key fields to NOT NULL for ISO conf. */
cfield->flags|= NOT_NULL_FLAG;
cfield->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
}
else
key_info->flags|= HA_NULL_PART_KEY;
}
key_parts.push_back(new key_part_spec(cfield->field_name,
key_part_length));
}