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 45eed73455c..150dc75f90c 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 6c8a447f627..4e621e69c47 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; } @@ -1951,7 +1960,7 @@ objectStateMapping[] = { static const ApiKernelMapping objectStoreMapping[] = { - { DictTabInfo::StoreTemporary, NdbDictionary::Object::StoreTemporary }, + { DictTabInfo::StoreNotLogged, NdbDictionary::Object::StoreNotLogged }, { DictTabInfo::StorePermanent, NdbDictionary::Object::StorePermanent }, { -1, -1 } }; @@ -2030,6 +2039,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; @@ -2472,6 +2482,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; @@ -2990,6 +3001,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; @@ -3081,6 +3093,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; @@ -4064,6 +4077,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()