MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:July 25 2008 4:40am
Subject:commit into mysql-6.0-falcon branch (cpowers:2745) Bug#38039, Bug#38041,
Bug#38043
View as plain text  
#At file:///home/cpowers/work/dev/dev-02/mysql/

 2745 Christopher Powers	2008-07-24
      Bug#38039   Assertion lockState == 0 failed in StorageTableShare::deleteTable
SyncObject
      Bug#38041   Bizarre errors when ALTER ADD/DROP KEY on Falcon tables
      Bug#38043   Deadlock between server and falcon when executing concurrent ALTER + DML
      
      Improvements to online add/drop index:
      
      - StorageTableShare::indexes[] is now a resizeable DenseArray
      - Added sync lock protection to get/set index
      - Call add/drop index from StorageTable rather than StorageTableShare
      - Rename internal Falcon indexes to preserve index name/id mapping after drop
      - Immediately update StorageTableShare::indexes[] after add/drop rather than wait
for subsequent open()
modified:
  storage/falcon/DenseArray.h
  storage/falcon/Statement.cpp
  storage/falcon/StorageTable.cpp
  storage/falcon/StorageTable.h
  storage/falcon/StorageTableShare.cpp
  storage/falcon/StorageTableShare.h
  storage/falcon/ha_falcon.cpp*
  storage/falcon/ha_falcon.h*

per-file comments:
  storage/falcon/DenseArray.h
    Delete old vector
    Added ::zap(n)
  storage/falcon/Statement.cpp
    Rename indexes to preserve name/id mapping after drop index
  storage/falcon/StorageTable.cpp
    Added create/dropIndex(), clearIndex()
  storage/falcon/StorageTable.h
    Added create/dropIndex(), clearIndex()
  storage/falcon/StorageTableShare.cpp
    StorageTableShare::indexes[] is now DenseArray for easy resizing
    Condense ::indexes[] after drop index
    Added locking around changes to ::indexes[] and get/setIndex()
    Added resize/buildIndexes
  storage/falcon/StorageTableShare.h
    Added constructor to StorageIndexDesc
    Added buildIndexes(), resizeIndexes(), getIndex(name), getIndexId(name)
  storage/falcon/ha_falcon.cpp
    Added locking around index stuff
    Add/drop index now call into StorageTable rather than StorageTableShare
    Added StorageInterface::setNewIndex() to immediately update indexes[] upon add
  storage/falcon/ha_falcon.h
    Added setNewIndex()
=== modified file 'storage/falcon/DenseArray.h'
--- a/storage/falcon/DenseArray.h	2007-11-30 18:19:43 +0000
+++ b/storage/falcon/DenseArray.h	2008-07-25 04:40:17 +0000
@@ -46,18 +46,36 @@
 		{
 		if (newLength < length)
 			return;
-			
+
+		T *newVector = new T[newLength];
+		T *oldVector = vector;
+		memcpy((void*) newVector, (void*) vector, length * sizeof(T));
+		memset((void*) (newVector + length), 0, (newLength - length) * sizeof(T));
+		vector = newVector;
+		int oldLength = length;
+		length = newLength;
+		memset((void*) oldVector, 0xbc, oldLength * sizeof(T));
+		delete [] oldVector;
+		
+		/**		
 		T *oldVector = vector;
 		vector = new T[newLength];
 		memcpy((void*) vector, (void*) oldVector, length * sizeof(T));
 		memset((void*) (vector + length), 0, (newLength - length) * sizeof(T));
 		length = newLength;
+		**/
 		};
 	
 	void zap ()
 		{
 		memset((void*) vector, 0, length * sizeof(T));
 		};
+		
+	void zap (uint n)
+		{
+		if (n < length)
+			memset(vector + n, 0, sizeof(T));
+		}
 	
 	T get (uint index)
 		{

=== modified file 'storage/falcon/Statement.cpp'
--- a/storage/falcon/Statement.cpp	2008-07-17 13:52:17 +0000
+++ b/storage/falcon/Statement.cpp	2008-07-25 04:40:17 +0000
@@ -2313,7 +2313,28 @@
 		database->commitSystemTransaction();
 		}
 
