From: Date: August 18 2008 6:53pm Subject: bzr push into mysql-6.0-falcon branch (cpowers:2786 to 2787) Bug#38039 Bug#38041 Bug#38043 Bug#38044 List-Archive: http://lists.mysql.com/commits/51859 X-Bug: 38039,38041,38043,38044 Message-Id: <20080818165325.EE7D11DB07A3@xeno.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 2787 Christopher Powers 2008-08-18 Bug#38044 Falcon crash in StorageTable::compareKey at StorageTable.cpp:412 Bug#38043 Deadlock between server and falcon when executing concurrent ALTER + DML Bug#38039 Assertion lockState == 0 failed in StorageTableShare::deleteTable SyncObject Bug#38041 Bizarre errors when ALTER ADD/DROP KEY on Falcon tables Improved index synchronization in the StorageInterface: - Falcon internal indexes no longer dependent upon server index id - Client connections lock StorageTableShare::syncIndexes to protect indexes across calls into StorageInterface - Changes to StorageTableShare::indexes are now protected by exclusive lock modified: storage/falcon/DenseArray.h storage/falcon/Index.cpp storage/falcon/Index.h storage/falcon/Statement.cpp storage/falcon/StorageDatabase.cpp storage/falcon/StorageDatabase.h storage/falcon/StorageTable.cpp storage/falcon/StorageTable.h storage/falcon/StorageTableShare.cpp storage/falcon/StorageTableShare.h storage/falcon/Table.cpp storage/falcon/Table.h storage/falcon/Transaction.cpp storage/falcon/ha_falcon.cpp storage/falcon/ha_falcon.h 2786 Vladislav Vaintroub 2008-08-15 [merge] merge modified: mysql-test/include/have_falcon.inc === modified file 'storage/falcon/DenseArray.h' --- a/storage/falcon/DenseArray.h 2007-11-30 18:19:43 +0000 +++ b/storage/falcon/DenseArray.h 2008-08-18 05:45:29 +0000 @@ -47,17 +47,35 @@ public: 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/Index.cpp' --- a/storage/falcon/Index.cpp 2008-07-25 18:07:24 +0000 +++ b/storage/falcon/Index.cpp 2008-08-18 05:45:29 +0000 @@ -45,6 +45,7 @@ #include "RSet.h" #include "WalkIndex.h" #include "WalkDeferred.h" +// #include "Interlock.h" // debug #define SEGMENT_BYTE(segment,count) ((indexVersion >= INDEX_VERSION_1) ? count - segment : segment) #define PAD_BYTE(field) ((indexVersion >= INDEX_VERSION_1) ? field->indexPadByte : 0) @@ -107,14 +108,20 @@ void Index::init(Table *tbl, const char DIHashTable = NULL; DIHashTableCounts = 0; DIHashTableSlotsUsed = 0; - syncDIHash.setName("Index::syncDIHash"); syncUnique.setName("Index::syncUnique"); deferredIndexes.syncObject.setName("Index::deferredIndexes.syncObject"); + + /*** debug + useCount = 1; + syncObject.setName("Index::syncObject"); + ***/ } Index::~Index() { + // ASSERT(useCount <= 2); // debug + if (deferredIndexes.first) { Sync sync(&deferredIndexes.syncObject, "Index::~Index"); @@ -1139,3 +1146,35 @@ void Index::scanDIHash(IndexKey* scanKey } } } + +#if 0 //debug +void Index::lock(bool exclusiveLock) +{ + syncObject.lock(NULL, (exclusiveLock) ? Exclusive : Shared); +} + +void Index::unlock(void) +{ + syncObject.unlock(); +} + +void Index::addRef() +{ + INTERLOCKED_INCREMENT(useCount); +} + +void Index::release() +{ + ASSERT (useCount > 0); + + if (INTERLOCKED_DECREMENT(useCount) == 0) + { + /*** debugging only + int cnt = useCount; + Table *t = table; + const char *tableName = table->name; + ***/ + //delete this; // disabled for debug + } +} +#endif === modified file 'storage/falcon/Index.h' --- a/storage/falcon/Index.h 2008-05-02 22:09:28 +0000 +++ b/storage/falcon/Index.h 2008-08-18 05:45:29 +0000 @@ -26,6 +26,7 @@ #include "Types.h" #include "Queue.h" +//#include "SyncObject.h" // debug static const int INDEX_VERSION_0 = 0; static const int INDEX_VERSION_1 = 1; @@ -128,6 +129,15 @@ public: Index(Table *tbl, const char *indexName, int indexType, int id, int numberFields); virtual ~Index(); + /*** debug + virtual void lock(bool exclusiveLock); + virtual void unlock(void); + void release(); + void addRef(); + SyncObject syncObject; // debug + volatile INTERLOCK_TYPE useCount; + ***/ + Table *table; Database *database; Dbb *dbb; === modified file 'storage/falcon/Statement.cpp' --- a/storage/falcon/Statement.cpp 2008-07-24 08:45:03 +0000 +++ b/storage/falcon/Statement.cpp 2008-08-18 05:45:29 +0000 @@ -144,7 +144,6 @@ Statement::Statement(Connection *pConnec special = false; active = false; memset (&stats, 0, sizeof (stats)); - syncObject.setName("Statement::syncObject"); } Statement::~Statement() @@ -2303,16 +2302,10 @@ void Statement::dropIndex(Syntax *syntax throw SQLEXCEPTION (DDL_ERROR, "table %s.%s not defined", (const char*) tableName, schema); checkAlterPriv (table); - Index *index = table->findIndex (name); - if (index) - { Transaction *sysTransaction = database->getSystemTransaction(); - table->dropIndex(index); - index->deleteIndex(sysTransaction); /* transaction */ - delete index; + table->dropIndex(name, sysTransaction); database->commitSystemTransaction(); - } Index::deleteIndex (database, schema, name); database->commitSystemTransaction(); === modified file 'storage/falcon/StorageDatabase.cpp' --- a/storage/falcon/StorageDatabase.cpp 2008-07-24 08:45:03 +0000 +++ b/storage/falcon/StorageDatabase.cpp 2008-08-18 05:45:29 +0000 @@ -688,7 +688,7 @@ int StorageDatabase::updateRow(StorageCo return 0; } -int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql) +int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* sql) { Connection *connection = storageConnection->connection; Statement *statement = connection->createStatement(); @@ -713,7 +713,7 @@ int StorageDatabase::createIndex(Storage return 0; } -int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql) +int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* sql) { Connection *connection = storageConnection->connection; Statement *statement = connection->createStatement(); @@ -746,17 +746,6 @@ int StorageDatabase::renameTable(Storage { Database *database = connection->database; Sequence *sequence = connection->findSequence(schemaName, table->name); - int numberIndexes = 0; - int firstIndex = 0; - Index *index; - - for (index = table->indexes; index; index = index->next) - { - if (index->type == PrimaryKey) - firstIndex = 1; - - ++numberIndexes; - } Sync syncDDL(&database->syncSysDDL, "StorageDatabase::renameTable(1)"); syncDDL.lock(Exclusive); @@ -764,19 +753,6 @@ int StorageDatabase::renameTable(Storage Sync syncTables(&database->syncTables, "StorageDatabase::renameTable(2)"); syncTables.lock(Exclusive); - for (int n = firstIndex; n < numberIndexes; ++n) - { - char indexName[256]; - sprintf(indexName, "%s$%d", (const char*) table->name, n); - Index *index = table->findIndex(indexName); - - if (index) - { - sprintf(indexName, "%s$%d", tableName, n); - index->rename(indexName); - } - } - table->rename(schemaName, tableName); if (sequence) === modified file 'storage/falcon/StorageDatabase.h' --- a/storage/falcon/StorageDatabase.h 2008-07-24 08:45:03 +0000 +++ b/storage/falcon/StorageDatabase.h 2008-08-18 05:45:29 +0000 @@ -40,7 +40,7 @@ class IndexWalker; CLASS(Field); -struct StorageIndexDesc; +class StorageIndexDesc; struct StorageKey; struct StorageBlob; struct StorageSegment; @@ -61,7 +61,6 @@ public: int savepointRollback(Connection* connection, int savePoint); int deleteTable(StorageConnection* storageConnection,StorageTableShare *tableShare); int truncateTable(StorageConnection* storageConnection, StorageTableShare *tableShare); - int createIndex(StorageConnection *storageConnection, Table* table, StorageIndexDesc* indexDesc); int renameTable(StorageConnection* storageConnection, Table* table, const char* newName, const char *schemaName); Bitmap* indexScan(Index* index, StorageKey *lower, StorageKey *upper, int searchFlags, StorageConnection* storageConnection, Bitmap *bitmap); IndexWalker* indexPosition(Index* index, StorageKey* lower, StorageKey* upper, int searchFlags, StorageConnection* storageConnection); @@ -74,8 +73,8 @@ public: void freeBlob(StorageBlob *blob); void close(void); void validateCache(void); - int createIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql); - int dropIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql); + int createIndex(StorageConnection* storageConnection, Table* table, const char* sql); + int dropIndex(StorageConnection* storageConnection, Table* table, const char* sql); int insert(Connection* connection, Table* table, Stream* stream); int nextRow(StorageTable* storageTable, int recordNumber, bool lockForUpdate); === modified file 'storage/falcon/StorageTable.cpp' --- a/storage/falcon/StorageTable.cpp 2008-08-11 13:22:53 +0000 +++ b/storage/falcon/StorageTable.cpp 2008-08-18 05:45:29 +0000 @@ -51,11 +51,13 @@ StorageTable::StorageTable(StorageConnec upperBound = lowerBound = NULL; record = NULL; recordLocked = false; - haveTruncateLock = false; + indexesLocked = false; } StorageTable::~StorageTable(void) { + clearCurrentIndex(); + if (bitmap) ((Bitmap*) bitmap)->release(); @@ -98,8 +100,6 @@ int StorageTable::truncateTable(void) return ret; } - - int StorageTable::insert(void) { try @@ -139,6 +139,16 @@ int StorageTable::updateRow(int recordNu return 0; } +int StorageTable::createIndex(StorageIndexDesc *indexDesc, int indexCount, const char *sql) +{ + return share->createIndex(storageConnection, indexDesc, indexCount, sql); +} + +int StorageTable::dropIndex(StorageIndexDesc *indexDesc, const char *sql) +{ + return share->dropIndex(storageConnection, indexDesc, sql); +} + int StorageTable::next(int recordNumber, bool lockForUpdate) { recordLocked = false; @@ -174,21 +184,66 @@ void StorageTable::transactionEnded(void { } -int StorageTable::setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex) +int StorageTable::setCurrentIndex(int indexId) { - if (!(currentIndex = share->getIndex(numberIndexes, indexId, storageIndex))) + if (!indexesLocked) + { + share->lockIndexes(); + indexesLocked = true; + } + + if (!(currentIndex = share->getIndex(indexId))) +{ + clearCurrentIndex(); return StorageErrorNoIndex; + } + + /*** debug + if (currentIndex->index) + currentIndex->index->addRef(); + else + currentIndex->index = NULL; + ***/ upperBound = lowerBound = NULL; searchFlags = 0; + return 0; +} + +int StorageTable::clearCurrentIndex() +{ + /*** debug + if (currentIndex) + if (currentIndex->index) + currentIndex->index->release(); + else + currentIndex->index = NULL; + ***/ + if (indexesLocked) + { + share->unlockIndexes(); + indexesLocked = false; + } + + currentIndex = NULL; + upperBound = lowerBound = NULL; + searchFlags = 0; return 0; } +int StorageTable::setIndex(int indexCount, StorageIndexDesc* indexDesc) +{ + return share->setIndex(indexCount, indexDesc); +} + int StorageTable::indexScan(int indexOrder) { if (!currentIndex) + { + clearCurrentIndex(); return StorageErrorNoIndex; + } int numberSegments = (upperBound) ? upperBound->numberSegments : (lowerBound) ? lowerBound->numberSegments : 0; @@ -203,26 +258,16 @@ int StorageTable::indexScan(int indexOrd return 0; } - void StorageTable::clearBitmap(void) { if (bitmap) ((Bitmap*) bitmap)->clear(); } -int StorageTable::setIndex(int indexId) -{ - if (!(currentIndex = share->getIndex(indexId))) - return StorageErrorNoIndex; - - upperBound = lowerBound = NULL; - searchFlags = 0; - - return 0; -} - void StorageTable::indexEnd(void) { + clearCurrentIndex(); + if (bitmap) clearBitmap(); @@ -236,7 +281,10 @@ void StorageTable::indexEnd(void) int StorageTable::setIndexBound(const unsigned char* key, int keyLength, int which) { if (!currentIndex) + { + clearCurrentIndex(); return StorageErrorNoIndex; + } if (which & LowerBound) { === modified file 'storage/falcon/StorageTable.h' --- a/storage/falcon/StorageTable.h 2008-08-11 13:22:53 +0000 +++ b/storage/falcon/StorageTable.h 2008-08-18 05:45:29 +0000 @@ -49,8 +49,7 @@ class Record; class SyncObject; class Format; class IndexWalker; - -struct StorageIndexDesc; +class StorageIndexDesc; class StorageTable { @@ -65,8 +64,6 @@ public: void clearAlter(void); bool setAlter(void); - - virtual void setConnection(StorageConnection* connection); virtual void clearIndexBounds(void); virtual void clearRecord(void); @@ -78,9 +75,10 @@ public: virtual int deleteTable(void); virtual int deleteRow(int recordNumber); virtual int truncateTable(void); - virtual int setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex); virtual int indexScan(int indexOrder); - virtual int setIndex(int indexId); + virtual int setCurrentIndex(int indexId); + virtual int clearCurrentIndex(); + virtual int setIndex(int indexCount, StorageIndexDesc* indexDesc); virtual void indexEnd(void); virtual int setIndexBound(const unsigned char* key, int keyLength, int which); virtual int storeBlob(StorageBlob* blob); @@ -96,6 +94,8 @@ public: virtual int fetch(int recordNumber, bool lockForUpdate); virtual int updateRow(int recordNumber); + virtual int createIndex(StorageIndexDesc *indexDesc, int indexCount, const char *sql); + virtual int dropIndex(StorageIndexDesc *indexDesc, const char *sql); virtual const unsigned char* getEncoding(int fieldIndex); virtual const char* getName(void); virtual const char* getSchemaName(void); @@ -128,7 +128,7 @@ public: Stream insertStream; int searchFlags; bool recordLocked; - bool haveTruncateLock; + bool indexesLocked; }; #endif === modified file 'storage/falcon/StorageTableShare.cpp' --- a/storage/falcon/StorageTableShare.cpp 2008-08-04 15:53:52 +0000 +++ b/storage/falcon/StorageTableShare.cpp 2008-08-18 05:45:29 +0000 @@ -33,14 +33,11 @@ #include "PreparedStatement.h" #include "ResultSet.h" #include "SQLException.h" +#include "CmdGen.h" static const char *FALCON_TEMPORARY = "/falcon_temporary"; static const char *DB_ROOT = ".fts"; -#ifndef ONLINE_ALTER -//#define ONLINE_ALTER -#endif - #if defined(_WIN32) && MYSQL_VERSION_ID < 0x50100 #define IS_SLASH(c) (c == '/' || c == '\\') #else @@ -63,13 +60,15 @@ StorageTableShare::StorageTableShare(Sto impure = new UCHAR[lockSize]; initialized = false; table = NULL; - indexes = NULL; format = NULL; syncObject = new SyncObject; syncObject->setName("StorageTableShare::syncObject"); + syncIndexes = new SyncObject; + syncIndexes->setName("StorageTableShare::syncIndexes"); sequence = NULL; tempTable = tempTbl; setPath(path); + numberIndexes = 0; if (tempTable) tableSpace = TEMPORARY_TABLESPACE; @@ -82,29 +81,37 @@ StorageTableShare::StorageTableShare(Sto StorageTableShare::~StorageTableShare(void) { delete syncObject; + delete syncIndexes; delete [] impure; 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) { - syncObject->lock(NULL, (exclusiveLock) ? Exclusive : Shared); + //syncObject->lock(NULL, (exclusiveLock) ? Exclusive : Shared); + syncIndexes->lock(NULL, (exclusiveLock) ? Exclusive : Shared); } void StorageTableShare::unlock(void) { - syncObject->unlock(); + //syncObject->unlock(); + syncIndexes->unlock(); +} + +void StorageTableShare::lockIndexes(bool exclusiveLock) +{ + syncIndexes->lock(NULL, (exclusiveLock) ? Exclusive : Shared); +} + +void StorageTableShare::unlockIndexes(void) +{ + syncIndexes->unlock(); } int StorageTableShare::open(void) @@ -189,7 +196,7 @@ int StorageTableShare::truncateTable(Sto return res; } -void StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength) +const char* StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength) { char *q = buffer; char *end = buffer + bufferLength - 1; @@ -211,6 +218,8 @@ void StorageTableShare::cleanupFieldName } *q = 0; + + return buffer; } const char* StorageTableShare::cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength) @@ -239,20 +248,54 @@ const char* StorageTableShare::cleanupTa return buffer; } -int StorageTableShare::createIndex(StorageConnection *storageConnection, const char* name, const char* sql) +char* StorageTableShare::createIndexName(const char *rawName, char *indexName) +{ + char nameBuffer[indexNameSize]; + cleanupFieldName(rawName, nameBuffer, sizeof(nameBuffer)); + sprintf(indexName, "%s$%s", name.getString(), nameBuffer); + return indexName; +} + +int StorageTableShare::createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, int indexCount, const char *sql) { if (!table) open(); - return storageDatabase->createIndex(storageConnection, table, name, sql); + // Always get syncIndexes before syncObject + + Sync syncIndex(syncIndexes, "StorageTableShare::createIndex(1)"); + syncIndex.lock(Exclusive); + + Sync syncObj(syncObject, "StorageTableShare::createIndex(2)"); + syncObj.lock(Exclusive); + + int ret = storageDatabase->createIndex(storageConnection, table, sql); + + if (!ret) + ret = setIndex(indexCount, indexDesc); + + return ret; } -int StorageTableShare::dropIndex(StorageConnection *storageConnection, const char* name, const char* sql) +int StorageTableShare::dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql) { if (!table) open(); - return storageDatabase->dropIndex(storageConnection, table, name, sql); + // Always get syncIndexes before syncObject + + Sync syncIndex(syncIndexes, "StorageTableShare::dropIndex(1)"); + syncIndex.lock(Exclusive); + + Sync syncObj(syncObject, "StorageTableShare::dropIndex(2)"); + syncObj.lock(Exclusive); + + int ret = storageDatabase->dropIndex(storageConnection, table, sql); + + if (!ret) + clearIndex(indexDesc); + + return ret; } int StorageTableShare::renameTable(StorageConnection *storageConnection, const char* newName) @@ -274,72 +317,132 @@ int StorageTableShare::renameTable(Stora return ret; } -StorageIndexDesc* StorageTableShare::getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc) +void StorageTableShare::resizeIndexes(int indexCount) { - // Rebuild array if indexes have been added or dropped + if (indexCount <= 0) + return; -#ifdef ONLINE_ALTER + if ((uint)indexCount > indexes.length) + indexes.extend(indexCount + 5); - // TODO: This does not work. It should be done at the time of index creation + numberIndexes = indexCount; +} - if (indexes && (numberIndexes != indexCount)) +int StorageTableShare::setIndex(int indexCount, const StorageIndexDesc *indexInfo) { - Sync sync(syncObject, "StorageTableShare::getIndex"); - sync.lock(Exclusive); - StorageIndexDesc **oldIndexes = indexes; - StorageIndexDesc **newIndexes = new StorageIndexDesc*[indexCount]; - memset(newIndexes, 0, indexCount * sizeof(StorageIndexDesc*)); + int indexId = indexInfo->id; - for (int n = 0; n < numberIndexes; ++n) - newIndexes[n] = indexes[n]; + if ((uint)indexId >= indexes.length || numberIndexes < indexCount) + resizeIndexes(indexCount); - indexes = newIndexes; - numberIndexes = indexCount; - delete [] oldIndexes; - } -#endif + // Allocate a new index if necessary - if (!indexes) - { - indexes = new StorageIndexDesc*[indexCount]; - memset(indexes, 0, indexCount * sizeof(StorageIndexDesc*)); - numberIndexes = indexCount; - } + StorageIndexDesc *indexDesc = indexes.get(indexId); - if (indexId >= numberIndexes) - return NULL; + if (!indexDesc) + indexes.vector[indexId] = indexDesc = new StorageIndexDesc(indexId); - StorageIndexDesc *index = indexes[indexId]; + // Copy index description info - if (index) - return index; + *indexDesc = *indexInfo; - indexes[indexId] = index = new StorageIndexDesc; - *index = *indexDesc; + // Find the corresponding Falcon index if (indexDesc->primaryKey) - index->index = table->primaryKey; + indexDesc->index = table->primaryKey; else { - char indexName[150]; - sprintf(indexName, "%s$%d", (const char*) name, indexId); - index->index = storageDatabase->findIndex(table, indexName); + char indexName[indexNameSize]; + sprintf(indexName, "%s$%s", name.getString(), indexDesc->name.getString()); + indexDesc->index = table->findIndex(indexName); } - if (index->index) - index->segmentRecordCounts = index->index->recordsPerSegment; + int ret = 0; + + if (indexDesc->index) + indexDesc->segmentRecordCounts = indexDesc->index->recordsPerSegment; else - index = NULL; + ret = StorageErrorNoIndex; - return index; + ASSERT((!ret ? validateIndexes() : true)); + + return ret; +} + +void StorageTableShare::clearIndex(StorageIndexDesc *indexDesc) +{ + if (numberIndexes > 0) + { + for (int n = indexDesc->id; n < numberIndexes-1; n++) + { + indexes.vector[n] = indexes.vector[n+1]; + indexes.vector[n]->id = n; // assume that index id will match server + } + + indexes.zap(numberIndexes-1); + numberIndexes--; + } + + ASSERT(validateIndexes()); +} + +bool StorageTableShare::validateIndexes() +{ + for (int n = 0; n < numberIndexes; n++) + { + StorageIndexDesc *indexDesc = indexes.get(n); + if (indexDesc && indexDesc->id != n) + return false; + } + + return true; } StorageIndexDesc* StorageTableShare::getIndex(int indexId) { - if (!indexes || indexId >= numberIndexes) + if (!indexes.length || indexId >= numberIndexes) return NULL; - return indexes[indexId]; + ASSERT(validateIndexes()); + + return indexes.get(indexId); +} + +StorageIndexDesc* StorageTableShare::getIndex(int indexId, StorageIndexDesc *indexDesc) +{ + StorageIndexDesc *index; + + if (!indexes.length || indexId >= numberIndexes) + index = NULL; + else + { + Sync sync(syncObject, "StorageTableShare::getIndex"); + sync.lock(Shared); + + ASSERT(validateIndexes()); + + index = indexes.get(indexId); + + if (index) + *indexDesc = *index; + } + + return index; +} + +StorageIndexDesc* StorageTableShare::getIndex(const char *name) +{ + Sync sync(syncObject, "StorageTableShare::getIndex(name)"); + sync.lock(Shared); + + for (int i = 0; i < numberIndexes; i++) + { + StorageIndexDesc *indexDesc = indexes.get(i); + if (indexDesc && indexDesc->name == name) + return indexDesc; + } + + return NULL; } INT64 StorageTableShare::getSequenceValue(int delta) @@ -365,34 +468,44 @@ int StorageTableShare::setSequenceValue( return 0; } +// Get index id using the internal (Falcon) index name + 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.get(n)->index; if (strcmp(index->getIndexName(), indexName) == 0 && strcmp(index->getSchemaName(), schemaName) == 0) + { +// if (n != indexes.get(n)->id) //debug +// return n; return n; } + } return -1; } 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) + { + StorageIndexDesc* index = indexes.get(n); + if (!index) return false; + + if (index && !index->index) + return false; + } return true; } === modified file 'storage/falcon/StorageTableShare.h' --- a/storage/falcon/StorageTableShare.h 2008-08-04 15:53:52 +0000 +++ b/storage/falcon/StorageTableShare.h 2008-08-18 05:45:29 +0000 @@ -18,6 +18,7 @@ #include "JString.h" #include "SyncObject.h" +#include "DenseArray.h" #ifndef _WIN32 #define __int64 long long @@ -26,6 +27,7 @@ typedef __int64 INT64; static const int MaxIndexSegments = 16; +static const int indexNameSize = 257; class StorageDatabase; class StorageConnection; @@ -47,11 +49,17 @@ struct StorageSegment { void *mysql_charset; }; -struct StorageIndexDesc { +class StorageIndexDesc +{ +public: + StorageIndexDesc(int indexId=0) : id (indexId), unique(0), primaryKey(0), numberSegments(0), /*name(NULL),*/ index(NULL), segmentRecordCounts(NULL){}; + + int id;//cwp int unique; int primaryKey; int numberSegments; - const char *name; + JString name; // clean name + JString rawName; // original name Index *index; uint64 *segmentRecordCounts; StorageSegment segments[MaxIndexSegments]; @@ -95,22 +103,28 @@ public: StorageTableShare(StorageHandler *handler, const char * path, const char *tableSpaceName, int lockSize, bool tempTbl); virtual ~StorageTableShare(void); - virtual void lock(bool exclusiveLock); + virtual void lock(bool exclusiveLock=false); 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 void lockIndexes(bool exclusiveLock=false); + virtual void unlockIndexes(void); + virtual int createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, int indexCount, const char *sql); + virtual int dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql); virtual int renameTable(StorageConnection *storageConnection, const char* newName); virtual INT64 getSequenceValue(int delta); virtual int setSequenceValue(INT64 value); virtual int haveIndexes(int indexCount); - virtual void cleanupFieldName(const char* name, char* buffer, int bufferLength); + virtual const char* cleanupFieldName(const char* name, char* buffer, int bufferLength); virtual void setTablePath(const char* path, bool tempTable); virtual void registerCollation(const char* collationName, void* arg); int open(void); - StorageIndexDesc* getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc); + void resizeIndexes(int indexCount); + int setIndex(int indexCount, const StorageIndexDesc* indexInfo); + void clearIndex(StorageIndexDesc *indexDesc); + bool validateIndexes(); StorageIndexDesc* getIndex(int indexId); - + StorageIndexDesc* getIndex(int indexId, StorageIndexDesc *indexDesc); + StorageIndexDesc* getIndex(const char *name); 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); @@ -129,6 +143,7 @@ public: static const char* getDefaultRoot(void); static const char* cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength); + char* createIndexName(const char *rawName, char *indexName); JString name; JString schemaName; @@ -140,10 +155,11 @@ public: unsigned char *impure; int initialized; SyncObject *syncObject; + SyncObject *syncIndexes; StorageDatabase *storageDatabase; StorageHandler *storageHandler; Table *table; - StorageIndexDesc **indexes; + DenseArray indexes; Sequence *sequence; Format *format; // format for insertion int numberIndexes; === modified file 'storage/falcon/Table.cpp' --- a/storage/falcon/Table.cpp 2008-08-13 10:18:40 +0000 +++ b/storage/falcon/Table.cpp 2008-08-18 05:45:29 +0000 @@ -209,6 +209,34 @@ Index* Table::addIndex(const char * name return index; } +void Table::dropIndex(const char* indexName, Transaction* transaction) +{ + Sync sync(&syncObject, "Table::dropIndex"); + sync.lock(Exclusive); + + Index *index = findIndex(indexName); + + if (index) + deleteIndex(index, transaction); +} + +void Table::renameIndexes(const char *newTableName) +{ + for (Index *index = indexes; index; index = index->next) + { + if (index->type != PrimaryKey) + { + + // Assume that index name is $ + + char newIndexName[256]; + const char *p = strchr((const char*)index->name, '$'); + sprintf(newIndexName, "%s%s", newTableName, (const char *)p); + index->rename(newIndexName); + } + } +} + const char* Table::getName() { return name; @@ -1706,6 +1734,19 @@ void Table::addIndex(Index * index) *ptr = index; } +void Table::dropIndex(Index *index) +{ + Sync sync(&syncObject, "Table::dropIndex"); + sync.lock(Exclusive); + + for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next) + if (*ptr == index) + { + *ptr = index->next; + break; + } +} + void Table::addAttachment(TableAttachment * attachment) { attachments.appendUnique(attachment); @@ -2226,15 +2267,6 @@ void Table::dropTrigger(Trigger *trigger #endif } -void Table::dropIndex(Index *index) -{ - for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next) - if (*ptr == index) - { - *ptr = index->next; - break; - } -} int Table::nextColumnId(int previous) { @@ -3196,6 +3228,8 @@ void Table::rename(const char *newSchema Index *primaryKey = getPrimaryKey(); database->renameTable(this, newSchema, newName); + renameIndexes(newName); + if (primaryKey) primaryKey->rename(getPrimaryKeyName()); } @@ -3491,7 +3525,7 @@ Record* Table::fetchForUpdate(Transactio ASSERT(IS_CONSISTENT_READ(transaction->isolationLevel)); record->release(); - Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s", + Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s\n", transaction->transactionId, record->recordNumber, schemaName, name); throw SQLError(UPDATE_CONFLICT, "update conflict in table %s.%s", schemaName, name); === modified file 'storage/falcon/Table.h' --- a/storage/falcon/Table.h 2008-08-11 13:22:53 +0000 +++ b/storage/falcon/Table.h 2008-08-18 05:45:29 +0000 @@ -180,6 +180,8 @@ public: void create (const char *tableType, Transaction *transaction); const char* getName(); Index* addIndex (const char *name, int numberFields, int type); + void dropIndex(const char* name, Transaction* transaction); + void renameIndexes(const char *newTableName); Field* addField (const char *name, Type type, int length, int precision, int scale, int flags); Field* findField (const char *name); int getFormatVersion(); === modified file 'storage/falcon/Transaction.cpp' --- a/storage/falcon/Transaction.cpp 2008-08-14 11:18:42 +0000 +++ b/storage/falcon/Transaction.cpp 2008-08-18 05:45:29 +0000 @@ -300,17 +300,19 @@ void Transaction::commit() database->flushInversion(this); // Transfer transaction from active list to committed list, set committed state + Sync syncCommitted(&transactionManager->committedTransactions.syncObject, "Transaction::commit(2)"); Sync syncActiveTransactions(&transactionManager->activeTransactions.syncObject, "Transaction::commit(3)"); - syncCommitted.lock(Exclusive); + syncActiveTransactions.lock(Exclusive); + syncCommitted.lock(Exclusive); transactionManager->activeTransactions.remove(this); transactionManager->committedTransactions.append(this); state = Committed; - syncActiveTransactions.unlock(); syncCommitted.unlock(); + syncActiveTransactions.unlock(); database->commit(this); === modified file 'storage/falcon/ha_falcon.cpp' --- a/storage/falcon/ha_falcon.cpp 2008-08-14 11:24:18 +0000 +++ b/storage/falcon/ha_falcon.cpp 2008-08-18 05:45:29 +0000 @@ -54,7 +54,7 @@ #endif #ifndef ONLINE_ALTER -//#define ONLINE_ALTER +#define ONLINE_ALTER #endif #ifdef DEBUG_BACKLOG @@ -398,6 +398,7 @@ StorageInterface::StorageInterface(handl ref_length = sizeof(lastRecord); stats.records = 1000; stats.data_file_length = 10000; + stats.index_file_length = 0; tableLocked = false; lockForUpdate = false; storageTable = NULL; @@ -424,6 +425,9 @@ StorageInterface::StorageInterface(handl StorageInterface::~StorageInterface(void) { + if (storageTable) + storageTable->clearCurrentIndex(); + if (activeBlobs) freeActiveBlobs(); @@ -482,6 +486,7 @@ int StorageInterface::open(const char *n if (!storageShare->initialized) { +// storageShare->lockIndexes(true); storageShare->lock(true); if (!storageShare->initialized) @@ -505,6 +510,7 @@ int StorageInterface::open(const char *n } storageShare->unlock(); +// storageShare->unlockIndexes(); } } @@ -535,6 +541,10 @@ StorageConnection* StorageInterface::get int StorageInterface::close(void) { DBUG_ENTER("StorageInterface::close"); + + if (storageTable) + storageTable->clearCurrentIndex(); + unmapFields(); // Temporarily comment out DTrace probes in Falcon, see bug #36403 @@ -672,23 +682,27 @@ void StorageInterface::getDemographics(v stats.block_size = 4096; + storageShare->lockIndexes(); + for (uint n = 0; n < table->s->keys; ++n) { KEY *key = table->s->key_info + n; - StorageIndexDesc *desc = storageShare->getIndex(n); + StorageIndexDesc *indexDesc = storageShare->getIndex(n); - if (desc) + if (indexDesc) { - ha_rows rows = 1 << desc->numberSegments; + ha_rows rows = 1 << indexDesc->numberSegments; for (uint segment = 0; segment < key->key_parts; ++segment, rows >>= 1) { - ha_rows recordsPerSegment = (ha_rows) desc->segmentRecordCounts[segment]; + ha_rows recordsPerSegment = (ha_rows)indexDesc->segmentRecordCounts[segment]; key->rec_per_key[segment] = (ulong) MAX(recordsPerSegment, rows); } } } + storageShare->unlockIndexes(); + DBUG_VOID_RETURN; } @@ -832,7 +846,7 @@ int StorageInterface::create(const char for (n = 0; n < form->s->keys; ++n) if (n != form->s->primary_key) - if ((ret = createIndex(schemaName, tableName, form->key_info + n, n))) + if ((ret = createIndex(schemaName, tableName, form, n))) { storageTable->deleteTable(); @@ -847,32 +861,42 @@ int StorageInterface::create(const char int StorageInterface::add_index(TABLE* table_arg, KEY* key_info, uint num_of_keys) { DBUG_ENTER("StorageInterface::add_index"); - int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), key_info, table_arg->s->keys); + int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), table_arg, table_arg->s->keys); DBUG_RETURN(ret); } -int StorageInterface::createIndex(const char *schemaName, const char *tableName, - KEY *key, int indexNumber) +int StorageInterface::createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId) { + KEY *key = table->key_info + indexId; + StorageIndexDesc indexDesc(indexId); + getKeyDesc(table, indexId, &indexDesc); + + char indexName[indexNameSize]; + storageShare->createIndexName(indexDesc.name.getString(), indexName); + CmdGen gen; const char *unique = (key->flags & HA_NOSAME) ? "unique " : ""; - gen.gen("create %sindex \"%s$%d\" on %s.\"%s\" ", unique, tableName, - indexNumber, schemaName, tableName); + gen.gen("create %sindex \"%s\" on %s.\"%s\" ", unique, indexName, schemaName, tableName); genKeyFields(key, &gen); const char *sql = gen.getString(); - return storageTable->share->createIndex(storageConnection, key->name, sql); + return storageTable->createIndex(&indexDesc, table->s->keys, sql); } -int StorageInterface::dropIndex(const char *schemaName, const char *tableName, - KEY *key, int indexNumber) +int StorageInterface::dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId) { + StorageIndexDesc indexDesc(indexId); + getKeyDesc(table, indexId, &indexDesc); + + char indexName[indexNameSize]; + storageShare->createIndexName(indexDesc.name.getString(), indexName); + CmdGen gen; - gen.gen("drop index %s.\"%s$%d\"", schemaName, tableName, indexNumber); + gen.gen("drop index %s.\"%s\"", schemaName, indexName); const char *sql = gen.getString(); - return storageTable->share->dropIndex(storageConnection, key->name, sql); + return storageTable->dropIndex(&indexDesc, sql); } #if 0 @@ -963,6 +987,7 @@ int StorageInterface::delete_table(const if (storageShare) { +// storageShare->lockIndexes(true); storageShare->lock(true); if (storageShare->initialized) @@ -973,6 +998,7 @@ int StorageInterface::delete_table(const } storageShare->unlock(); +// storageShare->unlockIndexes(); } int res = storageTable->deleteTable(); @@ -1358,7 +1384,6 @@ int StorageInterface::index_read(uchar * } } - int StorageInterface::index_init(uint idx, bool sorted) { DBUG_ENTER("StorageInterface::index_init"); @@ -1367,33 +1392,24 @@ int StorageInterface::index_init(uint id haveStartKey = false; haveEndKey = false; - if (!storageTable->setIndex(idx)) - DBUG_RETURN(0); - - StorageIndexDesc indexDesc; - getKeyDesc(table->key_info + idx, &indexDesc); - - if (idx == table->s->primary_key) - indexDesc.primaryKey = true; - - int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc); + int ret = storageTable->setCurrentIndex(idx); if (ret) DBUG_RETURN(error(ret)); - DBUG_RETURN(0); + DBUG_RETURN(ret); } - int StorageInterface::index_end(void) { DBUG_ENTER("StorageInterface::index_end"); + storageTable->indexEnd(); + DBUG_RETURN(0); } -ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower, - key_range *upper) +ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower, key_range *upper) { DBUG_ENTER("StorageInterface::records_in_range"); @@ -1406,9 +1422,9 @@ ha_rows StorageInterface::records_in_ran if (!lower) DBUG_RETURN(MAX(cardinality, 2)); - StorageIndexDesc *index = storageShare->getIndex(indexId); + StorageIndexDesc indexDesc; - if (!index) + if (!storageShare->getIndex(indexId, &indexDesc)) DBUG_RETURN(MAX(cardinality, 2)); int numberSegments = 0; @@ -1416,10 +1432,10 @@ ha_rows StorageInterface::records_in_ran for (int map = lower->keypart_map; map; map >>= 1) ++numberSegments; - if (index->unique && numberSegments == index->numberSegments) + if (indexDesc.unique && numberSegments == indexDesc.numberSegments) DBUG_RETURN(1); - ha_rows segmentRecords = (ha_rows) index->segmentRecordCounts[numberSegments - 1]; + ha_rows segmentRecords = (ha_rows)indexDesc.segmentRecordCounts[numberSegments - 1]; ha_rows guestimate = cardinality; if (lower->flag == HA_READ_KEY_EXACT) @@ -1436,22 +1452,27 @@ ha_rows StorageInterface::records_in_ran DBUG_RETURN(MAX(guestimate, 2)); } - -void StorageInterface::getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo) +void StorageInterface::getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexDesc) { + KEY *keyInfo = table->key_info + indexId; int numberKeys = keyInfo->key_parts; - indexInfo->numberSegments = numberKeys; - indexInfo->name = keyInfo->name; - indexInfo->unique = (keyInfo->flags & HA_NOSAME); - indexInfo->primaryKey = false; + char nameBuffer[indexNameSize]; + + indexDesc->rawName = keyInfo->name; + storageShare->cleanupFieldName(indexDesc->rawName, nameBuffer, sizeof(nameBuffer)); + indexDesc->name = nameBuffer; + indexDesc->numberSegments = numberKeys; + indexDesc->unique = (keyInfo->flags & HA_NOSAME); + indexDesc->primaryKey = (table->s->primary_key == (uint)indexId); for (int n = 0; n < numberKeys; ++n) { - StorageSegment *segment = indexInfo->segments + n; + StorageSegment *segment = indexDesc->segments + n; KEY_PART_INFO *part = keyInfo->key_part + n; - segment->offset = part->offset; - segment->length = part->length; - segment->type = part->field->key_type(); + + segment->offset = part->offset; + segment->length = part->length; + segment->type = part->field->key_type(); segment->nullBit = part->null_bit; segment->isUnsigned = (part->field->flags & ENUM_FLAG) ? true : ((Field_num*) part->field)->unsigned_flag; @@ -1472,7 +1493,6 @@ void StorageInterface::getKeyDesc(KEY *k } } - int StorageInterface::rename_table(const char *from, const char *to) { DBUG_ENTER("StorageInterface::rename_table"); @@ -1489,17 +1509,14 @@ int StorageInterface::rename_table(const DBUG_RETURN(error(ret)); DBUG_RETURN(ret); - } - 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) @@ -1634,7 +1651,6 @@ int StorageInterface::index_next(uchar * } } - int StorageInterface::index_next_same(uchar *buf, const uchar *key, uint key_len) { DBUG_ENTER("StorageInterface::index_next_same"); @@ -1654,7 +1670,6 @@ int StorageInterface::index_next_same(uc } } - double StorageInterface::scan_time(void) { DBUG_ENTER("StorageInterface::scan_time"); @@ -1691,13 +1706,11 @@ bool StorageInterface::threadSwitch(THD* return true; } - int StorageInterface::threadSwitchError(void) { return 1; } - int StorageInterface::error(int storageError) { DBUG_ENTER("StorageInterface::error"); @@ -1737,7 +1750,6 @@ int StorageInterface::error(int storageE DBUG_RETURN(mySqlError); } - int StorageInterface::getMySqlError(int storageError) { switch (storageError) @@ -1856,8 +1868,6 @@ int StorageInterface::reset() DBUG_RETURN(0); } - - int StorageInterface::external_lock(THD *thd, int lock_type) { DBUG_ENTER("StorageInterface::external_lock"); @@ -1873,7 +1883,10 @@ int StorageInterface::external_lock(THD storageConnection->releaseVerb(); if (storageTable) + { storageTable->clearStatement(); + storageTable->clearCurrentIndex(); + } } else { @@ -1894,6 +1907,9 @@ int StorageInterface::external_lock(THD if (ret) { + if (storageTable) + storageTable->clearCurrentIndex(); + DBUG_RETURN(error(ret)); } } @@ -1910,9 +1926,7 @@ int StorageInterface::external_lock(THD checkBinLog(); if (storageConnection->startTransaction(isolation)) - { trans_register_ha(thd, true, falcon_hton); - } if (storageConnection->markVerb()) trans_register_ha(thd, false, falcon_hton); @@ -1922,9 +1936,7 @@ int StorageInterface::external_lock(THD checkBinLog(); if (storageConnection->startImplicitTransaction(isolation)) - { trans_register_ha(thd, false, falcon_hton); - } } switch (thd_tx_isolation(mySqlThread)) @@ -1937,13 +1949,11 @@ int StorageInterface::external_lock(THD error(StorageWarningSerializable); break; } - } DBUG_RETURN(0); } - void StorageInterface::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, @@ -1956,7 +1966,6 @@ void StorageInterface::get_auto_incremen DBUG_VOID_RETURN; } - const char *StorageInterface::index_type(uint key_number) { DBUG_ENTER("StorageInterface::index_type"); @@ -1971,7 +1980,6 @@ void StorageInterface::dropDatabase(hand DBUG_VOID_RETURN; } - void StorageInterface::freeActiveBlobs(void) { for (StorageBlob *blob; (blob = activeBlobs); ) @@ -1983,14 +1991,12 @@ void StorageInterface::freeActiveBlobs(v } } - void StorageInterface::shutdown(handlerton *htons) { if(storageHandler) storageHandler->shutdownHandler(); } - int StorageInterface::panic(handlerton* hton, ha_panic_function flag) { if(storageHandler) @@ -1999,7 +2005,6 @@ int StorageInterface::panic(handlerton* return 0; } - int StorageInterface::closeConnection(handlerton *hton, THD *thd) { DBUG_ENTER("NfsStorageEngine::closeConnection"); @@ -2009,7 +2014,6 @@ int StorageInterface::closeConnection(ha DBUG_RETURN(0); } - int StorageInterface::alter_tablespace(handlerton* hton, THD* thd, st_alter_tablespace* ts_info) { DBUG_ENTER("NfsStorageEngine::alter_tablespace"); @@ -2243,10 +2247,11 @@ int StorageInterface::addIndex(THD* thd, break; if (tableKey >= tableEnd) - if ((ret = createIndex(schemaName, tableName, key, n))) + if ((ret = createIndex(schemaName, tableName, alteredTable, n))) return (error(ret)); } } + return 0; } @@ -2271,7 +2276,7 @@ int StorageInterface::dropIndex(THD* thd break; if (alterKey >= alterEnd) - if ((ret = dropIndex(schemaName, tableName, key, n))) + if ((ret = dropIndex(schemaName, tableName, table, n))) return (error(ret)); } } @@ -2288,7 +2293,6 @@ uint StorageInterface::max_supported_key return MAX_INDEX_KEY_LENGTH_4K; // Default value. } - uint StorageInterface::max_supported_key_part_length(void) const { // Assume 4K page unless proven otherwise. @@ -2298,7 +2302,6 @@ uint StorageInterface::max_supported_key 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) @@ -2314,32 +2317,31 @@ void StorageInterface::logger(int mask, } } +int StorageInterface::setIndex(TABLE *table, int indexId) +{ + StorageIndexDesc indexDesc(indexId); + getKeyDesc(table, indexId, &indexDesc); + + return storageTable->setIndex(table->s->keys, &indexDesc); +} + int StorageInterface::setIndexes(void) { + int ret = 0; + if (!table || storageShare->haveIndexes(table->s->keys)) - return 0; + return ret; - storageShare->lock(true); + storageShare->lockIndexes(true); if (!storageShare->haveIndexes(table->s->keys)) - { - StorageIndexDesc indexDesc; - for (uint n = 0; n < table->s->keys; ++n) - { - getKeyDesc(table->key_info + n, &indexDesc); - - if (n == table->s->primary_key) - indexDesc.primaryKey = true; + if ((ret = setIndex(table, n))) + break; - int ret = storageTable->setIndex(table->s->keys, n, &indexDesc); - if (ret) - return ret; - } - } + storageShare->unlockIndexes(); - storageShare->unlock(); - return 0; + return ret; } int StorageInterface::genTable(TABLE* table, CmdGen* gen) @@ -2348,7 +2350,7 @@ int StorageInterface::genTable(TABLE* ta const char *schemaName = storageTable->getSchemaName(); gen->gen("upgrade table \"%s\".\"%s\" (\n", schemaName, tableName); const char *sep = ""; - char nameBuffer[129]; + char nameBuffer[256]; for (uint n = 0; n < table->s->fields; ++n) { @@ -2495,18 +2497,16 @@ int StorageInterface::genType(Field* fie return 0; } - void StorageInterface::genKeyFields(KEY* key, CmdGen* gen) { const char *sep = "("; - char nameBuffer[129]; + char nameBuffer[256]; for (uint n = 0; n < key->key_parts; ++n) { KEY_PART_INFO *part = key->key_part + n; Field *field = part->field; - storageShare->cleanupFieldName(field->field_name, nameBuffer, - sizeof(nameBuffer)); + storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer)); if (part->key_part_flag & HA_PART_KEY_SEG) gen->gen("%s\"%s\"(%d)", sep, nameBuffer, part->length); @@ -2519,7 +2519,6 @@ void StorageInterface::genKeyFields(KEY* gen->gen(")"); } - void StorageInterface::encodeRecord(uchar *buf, bool updateFlag) { storageTable->preInsert(); @@ -3504,7 +3503,7 @@ void StorageInterface::mapFields(TABLE * unmapFields(); fieldMap = new Field*[maxFields]; memset(fieldMap, 0, sizeof(fieldMap[0]) * maxFields); - char nameBuffer[129]; + char nameBuffer[256]; for (uint n = 0; n < table->s->fields; ++n) { === modified file 'storage/falcon/ha_falcon.h' --- a/storage/falcon/ha_falcon.h 2008-07-29 10:45:39 +0000 +++ b/storage/falcon/ha_falcon.h 2008-08-18 05:45:29 +0000 @@ -29,7 +29,7 @@ static const int TRANSACTION_CONSISTENT_ static const int TRANSACTION_SERIALIZABLE = 16; // Dirty reads, non-repeatable reads and phantom reads are prevented. struct st_table_share; -struct StorageIndexDesc; +class StorageIndexDesc; struct StorageBlob; class StorageInterface : public handler @@ -113,14 +113,16 @@ public: int dropIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags); void getDemographics(void); - int createIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber); - int dropIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber); - void getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo); +// int createIndex(const char *schemaName, const char *tableName, KEY *key, int indexId); + int createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId); + int dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId); + void getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexInfo); void startTransaction(void); bool threadSwitch(THD *newThread); int threadSwitchError(void); int error(int storageError); void freeActiveBlobs(void); + int setIndex(TABLE *table, int indexId); int setIndexes(void); int genTable(TABLE* table, CmdGen* gen); int genType(Field *field, CmdGen *gen);