From 6ba273731dacae9ee8f024711208b87e30cc575b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Sep 2006 15:09:34 +0200 Subject: [PATCH] NDB temporary tables. Temporary tables are not written to disk by DDL operations. This makes DDL much faster (useful for tests), but tables are lost after system restart. New commit, since this feature will not be available in 5.1. storage/ndb/include/kernel/signaldata/CreateIndx.hpp: Add new error messages for temporary tables. storage/ndb/include/kernel/signaldata/CreateTable.hpp: Add new error messages for temporary tables. storage/ndb/include/kernel/signaldata/DiAddTab.hpp: Add parameter for making table temporary. storage/ndb/include/kernel/signaldata/DictTabInfo.hpp: Add parameter for making table temporary. storage/ndb/include/kernel/signaldata/ListTables.hpp: Add parameter for making table temporary. storage/ndb/include/ndb_constants.h: Add parameter for making table temporary. storage/ndb/include/ndbapi/NdbDictionary.hpp: Add parameter for making table temporary. storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp: Add parameter for making table temporary. storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Implement temporary tables. storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp: Implement temporary tables. storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp: Implement temporary tables. storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp: Implement temporary tables. storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Implement temporary tables. storage/ndb/src/ndbapi/NdbDictionary.cpp: Implement temporary tables. storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp: Implement temporary tables. storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp: Implement temporary tables. storage/ndb/src/ndbapi/ndberror.c: Add new error messages for temporary tables. storage/ndb/tools/listTables.cpp: Add display of table and index temporary status. --- .../include/kernel/signaldata/CreateIndx.hpp | 5 +- .../include/kernel/signaldata/CreateTable.hpp | 3 +- .../include/kernel/signaldata/DiAddTab.hpp | 5 +- .../include/kernel/signaldata/DictTabInfo.hpp | 5 +- .../include/kernel/signaldata/ListTables.hpp | 16 +- storage/ndb/include/ndb_constants.h | 8 +- storage/ndb/include/ndbapi/NdbDictionary.hpp | 12 +- .../debugger/signaldata/DictTabInfo.cpp | 2 + .../ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 300 ++++++++++++++---- .../ndb/src/kernel/blocks/dbdict/Dbdict.hpp | 9 +- .../src/kernel/blocks/dbdict/SchemaFile.hpp | 3 +- storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 7 +- .../ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 41 ++- storage/ndb/src/ndbapi/NdbDictionary.cpp | 20 ++ storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp | 16 +- storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp | 2 + storage/ndb/src/ndbapi/ndberror.c | 5 +- storage/ndb/tools/listTables.cpp | 73 ++++- 18 files changed, 437 insertions(+), 95 deletions(-) diff --git a/storage/ndb/include/kernel/signaldata/CreateIndx.hpp b/storage/ndb/include/kernel/signaldata/CreateIndx.hpp index 8a321d4a657..71688138f0a 100644 --- a/storage/ndb/include/kernel/signaldata/CreateIndx.hpp +++ b/storage/ndb/include/kernel/signaldata/CreateIndx.hpp @@ -208,7 +208,10 @@ public: NotUnique = 4251, AllocationError = 4252, CreateIndexTableFailed = 4253, - DuplicateAttributes = 4258 + DuplicateAttributes = 4258, + TableIsTemporary = 776, + TableIsNotTemporary = 777, + NoLoggingTemporaryIndex = 778, }; CreateIndxConf m_conf; diff --git a/storage/ndb/include/kernel/signaldata/CreateTable.hpp b/storage/ndb/include/kernel/signaldata/CreateTable.hpp index e5e78bddd49..2be69f41157 100644 --- a/storage/ndb/include/kernel/signaldata/CreateTable.hpp +++ b/storage/ndb/include/kernel/signaldata/CreateTable.hpp @@ -97,7 +97,8 @@ public: VarsizeBitfieldNotSupported = 757, NotATablespace = 758, InvalidTablespaceVersion = 759, - OutOfStringBuffer = 773 + OutOfStringBuffer = 773, + NoLoggingTemporaryTable = 778, }; private: diff --git a/storage/ndb/include/kernel/signaldata/DiAddTab.hpp b/storage/ndb/include/kernel/signaldata/DiAddTab.hpp index 47456f11842..dc3f976bb73 100644 --- a/storage/ndb/include/kernel/signaldata/DiAddTab.hpp +++ b/storage/ndb/include/kernel/signaldata/DiAddTab.hpp @@ -30,7 +30,7 @@ class DiAddTabReq { */ friend class Dbdih; public: - STATIC_CONST( SignalLength = 9 ); + STATIC_CONST( SignalLength = 10 ); SECTION( FRAGMENTATION = 0 ); SECTION( TS_RANGE = 0 ); @@ -40,10 +40,11 @@ private: Uint32 fragType; Uint32 kValue; Uint32 noOfReplicas; //Currently not used - Uint32 storedTable; + Uint32 loggedTable; Uint32 tableType; Uint32 schemaVersion; Uint32 primaryTableId; + Uint32 temporaryTable; }; class DiAddTabRef { diff --git a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp index 1382b09eabf..86186929394 100644 --- a/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/storage/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -118,6 +118,8 @@ public: FrmLen = 26, FrmData = 27, + TableTemporaryFlag = 28, //Default not Temporary + FragmentCount = 128, // No of fragments in table (!fragment replicas) FragmentDataLen = 129, FragmentData = 130, // CREATE_FRAGMENTATION reply @@ -278,7 +280,7 @@ public: // Object store for translating from/to API enum ObjectStore { StoreUndefined = 0, - StoreTemporary = 1, + StoreNotLogged = 1, StorePermanent = 2 }; @@ -297,6 +299,7 @@ public: char PrimaryTable[MAX_TAB_NAME_SIZE]; // Only used when "index" Uint32 PrimaryTableId; Uint32 TableLoggedFlag; + Uint32 TableTemporaryFlag; Uint32 NoOfKeyAttr; Uint32 NoOfAttributes; Uint32 NoOfNullable; diff --git a/storage/ndb/include/kernel/signaldata/ListTables.hpp b/storage/ndb/include/kernel/signaldata/ListTables.hpp index 7fbfab1294c..4c60e04ec75 100644 --- a/storage/ndb/include/kernel/signaldata/ListTables.hpp +++ b/storage/ndb/include/kernel/signaldata/ListTables.hpp @@ -39,10 +39,16 @@ public: BitmaskImpl::setField(1, &data, 12, 8, val); } static Uint32 getTableStore(Uint32 data) { - return BitmaskImpl::getField(1, &data, 20, 4); + return BitmaskImpl::getField(1, &data, 20, 3); } static void setTableStore(Uint32& data, Uint32 val) { - BitmaskImpl::setField(1, &data, 20, 4, val); + BitmaskImpl::setField(1, &data, 20, 3, val); + } + static Uint32 getTableTemp(Uint32 data) { + return BitmaskImpl::getField(1, &data, 23, 1); + } + static void setTableTemp(Uint32& data, Uint32 val) { + BitmaskImpl::setField(1, &data, 23, 1, val); } static Uint32 getTableState(Uint32 data) { return BitmaskImpl::getField(1, &data, 24, 4); @@ -161,6 +167,12 @@ public: void setTableState(unsigned pos, Uint32 val) { ListTablesData::setTableState(tableData[pos], val); } + static Uint32 getTableTemp(Uint32 data) { + return ListTablesData::getTableTemp(data); + } + void setTableTemp(unsigned pos, Uint32 val) { + ListTablesData::setTableTemp(tableData[pos], val); + } }; #endif diff --git a/storage/ndb/include/ndb_constants.h b/storage/ndb/include/ndb_constants.h index 0626fcb7bf3..750587507d4 100644 --- a/storage/ndb/include/ndb_constants.h +++ b/storage/ndb/include/ndb_constants.h @@ -84,5 +84,11 @@ #define NDB_STORAGETYPE_MEMORY 0 #define NDB_STORAGETYPE_DISK 1 - + +/* + * Table temporary status. + */ +#define NDB_TEMP_TAB_PERMANENT 0 +#define NDB_TEMP_TAB_TEMPORARY 1 + #endif diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp index 35b0d927bda..9e73bc00712 100644 --- a/storage/ndb/include/ndbapi/NdbDictionary.hpp +++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp @@ -136,7 +136,7 @@ public: */ enum Store { StoreUndefined = 0, ///< Undefined - StoreTemporary = 1, ///< Object or data deleted on system restart + StoreNotLogged = 1, ///< Object or data deleted on system restart StorePermanent = 2 ///< Permanent. logged to disk }; @@ -917,6 +917,9 @@ public: int createTableInDb(Ndb*, bool existingEqualIsOk = true) const ; int getReplicaCount() const ; + + bool getTemporary(); + void setTemporary(bool); #endif private: @@ -1104,6 +1107,9 @@ public: #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED void setStoredIndex(bool x) { setLogging(x); } bool getStoredIndex() const { return getLogging(); } + + bool getTemporary(); + void setTemporary(bool); #endif /** @} *******************************************************************/ @@ -1564,7 +1570,8 @@ public: unsigned id; ///< Id of object Object::Type type; ///< Type of object Object::State state; ///< State of object - Object::Store store; ///< How object is stored + Object::Store store; ///< How object is logged + Uint32 temp; ///< Temporary status of object char * database; ///< In what database the object resides char * schema; ///< What schema the object is defined in char * name; ///< Name of object @@ -1573,6 +1580,7 @@ public: type(Object::TypeUndefined), state(Object::StateUndefined), store(Object::StoreUndefined), + temp(NDB_TEMP_TAB_PERMANENT), database(0), schema(0), name(0) { diff --git a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp b/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp index 2ed97892488..62f372025ff 100644 --- a/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp +++ b/storage/ndb/src/common/debugger/signaldata/DictTabInfo.cpp @@ -26,6 +26,7 @@ DictTabInfo::TableMapping[] = { DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE), DTIMAP(Table, PrimaryTableId, PrimaryTableId), DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1), + DTIMAP2(Table, TableTemporaryFlag, TableTemporaryFlag, 0, 1), DTIMAP2(Table, TableKValue, TableKValue, 6, 6), DTIMAP2(Table, MinLoadFactor, MinLoadFactor, 0, 90), DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor, 25, 110), @@ -122,6 +123,7 @@ DictTabInfo::Table::init(){ memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index" PrimaryTableId = RNIL; TableLoggedFlag = 1; + TableTemporaryFlag = 0; NoOfKeyAttr = 0; NoOfAttributes = 0; NoOfNullable = 0; diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 02b0cb83847..ea6028b0ebb 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -448,6 +448,8 @@ Dbdict::packTableIntoPages(SimpleProperties::Writer & w, !!(tablePtr.p->m_bits & TableRecord::TR_RowGCI)); w.add(DictTabInfo::RowChecksumFlag, !!(tablePtr.p->m_bits & TableRecord::TR_RowChecksum)); + w.add(DictTabInfo::TableTemporaryFlag, + !!(tablePtr.p->m_bits & TableRecord::TR_Temporary)); w.add(DictTabInfo::MinLoadFactor, tablePtr.p->minLoadFactor); w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor); @@ -1086,8 +1088,8 @@ void Dbdict::closeReadTableConf(Signal* signal, /* ---------------------------------------------------------------- */ void Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, - SchemaFile::TableEntry* te, Callback* callback){ - + SchemaFile::TableEntry* te, Callback* callback, + bool savetodisk){ jam(); ndbrequire(tableId < c_tableRecordPool.getSize()); XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; @@ -1130,6 +1132,12 @@ Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, jam(); ok = true; break; + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ndbrequire(oldState == SchemaFile::ADD_STARTED || + oldState == SchemaFile::TEMPORARY_TABLE_COMMITTED); + ok = true; + break; case SchemaFile::INIT: jam(); ok = true; @@ -1140,16 +1148,23 @@ Dbdict::updateSchemaState(Signal* signal, Uint32 tableId, * tableEntry = * te; computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES); - ndbrequire(c_writeSchemaRecord.inUse == false); - c_writeSchemaRecord.inUse = true; - - c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; - c_writeSchemaRecord.newFile = false; - c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES; - c_writeSchemaRecord.noOfPages = 1; - c_writeSchemaRecord.m_callback = * callback; - - startWriteSchemaFile(signal); + if (savetodisk) + { + ndbrequire(c_writeSchemaRecord.inUse == false); + c_writeSchemaRecord.inUse = true; + + c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; + c_writeSchemaRecord.newFile = false; + c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES; + c_writeSchemaRecord.noOfPages = 1; + c_writeSchemaRecord.m_callback = * callback; + + startWriteSchemaFile(signal); + } + else + { + execute(signal, *callback, 0); + } } void Dbdict::startWriteSchemaFile(Signal* signal) @@ -2722,6 +2737,13 @@ void Dbdict::checkSchemaStatus(Signal* signal) newEntry->m_tableState = SchemaFile::INIT; restartDropTab(signal, tableId); return; + + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + // Temporary table is never written to disk, so just set to INIT. + jam(); + ok = true; + newEntry->m_tableState = SchemaFile::INIT; + break; }//switch ndbrequire(ok); break; @@ -2752,6 +2774,11 @@ void Dbdict::checkSchemaStatus(Signal* signal) newEntry->m_tableState = SchemaFile::INIT; restartDropTab(signal, tableId); return; + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ok = true; + newEntry->m_tableState = SchemaFile::INIT; + break; } ndbrequire(ok); break; @@ -2812,6 +2839,17 @@ void Dbdict::checkSchemaStatus(Signal* signal) restartCreateTab(signal, tableId, oldEntry, newEntry, false); return; }//if + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ok = true; + // For NR, we must re-create the table. + // For SR, we do nothing as the table was never saved to disk. + if(!c_systemRestart) + { + restartCreateTab(signal, tableId, oldEntry, newEntry, false); + return; + } + break; } ndbrequire(ok); break; @@ -2839,6 +2877,11 @@ void Dbdict::checkSchemaStatus(Signal* signal) newEntry->m_tableState = SchemaFile::INIT; restartDropTab(signal, tableId); return; + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ok = true; + newEntry->m_tableState = SchemaFile::INIT; + break; } ndbrequire(ok); break; @@ -2855,6 +2898,15 @@ void Dbdict::checkSchemaStatus(Signal* signal) jam(); case SchemaFile::DROP_TABLE_COMMITTED: jam(); + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ok = true; + if(!c_systemRestart) + { + restartCreateTab(signal, tableId, oldEntry, newEntry, false); + return; + } + break; case SchemaFile::TABLE_ADD_COMMITTED: jam(); ok = true; @@ -2885,6 +2937,37 @@ void Dbdict::checkSchemaStatus(Signal* signal) ndbrequire(ok); break; } + case SchemaFile::TEMPORARY_TABLE_COMMITTED: { + jam(); + bool ok = false; + switch(oldSchemaState){ + case SchemaFile::INIT: + jam(); + case SchemaFile::DROP_TABLE_COMMITTED: + jam(); + case SchemaFile::ADD_STARTED: + jam(); + case SchemaFile::TABLE_ADD_COMMITTED: + jam(); + case SchemaFile::DROP_TABLE_STARTED: + jam(); + case SchemaFile::ALTER_TABLE_COMMITTED: + jam(); + case SchemaFile::TEMPORARY_TABLE_COMMITTED: + jam(); + ok = true; + if(!c_systemRestart) + { + restartCreateTab(signal, tableId, oldEntry, newEntry, false); + return; + } else { + newEntry->m_tableState = SchemaFile::INIT; + } + break; + } + ndbrequire(ok); + break; + } } } @@ -3119,6 +3202,8 @@ Dbdict::execGET_TABINFO_CONF(Signal* signal){ handleTabInfoInit(r, &parseRecord); ndbrequire(parseRecord.errorCode == 0); + // save to disk + ndbrequire(tableId < c_tableRecordPool.getSize()); XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0]; SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, tableId); @@ -4205,6 +4290,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) SegmentedSectionPtr tabInfoPtr; signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO); alterTabPtr.p->m_tabInfoPtrI = tabInfoPtr.i; + bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary); signal->header.m_noOfSections = 0; @@ -4216,7 +4302,10 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) SchemaFile::TableEntry tabEntry; tabEntry.m_tableVersion = tableVersion; tabEntry.m_tableType = tablePtr.p->tableType; - tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED; + if (savetodisk) + tabEntry.m_tableState = SchemaFile::ALTER_TABLE_COMMITTED; + else + tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED; tabEntry.m_gcp = gci; tabEntry.m_info_words = tabInfoPtr.sz; memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused)); @@ -4226,7 +4315,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) callback.m_callbackFunction = safe_cast(&Dbdict::alterTab_writeSchemaConf); - updateSchemaState(signal, tableId, &tabEntry, &callback); + updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk); break; } case(AlterTabReq::AlterTableRevert): { @@ -4703,9 +4792,19 @@ Dbdict::alterTab_writeSchemaConf(Signal* signal, callback.m_callbackFunction = safe_cast(&Dbdict::alterTab_writeTableConf); - SegmentedSectionPtr tabInfoPtr; - getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI); - writeTableFile(signal, tableId, tabInfoPtr, &callback); + TableRecordPtr tablePtr; + c_tableRecordPool.getPtr(tablePtr, tableId); + bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary); + if (savetodisk) + { + SegmentedSectionPtr tabInfoPtr; + getSection(tabInfoPtr, alterTabPtr.p->m_tabInfoPtrI); + writeTableFile(signal, tableId, tabInfoPtr, &callback); + } + else + { + execute(signal, callback, 0); + } } void @@ -5136,7 +5235,8 @@ Dbdict::createTab_prepare(Signal* signal, CreateTabReq * req){ callback.m_callbackFunction = safe_cast(&Dbdict::createTab_writeSchemaConf1); - updateSchemaState(signal, tableId, &tabEntry, &callback); + bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary); + updateSchemaState(signal, tableId, &tabEntry, &callback, savetodisk); } void getSection(SegmentedSectionPtr & ptr, Uint32 i); @@ -5155,9 +5255,19 @@ Dbdict::createTab_writeSchemaConf1(Signal* signal, callback.m_callbackFunction = safe_cast(&Dbdict::createTab_writeTableConf); - SegmentedSectionPtr tabInfoPtr; - getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); - writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + TableRecordPtr tabPtr; + c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); + bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary); + if (savetodisk) + { + SegmentedSectionPtr tabInfoPtr; + getSection(tabInfoPtr, createTabPtr.p->m_tabInfoPtrI); + writeTableFile(signal, createTabPtr.p->m_tablePtrI, tabInfoPtr, &callback); + } + else + { + execute(signal, callback, 0); + } #if 0 createTabPtr.p->m_tabInfoPtrI = RNIL; signal->setSection(tabInfoPtr, 0); @@ -5203,10 +5313,11 @@ Dbdict::createTab_dih(Signal* signal, req->fragType = tabPtr.p->fragmentType; req->kValue = tabPtr.p->kValue; req->noOfReplicas = 0; - req->storedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged); + req->loggedTable = !!(tabPtr.p->m_bits & TableRecord::TR_Logged); req->tableType = tabPtr.p->tableType; req->schemaVersion = tabPtr.p->tableVersion; req->primaryTableId = tabPtr.p->primaryTableId; + req->temporaryTable = !!(tabPtr.p->m_bits & TableRecord::TR_Temporary); /* Behöver fiska upp fragDataPtr från table object istället @@ -5618,11 +5729,16 @@ Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){ TableRecordPtr tabPtr; c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); - + bool savetodisk = !(tabPtr.p->m_bits & TableRecord::TR_Temporary); + SchemaFile::TableEntry tabEntry; tabEntry.m_tableVersion = tabPtr.p->tableVersion; tabEntry.m_tableType = tabPtr.p->tableType; - tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED; + if (savetodisk) + tabEntry.m_tableState = SchemaFile::TABLE_ADD_COMMITTED; + else + tabEntry.m_tableState = SchemaFile::TEMPORARY_TABLE_COMMITTED; + tabEntry.m_gcp = tabPtr.p->gciTableCreated; tabEntry.m_info_words = tabPtr.p->packedSize; memset(tabEntry.m_unused, 0, sizeof(tabEntry.m_unused)); @@ -5632,7 +5748,7 @@ Dbdict::createTab_commit(Signal * signal, CreateTabReq * req){ callback.m_callbackFunction = safe_cast(&Dbdict::createTab_writeSchemaConf2); - updateSchemaState(signal, tabPtr.i, &tabEntry, &callback); + updateSchemaState(signal, tabPtr.i, &tabEntry, &callback, savetodisk); } void @@ -5967,6 +6083,10 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, #endif } + // Disallow logging of a temporary table. + tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag), + CreateTableRef::NoLoggingTemporaryTable); + tablePtr.p->noOfAttributes = c_tableDesc.NoOfAttributes; tablePtr.p->m_bits |= (c_tableDesc.TableLoggedFlag ? TableRecord::TR_Logged : 0); @@ -5974,6 +6094,8 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, (c_tableDesc.RowChecksumFlag ? TableRecord::TR_RowChecksum : 0); tablePtr.p->m_bits |= (c_tableDesc.RowGCIFlag ? TableRecord::TR_RowGCI : 0); + tablePtr.p->m_bits |= + (c_tableDesc.TableTemporaryFlag ? TableRecord::TR_Temporary : 0); tablePtr.p->minLoadFactor = c_tableDesc.MinLoadFactor; tablePtr.p->maxLoadFactor = c_tableDesc.MaxLoadFactor; tablePtr.p->fragmentType = (DictTabInfo::FragmentType)c_tableDesc.FragmentType; @@ -6775,21 +6897,31 @@ Dbdict::execPREP_DROP_TAB_REQ(Signal* signal){ SchemaFile::TableState tabState = (SchemaFile::TableState)tableEntry->m_tableState; ndbrequire(tabState == SchemaFile::TABLE_ADD_COMMITTED || - tabState == SchemaFile::ALTER_TABLE_COMMITTED); + tabState == SchemaFile::ALTER_TABLE_COMMITTED || + tabState == SchemaFile::TEMPORARY_TABLE_COMMITTED); tableEntry->m_tableState = SchemaFile::DROP_TABLE_STARTED; computeChecksum(xsf, tablePtr.i / NDB_SF_PAGE_ENTRIES); - - ndbrequire(c_writeSchemaRecord.inUse == false); - c_writeSchemaRecord.inUse = true; - - c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; - c_writeSchemaRecord.newFile = false; - c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES; - c_writeSchemaRecord.noOfPages = 1; - c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key; - c_writeSchemaRecord.m_callback.m_callbackFunction = - safe_cast(&Dbdict::prepDropTab_writeSchemaConf); - startWriteSchemaFile(signal); + + bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary); + Callback callback; + callback.m_callbackData = dropTabPtr.p->key; + callback.m_callbackFunction = safe_cast(&Dbdict::prepDropTab_writeSchemaConf); + if (savetodisk) + { + ndbrequire(c_writeSchemaRecord.inUse == false); + c_writeSchemaRecord.inUse = true; + + c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; + c_writeSchemaRecord.newFile = false; + c_writeSchemaRecord.firstPage = tablePtr.i / NDB_SF_PAGE_ENTRIES; + c_writeSchemaRecord.noOfPages = 1; + c_writeSchemaRecord.m_callback = callback; + startWriteSchemaFile(signal); + } + else + { + execute(signal, callback, 0); + } } void @@ -6960,17 +7092,28 @@ Dbdict::dropTab_complete(Signal* signal, ndbrequire(tabState == SchemaFile::DROP_TABLE_STARTED); tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED; computeChecksum(xsf, tableId / NDB_SF_PAGE_ENTRIES); - - ndbrequire(c_writeSchemaRecord.inUse == false); - c_writeSchemaRecord.inUse = true; - c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; - c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES; - c_writeSchemaRecord.noOfPages = 1; - c_writeSchemaRecord.m_callback.m_callbackData = dropTabPtr.p->key; - c_writeSchemaRecord.m_callback.m_callbackFunction = - safe_cast(&Dbdict::dropTab_writeSchemaConf); - startWriteSchemaFile(signal); + TableRecordPtr tablePtr; + c_tableRecordPool.getPtr(tablePtr, tableId); + bool savetodisk = !(tablePtr.p->m_bits & TableRecord::TR_Temporary); + Callback callback; + callback.m_callbackData = dropTabPtr.p->key; + callback.m_callbackFunction = safe_cast(&Dbdict::dropTab_writeSchemaConf); + if (savetodisk) + { + ndbrequire(c_writeSchemaRecord.inUse == false); + c_writeSchemaRecord.inUse = true; + + c_writeSchemaRecord.pageId = c_schemaRecord.schemaPage; + c_writeSchemaRecord.firstPage = tableId / NDB_SF_PAGE_ENTRIES; + c_writeSchemaRecord.noOfPages = 1; + c_writeSchemaRecord.m_callback = callback; + startWriteSchemaFile(signal); + } + else + { + execute(signal, callback, 0); + } } void @@ -7260,9 +7403,12 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal) sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined); return; }//if - + + // If istable/index, allow ADD_STARTED (not to ref) + if (objEntry->m_tableState != SchemaFile::TABLE_ADD_COMMITTED && - objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED){ + objEntry->m_tableState != SchemaFile::ALTER_TABLE_COMMITTED && + objEntry->m_tableState != SchemaFile::TEMPORARY_TABLE_COMMITTED){ jam(); sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined); return; @@ -7281,6 +7427,8 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal) sendGET_TABINFOREF(signal, req, GetTabInfoRef::TableNotDefined); return; } + ndbrequire(objEntry->m_tableState == SchemaFile::TEMPORARY_TABLE_COMMITTED || + !(tabPtr.p->m_bits & TableRecord::TR_Temporary)); } c_retrieveRecord.busyState = true; @@ -7463,12 +7611,18 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal) break; } } - // store + // Logging status if (! (tablePtr.p->m_bits & TableRecord::TR_Logged)) { - conf->setTableStore(pos, DictTabInfo::StoreTemporary); + conf->setTableStore(pos, DictTabInfo::StoreNotLogged); } else { conf->setTableStore(pos, DictTabInfo::StorePermanent); } + // Temporary status + if (tablePtr.p->m_bits & TableRecord::TR_Temporary) { + conf->setTableTemp(pos, NDB_TEMP_TAB_TEMPORARY); + } else { + conf->setTableTemp(pos, NDB_TEMP_TAB_PERMANENT); + } pos++; } if(DictTabInfo::isTrigger(type)){ @@ -7489,7 +7643,7 @@ Dbdict::execLIST_TABLES_REQ(Signal* signal) conf->setTableState(pos, DictTabInfo::StateBroken); break; } - conf->setTableStore(pos, DictTabInfo::StoreTemporary); + conf->setTableStore(pos, DictTabInfo::StoreNotLogged); pos++; } if (DictTabInfo::isFilegroup(type)){ @@ -7666,7 +7820,8 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) return; } memcpy(opPtr.p->m_indexName, c_tableDesc.TableName, MAX_TAB_NAME_SIZE); - opPtr.p->m_storedIndex = c_tableDesc.TableLoggedFlag; + opPtr.p->m_loggedIndex = c_tableDesc.TableLoggedFlag; + opPtr.p->m_temporaryIndex = c_tableDesc.TableTemporaryFlag; releaseSections(signal); // master expects to hear from all if (opPtr.p->m_isMaster) @@ -7828,6 +7983,34 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) opPtr.p->m_errorLine = __LINE__; return; } + + // Check that the temporary status of index is compatible with table. + if (!opPtr.p->m_temporaryIndex && + tablePtr.p->m_bits & TableRecord::TR_Temporary) + { + jam(); + opPtr.p->m_errorCode= CreateIndxRef::TableIsTemporary; + opPtr.p->m_errorLine= __LINE__; + return; + } + if (opPtr.p->m_temporaryIndex && + !(tablePtr.p->m_bits & TableRecord::TR_Temporary)) + { + // This could be implemented later, but mysqld does currently not detect + // that the index disappears after SR, and it appears not too useful. + jam(); + opPtr.p->m_errorCode= CreateIndxRef::TableIsNotTemporary; + opPtr.p->m_errorLine= __LINE__; + return; + } + if (opPtr.p->m_temporaryIndex && opPtr.p->m_loggedIndex) + { + jam(); + opPtr.p->m_errorCode= CreateIndxRef::NoLoggingTemporaryIndex; + opPtr.p->m_errorLine= __LINE__; + return; + } + // compute index table record TableRecord indexRec; TableRecordPtr indexPtr; @@ -7836,16 +8019,20 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) initialiseTableRecord(indexPtr); indexPtr.p->m_bits = TableRecord::TR_RowChecksum; if (req->getIndexType() == DictTabInfo::UniqueHashIndex) { - indexPtr.p->m_bits |= (opPtr.p->m_storedIndex ? TableRecord::TR_Logged:0); + indexPtr.p->m_bits |= (opPtr.p->m_loggedIndex ? TableRecord::TR_Logged:0); + indexPtr.p->m_bits |= + (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0); indexPtr.p->fragmentType = DictTabInfo::DistrKeyUniqueHashIndex; } else if (req->getIndexType() == DictTabInfo::OrderedIndex) { // first version will not supported logging - if (opPtr.p->m_storedIndex) { + if (opPtr.p->m_loggedIndex) { jam(); opPtr.p->m_errorCode = CreateIndxRef::InvalidIndexType; opPtr.p->m_errorLine = __LINE__; return; } + indexPtr.p->m_bits |= + (opPtr.p->m_temporaryIndex ? TableRecord::TR_Temporary : 0); indexPtr.p->fragmentType = DictTabInfo::DistrKeyOrderedIndex; } else { jam(); @@ -7930,6 +8117,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) // write index table w.add(DictTabInfo::TableName, opPtr.p->m_indexName); w.add(DictTabInfo::TableLoggedFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Logged)); + w.add(DictTabInfo::TableTemporaryFlag, !!(indexPtr.p->m_bits & TableRecord::TR_Temporary)); w.add(DictTabInfo::FragmentTypeVal, indexPtr.p->fragmentType); w.add(DictTabInfo::TableTypeVal, indexPtr.p->tableType); Rope name(c_rope_pool, tablePtr.p->tableName); diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index b196d0a503b..046518aeddc 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -238,7 +238,8 @@ public: { TR_Logged = 0x1, TR_RowGCI = 0x2, - TR_RowChecksum = 0x4 + TR_RowChecksum = 0x4, + TR_Temporary = 0x8 }; Uint16 m_bits; @@ -1238,7 +1239,8 @@ private: CreateIndxReq m_request; AttributeList m_attrList; char m_indexName[MAX_TAB_NAME_SIZE]; - bool m_storedIndex; + bool m_loggedIndex; + bool m_temporaryIndex; // coordinator DICT Uint32 m_coordinatorRef; bool m_isMaster; @@ -2194,7 +2196,8 @@ private: // Read/Write Schema and Table files /* ------------------------------------------------------------ */ void updateSchemaState(Signal* signal, Uint32 tableId, - SchemaFile::TableEntry*, Callback*); + SchemaFile::TableEntry*, Callback*, + bool savetodisk = 1); void startWriteSchemaFile(Signal* signal); void openSchemaFile(Signal* signal, Uint32 fileNo, diff --git a/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp b/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp index 0226991a073..9fd9748f0e2 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp +++ b/storage/ndb/src/kernel/blocks/dbdict/SchemaFile.hpp @@ -54,7 +54,8 @@ struct SchemaFile { TABLE_ADD_COMMITTED = 2, DROP_TABLE_STARTED = 3, DROP_TABLE_COMMITTED = 4, - ALTER_TABLE_COMMITTED = 5 + ALTER_TABLE_COMMITTED = 5, + TEMPORARY_TABLE_COMMITTED = 6 }; // entry size 32 bytes diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index 9d9ea6af2f5..d0b97c0eb81 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -469,11 +469,17 @@ public: NORMAL_HASH = 2, USER_DEFINED = 3 }; + enum Storage { + ST_NOLOGGING = 0, // Table is not logged, but survives SR + ST_NORMAL = 1, // Normal table, logged and durable + ST_TEMPORARY = 2 // Table is lost after SR, not logged + }; CopyStatus tabCopyStatus; UpdateState tabUpdateState; TabLcpStatus tabLcpStatus; TabStatus tabStatus; Method method; + Storage tabStorage; Uint32 pageRef[8]; //----------------------------------------------------------------------------- @@ -506,7 +512,6 @@ public: Uint8 kvalue; Uint8 noOfBackups; Uint8 noPages; - Uint8 storedTable; /* 0 IF THE TABLE IS A TEMPORARY TABLE */ Uint16 tableType; Uint16 primaryTableId; }; diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 43850f297c6..4f20f7bdd22 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -5507,7 +5507,7 @@ void Dbdih::removeNodeFromTable(Signal* signal, //const Uint32 lcpId = SYSFILE->latestLCP_ID; const bool lcpOngoingFlag = (tabPtr.p->tabLcpStatus== TabRecord::TLS_ACTIVE); - const bool temporary = !tabPtr.p->storedTable; + const bool unlogged = (tabPtr.p->tabStorage != TabRecord::ST_NORMAL); FragmentstorePtr fragPtr; for(Uint32 fragNo = 0; fragNo < tabPtr.p->totalfragments; fragNo++){ @@ -5528,7 +5528,7 @@ void Dbdih::removeNodeFromTable(Signal* signal, jam(); found = true; noOfRemovedReplicas++; - removeNodeFromStored(nodeId, fragPtr, replicaPtr, temporary); + removeNodeFromStored(nodeId, fragPtr, replicaPtr, unlogged); if(replicaPtr.p->lcpOngoingFlag){ jam(); /** @@ -6796,7 +6796,12 @@ void Dbdih::execDIADDTABREQ(Signal* signal) /* BUT THEY DO NOT HAVE ANY INFORMATION ABOUT ANY TABLE*/ /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ tabPtr.p->tabStatus = TabRecord::TS_CREATING; - tabPtr.p->storedTable = req->storedTable; + if(req->loggedTable) + tabPtr.p->tabStorage= TabRecord::ST_NORMAL; + else if(req->temporaryTable) + tabPtr.p->tabStorage= TabRecord::ST_TEMPORARY; + else + tabPtr.p->tabStorage= TabRecord::ST_NOLOGGING; tabPtr.p->kvalue = req->kValue; switch ((DictTabInfo::FragmentType)fragType) @@ -6961,7 +6966,7 @@ Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr, ndbrequire(replicaPtr.p->procNode == getOwnNodeId()); Uint32 requestInfo = 0; - if(!tabPtr.p->storedTable){ + if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){ requestInfo |= LqhFragReq::TemporaryTable; } @@ -8391,9 +8396,9 @@ void Dbdih::initLcpLab(Signal* signal, Uint32 senderRef, Uint32 tableId) continue; } - if (tabPtr.p->storedTable == 0) { + if (tabPtr.p->tabStorage != TabRecord::ST_NORMAL) { /** - * Temporary table + * Table is not logged */ jam(); tabPtr.p->tabLcpStatus = TabRecord::TLS_COMPLETED; @@ -8881,10 +8886,10 @@ void Dbdih::readPagesIntoTableLab(Signal* signal, Uint32 tableId) rf.rwfTabPtr.p->kvalue = readPageWord(&rf); rf.rwfTabPtr.p->mask = readPageWord(&rf); rf.rwfTabPtr.p->method = (TabRecord::Method)readPageWord(&rf); - /* ---------------------------------- */ - /* Type of table, 2 = temporary table */ - /* ---------------------------------- */ - rf.rwfTabPtr.p->storedTable = readPageWord(&rf); + /* ------------- */ + /* Type of table */ + /* ------------- */ + rf.rwfTabPtr.p->tabStorage = (TabRecord::Storage)(readPageWord(&rf)); Uint32 noOfFrags = rf.rwfTabPtr.p->totalfragments; ndbrequire(noOfFrags > 0); @@ -8975,7 +8980,7 @@ void Dbdih::packTableIntoPagesLab(Signal* signal, Uint32 tableId) writePageWord(&wf, tabPtr.p->kvalue); writePageWord(&wf, tabPtr.p->mask); writePageWord(&wf, tabPtr.p->method); - writePageWord(&wf, tabPtr.p->storedTable); + writePageWord(&wf, tabPtr.p->tabStorage); signal->theData[0] = DihContinueB::ZPACK_FRAG_INTO_PAGES; signal->theData[1] = tabPtr.i; @@ -9180,7 +9185,7 @@ void Dbdih::startFragment(Signal* signal, Uint32 tableId, Uint32 fragId) continue; } - if(tabPtr.p->storedTable == 0){ + if(tabPtr.p->tabStorage != TabRecord::ST_NORMAL){ jam(); TloopCount++; tableId++; @@ -9805,7 +9810,7 @@ void Dbdih::calculateKeepGciLab(Signal* signal, Uint32 tableId, Uint32 fragId) }//if ptrCheckGuard(tabPtr, ctabFileSize, tabRecord); if (tabPtr.p->tabStatus != TabRecord::TS_ACTIVE || - tabPtr.p->storedTable == 0) { + tabPtr.p->tabStorage != TabRecord::ST_NORMAL) { if (TloopCount > 100) { jam(); signal->theData[0] = DihContinueB::ZCALCULATE_KEEP_GCI; @@ -10723,6 +10728,14 @@ void Dbdih::allNodesLcpCompletedLab(Signal* signal) /* ------------------------------------------------------------------------- */ void Dbdih::tableUpdateLab(Signal* signal, TabRecordPtr tabPtr) { FileRecordPtr filePtr; + if(tabPtr.p->tabStorage == TabRecord::ST_TEMPORARY) { + // For temporary tables we do not write to disk. Mark both copies 0 and 1 + // as done, and go straight to the after-close code. + filePtr.i = tabPtr.p->tabFile[1]; + ptrCheckGuard(filePtr, cfileFileSize, fileRecord); + tableCloseLab(signal, filePtr); + return; + } filePtr.i = tabPtr.p->tabFile[0]; ptrCheckGuard(filePtr, cfileFileSize, fileRecord); createFileRw(signal, filePtr); @@ -11758,7 +11771,7 @@ void Dbdih::initTable(TabRecordPtr tabPtr) tabPtr.p->kvalue = 0; tabPtr.p->hashpointer = (Uint32)-1; tabPtr.p->mask = 0; - tabPtr.p->storedTable = 1; + tabPtr.p->tabStorage = TabRecord::ST_NORMAL; tabPtr.p->tabErrorCode = 0; tabPtr.p->schemaVersion = (Uint32)-1; tabPtr.p->tabRemoveNode = RNIL; diff --git a/storage/ndb/src/ndbapi/NdbDictionary.cpp b/storage/ndb/src/ndbapi/NdbDictionary.cpp index 4948095f970..269994e01f4 100644 --- a/storage/ndb/src/ndbapi/NdbDictionary.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionary.cpp @@ -632,6 +632,16 @@ NdbDictionary::Table::getReplicaCount() const { return m_impl.m_replicaCount; } +bool +NdbDictionary::Table::getTemporary() { + return m_impl.m_temporary; +} + +void +NdbDictionary::Table::setTemporary(bool val) { + m_impl.m_temporary = val; +} + int NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const { const NdbDictionary::Table * pTab = @@ -808,6 +818,16 @@ NdbDictionary::Index::setLogging(bool val){ m_impl.m_logging = val; } +bool +NdbDictionary::Index::getTemporary(){ + return m_impl.m_temporary; +} + +void +NdbDictionary::Index::setTemporary(bool val){ + m_impl.m_temporary = val; +} + bool NdbDictionary::Index::getLogging() const { return m_impl.m_logging; diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 9c2284e147c..c5f4182d034 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -452,6 +452,7 @@ NdbTableImpl::init(){ m_primaryTable.clear(); m_default_no_part_flag = 1; m_logging= true; + m_temporary = false; m_row_gci = true; m_row_checksum = true; m_kvalue= 6; @@ -571,6 +572,12 @@ NdbTableImpl::equal(const NdbTableImpl& obj) const DBUG_RETURN(false); } + if(m_temporary != obj.m_temporary) + { + DBUG_PRINT("info",("m_temporary %d != %d",m_temporary,obj.m_temporary)); + DBUG_RETURN(false); + } + if(m_row_gci != obj.m_row_gci) { DBUG_PRINT("info",("m_row_gci %d != %d",m_row_gci,obj.m_row_gci)); @@ -711,6 +718,7 @@ NdbTableImpl::assign(const NdbTableImpl& org) m_max_rows = org.m_max_rows; m_default_no_part_flag = org.m_default_no_part_flag; m_logging = org.m_logging; + m_temporary = org.m_temporary; m_row_gci = org.m_row_gci; m_row_checksum = org.m_row_checksum; m_kvalue = org.m_kvalue; @@ -1080,6 +1088,7 @@ void NdbIndexImpl::init() m_id= RNIL; m_type= NdbDictionary::Object::TypeUndefined; m_logging= true; + m_temporary= false; m_table= NULL; } @@ -2006,7 +2015,7 @@ objectStateMapping[] = { static const ApiKernelMapping objectStoreMapping[] = { - { DictTabInfo::StoreTemporary, NdbDictionary::Object::StoreTemporary }, + { DictTabInfo::StoreNotLogged, NdbDictionary::Object::StoreNotLogged }, { DictTabInfo::StorePermanent, NdbDictionary::Object::StorePermanent }, { -1, -1 } }; @@ -2085,6 +2094,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_default_no_part_flag = tableDesc->DefaultNoPartFlag; impl->m_linear_flag = tableDesc->LinearHashFlag; impl->m_logging = tableDesc->TableLoggedFlag; + impl->m_temporary = tableDesc->TableTemporaryFlag; impl->m_row_gci = tableDesc->RowGCIFlag; impl->m_row_checksum = tableDesc->RowChecksumFlag; impl->m_kvalue = tableDesc->TableKValue; @@ -2527,6 +2537,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, tmpTab->FragmentCount= impl.m_fragmentCount; tmpTab->TableLoggedFlag = impl.m_logging; + tmpTab->TableTemporaryFlag = impl.m_temporary; tmpTab->RowGCIFlag = impl.m_row_gci; tmpTab->RowChecksumFlag = impl.m_row_checksum; tmpTab->TableKValue = impl.m_kvalue; @@ -3045,6 +3056,7 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, idx->m_tableName.assign(prim->m_externalName); NdbDictionary::Object::Type type = idx->m_type = tab->m_indexType; idx->m_logging = tab->m_logging; + idx->m_temporary = tab->m_temporary; // skip last attribute (NDB$PK or NDB$TNODE) const Uint32 distKeys = prim->m_noOfDistributionKeys; @@ -3136,6 +3148,7 @@ NdbDictInterface::createIndex(Ndb & ndb, ndb.internalize_index_name(&table, impl.getName())); w.add(DictTabInfo::TableName, internalName.c_str()); w.add(DictTabInfo::TableLoggedFlag, impl.m_logging); + w.add(DictTabInfo::TableTemporaryFlag, impl.m_temporary); NdbApiSignal tSignal(m_reference); tSignal.theReceiversBlockNumber = DBDICT; @@ -4119,6 +4132,7 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list, getApiConstant(ListTablesConf::getTableState(d), objectStateMapping, 0); element.store = (NdbDictionary::Object::Store) getApiConstant(ListTablesConf::getTableStore(d), objectStoreMapping, 0); + element.temp = ListTablesConf::getTableTemp(d); // table or index name Uint32 n = (data[pos++] + 3) >> 2; BaseString databaseName; diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 35db103aa9f..4e8ef471014 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -198,6 +198,7 @@ public: Uint32 m_default_no_part_flag; bool m_linear_flag; bool m_logging; + bool m_temporary; bool m_row_gci; bool m_row_checksum; int m_kvalue; @@ -273,6 +274,7 @@ public: Vector m_key_ids; bool m_logging; + bool m_temporary; NdbTableImpl * m_table; diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index c3874cbf8eb..460c4fa443b 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -421,6 +421,9 @@ ErrorBundle ErrorCodes[] = { { 773, DMEC, SE, "Out of string memory, please modify StringMemory config parameter" }, { 775, DMEC, SE, "Create file is not supported when Diskless=1" }, + { 776, DMEC, AE, "Index created on temporary table must itself be temporary" }, + { 777, DMEC, AE, "Cannot create a temporary index on a non-temporary table" }, + { 778, DMEC, AE, "A temporary table or index must be specified as not logging" }, /** * FunctionNotImplemented @@ -611,7 +614,7 @@ ErrorBundle ErrorCodes[] = { { 4272, DMEC, AE, "Table definition has undefined column" }, { 4273, DMEC, IE, "No blob table in dict cache" }, { 4274, DMEC, IE, "Corrupted main table PK in blob operation" }, - { 4275, DMEC, AE, "The blob method is incompatible with operation type or lock mode" } + { 4275, DMEC, AE, "The blob method is incompatible with operation type or lock mode" }, }; static diff --git a/storage/ndb/tools/listTables.cpp b/storage/ndb/tools/listTables.cpp index a221156280d..44c69d7e5a8 100644 --- a/storage/ndb/tools/listTables.cpp +++ b/storage/ndb/tools/listTables.cpp @@ -32,6 +32,7 @@ static Ndb* ndb = 0; static const NdbDictionary::Dictionary * dic = 0; static int _unqualified = 0; static int _parsable = 0; +static int show_temp_status = 0; static void fatal(char const* fmt, ...) @@ -80,9 +81,19 @@ list(const char * tabname, if (!_parsable) { if (ndb->usingFullyQualifiedNames()) - ndbout_c("%-5s %-20s %-8s %-7s %-12s %-8s %s", "id", "type", "state", "logging", "database", "schema", "name"); + { + if (show_temp_status) + ndbout_c("%-5s %-20s %-8s %-7s %-4s %-12s %-8s %s", "id", "type", "state", "logging", "temp", "database", "schema", "name"); + else + ndbout_c("%-5s %-20s %-8s %-7s %-12s %-8s %s", "id", "type", "state", "logging", "database", "schema", "name"); + } else - ndbout_c("%-5s %-20s %-8s %-7s %s", "id", "type", "state", "logging", "name"); + { + if (show_temp_status) + ndbout_c("%-5s %-20s %-8s %-7s %-4s %s", "id", "type", "state", "logging", "temp", "name"); + else + ndbout_c("%-5s %-20s %-8s %-7s %s", "id", "type", "state", "logging", "name"); + } } for (unsigned i = 0; i < list.count; i++) { NdbDictionary::Dictionary::List::Element& elt = list.elements[i]; @@ -162,30 +173,69 @@ list(const char * tabname, strcpy(store, "-"); else { switch (elt.store) { - case NdbDictionary::Object::StoreTemporary: + case NdbDictionary::Object::StoreNotLogged: strcpy(store, "No"); break; case NdbDictionary::Object::StorePermanent: strcpy(store, "Yes"); break; default: - sprintf(state, "%d", (int)elt.store); + sprintf(store, "%d", (int)elt.store); break; } } + char temp[100]; + if (show_temp_status) + { + if (! isTable) + strcpy(temp, "-"); + else { + switch (elt.temp) { + case NDB_TEMP_TAB_PERMANENT: + strcpy(temp, "No"); + break; + case NDB_TEMP_TAB_TEMPORARY: + strcpy(temp, "Yes"); + break; + default: + sprintf(temp, "%d", (int)elt.temp); + break; + } + } + } if (ndb->usingFullyQualifiedNames()) { if (_parsable) - ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + { + if (show_temp_status) + ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, temp, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + else + ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + } else - ndbout_c("%-5d %-20s %-8s %-7s %-12s %-8s %s", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + { + if (show_temp_status) + ndbout_c("%-5d %-20s %-8s %-7s %-4s %-12s %-8s %s", elt.id, type, state, store, temp, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + else + ndbout_c("%-5d %-20s %-8s %-7s %-12s %-8s %s", elt.id, type, state, store, (elt.database)?elt.database:"", (elt.schema)?elt.schema:"", elt.name); + } } else { if (_parsable) - ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, elt.name); + { + if (show_temp_status) + ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, temp, elt.name); + else + ndbout_c("%d\t'%s'\t'%s'\t'%s'\t'%s'", elt.id, type, state, store, elt.name); + } else - ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name); + { + if (show_temp_status) + ndbout_c("%-5d %-20s %-8s %-7s %-4s %s", elt.id, type, state, store, temp, elt.name); + else + ndbout_c("%-5d %-20s %-8s %-7s %s", elt.id, type, state, store, elt.name); + } } } if (_parsable) @@ -197,6 +247,10 @@ NDB_STD_OPTS_VARS; static const char* _dbname = "TEST_DB"; static int _loops; static int _type; +enum options_ndb_show_tables +{ + OPT_SHOW_TMP_STATUS=256, +}; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_show_tables"), @@ -215,6 +269,9 @@ static struct my_option my_long_options[] = { "parsable", 'p', "Return output suitable for mysql LOAD DATA INFILE", (gptr*) &_parsable, (gptr*) &_parsable, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "show-temp-status", OPT_SHOW_TMP_STATUS, "Show table temporary flag", + (gptr*) &show_temp_status, (gptr*) &show_temp_status, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; static void usage()