#At file:///home/cpowers/work/dev/dev-06/mysql/
3030 Christopher Powers 2009-02-21
Bug #39445 "Falcon: Update fails following online add column"
Enabled online ALTER ADD COLUMN.
The problem is that online ALTER ADD COLUMN creates a new default
record format for the table that has more fields than the older
record formats associated with existing rows.
This causes inconsistent results during row updates because the
the older, shorter rows lacked the encoding for new columns.
StorageInterface::decodeRecord() now sets the NULL flag for fields
that are not physically represented. The assumption of NULL can be
safely made because online ALTER ADD COLUMN only supports nullable
columns and a default value of NULL.
Columns added outside of this restriction, e.g. with a non-null
default value, will be created via the slow ALTER in which all
rows are copied into a new table and thus assigned the newer
record format.
modified:
storage/falcon/ha_falcon.cpp
per-file messages:
storage/falcon/ha_falcon.cpp
StorageInterface::check_if_supported_alter()
- Enable HA_ADD_COLUMN
StorageInteface::decodeRecord()
- Set the NULL bit for fields that are not encoded.
=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp 2009-02-11 18:23:17 +0000
+++ b/storage/falcon/ha_falcon.cpp 2009-02-21 22:48:03 +0000
@@ -2454,10 +2454,8 @@ int StorageInterface::check_if_supported
DBUG_ENTER("StorageInterface::check_if_supported_alter");
tempTable = (create_info->options & HA_LEX_CREATE_TMP_TABLE) ? true : false;
HA_ALTER_FLAGS supported;
- supported = supported | HA_ADD_INDEX | HA_DROP_INDEX | HA_ADD_UNIQUE_INDEX | HA_DROP_UNIQUE_INDEX | HA_ADD_PK_INDEX | HA_DROP_PK_INDEX;
- /**
- | HA_ADD_COLUMN | HA_COLUMN_STORAGE | HA_COLUMN_FORMAT ;
- **/
+ supported = supported | HA_ADD_INDEX | HA_DROP_INDEX | HA_ADD_UNIQUE_INDEX | HA_DROP_UNIQUE_INDEX
+ | HA_ADD_PK_INDEX | HA_DROP_PK_INDEX | HA_ADD_COLUMN;
HA_ALTER_FLAGS notSupported = ~(supported);
#ifndef ONLINE_ALTER
@@ -3130,11 +3128,36 @@ void StorageInterface::decodeRecord(ucha
my_ptrdiff_t ptrDiff = buf - table->record[0];
my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set);
DBUG_ENTER("StorageInterface::decodeRecord");
+
+ // Format of this record
+
FieldFormat *fieldFormat = storageTable->format->format;
int maxId = storageTable->format->maxId;
- for (int n = 0; n < maxId; ++n, ++fieldFormat)
+ // Current format for the table, possibly newer than the record format
+
+ int tableMaxId = storageTable->share->format->maxId;
+ FieldFormat *tableFieldFormat = storageTable->share->format->format;
+
+ for (int n = 0; n < tableMaxId; ++n, ++fieldFormat, ++tableFieldFormat)
{
+ // Online ALTER ADD COLUMN creates a new record format for the table
+ // that will have more fields than the older formats associated with
+ // existing rows.
+ //
+ // Currently, online ALTER ADD COLUMN only supports nullable columns and
+ // no default value. If the format of this record has fewer fields
+ // than the default format of the table, then there are no fields to
+ // decode beyond maxId, so set them to NULL.
+
+ if (n >= maxId)
+ {
+ Field *newField = fieldMap[tableFieldFormat->fieldId];
+ newField->set_null();
+ newField->reset();
+ continue;
+ }
+
// If the format doesn't have an offset, the field doesn't exist in the record
if (fieldFormat->fieldId < 0 || fieldFormat->offset == 0)
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (christopher.powers:3030)Bug#39445 | Christopher Powers | 22 Feb |