-	Index::deleteIndex (database, schema, name);
+	Index::deleteIndex(database, schema, name);
+	database->commitSystemTransaction();
+	
+	// Rename indexes to preserve name/id mapping
+	
+	Transaction *sysTransaction = database->getSystemTransaction();
+	int indexNumber = 0;
+
+	for (index = table->indexes; index; index = index->next)
+		if (index->type == PrimaryKey)
+			indexNumber = 1;
+
+	for (index = table->indexes; index; index = index->next)
+		{
+		if (index->type != PrimaryKey)
+			{
+			char indexName[256];
+			sprintf(indexName, "%s$%d", (const char*)table->name, indexNumber++);
+			index->rename(indexName);
+			}
+		}
+		
 	database->commitSystemTransaction();
 }
 

=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp	2008-05-02 22:09:28 +0000
+++ b/storage/falcon/StorageTable.cpp	2008-07-25 04:40:17 +0000
@@ -162,6 +162,17 @@
 	return 0;
 }
 
+int StorageTable::createIndex(const char* indexName, int indexNumber, const char* sql)
+{
+	return share->createIndex(storageConnection, indexName, indexNumber, sql);
+}
+
+int StorageTable::dropIndex(const char* indexName, int indexNumber, const char* sql)
+{
+	clearIndex();
+	return share->dropIndex(storageConnection, indexName, indexNumber, sql);
+}
+
 int StorageTable::next(int recordNumber, bool lockForUpdate)
 {
 	recordLocked = false;
@@ -197,9 +208,9 @@
 {
 }
 
-int StorageTable::setIndex(int numberIndexes, int indexId, StorageIndexDesc*
storageIndex)
+int StorageTable::setIndex(int numberIndexes, int indexId, StorageIndexDesc*
storageIndex, bool exclusiveLock)
 {
-	if (!(currentIndex = share->getIndex(numberIndexes, indexId, storageIndex)))
+	if (!(currentIndex = share->getIndex(numberIndexes, indexId, storageIndex,
exclusiveLock)))
 		return StorageErrorNoIndex;
 
 	upperBound = lowerBound = NULL;
@@ -208,6 +219,14 @@
 	return 0;
 }
 
+int StorageTable::clearIndex()
+{
+	currentIndex = NULL;
+	upperBound = lowerBound = NULL;
+	searchFlags = 0;
+	return 0;
+}
+
 int StorageTable::indexScan(int indexOrder)
 {
 	if (!currentIndex)

=== modified file 'storage/falcon/StorageTable.h'
--- a/storage/falcon/StorageTable.h	2008-05-02 22:09:28 +0000
+++ b/storage/falcon/StorageTable.h	2008-07-25 04:40:17 +0000
@@ -23,7 +23,6 @@
 
 static const int UpperBound	= 1;
 static const int LowerBound = 2;
-
 static const int MaxRetryAferWait = 5;
 
 struct StorageKey {
@@ -78,9 +77,10 @@
 	virtual int		deleteTable(void);
 	virtual int		deleteRow(int recordNumber);
 	virtual int		truncateTable(void);
-	virtual int		setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex);
+	virtual int		setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex,
bool exclusiveLock);
 	virtual int		indexScan(int indexOrder);
 	virtual int		setIndex(int indexId);
+	virtual int		clearIndex();
 	virtual void	indexEnd(void);
 	virtual int		setIndexBound(const unsigned char* key, int keyLength, int which);
 	virtual int		storeBlob(StorageBlob* blob);
@@ -96,6 +96,8 @@
 	virtual int		fetch(int recordNumber, bool lockForUpdate);
 	
 	virtual int		updateRow(int recordNumber);
+	virtual int		createIndex(const char* indexName, int indexNumber, const char* sql);
+	virtual int		dropIndex(const char* indexName, int indexNumber, const char* sql);
 	virtual const unsigned char* getEncoding(int fieldIndex);
 	virtual const char*			 getName(void);
 	virtual const char*			 getSchemaName(void);

=== modified file 'storage/falcon/StorageTableShare.cpp'
--- a/storage/falcon/StorageTableShare.cpp	2008-07-15 18:57:27 +0000
+++ b/storage/falcon/StorageTableShare.cpp	2008-07-25 04:40:17 +0000
@@ -38,7 +38,7 @@
 static const char *DB_ROOT				= ".fts";
 
 #ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
+#define ONLINE_ALTER
 #endif
 
 #if defined(_WIN32) && MYSQL_VERSION_ID < 0x50100
@@ -63,7 +63,6 @@
 	impure = new UCHAR[lockSize];
 	initialized = false;
 	table = NULL;
-	indexes = NULL;
 	format = NULL;
 	syncObject = new SyncObject;
 	syncObject->setName("StorageTableShare::syncObject");
@@ -73,6 +72,7 @@
 	syncTruncate = new SyncObject;
 	syncTruncate->setName("StorageTableShare::syncTruncate");
 	truncateLockCount = 0;
+	numberIndexes = 0;
 	
 	if (tempTable)
 		tableSpace = TEMPORARY_TABLESPACE;
@@ -94,14 +94,9 @@
 	if (storageDatabase)
 		storageDatabase->release();
 		
-	if (indexes)
-		{
-		for (int n = 0; n < numberIndexes; ++n)
-			delete indexes[n];
-			
-		delete [] indexes;
-		indexes = NULL;
-		}
+	for (uint n = 0; n < indexes.length; n++)
+		if (indexes.vector[n])
+			delete indexes.get(n);
 }
 
 void StorageTableShare::lock(bool exclusiveLock)
