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<StorageIndexDesc *,10> 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 <table>$<index>
+
+ 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);
Thread |
---|
• bzr push into mysql-6.0-falcon branch (cpowers:2786 to 2787) Bug#38039Bug#38041 Bug#38043 Bug#38044 | Christopher Powers | 18 Aug |