DropTableProcessor::DDLResult DropTableProcessor::processPackage(ddlpackage::DropTableStatement& dropTableStmt) { SUMMARY_INFO("DropTableProcessor::processPackage"); DDLResult result; result.result = NO_ERROR; std::string err; VERBOSE_INFO(dropTableStmt); // Commit current transaction. // all DDL statements cause an implicit commit VERBOSE_INFO("Getting current txnID"); ByteStream::byte rc = 0; BRM::TxnID txnID; txnID.id= fTxnid.id; txnID.valid= fTxnid.valid; int rc1 = 0; rc1= fDbrm->isReadWrite(); if (rc1 != 0 ) { Message::Args args; Message message(9); args.add("Unable to execute the statement due to DBRM is read only"); message.format(args); result.result = DROP_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } string stmt = dropTableStmt.fSql + "|" + dropTableStmt.fTableName->fSchema +"|"; SQLLogger logger(stmt, fDDLLoggingId, dropTableStmt.fSessionID, txnID.id); std::vector <CalpontSystemCatalog::OID> oidList; CalpontSystemCatalog::RIDList tableColRidList; CalpontSystemCatalog::DictOIDList dictOIDList; execplan::CalpontSystemCatalog::ROPair roPair; std::string errorMsg; ByteStream bytestream; uint64_t uniqueId = 0; //Bug 5070. Added exception handling try { uniqueId = fDbrm->getUnique64(); } catch (std::exception& ex) { Message::Args args; Message message(9); args.add(ex.what()); message.format(args); result.result = DROP_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } catch ( ... ) { Message::Args args; Message message(9); args.add("Unknown error occured while getting unique number."); message.format(args); result.result = DROP_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } fWEClient->addQueue(uniqueId); int pmNum = 1; boost::shared_ptr<messageqcpp::ByteStream> bsIn; uint64_t tableLockId = 0; OamCache* oamcache = OamCache::makeOamCache(); std::vector<int> moduleIds = oamcache->getModuleIds(); try { //check table lock CalpontSystemCatalog *systemCatalogPtr = CalpontSystemCatalog::makeCalpontSystemCatalog(dropTableStmt.fSessionID); systemCatalogPtr->identity(CalpontSystemCatalog::EC); systemCatalogPtr->sessionID(dropTableStmt.fSessionID); CalpontSystemCatalog::TableName tableName; tableName.schema = dropTableStmt.fTableName->fSchema; tableName.table = dropTableStmt.fTableName->fName; roPair = systemCatalogPtr->tableRID( tableName ); u_int32_t processID = ::getpid(); int32_t txnid = txnID.id; int32_t sessionId = dropTableStmt.fSessionID; std::string processName("DDLProc"); int i = 0; std::vector<uint> pms; for (unsigned i=0; i < moduleIds.size(); i++) { pms.push_back((uint)moduleIds[i]); } try { tableLockId = fDbrm->getTableLock(pms, roPair.objnum, &processName, &processID, &sessionId, &txnid, BRM::LOADING ); } catch (std::exception&) { throw std::runtime_error(IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE)); } if ( tableLockId == 0 ) { int waitPeriod = 10; int sleepTime = 100; // sleep 100 milliseconds between checks int numTries = 10; // try 10 times per second waitPeriod = WriteEngine::Config::getWaitPeriod(); numTries = waitPeriod * 10; struct timespec rm_ts; rm_ts.tv_sec = sleepTime/1000; rm_ts.tv_nsec = sleepTime%1000 *1000000; for (; i < numTries; i++) { #ifdef _MSC_VER Sleep(rm_ts.tv_sec * 1000); #else struct timespec abs_ts; do { abs_ts.tv_sec = rm_ts.tv_sec; abs_ts.tv_nsec = rm_ts.tv_nsec; } while(nanosleep(&abs_ts,&rm_ts) < 0); #endif try { processID = ::getpid(); txnid = txnID.id; sessionId = dropTableStmt.fSessionID;; processName = "DDLProc"; tableLockId = fDbrm->getTableLock(pms, roPair.objnum, &processName, &processID, &sessionId, &txnid, BRM::LOADING ); } catch (std::exception&) { throw std::runtime_error(IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE)); } if (tableLockId > 0) break; } if (i >= numTries) //error out { Message::Args args; args.add(processName); args.add((uint64_t)processID); args.add(sessionId); throw std::runtime_error(IDBErrorInfo::instance()->errorMsg(ERR_TABLE_LOCKED,args)); } } // 1. Get the OIDs for the columns // 2. Get the OIDs for the dictionaries // 3. Save the OIDs to a log file // 4. Remove the Table from SYSTABLE // 5. Remove the columns from SYSCOLUMN // 6. Commit the changes made to systables // 7. Flush PrimProc Cache // 8. Update extent map // 9. Remove the column and dictionary files // 10.Return the OIDs CalpontSystemCatalog::TableName userTableName; userTableName.schema = dropTableStmt.fTableName->fSchema; userTableName.table = dropTableStmt.fTableName->fName; tableColRidList = systemCatalogPtr->columnRIDs( userTableName ); dictOIDList = systemCatalogPtr->dictOIDs( userTableName ); Oam oam; //Save qualified tablename, all column, dictionary OIDs, and transaction ID into a file in ASCII format for ( unsigned i=0; i < tableColRidList.size(); i++ ) { if ( tableColRidList[i].objnum > 3000 ) oidList.push_back( tableColRidList[i].objnum ); } for ( unsigned i=0; i < dictOIDList.size(); i++ ) { if ( dictOIDList[i].dictOID > 3000 ) oidList.push_back( dictOIDList[i].dictOID ); } //get a unique number VERBOSE_INFO("Removing the SYSTABLE meta data"); #ifdef IDB_DDL_DEBUG cout << "Removing the SYSTABLEs meta data" << endl; #endif bytestream << (ByteStream::byte)WE_SVR_DELETE_SYSTABLES; bytestream << uniqueId; bytestream << (u_int32_t) dropTableStmt.fSessionID; bytestream << (u_int32_t)txnID.id; bytestream << dropTableStmt.fTableName->fSchema; bytestream << dropTableStmt.fTableName->fName; //Find out where systable is BRM::OID_t sysOid = 1001; ByteStream::byte rc = 0; u_int16_t dbRoot; rc = fDbrm->getSysCatDBRoot(sysOid, dbRoot); if (rc != 0) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Error while calling getSysCatDBRoot"); args.add(errorMsg); result.message = message; //release transaction fSessionManager.rolledback(txnID); return result; } boost::shared_ptr<std::map<int, int> > dbRootPMMap = oamcache->getDBRootToPMMap(); pmNum = (*dbRootPMMap)[dbRoot]; try { //cout << "deleting systable entries with txnid " << txnID.id << endl; fWEClient->write(bytestream, (uint)pmNum); #ifdef IDB_DDL_DEBUG cout << "Drop table sending WE_SVR_DELETE_SYSTABLES to pm " << pmNum << endl; #endif while (1) { bsIn.reset(new ByteStream()); fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { rc = NETWORK_ERROR; errorMsg = "Lost connection to Write Engine Server while updating SYSTABLES"; break; } else { *bsIn >> rc; if (rc != 0) { *bsIn >> errorMsg; } break; } } } catch (runtime_error& ex) //write error { #ifdef IDB_DDL_DEBUG cout << "Drop table got exception" << endl; #endif rc = NETWORK_ERROR; errorMsg = ex.what(); } catch (...) { rc = NETWORK_ERROR; #ifdef IDB_DDL_DEBUG cout << "Drop table got unknown exception" << endl; #endif } if (rc != 0) { Message::Args args; Message message(9); args.add("Error in dropping table from systables."); args.add(errorMsg); message.format(args); result.result = (ResultCode)rc; result.message = message; //release table lock and session fSessionManager.rolledback(txnID); (void)fDbrm->releaseTableLock(tableLockId); fWEClient->removeQueue(uniqueId); return result; } rc = commitTransaction(uniqueId, txnID); //cout << "commiting transaction " << txnID.id << " and valid is " << txnID.valid << endl; if (rc != 0) fSessionManager.rolledback(txnID); else fSessionManager.committed(txnID); if (rc != 0) { Message::Args args; Message message(9); ostringstream oss; oss << " Commit failed with error code " << rc; args.add(oss.str()); fSessionManager.rolledback(txnID); (void)fDbrm->releaseTableLock(tableLockId); message.format(args); result.result = (ResultCode)rc; result.message = message; fWEClient->removeQueue(uniqueId); return result; } // Log the DDL statement logDDL(dropTableStmt.fSessionID, txnID.id, dropTableStmt.fSql, dropTableStmt.fOwner); } catch (std::exception& ex) { result.result = DROP_ERROR; Message::Args args; Message message(9); args.add("Drop table failed due to "); args.add(ex.what()); fSessionManager.rolledback(txnID); try { (void)fDbrm->releaseTableLock(tableLockId); } catch (std::exception&) { args.add(IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE)); } message.format( args ); result.message = message; fWEClient->removeQueue(uniqueId); return result; } catch (...) { result.result = DROP_ERROR; errorMsg = "Error in getting information from system catalog or from dbrm."; Message::Args args; Message message(9); args.add("Drop table failed due to "); args.add(errorMsg); fSessionManager.rolledback(txnID); try { (void)fDbrm->releaseTableLock(tableLockId); } catch (std::exception&) { args.add(IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE)); } message.format( args ); result.message = message; fWEClient->removeQueue(uniqueId); return result; } try { (void)fDbrm->releaseTableLock(tableLockId); } catch (std::exception&) { result.result = DROP_ERROR; Message::Args args; Message message(9); args.add("Drop table failed due to "); args.add(IDBErrorInfo::instance()->errorMsg(ERR_HARD_FAILURE)); fSessionManager.rolledback(txnID); message.format( args ); result.message = message; fWEClient->removeQueue(uniqueId); return result; } //Save the oids to a file try { createWriteDropLogFile( roPair.objnum, uniqueId, oidList ); } catch (std::exception& ex) { result.result = WARNING; Message::Args args; Message message(9); args.add("Drop table failed due to "); args.add(ex.what()); message.format(args); result.message = message; fSessionManager.rolledback(txnID); fWEClient->removeQueue(uniqueId); return result; } // Bug 4208 Drop the PrimProcFDCache before droping the column files // FOr Windows, this ensures (most likely) that the column files have // no open handles to hinder the deletion of the files. rc = cacheutils::dropPrimProcFdCache(); //Drop files bytestream.restart(); bytestream << (ByteStream::byte)WE_SVR_WRITE_DROPFILES; bytestream << uniqueId; bytestream << (uint32_t) oidList.size(); for (unsigned i=0; i < oidList.size(); i++) { bytestream << (uint32_t) oidList[i]; } #ifdef IDB_DDL_DEBUG cout << "Drop table removing column files" << endl; #endif uint msgRecived = 0; try { fWEClient->write_to_all(bytestream); bsIn.reset(new ByteStream()); ByteStream::byte tmp8; while (1) { if (msgRecived == fWEClient->getPmCount()) break; fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { rc = NETWORK_ERROR; fWEClient->removeQueue(uniqueId); break; } else { *bsIn >> tmp8; rc = tmp8; if (rc != 0) { *bsIn >> errorMsg; fWEClient->removeQueue(uniqueId); break; } else msgRecived++; } }
CreateTableProcessor::DDLResult CreateTableProcessor::processPackage( ddlpackage::CreateTableStatement& createTableStmt) { SUMMARY_INFO("CreateTableProcessor::processPackage"); DDLResult result; BRM::TxnID txnID; txnID.id= fTxnid.id; txnID.valid= fTxnid.valid; result.result = NO_ERROR; int rc1 = 0; rc1 = fDbrm->isReadWrite(); if (rc1 != 0 ) { Message::Args args; Message message(9); args.add("Unable to execute the statement due to DBRM is read only"); message.format(args); result.result = CREATE_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } DETAIL_INFO(createTableStmt); ddlpackage::TableDef& tableDef = *createTableStmt.fTableDef; //If schema = CALPONTSYS, do not create table boost::algorithm::to_lower(tableDef.fQualifiedName->fSchema); if (tableDef.fQualifiedName->fSchema == CALPONT_SCHEMA) { //release the transaction fSessionManager.rolledback(txnID); return result; } // Commit current transaction. // all DDL statements cause an implicut commit VERBOSE_INFO("Getting current txnID"); //Check whether the table is existed already boost::shared_ptr<CalpontSystemCatalog> systemCatalogPtr = CalpontSystemCatalog::makeCalpontSystemCatalog(createTableStmt.fSessionID); execplan::CalpontSystemCatalog::TableName tableName; tableName.schema = tableDef.fQualifiedName->fSchema; tableName.table = tableDef.fQualifiedName->fName; execplan::CalpontSystemCatalog::ROPair roPair; roPair.objnum = 0; ByteStream::byte rc = 0; /** @Bug 217 */ /** @Bug 225 */ try { roPair = systemCatalogPtr->tableRID(tableName); } catch (IDBExcept &ie) { // TODO: What is and is not an error here? if (ie.errorCode() == ERR_DATA_OFFLINE) { //release transaction fSessionManager.rolledback(txnID); // Return the error for display to user Message::Args args; Message message(9); args.add(ie.what()); message.format(args); result.result = CREATE_ERROR; result.message = message; return result; } else if ( ie.errorCode() == ERR_TABLE_NOT_IN_CATALOG) { roPair.objnum = 0; } else //error out { //release transaction fSessionManager.rolledback(txnID); // Return the error for display to user Message::Args args; Message message(9); args.add(ie.what()); message.format(args); result.result = CREATE_ERROR; result.message = message; return result; } } catch (std::exception& ex) //error out { //release transaction fSessionManager.rolledback(txnID); // Return the error for display to user Message::Args args; Message message(9); args.add(ex.what()); message.format(args); result.result = CREATE_ERROR; result.message = message; return result; } catch (...) //error out { //release transaction fSessionManager.rolledback(txnID); // Return the error for display to user Message::Args args; Message message(9); args.add("Unknown exception caught when checking if the table name is already in use."); message.format(args); result.result = CREATE_ERROR; result.message = message; return result; } //This is a current db bug, it should not turn OID is it cannot find if (roPair.objnum >= 3000) { #ifdef _MSC_VER //FIXME: Why do we need to do this??? systemCatalogPtr->flushCache(); try { roPair = systemCatalogPtr->tableRID(tableName); } catch (...) { roPair.objnum = 0; } if (roPair.objnum < 3000) goto keepGoing; #endif Message::Args args; Message message(9); args.add("Internal create table error for"); args.add(tableName.toString()); args.add(": table already exists"); args.add("(your schema is probably out-of-sync)"); message.format(args); result.result = CREATE_ERROR; result.message = message; //release the transaction fSessionManager.rolledback(txnID); return result; } #ifdef _MSC_VER keepGoing: #endif // Start a new transaction VERBOSE_INFO("Starting a new transaction"); string stmt = createTableStmt.fSql + "|" + tableDef.fQualifiedName->fSchema +"|"; SQLLogger logger(stmt, fDDLLoggingId, createTableStmt.fSessionID, txnID.id); std::string err; execplan::ObjectIDManager fObjectIDManager; OamCache * oamcache = OamCache::makeOamCache(); string errorMsg; //get a unique number uint64_t uniqueId = 0; //Bug 5070. Added exception handling try { uniqueId = fDbrm->getUnique64(); } catch (std::exception& ex) { Message::Args args; Message message(9); args.add(ex.what()); message.format(args); result.result = CREATE_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } catch ( ... ) { Message::Args args; Message message(9); args.add("Unknown error occured while getting unique number."); message.format(args); result.result = CREATE_ERROR; result.message = message; fSessionManager.rolledback(txnID); return result; } fWEClient->addQueue(uniqueId); try { //Allocate tableoid table identification VERBOSE_INFO("Allocating object ID for table"); // Allocate a object ID for each column we are about to create VERBOSE_INFO("Allocating object IDs for columns"); uint32_t numColumns = tableDef.fColumns.size(); uint32_t numDictCols = 0; for (unsigned i=0; i < numColumns; i++) { int dataType; dataType = convertDataType(tableDef.fColumns[i]->fType->fType); if ( (dataType == CalpontSystemCatalog::CHAR && tableDef.fColumns[i]->fType->fLength > 8) || (dataType == CalpontSystemCatalog::VARCHAR && tableDef.fColumns[i]->fType->fLength > 7) || (dataType == CalpontSystemCatalog::VARBINARY && tableDef.fColumns[i]->fType->fLength > 7) ) numDictCols++; } fStartingColOID = fObjectIDManager.allocOIDs(numColumns+numDictCols+1); //include column, oids,dictionary oids and tableoid #ifdef IDB_DDL_DEBUG cout << "Create table allocOIDs got the stating oid " << fStartingColOID << endl; #endif if (fStartingColOID < 0) { result.result = CREATE_ERROR; errorMsg = "Error in getting objectid from oidmanager."; Message::Args args; Message message(9); args.add("Create table failed due to "); args.add(errorMsg); message.format(args); result.message = message; fSessionManager.rolledback(txnID); return result; } // Write the table metadata to the systemtable VERBOSE_INFO("Writing meta data to SYSTABLE"); ByteStream bytestream; bytestream << (ByteStream::byte)WE_SVR_WRITE_SYSTABLE; bytestream << uniqueId; bytestream << (uint32_t) createTableStmt.fSessionID; bytestream << (uint32_t)txnID.id; bytestream << (uint32_t)fStartingColOID; bytestream << (uint32_t)createTableStmt.fTableWithAutoi; uint16_t dbRoot; BRM::OID_t sysOid = 1001; //Find out where systable is rc = fDbrm->getSysCatDBRoot(sysOid, dbRoot); if (rc != 0) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Error while calling getSysCatDBRoot "); args.add(errorMsg); message.format(args); result.message = message; //release transaction fSessionManager.rolledback(txnID); return result; } int pmNum = 1; bytestream << (uint32_t)dbRoot; tableDef.serialize(bytestream); boost::shared_ptr<messageqcpp::ByteStream> bsIn; boost::shared_ptr<std::map<int, int> > dbRootPMMap = oamcache->getDBRootToPMMap(); pmNum = (*dbRootPMMap)[dbRoot]; try { fWEClient->write(bytestream, (unsigned)pmNum); #ifdef IDB_DDL_DEBUG cout << "create table sending We_SVR_WRITE_SYSTABLE to pm " << pmNum << endl; #endif while (1) { bsIn.reset(new ByteStream()); fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { rc = NETWORK_ERROR; errorMsg = "Lost connection to Write Engine Server while updating SYSTABLES"; break; } else { *bsIn >> rc; if (rc != 0) { errorMsg.clear(); *bsIn >> errorMsg; #ifdef IDB_DDL_DEBUG cout << "Create table We_SVR_WRITE_CREATETABLEFILES: " << errorMsg << endl; #endif } break; } } } catch (runtime_error& ex) //write error { #ifdef IDB_DDL_DEBUG cout << "create table got exception" << ex.what() << endl; #endif rc = NETWORK_ERROR; errorMsg = ex.what(); } catch (...) { rc = NETWORK_ERROR; #ifdef IDB_DDL_DEBUG cout << "create table got unknown exception" << endl; #endif } if (rc != 0) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Create table failed due to "); args.add(errorMsg); message.format( args ); result.message = message; if (rc != NETWORK_ERROR) { rollBackTransaction( uniqueId, txnID, createTableStmt.fSessionID ); //What to do with the error code } //release transaction fSessionManager.rolledback(txnID); return result; } VERBOSE_INFO("Writing meta data to SYSCOLUMN"); bytestream.restart(); bytestream << (ByteStream::byte)WE_SVR_WRITE_CREATE_SYSCOLUMN; bytestream << uniqueId; bytestream << (uint32_t) createTableStmt.fSessionID; bytestream << (uint32_t)txnID.id; bytestream << numColumns; for (unsigned i = 0; i <numColumns; ++i) { bytestream << (uint32_t)(fStartingColOID+i+1); } bytestream << numDictCols; for (unsigned i = 0; i <numDictCols; ++i) { bytestream << (uint32_t)(fStartingColOID+numColumns+i+1); } uint8_t alterFlag = 0; int colPos = 0; bytestream << (ByteStream::byte)alterFlag; bytestream << (uint32_t)colPos; sysOid = 1021; //Find out where syscolumn is rc = fDbrm->getSysCatDBRoot(sysOid, dbRoot); if (rc != 0) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Error while calling getSysCatDBRoot "); args.add(errorMsg); message.format(args); result.message = message; //release transaction fSessionManager.rolledback(txnID); return result; } bytestream << (uint32_t)dbRoot; tableDef.serialize(bytestream); pmNum = (*dbRootPMMap)[dbRoot]; try { fWEClient->write(bytestream, (uint32_t)pmNum); #ifdef IDB_DDL_DEBUG cout << "create table sending We_SVR_WRITE_SYSTABLE to pm " << pmNum << endl; #endif while (1) { bsIn.reset(new ByteStream()); fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { rc = NETWORK_ERROR; errorMsg = "Lost connection to Write Engine Server while updating SYSTABLES"; break; } else { *bsIn >> rc; if (rc != 0) { errorMsg.clear(); *bsIn >> errorMsg; #ifdef IDB_DDL_DEBUG cout << "Create table We_SVR_WRITE_CREATETABLEFILES: " << errorMsg << endl; #endif } break; } } } catch (runtime_error& ex) //write error { #ifdef IDB_DDL_DEBUG cout << "create table got exception" << ex.what() << endl; #endif rc = NETWORK_ERROR; errorMsg = ex.what(); } catch (...) { rc = NETWORK_ERROR; #ifdef IDB_DDL_DEBUG cout << "create table got unknown exception" << endl; #endif } if (rc != 0) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Create table failed due to "); args.add(errorMsg); message.format( args ); result.message = message; if (rc != NETWORK_ERROR) { rollBackTransaction( uniqueId, txnID, createTableStmt.fSessionID ); //What to do with the error code } //release transaction fSessionManager.rolledback(txnID); return result; } //Get the number of tables in the database, the current table is included. int tableCount = systemCatalogPtr->getTableCount(); //Calculate which dbroot the columns should start DBRootConfigList dbRootList = oamcache->getDBRootNums(); uint16_t useDBRootIndex = tableCount % dbRootList.size(); //Find out the dbroot# corresponding the useDBRootIndex from oam uint16_t useDBRoot = dbRootList[useDBRootIndex]; VERBOSE_INFO("Creating column files"); ColumnDef* colDefPtr; ddlpackage::ColumnDefList tableDefCols = tableDef.fColumns; ColumnDefList::const_iterator iter = tableDefCols.begin(); bytestream.restart(); bytestream << (ByteStream::byte)WE_SVR_WRITE_CREATETABLEFILES; bytestream << uniqueId; bytestream << (uint32_t)txnID.id; bytestream << (numColumns + numDictCols); unsigned colNum = 0; unsigned dictNum = 0; while (iter != tableDefCols.end()) { colDefPtr = *iter; CalpontSystemCatalog::ColDataType dataType = convertDataType(colDefPtr->fType->fType); if (dataType == CalpontSystemCatalog::DECIMAL || dataType == CalpontSystemCatalog::UDECIMAL) { if (colDefPtr->fType->fPrecision == -1 || colDefPtr->fType->fPrecision == 0) { colDefPtr->fType->fLength = 8; } else if ((colDefPtr->fType->fPrecision > 0) && (colDefPtr->fType->fPrecision < 3)) { colDefPtr->fType->fLength = 1; } else if (colDefPtr->fType->fPrecision < 5 && (colDefPtr->fType->fPrecision > 2)) { colDefPtr->fType->fLength = 2; } else if (colDefPtr->fType->fPrecision > 4 && colDefPtr->fType->fPrecision < 10) { colDefPtr->fType->fLength = 4; } else if (colDefPtr->fType->fPrecision > 9 && colDefPtr->fType->fPrecision < 19) { colDefPtr->fType->fLength = 8; } } bytestream << (fStartingColOID + (colNum++) + 1); bytestream << (uint8_t) dataType; bytestream << (uint8_t) false; bytestream << (uint32_t) colDefPtr->fType->fLength; bytestream << (uint16_t) useDBRoot; bytestream << (uint32_t) colDefPtr->fType->fCompressiontype; if ( (dataType == CalpontSystemCatalog::CHAR && colDefPtr->fType->fLength > 8) || (dataType == CalpontSystemCatalog::VARCHAR && colDefPtr->fType->fLength > 7) || (dataType == CalpontSystemCatalog::VARBINARY && colDefPtr->fType->fLength > 7) ) { bytestream << (uint32_t) (fStartingColOID+numColumns+(dictNum++)+1); bytestream << (uint8_t) dataType; bytestream << (uint8_t) true; bytestream << (uint32_t) colDefPtr->fType->fLength; bytestream << (uint16_t) useDBRoot; bytestream << (uint32_t) colDefPtr->fType->fCompressiontype; } ++iter; } //@Bug 4176. save oids to a log file for cleanup after fail over. std::vector <CalpontSystemCatalog::OID> oidList; for (unsigned i = 0; i <numColumns; ++i) { oidList.push_back(fStartingColOID+i+1); } bytestream << numDictCols; for (unsigned i = 0; i <numDictCols; ++i) { oidList.push_back(fStartingColOID+numColumns+i+1); } try { createWriteDropLogFile( fStartingColOID, uniqueId, oidList ); } catch (std::exception& ex) { result.result =(ResultCode) rc; Message::Args args; Message message(9); args.add("Create table failed due to "); args.add(ex.what()); message.format( args ); result.message = message; if (rc != NETWORK_ERROR) { rollBackTransaction( uniqueId, txnID, createTableStmt.fSessionID ); //What to do with the error code } //release transaction fSessionManager.rolledback(txnID); return result; } pmNum = (*dbRootPMMap)[useDBRoot]; try { fWEClient->write(bytestream, pmNum); while (1) { bsIn.reset(new ByteStream()); fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { rc = NETWORK_ERROR; errorMsg = "Lost connection to Write Engine Server while updating SYSTABLES"; break; } else { *bsIn >> rc; if (rc != 0) { errorMsg.clear(); *bsIn >> errorMsg; #ifdef IDB_DDL_DEBUG cout << "Create table We_SVR_WRITE_CREATETABLEFILES: " << errorMsg << endl; #endif } break; } } if (rc != 0) { //drop the newly created files bytestream.restart(); bytestream << (ByteStream::byte) WE_SVR_WRITE_DROPFILES; bytestream << uniqueId; bytestream << (uint32_t)(numColumns+numDictCols); for (unsigned i = 0; i < (numColumns+numDictCols); i++) { bytestream << (uint32_t)(fStartingColOID + i + 1); } fWEClient->write(bytestream, pmNum); while (1) { bsIn.reset(new ByteStream()); fWEClient->read(uniqueId, bsIn); if ( bsIn->length() == 0 ) //read error { break; } else { break; } } //@Bug 5464. Delete from extent map. fDbrm->deleteOIDs(oidList); } } catch (runtime_error&) { errorMsg = "Lost connection to Write Engine Server"; } if (rc != 0) { rollBackTransaction( uniqueId, txnID, createTableStmt.fSessionID); //What to do with the error code fSessionManager.rolledback(txnID); } else { commitTransaction(uniqueId, txnID); fSessionManager.committed(txnID); fWEClient->removeQueue(uniqueId); deleteLogFile(DROPTABLE_LOG, fStartingColOID, uniqueId); } // Log the DDL statement. logDDL(createTableStmt.fSessionID, txnID.id, createTableStmt.fSql, createTableStmt.fOwner); }