@@ -246,7 +241,7 @@
 	return buffer;
 }
 
-int StorageTableShare::createIndex(StorageConnection *storageConnection, const char*
name, const char* sql)
+int StorageTableShare::createIndex(StorageConnection *storageConnection, const char*
name, int indexNumber, const char* sql)
 {
 	if (!table)
 		open();
@@ -254,12 +249,28 @@
 	return storageDatabase->createIndex(storageConnection, table, name, sql);
 }
 
-int StorageTableShare::dropIndex(StorageConnection *storageConnection, const char* name,
const char* sql)
+int StorageTableShare::dropIndex(StorageConnection *storageConnection, const char* name,
int indexNumber, const char* sql)
 {
 	if (!table)
 		open();
-
-	return storageDatabase->dropIndex(storageConnection, table, name, sql);
+		
+	Sync sync(syncObject, "StorageTableShare::dropIndex");
+	sync.lock(Exclusive);
+	
+	int ret = storageDatabase->dropIndex(storageConnection, table, name, sql);
+	
+	if (!ret)
+		{
+		if (numberIndexes > 0)
+			{
+			for (int i = indexNumber; i < numberIndexes-1; i++)
+				indexes.vector[i] = indexes.vector[i+1];
+			indexes.zap(numberIndexes-1);
+			numberIndexes--;
+			}
+		}
+		
+	return ret;
 }
 
 int StorageTableShare::renameTable(StorageConnection *storageConnection, const char*
newName)
@@ -281,49 +292,55 @@
 	return ret;
 }
 
