From: Date: July 25 2008 6:40am Subject: commit into mysql-6.0-falcon branch (cpowers:2745) Bug#38039, Bug#38041, Bug#38043 List-Archive: http://lists.mysql.com/commits/50471 X-Bug: 38043 Message-Id: <20080725044022.5E35A1DB0720@xeno.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #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 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);