List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:February 21 2009 10:48pm
Subject:bzr commit into mysql-6.0-falcon-team branch (christopher.powers:3030)
Bug#39445
View as plain text  
#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#39445Christopher Powers22 Feb