-StorageIndexDesc* StorageTableShare::getIndex(int indexCount, int indexId,
StorageIndexDesc* indexDesc)
-{
-	// Rebuild array if indexes have been added or dropped
-	
-#ifdef ONLINE_ALTER
-
-	// TODO: This does not work. It should be done at the time of index creation
-
-	if (indexes && (numberIndexes != indexCount))
-		{
-		Sync sync(syncObject, "StorageTableShare::getIndex");
-		sync.lock(Exclusive);
-		StorageIndexDesc **oldIndexes = indexes;
-		StorageIndexDesc **newIndexes = new StorageIndexDesc*[indexCount];
-		memset(newIndexes, 0, indexCount * sizeof(StorageIndexDesc*));
-		
-		for (int n = 0; n < numberIndexes; ++n)
-			newIndexes[n] = indexes[n];
-		
-		indexes = newIndexes;
-		numberIndexes = indexCount;
-		delete [] oldIndexes;
-		}
-#endif
-	
-	if (!indexes)
-		{
-		indexes = new StorageIndexDesc*[indexCount];
-		memset(indexes, 0, indexCount * sizeof(StorageIndexDesc*));
-		numberIndexes = indexCount;
-		}
-	
-	if (indexId >= numberIndexes)
-		return NULL;
-	
-	StorageIndexDesc *index = indexes[indexId];
-	
-	if (index)
-		return index;
-
-	indexes[indexId] = index = new StorageIndexDesc;
+void StorageTableShare::resizeIndexes(int newIndexCount)
+{
+	if (newIndexCount <= 0)
+		return;
+		
+	Sync sync(syncObject, "StorageTableShare::resizeIndexes");
+	sync.lock(Exclusive);
+	
+	if ((uint)newIndexCount > indexes.length)
+		indexes.extend(newIndexCount + 5);
+		
+	numberIndexes = newIndexCount;
+}	
+
+void StorageTableShare::buildIndexes(int indexCount)
+{
+	if (indexCount > 0 && indexes.length == 0)
+		{		
+		indexes.extend(indexCount + 5);
+		numberIndexes = indexCount;
+		}
+}
+
+int StorageTableShare::setIndex(int indexCount, int indexId, const StorageIndexDesc*
indexDesc, StorageIndexDesc **indexSet)
+{
+	Sync sync(syncObject, "StorageTableShare::setIndex");
+	sync.lock(Exclusive);
+	
+	int ret = 0;
+	
+	if (indexes.length == 0)
+		buildIndexes(indexCount);
+	
+	if (indexId > numberIndexes)
+		return StorageErrorNoIndex;
+		
+	// Allocate a new index if necessary
+	
+	StorageIndexDesc* index = indexes.get(indexId);
+	
+	if (!index)
+		indexes.vector[indexId] = index = new StorageIndexDesc;
+		
+	// Copy index description info
+	
 	*index = *indexDesc;
 	
+	// Find the corresponding Falcon index
+
 	if (indexDesc->primaryKey)
 		index->index = table->primaryKey;
 	else
@@ -336,17 +353,60 @@
 	if (index->index)
 		index->segmentRecordCounts = index->index->recordsPerSegment;
 	else
+		{
 		index = NULL;
+		ret = StorageErrorNoIndex;
+		}
+		
+	if (indexSet)
+		*indexSet = index;
+		
+	return ret;
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(int indexCount, int indexId, const
StorageIndexDesc* indexDesc, bool exclusiveLock)
+{
+	if (indexId >= numberIndexes)
+		return NULL;
+		
+	LockType lockType = (exclusiveLock ? Exclusive : Shared);
+	Sync sync(syncObject, "StorageTableShare::getIndex(1)");
+	sync.lock(lockType);
+
+	StorageIndexDesc *index = indexes.get(indexId);
+	
+	if (index && index->index)
+		return index;
+		
+	if (lockType == Shared)
+		sync.unlock();
+		
+	int ret = setIndex(indexCount, indexId, indexDesc, &index);
 	
 	return index;
 }
 
 StorageIndexDesc* StorageTableShare::getIndex(int indexId)
 {
-	if (!indexes || indexId >= numberIndexes)
+	if (!indexes.length || indexId >= numberIndexes)
 		return NULL;
 	
-	return indexes[indexId];
+	Sync sync(syncObject, "StorageTableShare::getIndex(2)");
+	sync.lock(Shared);
+	
+	return indexes.get(indexId);
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(const char *name)
+{
+	for (int i = 0; i < numberIndexes; i++)
+		{
+		StorageIndexDesc *index = indexes.get(i);
+		if (index && index->name == name)
+			return index;
+		}
+
+	return NULL;
 }
 
 INT64 StorageTableShare::getSequenceValue(int delta)
@@ -372,12 +432,22 @@
 	return 0;
 }
 
+int StorageTableShare::getIndexId(const char* indexName)
+{
+	if (indexes.length > 0)
+		for (int n = 0; n < numberIndexes; ++n)
+			if (strcmp(indexes.vector[n]->name, indexName) == 0)
+				return n;
+		
+	return -1;
+}
+
 int StorageTableShare::getIndexId(const char* schemaName, const char* indexName)
 {
-	if (indexes)
+	if (indexes.length > 0)
 		for (int n = 0; n < numberIndexes; ++n)
 			{
-			Index *index = indexes[n]->index;
+			Index *index = indexes.vector[n]->index;
 			
 			if (strcmp(index->getIndexName(), indexName) == 0 &&
 				strcmp(index->getSchemaName(), schemaName) == 0)
@@ -389,17 +459,20 @@
 
 int StorageTableShare::haveIndexes(int indexCount)
 {
-	if (indexes == NULL)
+	if (indexes.length == 0)
 		return false;
 		
-#ifdef ONLINE_ALTER
-	if (indexCount != numberIndexes)
+	if (indexCount > numberIndexes)
 		return false;
-#endif	
 	
 	for (int n = 0; n < numberIndexes; ++n)
-		if (indexes[n]== NULL)
-			return false;
+		{
+		if (indexes.vector[n]== NULL)
+			return false;
+			
+		if (indexes.vector[n] != NULL && indexes.vector[n]->index == NULL)
+			return false;
+		}
 	
 	return true;
 }

=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h	2008-07-09 04:38:02 +0000
+++ b/storage/falcon/StorageTableShare.h	2008-07-25 04:40:17 +0000
@@ -18,6 +18,7 @@
 
 #include "JString.h"
 #include "SyncObject.h"
+#include "DenseArray.h"
 
 #ifndef _WIN32
 #define __int64			long long
@@ -48,13 +49,15 @@
 	};
 
 struct StorageIndexDesc {
+	int			state;
 	int			unique;
 	int			primaryKey;
 	int			numberSegments;
-	const char	*name;
+	JString		name;
 	Index		*index;
 	uint64		*segmentRecordCounts;
 	StorageSegment segments[MaxIndexSegments];
+	StorageIndexDesc(): unique(0), primaryKey(0), numberSegments(0), /*name(NULL),*/
index(NULL), segmentRecordCounts(NULL){};
 	};
 
 
@@ -97,8 +100,8 @@
 	
 	virtual void		lock(bool exclusiveLock);
 	virtual void		unlock(void);
-	virtual int			createIndex(StorageConnection *storageConnection, const char* name, const
char* sql);
-	virtual int			dropIndex(StorageConnection *storageConnection, const char* name, const
char* sql);
+	virtual int			createIndex(StorageConnection *storageConnection, const char* name, int
indexNumber, const char* sql);
+	virtual int			dropIndex(StorageConnection *storageConnection, const char* name, int
indexNumber, const char* sql);
 	virtual int			renameTable(StorageConnection *storageConnection, const char* newName);
 	virtual INT64		getSequenceValue(int delta);
 	virtual int			setSequenceValue(INT64 value);
@@ -108,9 +111,14 @@
 	virtual void		registerCollation(const char* collationName, void* arg);
 
 	int					open(void);
-	StorageIndexDesc*	getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc);
+	void				buildIndexes(int indexCount);
+	void				resizeIndexes(int newIndexCount);
+	int					setIndex(int indexCount, int indexId, const StorageIndexDesc* indexDesc,
StorageIndexDesc** index);
+	StorageIndexDesc*	getIndex(int indexCount, int indexId, const StorageIndexDesc*
indexDesc, bool exclusiveLock);
 	StorageIndexDesc*	getIndex(int indexId);
+	StorageIndexDesc*	getIndex(const char *name);
 
+	int					getIndexId(const char* indexName);
 	int					getIndexId(const char* schemaName, const char* indexName);
 	int					create(StorageConnection *storageConnection, const char* sql, int64
autoIncrementValue);
 	int					upgrade(StorageConnection *storageConnection, const char* sql, int64
autoIncrementValue);
@@ -146,7 +154,7 @@
 	StorageDatabase		*storageDatabase;
 	StorageHandler		*storageHandler;
 	Table				*table;
-	StorageIndexDesc	**indexes;
+	DenseArray<StorageIndexDesc *,10> indexes;
 	Sequence			*sequence;
 	Format				*format;						// format for insertion
 	int					numberIndexes;

=== modified file 'storage/falcon/ha_falcon.cpp' (properties changed: -x to +x)
--- a/storage/falcon/ha_falcon.cpp	2008-07-17 13:52:17 +0000
+++ b/storage/falcon/ha_falcon.cpp	2008-07-25 04:40:17 +0000
@@ -54,7 +54,7 @@
 #endif
 
 #ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
+#define ONLINE_ALTER
 #endif
 
 #ifdef DEBUG_BACKLOG
@@ -456,7 +456,6 @@
 	DBUG_RETURN(0);
 }
 
-
 int StorageInterface::open(const char *name, int mode, uint test_if_locked)
 {
 	DBUG_ENTER("StorageInterface::open");
@@ -663,7 +662,6 @@
 	DBUG_RETURN(0);
 }
 
-
 void StorageInterface::getDemographics(void)
 {
 	DBUG_ENTER("StorageInterface::getDemographics");
@@ -675,6 +673,8 @@
 
 	stats.block_size = 4096;
 
+	storageTable->share->lock(false);
+
 	for (uint n = 0; n < table->s->keys; ++n)
 		{
 		KEY *key = table->s->key_info + n;
@@ -692,6 +692,8 @@
 			}
 		}
 
+	storageTable->share->unlock();
+	
 	DBUG_VOID_RETURN;
 }
 
@@ -841,6 +843,8 @@
 
 				DBUG_RETURN(error(ret));
 				}
+				
+	setIndexes();
 
 	mapFields(form);
 
@@ -864,18 +868,23 @@
 	        indexNumber, schemaName, tableName);
 	genKeyFields(key, &gen);
 	const char *sql = gen.getString();
-
-	return storageTable->share->createIndex(storageConnection, key->name, sql);
+	
+	return storageTable->createIndex(key->name, indexNumber, sql);
 }
 
 int StorageInterface::dropIndex(const char *schemaName, const char *tableName,
                                  KEY *key, int indexNumber)
 {
+	// A previous drop index may have already changed the index numbering, so use
+	// the external index name to find the index id.
+	
+	int indexId = storageTable->share->getIndexId(key->name);
+
 	CmdGen gen;
-	gen.gen("drop index %s.\"%s$%d\"", schemaName, tableName, indexNumber);
+	gen.gen("drop index %s.\"%s$%d\"", schemaName, tableName, indexId);
 	const char *sql = gen.getString();
-
-	return storageTable->share->dropIndex(storageConnection, key->name, sql);
+	
+	return storageTable->dropIndex(key->name, indexId, sql);
 }
 
 #if 0
@@ -1139,9 +1148,6 @@
 	DBUG_ASSERT (lastRecord >= 0);
 	ha_statistic_increment(&SSV::ha_delete_count);
 
-	if (activeBlobs)
-		freeActiveBlobs();
-
 	int ret = storageTable->deleteRow(lastRecord);
 
 	if (ret < 0)
@@ -1366,7 +1372,6 @@
 		}
 }
 
-
 int StorageInterface::index_init(uint idx, bool sorted)
 {
 	DBUG_ENTER("StorageInterface::index_init");
@@ -1384,7 +1389,7 @@
 	if (idx == table->s->primary_key)
 		indexDesc.primaryKey = true;
 
-	int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc);
+	int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc, false);
 
 	if (ret)
 		DBUG_RETURN(error(ret));
@@ -1392,7 +1397,6 @@
 	DBUG_RETURN(0);
 }
 
-
 int StorageInterface::index_end(void)
 {
 	DBUG_ENTER("StorageInterface::index_end");
@@ -1444,7 +1448,6 @@
 	DBUG_RETURN(MAX(guestimate, 2));
 }
 
-
 void StorageInterface::getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo)
 {
 	int numberKeys = keyInfo->key_parts;
@@ -1480,7 +1483,6 @@
 		}
 }
 
-
 int StorageInterface::rename_table(const char *from, const char *to)
 {
 	DBUG_ENTER("StorageInterface::rename_table");
@@ -1500,14 +1502,12 @@
 
 }
 
-
 double StorageInterface::read_time(uint index, uint ranges, ha_rows rows)
 {
 	DBUG_ENTER("StorageInterface::read_time");
 	DBUG_RETURN(rows2double(rows / 3));
 }
 
-
 int StorageInterface::read_range_first(const key_range *start_key,
                                       const key_range *end_key,
                                       bool eq_range_arg, bool sorted)
@@ -2058,7 +2058,6 @@
 	currently not supported by Falcon. LOGFILE GROUP, NODEGROUP and WAIT are
 	for NDB only.
 	*/
-
 	if (ts_info->data_file_name)
 		{
 		char buff[FN_REFLEN];
@@ -2249,7 +2248,7 @@
 
 int StorageInterface::addIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo,
HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags)
 {
-	int ret;
+	int ret = 0;
 	const char *tableName = storageTable->getName();
 	const char *schemaName = storageTable->getSchemaName();
 
@@ -2268,8 +2267,14 @@
 					break;
 					
 			if (tableKey >= tableEnd)
-				if ((ret = createIndex(schemaName, tableName, key, n)))
+				{
+				ret = createIndex(schemaName, tableName, key, n);
+				
+				if (!ret)
+					setNewIndex(alteredTable, n);
+				else
 					return (error(ret));
+				}
 			}
 		}
 	return 0;
@@ -2297,7 +2302,7 @@
 
 			if (alterKey >= alterEnd)
 				if ((ret = dropIndex(schemaName, tableName, key, n)))
-				return (error(ret));
+					return (error(ret));
 				}
 		}
 	
@@ -2313,7 +2318,6 @@
 	return MAX_INDEX_KEY_LENGTH_4K;  // Default value.
 }
 
-
 uint StorageInterface::max_supported_key_part_length(void) const
 {
 	// Assume 4K page unless proven otherwise.
@@ -2323,7 +2327,6 @@
 	return MAX_INDEX_KEY_LENGTH_4K;  // Default for future sizes.
 }
 
-
 void StorageInterface::logger(int mask, const char* text, void* arg)
 {
 	if (mask & falcon_debug_mask)
@@ -2339,6 +2342,35 @@
 		}
 }
 
+int StorageInterface::setNewIndex(TABLE* alteredTable, int indexId)
+{
+	if (!table)
+		return 0;
+
+	storageShare->lock(true);
+
+	if ((uint)indexId >= storageShare->indexes.length ||
(uint)storageShare->numberIndexes < alteredTable->s->keys)
+		storageShare->resizeIndexes(alteredTable->s->keys);
+		
+	StorageIndexDesc indexDesc, *index;
+
+	getKeyDesc(alteredTable->key_info + indexId, &indexDesc);
+
+	if (indexId == table->s->primary_key)
+		indexDesc.primaryKey = true;
+
+	int ret = storageShare->setIndex(alteredTable->s->keys, indexId,
&indexDesc, &index);
+	
+	if (ret)
+		{
+		storageShare->unlock();
+		return ret;
+		}
+
+	storageShare->unlock();
+	return 0;
+}
+
 int StorageInterface::setIndexes(void)
 {
 	if (!table || storageShare->haveIndexes(table->s->keys))
@@ -2348,6 +2380,9 @@
 
 	if (!storageShare->haveIndexes(table->s->keys))
 		{
+		if (storageShare->numberIndexes != table->s->keys)
+			storageShare->resizeIndexes(table->s->keys);
+		
 		StorageIndexDesc indexDesc;
 
 		for (uint n = 0; n < table->s->keys; ++n)
@@ -2357,9 +2392,13 @@
 			if (n == table->s->primary_key)
 				indexDesc.primaryKey = true;
 
-			int ret = storageTable->setIndex(table->s->keys, n, &indexDesc);
+			int ret = storageShare->setIndex(table->s->keys, n, &indexDesc, NULL);
+			
 			if (ret)
+				{
+				storageShare->unlock();
 				return ret;
+				}
 			}
 		}
 

=== modified file 'storage/falcon/ha_falcon.h' (properties changed: -x to +x)
--- a/storage/falcon/ha_falcon.h	2008-07-09 04:38:02 +0000
+++ b/storage/falcon/ha_falcon.h	2008-07-25 04:40:17 +0000
@@ -121,6 +121,7 @@
 	int				threadSwitchError(void);
 	int				error(int storageError);
 	void			freeActiveBlobs(void);
+	int				setNewIndex(TABLE* alteredTable, int indexId);
 	int				setIndexes(void);
 	int				genTable(TABLE* table, CmdGen* gen);
 	int				genType(Field *field, CmdGen *gen);

Thread
commit into mysql-6.0-falcon branch (cpowers:2745) Bug#38039, Bug#38041,Bug#38043Christopher Powers25 Jul