diff options
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp')
-rw-r--r-- | storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp | 2608 |
1 files changed, 0 insertions, 2608 deletions
diff --git a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp deleted file mode 100644 index 398c63add84..00000000000 --- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp +++ /dev/null @@ -1,2608 +0,0 @@ -/* Copyright (c) 2003-2007 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ - -#include <ndb_global.h> - -#include "DbUtil.hpp" - -#include <ndb_version.h> - -#include <signaldata/WaitGCP.hpp> -#include <signaldata/KeyInfo.hpp> -#include <signaldata/AttrInfo.hpp> -#include <signaldata/TcKeyConf.hpp> -#include <signaldata/TcKeyFailConf.hpp> -#include <signaldata/GetTabInfo.hpp> -#include <signaldata/DictTabInfo.hpp> - -#include <signaldata/UtilSequence.hpp> -#include <signaldata/UtilPrepare.hpp> -#include <signaldata/UtilRelease.hpp> -#include <signaldata/UtilExecute.hpp> -#include <signaldata/UtilLock.hpp> - -#include <SectionReader.hpp> -#include <Interpreter.hpp> -#include <AttributeHeader.hpp> - -#include <NdbTick.h> - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Startup - * ------------------------------------------------------------------------ - * - * Constructors, startup, initializations - **************************************************************************/ - -DbUtil::DbUtil(Block_context& ctx) : - SimulatedBlock(DBUTIL, ctx), - c_runningPrepares(c_preparePool), - c_seizingTransactions(c_transactionPool), - c_runningTransactions(c_transactionPool), - c_lockQueues(c_lockQueuePool) -{ - BLOCK_CONSTRUCTOR(DbUtil); - - // Add received signals - addRecSignal(GSN_READ_CONFIG_REQ, &DbUtil::execREAD_CONFIG_REQ); - addRecSignal(GSN_STTOR, &DbUtil::execSTTOR); - addRecSignal(GSN_NDB_STTOR, &DbUtil::execNDB_STTOR); - addRecSignal(GSN_DUMP_STATE_ORD, &DbUtil::execDUMP_STATE_ORD); - addRecSignal(GSN_CONTINUEB, &DbUtil::execCONTINUEB); - - //addRecSignal(GSN_TCSEIZEREF, &DbUtil::execTCSEIZEREF); - addRecSignal(GSN_TCSEIZECONF, &DbUtil::execTCSEIZECONF); - addRecSignal(GSN_TCKEYCONF, &DbUtil::execTCKEYCONF); - addRecSignal(GSN_TCKEYREF, &DbUtil::execTCKEYREF); - addRecSignal(GSN_TCROLLBACKREP, &DbUtil::execTCROLLBACKREP); - - //addRecSignal(GSN_TCKEY_FAILCONF, &DbUtil::execTCKEY_FAILCONF); - //addRecSignal(GSN_TCKEY_FAILREF, &DbUtil::execTCKEY_FAILREF); - addRecSignal(GSN_TRANSID_AI, &DbUtil::execTRANSID_AI); - - /** - * Sequence Service - */ - addRecSignal(GSN_UTIL_SEQUENCE_REQ, &DbUtil::execUTIL_SEQUENCE_REQ); - // Debug - addRecSignal(GSN_UTIL_SEQUENCE_REF, &DbUtil::execUTIL_SEQUENCE_REF); - addRecSignal(GSN_UTIL_SEQUENCE_CONF, &DbUtil::execUTIL_SEQUENCE_CONF); - - /** - * Locking - */ - addRecSignal(GSN_UTIL_CREATE_LOCK_REQ, &DbUtil::execUTIL_CREATE_LOCK_REQ); - addRecSignal(GSN_UTIL_DESTROY_LOCK_REQ, &DbUtil::execUTIL_DESTORY_LOCK_REQ); - addRecSignal(GSN_UTIL_LOCK_REQ, &DbUtil::execUTIL_LOCK_REQ); - addRecSignal(GSN_UTIL_UNLOCK_REQ, &DbUtil::execUTIL_UNLOCK_REQ); - - /** - * Backend towards Dict - */ - addRecSignal(GSN_GET_TABINFOREF, &DbUtil::execGET_TABINFOREF); - addRecSignal(GSN_GET_TABINFO_CONF, &DbUtil::execGET_TABINFO_CONF); - - /** - * Prepare / Execute / Release Services - */ - addRecSignal(GSN_UTIL_PREPARE_REQ, &DbUtil::execUTIL_PREPARE_REQ); - addRecSignal(GSN_UTIL_PREPARE_CONF, &DbUtil::execUTIL_PREPARE_CONF); - addRecSignal(GSN_UTIL_PREPARE_REF, &DbUtil::execUTIL_PREPARE_REF); - - addRecSignal(GSN_UTIL_EXECUTE_REQ, &DbUtil::execUTIL_EXECUTE_REQ); - addRecSignal(GSN_UTIL_EXECUTE_CONF, &DbUtil::execUTIL_EXECUTE_CONF); - addRecSignal(GSN_UTIL_EXECUTE_REF, &DbUtil::execUTIL_EXECUTE_REF); - - addRecSignal(GSN_UTIL_RELEASE_REQ, &DbUtil::execUTIL_RELEASE_REQ); - addRecSignal(GSN_UTIL_RELEASE_CONF, &DbUtil::execUTIL_RELEASE_CONF); - addRecSignal(GSN_UTIL_RELEASE_REF, &DbUtil::execUTIL_RELEASE_REF); -} - -DbUtil::~DbUtil() -{ -} - -BLOCK_FUNCTIONS(DbUtil) - -void -DbUtil::releasePrepare(PreparePtr prepPtr) { - prepPtr.p->preparePages.release(); - c_runningPrepares.release(prepPtr); // Automatic release in pool -} - -void -DbUtil::releasePreparedOperation(PreparedOperationPtr prepOpPtr) { - prepOpPtr.p->attrMapping.release(); - prepOpPtr.p->attrInfo.release(); - prepOpPtr.p->rsInfo.release(); - prepOpPtr.p->pkBitmask.clear(); - c_preparedOperationPool.release(prepOpPtr); // No list holding these structs -} - -void -DbUtil::releaseTransaction(TransactionPtr transPtr){ - transPtr.p->executePages.release(); - OperationPtr opPtr; - for(transPtr.p->operations.first(opPtr); opPtr.i != RNIL; - transPtr.p->operations.next(opPtr)){ - opPtr.p->attrInfo.release(); - opPtr.p->keyInfo.release(); - opPtr.p->rs.release(); - if (opPtr.p->prepOp != 0 && opPtr.p->prepOp_i != RNIL) { - if (opPtr.p->prepOp->releaseFlag) { - PreparedOperationPtr prepOpPtr; - prepOpPtr.i = opPtr.p->prepOp_i; - prepOpPtr.p = opPtr.p->prepOp; - releasePreparedOperation(prepOpPtr); - } - } - } - transPtr.p->operations.release(); - c_runningTransactions.release(transPtr); -} - -void -DbUtil::execREAD_CONFIG_REQ(Signal* signal) -{ - jamEntry(); - - const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); - - Uint32 ref = req->senderRef; - Uint32 senderData = req->senderData; - - const ndb_mgm_configuration_iterator * p = - m_ctx.m_config.getOwnConfigIterator(); - ndbrequire(p != 0); - - c_pagePool.setSize(10); - c_preparePool.setSize(1); // one parallel prepare at a time - c_preparedOperationPool.setSize(5); // three hardcoded, two for test - c_operationPool.setSize(64); // 64 parallel operations - c_transactionPool.setSize(32); // 16 parallel transactions - c_attrMappingPool.setSize(100); - c_dataBufPool.setSize(6000); // 6000*11*4 = 264K > 8k+8k*16 = 256k - { - SLList<Prepare> tmp(c_preparePool); - PreparePtr ptr; - while(tmp.seize(ptr)) - new (ptr.p) Prepare(c_pagePool); - tmp.release(); - } - { - SLList<Operation> tmp(c_operationPool); - OperationPtr ptr; - while(tmp.seize(ptr)) - new (ptr.p) Operation(c_dataBufPool, c_dataBufPool, c_dataBufPool); - tmp.release(); - } - { - SLList<PreparedOperation> tmp(c_preparedOperationPool); - PreparedOperationPtr ptr; - while(tmp.seize(ptr)) - new (ptr.p) PreparedOperation(c_attrMappingPool, - c_dataBufPool, c_dataBufPool); - tmp.release(); - } - { - SLList<Transaction> tmp(c_transactionPool); - TransactionPtr ptr; - while(tmp.seize(ptr)) - new (ptr.p) Transaction(c_pagePool, c_operationPool); - tmp.release(); - } - - c_lockQueuePool.setSize(5); - c_lockElementPool.setSize(5); - c_lockQueues.setSize(8); - - ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); - conf->senderRef = reference(); - conf->senderData = senderData; - sendSignal(ref, GSN_READ_CONFIG_CONF, signal, - ReadConfigConf::SignalLength, JBB); -} - -void -DbUtil::execSTTOR(Signal* signal) -{ - jamEntry(); - - const Uint32 startphase = signal->theData[1]; - - if(startphase == 1){ - c_transId[0] = (number() << 20) + (getOwnNodeId() << 8); - c_transId[1] = 0; - } - - if(startphase == 6){ - hardcodedPrepare(); - connectTc(signal); - } - - signal->theData[0] = 0; - signal->theData[3] = 1; - signal->theData[4] = 6; - signal->theData[5] = 255; - sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB); - - return; -} - -void -DbUtil::execNDB_STTOR(Signal* signal) -{ - (void)signal; // Don't want compiler warning - - jamEntry(); -} - - -/*************************** - * Seize a number of TC records - * to use for Util transactions - */ - -void -DbUtil::connectTc(Signal* signal){ - - TransactionPtr ptr; - while(c_seizingTransactions.seize(ptr)){ - signal->theData[0] = ptr.i << 1; // See TcCommitConf - signal->theData[1] = reference(); - sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB); - } -} - -void -DbUtil::execTCSEIZECONF(Signal* signal){ - jamEntry(); - - TransactionPtr ptr; - ptr.i = signal->theData[0] >> 1; - c_seizingTransactions.getPtr(ptr, signal->theData[0] >> 1); - ptr.p->connectPtr = signal->theData[1]; - - c_seizingTransactions.release(ptr); -} - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Misc - * ------------------------------------------------------------------------ - * - * ContinueB, Dump - **************************************************************************/ - -void -DbUtil::execCONTINUEB(Signal* signal){ - jamEntry(); - const Uint32 Tdata0 = signal->theData[0]; - - switch(Tdata0){ - default: - ndbrequire(0); - } -} - -void -DbUtil::execDUMP_STATE_ORD(Signal* signal){ - jamEntry(); - - /**************************************************************************** - * SEQUENCE SERVICE - * - * 200 : Simple test of Public Sequence Interface - * ---------------------------------------------- - * - Sends a SEQUENCE_REQ signal to Util (itself) - */ - const Uint32 tCase = signal->theData[0]; - if(tCase == 200){ - jam() - ndbout << "--------------------------------------------------" << endl; - UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend(); - Uint32 seqId = 1; - Uint32 reqTy = UtilSequenceReq::CurrVal; - - if(signal->length() > 1) seqId = signal->theData[1]; - if(signal->length() > 2) reqTy = signal->theData[2]; - - req->senderData = 12; - req->sequenceId = seqId; - req->requestType = reqTy; - - sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ, - signal, UtilSequenceReq::SignalLength, JBB); - } - - /****************************************************************************/ - /* // Obsolete tests, should be rewritten for long signals!! - if(tCase == 210){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0], 128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete); - w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); - w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 211){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert); - w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); - w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 - w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 212){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update); - w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); - w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 - w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 213){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read); - w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); - w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 214){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0], 128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete); - w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 - w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 215){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert); - w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 - w.add(UtilPrepareReq::AttributeId, (unsigned int)0); // SYSKEY_0 - w.add(UtilPrepareReq::AttributeId, 1); // NEXTID - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 216){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update); - w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 - w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 - w.add(UtilPrepareReq::AttributeId, 1); // NEXTID - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - if(tCase == 217){ - jam(); - ndbout << "--------------------------------------------------" << endl; - const Uint32 pageSizeInWords = 128; - Uint32 propPage[pageSizeInWords]; - LinearWriter w(&propPage[0],128); - w.first(); - w.add(UtilPrepareReq::NoOfOperations, 1); - w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read); - w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 - w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 - Uint32 length = w.getWordsUsed(); - ndbassert(length <= pageSizeInWords); - - sendUtilPrepareReqSignals(signal, propPage, length); - } - */ - /****************************************************************************/ - /* // Obsolete tests, should be rewritten for long signals!! - if(tCase == 220){ - jam(); - ndbout << "--------------------------------------------------" << endl; - Uint32 prepI = signal->theData[1]; - Uint32 length = signal->theData[2]; - Uint32 attributeValue0 = signal->theData[3]; - Uint32 attributeValue1a = signal->theData[4]; - Uint32 attributeValue1b = signal->theData[5]; - ndbrequire(prepI != 0); - - UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtrSend(); - - req->senderData = 221; - req->prepareId = prepI; - req->totalDataLen = length; // Including headers - req->offset = 0; - - AttributeHeader::init(&req->attrData[0], 0, 1); // AttrNo 0, DataSize - req->attrData[1] = attributeValue0; // AttrValue - AttributeHeader::init(&req->attrData[2], 1, 2); // AttrNo 1, DataSize - req->attrData[3] = attributeValue1a; // AttrValue - req->attrData[4] = attributeValue1b; // AttrValue - - printUTIL_EXECUTE_REQ(stdout, signal->getDataPtrSend(), 3 + 5,0); - sendSignal(DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal, 3 + 5, JBB); - } -*/ - /**************************************************************************** - * 230 : PRINT STATE - */ -#ifdef ARRAY_GUARD - if(tCase == 230){ - jam(); - - ndbout << "--------------------------------------------------" << endl; - if (signal->length() <= 1) { - ndbout << "Usage: DUMP 230 <recordType> <recordNo>" << endl - << "[1] Print Prepare (running) records" << endl - << "[2] Print PreparedOperation records" << endl - << "[3] Print Transaction records" << endl - << "[4] Print Operation records" << endl - << "Ex. \"dump 230 1 2\" prints Prepare record no 2." << endl - << endl - << "210 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0" << endl - << "211 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID" << endl - << "212 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID" << endl - << "213 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0" << endl - << "214 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0 using id" << endl - << "215 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID using id" << endl - << "216 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID using id" << endl - << "217 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0 using id" << endl - << "220 : EXECUTE_REQ <PrepId> <Len> <Val1> <Val2a> <Val2b>" <<endl - << "299 : Crash system (using ndbrequire(0))" - << endl - << "Ex. \"dump 220 3 5 1 0 17 \" prints Prepare record no 2." - << endl; - return; - } - - switch (signal->theData[1]) { - case 1: - // ** Print a specific record ** - if (signal->length() >= 3) { - PreparePtr prepPtr; - if (!c_preparePool.isSeized(signal->theData[2])) { - ndbout << "Prepare Id: " << signal->theData[2] - << " (Not seized!)" << endl; - } else { - c_preparePool.getPtr(prepPtr, signal->theData[2]); - prepPtr.p->print(); - } - return; - } - - // ** Print all records ** - PreparePtr prepPtr; - if (!c_runningPrepares.first(prepPtr)) { - ndbout << "No Prepare records exist" << endl; - return; - } - - while (!prepPtr.isNull()) { - prepPtr.p->print(); - c_runningPrepares.next(prepPtr); - } - return; - - case 2: - // ** Print a specific record ** - if (signal->length() >= 3) { - if (!c_preparedOperationPool.isSeized(signal->theData[2])) { - ndbout << "PreparedOperation Id: " << signal->theData[2] - << " (Not seized!)" << endl; - return; - } - ndbout << "PreparedOperation Id: " << signal->theData[2] << endl; - PreparedOperationPtr prepOpPtr; - c_preparedOperationPool.getPtr(prepOpPtr, signal->theData[2]); - prepOpPtr.p->print(); - return; - } - - // ** Print all records ** -#if 0 // not implemented - PreparedOperationPtr prepOpPtr; - if (!c_runningPreparedOperations.first(prepOpPtr)) { - ndbout << "No PreparedOperations exist" << endl; - return; - } - while (!prepOpPtr.isNull()) { - ndbout << "[-PreparedOperation no " << prepOpPtr.i << ":"; - prepOpPtr.p->print(); - ndbout << "]"; - c_runningPreparedOperations.next(prepOpPtr); - } -#endif - return; - - case 3: - // ** Print a specific record ** - if (signal->length() >= 3) { - ndbout << "Print specific record not implemented." << endl; - return; - } - - // ** Print all records ** - ndbout << "Print all records not implemented, specify an Id." << endl; - return; - - case 4: - ndbout << "Not implemented" << endl; - return; - - default: - ndbout << "Unknown input (try without any data)" << endl; - return; - } - } -#endif - if(tCase == 240 && signal->getLength() == 2){ - MutexManager::ActiveMutexPtr ptr; - ndbrequire(c_mutexMgr.seize(ptr)); - ptr.p->m_mutexId = signal->theData[1]; - Callback c = { safe_cast(&DbUtil::mutex_created), ptr.i }; - ptr.p->m_callback = c; - c_mutexMgr.create(signal, ptr); - ndbout_c("c_mutexMgr.create ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); - } - - if(tCase == 241 && signal->getLength() == 2){ - MutexManager::ActiveMutexPtr ptr; - ndbrequire(c_mutexMgr.seize(ptr)); - ptr.p->m_mutexId = signal->theData[1]; - Callback c = { safe_cast(&DbUtil::mutex_locked), ptr.i }; - ptr.p->m_callback = c; - c_mutexMgr.lock(signal, ptr); - ndbout_c("c_mutexMgr.lock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); - } - - if(tCase == 242 && signal->getLength() == 2){ - MutexManager::ActiveMutexPtr ptr; - ptr.i = signal->theData[1]; - c_mutexMgr.getPtr(ptr); - Callback c = { safe_cast(&DbUtil::mutex_unlocked), ptr.i }; - ptr.p->m_callback = c; - c_mutexMgr.unlock(signal, ptr); - ndbout_c("c_mutexMgr.unlock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); - } - - if(tCase == 243 && signal->getLength() == 3){ - MutexManager::ActiveMutexPtr ptr; - ndbrequire(c_mutexMgr.seize(ptr)); - ptr.p->m_mutexId = signal->theData[1]; - ptr.p->m_mutexKey = signal->theData[2]; - Callback c = { safe_cast(&DbUtil::mutex_destroyed), ptr.i }; - ptr.p->m_callback = c; - c_mutexMgr.destroy(signal, ptr); - ndbout_c("c_mutexMgr.destroy ptrI=%d mutexId=%d key=%d", - ptr.i, ptr.p->m_mutexId, ptr.p->m_mutexKey); - } -} - -void -DbUtil::mutex_created(Signal* signal, Uint32 ptrI, Uint32 retVal){ - MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; - c_mutexMgr.getPtr(ptr); - ndbout_c("mutex_created - mutexId=%d, retVal=%d", - ptr.p->m_mutexId, retVal); - c_mutexMgr.release(ptrI); -} - -void -DbUtil::mutex_destroyed(Signal* signal, Uint32 ptrI, Uint32 retVal){ - MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; - c_mutexMgr.getPtr(ptr); - ndbout_c("mutex_destroyed - mutexId=%d, retVal=%d", - ptr.p->m_mutexId, retVal); - c_mutexMgr.release(ptrI); -} - -void -DbUtil::mutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){ - MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; - c_mutexMgr.getPtr(ptr); - ndbout_c("mutex_locked - mutexId=%d, retVal=%d key=%d ptrI=%d", - ptr.p->m_mutexId, retVal, ptr.p->m_mutexKey, ptrI); - if(retVal) - c_mutexMgr.release(ptrI); -} - -void -DbUtil::mutex_unlocked(Signal* signal, Uint32 ptrI, Uint32 retVal){ - MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; - c_mutexMgr.getPtr(ptr); - ndbout_c("mutex_unlocked - mutexId=%d, retVal=%d", - ptr.p->m_mutexId, retVal); - if(!retVal) - c_mutexMgr.release(ptrI); -} - -void -DbUtil::execUTIL_SEQUENCE_REF(Signal* signal){ - jamEntry(); - ndbout << "UTIL_SEQUENCE_REF" << endl; - printUTIL_SEQUENCE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); -} - -void -DbUtil::execUTIL_SEQUENCE_CONF(Signal* signal){ - jamEntry(); - ndbout << "UTIL_SEQUENCE_CONF" << endl; - printUTIL_SEQUENCE_CONF(stdout, signal->getDataPtrSend(), signal->length(),0); -} - -void -DbUtil::execUTIL_PREPARE_CONF(Signal* signal){ - jamEntry(); - ndbout << "UTIL_PREPARE_CONF" << endl; - printUTIL_PREPARE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0); -} - -void -DbUtil::execUTIL_PREPARE_REF(Signal* signal){ - jamEntry(); - ndbout << "UTIL_PREPARE_REF" << endl; - printUTIL_PREPARE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); -} - -void -DbUtil::execUTIL_EXECUTE_CONF(Signal* signal) { - jamEntry(); - ndbout << "UTIL_EXECUTE_CONF" << endl; - printUTIL_EXECUTE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0); -} - -void -DbUtil::execUTIL_EXECUTE_REF(Signal* signal) { - jamEntry(); - - ndbout << "UTIL_EXECUTE_REF" << endl; - printUTIL_EXECUTE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); -} - -void -DbUtil::execUTIL_RELEASE_CONF(Signal* signal) { - jamEntry(); - ndbout << "UTIL_RELEASE_CONF" << endl; -} - -void -DbUtil::execUTIL_RELEASE_REF(Signal* signal) { - jamEntry(); - - ndbout << "UTIL_RELEASE_REF" << endl; -} - -void -DbUtil::sendUtilPrepareRef(Signal* signal, UtilPrepareRef::ErrorCode error, - Uint32 recipient, Uint32 senderData){ - UtilPrepareRef * ref = (UtilPrepareRef *)signal->getDataPtrSend(); - ref->errorCode = error; - ref->senderData = senderData; - - sendSignal(recipient, GSN_UTIL_PREPARE_REF, signal, - UtilPrepareRef::SignalLength, JBB); -} - -void -DbUtil::sendUtilExecuteRef(Signal* signal, UtilExecuteRef::ErrorCode error, - Uint32 TCerror, Uint32 recipient, Uint32 senderData){ - - UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend(); - ref->senderData = senderData; - ref->errorCode = error; - ref->TCErrorCode = TCerror; - - sendSignal(recipient, GSN_UTIL_EXECUTE_REF, signal, - UtilPrepareRef::SignalLength, JBB); -} - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Prepare service - * ------------------------------------------------------------------------ - * - * Prepares a transaction by storing info in some structs - **************************************************************************/ - -void -DbUtil::execUTIL_PREPARE_REQ(Signal* signal) -{ - jamEntry(); - - /**************** - * Decode Signal - ****************/ - UtilPrepareReq * req = (UtilPrepareReq *)signal->getDataPtr(); - const Uint32 senderRef = req->senderRef; - const Uint32 senderData = req->senderData; - - if(signal->getNoOfSections() == 0) { - // Missing prepare data - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, UtilPrepareRef::MISSING_PROPERTIES_SECTION, - senderRef, senderData); - return; - } - - PreparePtr prepPtr; - SegmentedSectionPtr ptr; - - jam(); - if(!c_runningPrepares.seize(prepPtr)) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR, - senderRef, senderData); - return; - }; - signal->getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION); - const Uint32 noPages = (ptr.sz + sizeof(Page32)) / sizeof(Page32); - ndbassert(noPages > 0); - if (!prepPtr.p->preparePages.seize(noPages)) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR, - senderRef, senderData); - c_preparePool.release(prepPtr); - return; - } - // Save SimpleProperties - Uint32* target = &prepPtr.p->preparePages.getPtr(0)->data[0]; - copy(target, ptr); - prepPtr.p->prepDataLen = ptr.sz; - // Release long signal sections - releaseSections(signal); - // Check table properties with DICT - SimplePropertiesSectionReader reader(ptr, getSectionSegmentPool()); - prepPtr.p->clientRef = senderRef; - prepPtr.p->clientData = senderData; - // Release long signal sections - releaseSections(signal); - readPrepareProps(signal, &reader, prepPtr.i); -} - -void DbUtil::readPrepareProps(Signal* signal, - SimpleProperties::Reader* reader, - Uint32 senderData) -{ - jam(); -#if 0 - printf("DbUtil::readPrepareProps: Received SimpleProperties:\n"); - reader->printAll(ndbout); -#endif - ndbrequire(reader->first()); - ndbrequire(reader->getKey() == UtilPrepareReq::NoOfOperations); - ndbrequire(reader->getUint32() == 1); // Only one op/trans implemented - - ndbrequire(reader->next()); - ndbrequire(reader->getKey() == UtilPrepareReq::OperationType); - - ndbrequire(reader->next()); - UtilPrepareReq::KeyValue tableKey = - (UtilPrepareReq::KeyValue) reader->getKey(); - ndbrequire((tableKey == UtilPrepareReq::TableName) || - (tableKey == UtilPrepareReq::TableId)); - - /************************ - * Ask Dict for metadata - ************************/ - { - GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend(); - req->senderRef = reference(); - req->senderData = senderData; - if (tableKey == UtilPrepareReq::TableName) { - jam(); - char tableName[MAX_TAB_NAME_SIZE]; - req->requestType = GetTabInfoReq::RequestByName | - GetTabInfoReq::LongSignalConf; - - req->tableNameLen = reader->getValueLen(); // Including trailing \0 - - /******************************************** - * Code signal data and send signals to DICT - ********************************************/ - - ndbrequire(req->tableNameLen < MAX_TAB_NAME_SIZE); - reader->getString((char*)tableName); - LinearSectionPtr ptr[1]; - ptr[0].p = (Uint32*)tableName; - ptr[0].sz = req->tableNameLen; - sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, - GetTabInfoReq::SignalLength, JBB, ptr,1); - - } - else { // (tableKey == UtilPrepareReq::TableId) - jam(); - req->requestType = GetTabInfoReq::RequestById | - GetTabInfoReq::LongSignalConf; - req->tableId = reader->getUint32(); - sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, - GetTabInfoReq::SignalLength, JBB); - } - - } -} - -/** - * @note We assume that this signal comes due to a request related - * to a Prepare struct. DictTabInfo:s 'senderData' denotes - * the Prepare struct related to the request. - */ -void -DbUtil::execGET_TABINFO_CONF(Signal* signal){ - jamEntry(); - - if(!assembleFragments(signal)){ - jam(); - return; - } - - /**************** - * Decode signal - ****************/ - GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr(); - const Uint32 prepI = conf->senderData; - const Uint32 totalLen = conf->totalLen; - - SegmentedSectionPtr dictTabInfoPtr; - signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO); - ndbrequire(dictTabInfoPtr.sz == totalLen); - - PreparePtr prepPtr; - c_runningPrepares.getPtr(prepPtr, prepI); - prepareOperation(signal, prepPtr); -} - -void -DbUtil::execGET_TABINFOREF(Signal* signal){ - jamEntry(); - - GetTabInfoRef * ref = (GetTabInfoRef *)signal->getDataPtr(); - Uint32 prepI = ref->senderData; -#define EVENT_DEBUG -#if 0 //def EVENT_DEBUG - ndbout << "Signal GET_TABINFOREF received." << endl; - ndbout << "Error Code: " << ref->errorCode << endl; - - switch (ref->errorCode) { - case GetTabInfoRef::InvalidTableId: - ndbout << " Msg: Invalid table id" << endl; - break; - case GetTabInfoRef::TableNotDefined: - ndbout << " Msg: Table not defined" << endl; - break; - case GetTabInfoRef::TableNameToLong: - ndbout << " Msg: Table node too long" << endl; - break; - default: - ndbout << " Msg: Unknown error returned from Dict" << endl; - break; - } -#endif - - PreparePtr prepPtr; - c_runningPrepares.getPtr(prepPtr, prepI); - - sendUtilPrepareRef(signal, UtilPrepareRef::DICT_TAB_INFO_ERROR, - prepPtr.p->clientRef, prepPtr.p->clientData); - - releasePrepare(prepPtr); -} - - -/****************************************************************************** - * Prepare Operation - * - * Using a prepare record, prepare an operation (i.e. create PreparedOperation). - * Info from both Pepare request (PreparePages) and DictTabInfo is used. - * - * Algorithm: - * -# Seize AttrbuteMapping - * - Lookup in preparePages how many attributes should be prepared - * - Seize AttributeMapping - * -# For each attributes in preparePages - * - Lookup id and isPK in dictInfoPages - * - Store "no -> (AttributeId, Position)" in AttributeMapping - * -# For each map in AttributeMapping - * - if (isPK) then assign offset - ******************************************************************************/ -void -DbUtil::prepareOperation(Signal* signal, PreparePtr prepPtr) -{ - jam(); - - /******************************************* - * Seize and store PreparedOperation struct - *******************************************/ - PreparedOperationPtr prepOpPtr; - if(!c_preparedOperationPool.seize(prepOpPtr)) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR, - prepPtr.p->clientRef, prepPtr.p->clientData); - releasePrepare(prepPtr); - return; - } - prepPtr.p->prepOpPtr = prepOpPtr; - - /******************** - * Read request info - ********************/ - SimplePropertiesLinearReader prepPagesReader(&prepPtr.p->preparePages.getPtr(0)->data[0], - prepPtr.p->prepDataLen); - - ndbrequire(prepPagesReader.first()); - ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::NoOfOperations); - const Uint32 noOfOperations = prepPagesReader.getUint32(); - ndbrequire(noOfOperations == 1); - - ndbrequire(prepPagesReader.next()); - ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::OperationType); - const Uint32 operationType = prepPagesReader.getUint32(); - - ndbrequire(prepPagesReader.next()); - - char tableName[MAX_TAB_NAME_SIZE]; - Uint32 tableId; - UtilPrepareReq::KeyValue tableKey = - (UtilPrepareReq::KeyValue) prepPagesReader.getKey(); - if (tableKey == UtilPrepareReq::TableId) { - jam(); - tableId = prepPagesReader.getUint32(); - } - else { - jam(); - ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::TableName); - ndbrequire(prepPagesReader.getValueLen() <= MAX_TAB_NAME_SIZE); - prepPagesReader.getString(tableName); - } - /****************************************************************** - * Seize AttributeMapping (by counting no of attribs in prepPages) - ******************************************************************/ - Uint32 noOfAttributes = 0; // No of attributes in PreparePages (used later) - while(prepPagesReader.next()) { - if (tableKey == UtilPrepareReq::TableName) { - jam(); - ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeName); - } else { - jam(); - ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeId); - } - noOfAttributes++; - } - ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.seize(noOfAttributes)); - if (operationType == UtilPrepareReq::Read) { - ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.seize(noOfAttributes)); - } - /*************************************** - * For each attribute name, lookup info - ***************************************/ - // Goto start of attribute names - ndbrequire(prepPagesReader.first() && prepPagesReader.next() && - prepPagesReader.next()); - - DictTabInfo::Table tableDesc; tableDesc.init(); - AttrMappingBuffer::DataBufferIterator attrMappingIt; - ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.first(attrMappingIt)); - - ResultSetBuffer::DataBufferIterator rsInfoIt; - if (operationType == UtilPrepareReq::Read) { - ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.first(rsInfoIt)); - } - - Uint32 noOfPKAttribsStored = 0; - Uint32 noOfNonPKAttribsStored = 0; - Uint32 attrLength = 0; - Uint32 pkAttrLength = 0; - char attrNameRequested[MAX_ATTR_NAME_SIZE]; - Uint32 attrIdRequested; - - while(prepPagesReader.next()) { - UtilPrepareReq::KeyValue attributeKey = - (UtilPrepareReq::KeyValue) prepPagesReader.getKey(); - - ndbrequire((attributeKey == UtilPrepareReq::AttributeName) || - (attributeKey == UtilPrepareReq::AttributeId)); - if (attributeKey == UtilPrepareReq::AttributeName) { - jam(); - ndbrequire(prepPagesReader.getValueLen() <= MAX_ATTR_NAME_SIZE); - - prepPagesReader.getString(attrNameRequested); - attrIdRequested= ~0u; - } else { - jam(); - attrIdRequested = prepPagesReader.getUint32(); - } - /***************************************** - * Copy DictTabInfo into tableDesc struct - *****************************************/ - - SegmentedSectionPtr ptr; - signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO); - SimplePropertiesSectionReader dictInfoReader(ptr, getSectionSegmentPool()); - - SimpleProperties::UnpackStatus unpackStatus; - unpackStatus = SimpleProperties::unpack(dictInfoReader, &tableDesc, - DictTabInfo::TableMapping, - DictTabInfo::TableMappingSize, - true, true); - ndbrequire(unpackStatus == SimpleProperties::Break); - - /************************ - * Lookup in DictTabInfo - ************************/ - DictTabInfo::Attribute attrDesc; attrDesc.init(); - char attrName[MAX_ATTR_NAME_SIZE]; - Uint32 attrId= ~(Uint32)0; - bool attributeFound = false; - Uint32 noOfKeysFound = 0; // # PK attrs found before attr in DICTdata - Uint32 noOfNonKeysFound = 0; // # nonPK attrs found before attr in DICTdata - for (Uint32 i=0; i<tableDesc.NoOfAttributes; i++) { - if (tableKey == UtilPrepareReq::TableName) { - jam(); - ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeName); - ndbrequire(dictInfoReader.getValueLen() <= MAX_ATTR_NAME_SIZE); - dictInfoReader.getString(attrName); - attrId= ~(Uint32)0; // attrId not used - } else { // (tableKey == UtilPrepareReq::TableId) - jam(); - dictInfoReader.next(); // Skip name - ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeId); - attrId = dictInfoReader.getUint32(); - attrName[0]= '\0'; // attrName not used - } - unpackStatus = SimpleProperties::unpack(dictInfoReader, &attrDesc, - DictTabInfo::AttributeMapping, - DictTabInfo::AttributeMappingSize, - true, true); - ndbrequire(unpackStatus == SimpleProperties::Break); - //attrDesc.print(stdout); - - if (attrDesc.AttributeKeyFlag) { jam(); noOfKeysFound++; } - else { jam(); noOfNonKeysFound++; } - if (attributeKey == UtilPrepareReq::AttributeName) { - if (strcmp(attrName, attrNameRequested) == 0) { - attributeFound = true; - break; - } - } - else // (attributeKey == UtilPrepareReq::AttributeId) - if (attrId == attrIdRequested) { - attributeFound = true; - break; - } - - // Move to next attribute - ndbassert(dictInfoReader.getKey() == DictTabInfo::AttributeEnd); - dictInfoReader.next(); - } - - /********************** - * Attribute not found - **********************/ - if (!attributeFound) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, - UtilPrepareRef::DICT_TAB_INFO_ERROR, - prepPtr.p->clientRef, prepPtr.p->clientData); - infoEvent("UTIL: Unknown attribute requested: %s in table: %s", - attrNameRequested, tableName); - releasePreparedOperation(prepOpPtr); - releasePrepare(prepPtr); - return; - } - - /************************************************************** - * Attribute found - store in mapping (AttributeId, Position) - **************************************************************/ - AttributeHeader attrMap(attrDesc.AttributeId, // 1. Store AttrId - 0); - - if (attrDesc.AttributeKeyFlag) { - // ** Attribute belongs to PK ** - prepOpPtr.p->pkBitmask.set(attrDesc.AttributeId); - attrMap.setDataSize(noOfKeysFound - 1); // 2. Store Position - noOfPKAttribsStored++; - } else { - attrMap.setDataSize(0x3fff); // 2. Store Position (fake) - noOfNonPKAttribsStored++; - - /*********************************************************** - * Error: Read nonPK Attr before all PK attr have been read - ***********************************************************/ - if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, - UtilPrepareRef::DICT_TAB_INFO_ERROR, - prepPtr.p->clientRef, prepPtr.p->clientData); - infoEvent("UTIL: Non-PK attr not allowed before " - "all PK attrs have been defined, table: %s", - tableName); - releasePreparedOperation(prepOpPtr); - releasePrepare(prepPtr); - return; - } - } - *(attrMappingIt.data) = attrMap.m_value; -#if 0 - ndbout << "BEFORE: attrLength: " << attrLength << endl; -#endif - { - int len = 0; - switch (attrDesc.AttributeSize) { - case DictTabInfo::an8Bit: - len = (attrDesc.AttributeArraySize + 3)/ 4; - break; - case DictTabInfo::a16Bit: - len = (attrDesc.AttributeArraySize + 1) / 2; - break; - case DictTabInfo::a32Bit: - len = attrDesc.AttributeArraySize; - break; - case DictTabInfo::a64Bit: - len = attrDesc.AttributeArraySize * 2; - break; - case DictTabInfo::a128Bit: - len = attrDesc.AttributeArraySize * 4; - break; - } - attrLength += len; - if (attrDesc.AttributeKeyFlag) - pkAttrLength += len; - - if (operationType == UtilPrepareReq::Read) { - AttributeHeader::init(rsInfoIt.data, - attrDesc.AttributeId, // 1. Store AttrId - len << 2); - prepOpPtr.p->rsInfo.next(rsInfoIt, 1); - } - } -#if 0 - ndbout << ": AttributeSize: " << attrDesc.AttributeSize << endl; - ndbout << ": AttributeArraySize: " << attrDesc.AttributeArraySize << endl; - ndbout << "AFTER: attrLength: " << attrLength << endl; -#endif - //attrMappingIt.print(stdout); - //prepPtr.p->prepOpPtr.p->attrMapping.print(stdout); - prepPtr.p->prepOpPtr.p->attrMapping.next(attrMappingIt, 1); - } - - /*************************** - * Error: Not all PKs found - ***************************/ - if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) { - jam(); - releaseSections(signal); - sendUtilPrepareRef(signal, - UtilPrepareRef::DICT_TAB_INFO_ERROR, - prepPtr.p->clientRef, prepPtr.p->clientData); - infoEvent("UTIL: Not all primary key attributes requested for table: %s", - tableName); - releasePreparedOperation(prepOpPtr); - releasePrepare(prepPtr); - return; - } - -#if 0 - AttrMappingBuffer::ConstDataBufferIterator tmpIt; - for (prepPtr.p->prepOpPtr.p->attrMapping.first(tmpIt); tmpIt.curr.i != RNIL; - prepPtr.p->prepOpPtr.p->attrMapping.next(tmpIt)) { - AttributeHeader* ah = (AttributeHeader *) tmpIt.data; - ah->print(stdout); - } -#endif - - /********************************************** - * Preparing of PreparedOperation signal train - **********************************************/ - Uint32 static_len = TcKeyReq::StaticLength; - prepOpPtr.p->tckey.tableId = tableDesc.TableId; - prepOpPtr.p->tckey.tableSchemaVersion = tableDesc.TableVersion; - prepOpPtr.p->noOfKeyAttr = tableDesc.NoOfKeyAttr; - prepOpPtr.p->keyLen = tableDesc.KeyLength; // Total no of words in PK - if (prepOpPtr.p->keyLen > TcKeyReq::MaxKeyInfo) { - jam(); - prepOpPtr.p->tckeyLenInBytes = (static_len + TcKeyReq::MaxKeyInfo) * 4; - } else { - jam(); - prepOpPtr.p->tckeyLenInBytes = (static_len + prepOpPtr.p->keyLen) * 4; - } - prepOpPtr.p->keyDataPos = static_len; // Start of keyInfo[] in tckeyreq - - Uint32 requestInfo = 0; - TcKeyReq::setAbortOption(requestInfo, TcKeyReq::AbortOnError); - TcKeyReq::setKeyLength(requestInfo, tableDesc.KeyLength); - switch(operationType) { - case(UtilPrepareReq::Read): - prepOpPtr.p->rsLen = - attrLength + - tableDesc.NoOfKeyAttr + - noOfNonPKAttribsStored; // Read needs a resultset - prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; - prepOpPtr.p->tckey.attrLen = prepOpPtr.p->noOfAttr; - TcKeyReq::setOperationType(requestInfo, ZREAD); - break; - case(UtilPrepareReq::Update): - prepOpPtr.p->rsLen = 0; - prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; - prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; - TcKeyReq::setOperationType(requestInfo, ZUPDATE); - break; - case(UtilPrepareReq::Insert): - prepOpPtr.p->rsLen = 0; - prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; - prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; - TcKeyReq::setOperationType(requestInfo, ZINSERT); - break; - case(UtilPrepareReq::Delete): - // The number of attributes should equal the size of the primary key - ndbrequire(tableDesc.KeyLength == attrLength); - prepOpPtr.p->rsLen = 0; - prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr; - prepOpPtr.p->tckey.attrLen = 0; - TcKeyReq::setOperationType(requestInfo, ZDELETE); - break; - case(UtilPrepareReq::Write): - prepOpPtr.p->rsLen = 0; - prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; - prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; - TcKeyReq::setOperationType(requestInfo, ZWRITE); - break; - } - TcKeyReq::setAIInTcKeyReq(requestInfo, 0); // Attrinfo sent separately - prepOpPtr.p->tckey.requestInfo = requestInfo; - - /**************************** - * Confirm completed prepare - ****************************/ - UtilPrepareConf * conf = (UtilPrepareConf *)signal->getDataPtr(); - conf->senderData = prepPtr.p->clientData; - conf->prepareId = prepPtr.p->prepOpPtr.i; - - releaseSections(signal); - sendSignal(prepPtr.p->clientRef, GSN_UTIL_PREPARE_CONF, signal, - UtilPrepareConf::SignalLength, JBB); - -#if 0 - prepPtr.p->prepOpPtr.p->print(); -#endif - releasePrepare(prepPtr); -} - - -void -DbUtil::execUTIL_RELEASE_REQ(Signal* signal){ - jamEntry(); - - UtilReleaseReq * req = (UtilReleaseReq *)signal->getDataPtr(); - const Uint32 clientRef = signal->senderBlockRef(); - const Uint32 prepareId = req->prepareId; - const Uint32 senderData = req->senderData; - -#if 0 - /** - * This only works in when ARRAY_GUARD is defined (debug-mode) - */ - if (!c_preparedOperationPool.isSeized(prepareId)) { - UtilReleaseRef * ref = (UtilReleaseRef *)signal->getDataPtr(); - ref->prepareId = prepareId; - ref->errorCode = UtilReleaseRef::NO_SUCH_PREPARE_SEIZED; - sendSignal(clientRef, GSN_UTIL_RELEASE_REF, signal, - UtilReleaseRef::SignalLength, JBB); - } -#endif - PreparedOperationPtr prepOpPtr; - c_preparedOperationPool.getPtr(prepOpPtr, prepareId); - - releasePreparedOperation(prepOpPtr); - - UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend(); - conf->senderData = senderData; - sendSignal(clientRef, GSN_UTIL_RELEASE_CONF, signal, - UtilReleaseConf::SignalLength, JBB); -} - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Sequence Service - * ------------------------------------------------------------------------ - * - * A service with a stored incrementable number - **************************************************************************/ - -void -DbUtil::hardcodedPrepare() { - /** - * Prepare SequenceCurrVal (READ) - */ - { - PreparedOperationPtr ptr; - ndbrequire(c_preparedOperationPool.seizeId(ptr, 0)); - ptr.p->keyLen = 1; - ptr.p->tckey.attrLen = 1; - ptr.p->rsLen = 3; - ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + - ptr.p->keyLen + ptr.p->tckey.attrLen) * 4; - ptr.p->keyDataPos = TcKeyReq::StaticLength; - ptr.p->tckey.tableId = 0; - Uint32 requestInfo = 0; - TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); - TcKeyReq::setOperationType(requestInfo, ZREAD); - TcKeyReq::setKeyLength(requestInfo, 1); - TcKeyReq::setAIInTcKeyReq(requestInfo, 1); - ptr.p->tckey.requestInfo = requestInfo; - ptr.p->tckey.tableSchemaVersion = 1; - - // This is actually attr data - AttributeHeader::init(&ptr.p->tckey.distrGroupHashValue, 1, 0); - - ndbrequire(ptr.p->rsInfo.seize(1)); - ResultSetInfoBuffer::DataBufferIterator it; - ptr.p->rsInfo.first(it); - AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words - } - - /** - * Prepare SequenceNextVal (UPDATE) - */ - { - PreparedOperationPtr ptr; - ndbrequire(c_preparedOperationPool.seizeId(ptr, 1)); - ptr.p->keyLen = 1; - ptr.p->rsLen = 3; - ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + ptr.p->keyLen + 5) * 4; - ptr.p->keyDataPos = TcKeyReq::StaticLength; - ptr.p->tckey.attrLen = 11; - ptr.p->tckey.tableId = 0; - Uint32 requestInfo = 0; - TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); - TcKeyReq::setOperationType(requestInfo, ZUPDATE); - TcKeyReq::setKeyLength(requestInfo, 1); - TcKeyReq::setAIInTcKeyReq(requestInfo, 5); - TcKeyReq::setInterpretedFlag(requestInfo, 1); - ptr.p->tckey.requestInfo = requestInfo; - ptr.p->tckey.tableSchemaVersion = 1; - - // Signal is packed, which is why attrInfo is at distrGroupHashValue - // position - Uint32 * attrInfo = &ptr.p->tckey.distrGroupHashValue; - attrInfo[0] = 0; // IntialReadSize - attrInfo[1] = 5; // InterpretedSize - attrInfo[2] = 0; // FinalUpdateSize - attrInfo[3] = 1; // FinalReadSize - attrInfo[4] = 0; // SubroutineSize - - { // AttrInfo - ndbrequire(ptr.p->attrInfo.seize(6)); - AttrInfoBuffer::DataBufferIterator it; - ptr.p->attrInfo.first(it); - * it.data = Interpreter::Read(1, 6); - ndbrequire(ptr.p->attrInfo.next(it)); - * it.data = Interpreter::LoadConst16(7, 1); - ndbrequire(ptr.p->attrInfo.next(it)); - * it.data = Interpreter::Add(7, 6, 7); - ndbrequire(ptr.p->attrInfo.next(it)); - * it.data = Interpreter::Write(1, 7); - ndbrequire(ptr.p->attrInfo.next(it)); - * it.data = Interpreter::ExitOK(); - - ndbrequire(ptr.p->attrInfo.next(it)); - AttributeHeader::init(it.data, 1, 0); - } - - { // ResultSet - ndbrequire(ptr.p->rsInfo.seize(1)); - ResultSetInfoBuffer::DataBufferIterator it; - ptr.p->rsInfo.first(it); - AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words - } - } - - /** - * Prepare CreateSequence (INSERT) - */ - { - PreparedOperationPtr ptr; - ndbrequire(c_preparedOperationPool.seizeId(ptr, 2)); - ptr.p->keyLen = 1; - ptr.p->tckey.attrLen = 5; - ptr.p->rsLen = 0; - ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + - ptr.p->keyLen + ptr.p->tckey.attrLen) * 4; - ptr.p->keyDataPos = TcKeyReq::StaticLength; - ptr.p->tckey.tableId = 0; - Uint32 requestInfo = 0; - TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); - TcKeyReq::setOperationType(requestInfo, ZINSERT); - TcKeyReq::setKeyLength(requestInfo, 1); - TcKeyReq::setAIInTcKeyReq(requestInfo, 0); - ptr.p->tckey.requestInfo = requestInfo; - ptr.p->tckey.tableSchemaVersion = 1; - } -} - -void -DbUtil::execUTIL_SEQUENCE_REQ(Signal* signal){ - jamEntry(); - - UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtr(); - - PreparedOperation * prepOp; - - switch(req->requestType){ - case UtilSequenceReq::CurrVal: - prepOp = c_preparedOperationPool.getPtr(0); //c_SequenceCurrVal - break; - case UtilSequenceReq::NextVal: - prepOp = c_preparedOperationPool.getPtr(1); //c_SequenceNextVal - break; - case UtilSequenceReq::Create: - prepOp = c_preparedOperationPool.getPtr(2); //c_CreateSequence - break; - default: - ndbrequire(false); - prepOp = 0; // remove warning - } - - /** - * 1 Transaction with 1 operation - */ - TransactionPtr transPtr; - ndbrequire(c_runningTransactions.seize(transPtr)); - - OperationPtr opPtr; - ndbrequire(transPtr.p->operations.seize(opPtr)); - - ndbrequire(opPtr.p->rs.seize(prepOp->rsLen)); - ndbrequire(opPtr.p->keyInfo.seize(prepOp->keyLen)); - - transPtr.p->gsn = GSN_UTIL_SEQUENCE_REQ; - transPtr.p->clientRef = signal->senderBlockRef(); - transPtr.p->clientData = req->senderData; - transPtr.p->sequence.sequenceId = req->sequenceId; - transPtr.p->sequence.requestType = req->requestType; - - opPtr.p->prepOp = prepOp; - opPtr.p->prepOp_i = RNIL; - - KeyInfoBuffer::DataBufferIterator it; - opPtr.p->keyInfo.first(it); - it.data[0] = transPtr.p->sequence.sequenceId; - - if(req->requestType == UtilSequenceReq::Create){ - ndbrequire(opPtr.p->attrInfo.seize(5)); - AttrInfoBuffer::DataBufferIterator it; - - opPtr.p->attrInfo.first(it); - AttributeHeader::init(it.data, 0, 1 << 2); - - ndbrequire(opPtr.p->attrInfo.next(it)); - * it.data = transPtr.p->sequence.sequenceId; - - ndbrequire(opPtr.p->attrInfo.next(it)); - AttributeHeader::init(it.data, 1, 2 << 2); - - ndbrequire(opPtr.p->attrInfo.next(it)); - * it.data = 0; - - ndbrequire(opPtr.p->attrInfo.next(it)); - * it.data = 0; - } - - runTransaction(signal, transPtr); -} - -int -DbUtil::getResultSet(Signal* signal, const Transaction * transP, - struct LinearSectionPtr sectionsPtr[]) { - OperationPtr opPtr; - ndbrequire(transP->operations.first(opPtr)); - ndbrequire(transP->operations.hasNext(opPtr) == false); - - int noAttr = 0; - int dataSz = 0; - Uint32* tmpBuf = signal->theData + 25; - const Uint32* headerBuffer = tmpBuf; - - const ResultSetBuffer & rs = opPtr.p->rs; - ResultSetInfoBuffer::ConstDataBufferIterator it; - - // extract headers - for(rs.first(it); it.curr.i != RNIL; ) { - *tmpBuf++ = it.data[0]; - rs.next(it, ((AttributeHeader*)&it.data[0])->getDataSize() + 1); - noAttr++; - } - - if (noAttr == 0) - return 0; - - const Uint32* dataBuffer = tmpBuf; - - // extract data - for(rs.first(it); it.curr.i != RNIL; ) { - int sz = ((AttributeHeader*)&it.data[0])->getDataSize(); - rs.next(it,1); - for (int i = 0; i < sz; i++) { - *tmpBuf++ = *it.data; - rs.next(it,1); - dataSz++; - } - } - - sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = (Uint32 *)headerBuffer; - sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr; - sectionsPtr[UtilExecuteReq::DATA_SECTION].p = (Uint32 *)dataBuffer; - sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataSz; - - return 1; -} - -void -DbUtil::reportSequence(Signal* signal, const Transaction * transP){ - OperationPtr opPtr; - ndbrequire(transP->operations.first(opPtr)); - ndbrequire(transP->operations.hasNext(opPtr) == false); - - if(transP->errorCode == 0){ - jam(); // OK - - UtilSequenceConf * ret = (UtilSequenceConf *)signal->getDataPtrSend(); - ret->senderData = transP->clientData; - ret->sequenceId = transP->sequence.sequenceId; - ret->requestType = transP->sequence.requestType; - - bool ok = false; - switch(transP->sequence.requestType){ - case UtilSequenceReq::CurrVal: - case UtilSequenceReq::NextVal:{ - ok = true; - ndbrequire(opPtr.p->rsRecv == 3); - - ResultSetBuffer::DataBufferIterator rsit; - ndbrequire(opPtr.p->rs.first(rsit)); - - ret->sequenceValue[0] = rsit.data[1]; - ret->sequenceValue[1] = rsit.data[2]; - break; - } - case UtilSequenceReq::Create: - ok = true; - ret->sequenceValue[0] = 0; - ret->sequenceValue[1] = 0; - break; - } - ndbrequire(ok); - sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_CONF, signal, - UtilSequenceConf::SignalLength, JBB); - return; - } - - UtilSequenceRef::ErrorCode errCode = UtilSequenceRef::TCError; - - switch(transP->sequence.requestType) - { - case UtilSequenceReq::CurrVal: - case UtilSequenceReq::NextVal:{ - if (transP->errorCode == 626) - errCode = UtilSequenceRef::NoSuchSequence; - break; - } - case UtilSequenceReq::Create: - break; - } - - UtilSequenceRef * ret = (UtilSequenceRef *)signal->getDataPtrSend(); - ret->senderData = transP->clientData; - ret->sequenceId = transP->sequence.sequenceId; - ret->requestType = transP->sequence.requestType; - ret->errorCode = (Uint32)errCode; - sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_REF, signal, - UtilSequenceRef::SignalLength, JBB); -} -#if 0 - Ndb ndb("ndb","def"); - NdbConnection* tConnection = ndb.startTransaction(); - NdbOperation* tOperation = tConnection->getNdbOperation("SYSTAB_0"); - - //#if 0 && API_CODE - if( tOperation != NULL ) { - tOperation->interpretedUpdateTuple(); - tOperation->equal((U_Int32)0, keyValue ); - tNextId_Result = tOperation->getValue((U_Int32)1); - tOperation->incValue((U_Int32)1, (U_Int32)8192); - - if (tConnection->execute( Commit ) != -1 ) { - U_Int64 tValue = tNextId_Result->u_64_value(); // Read result value - theFirstTransId = tValue; - theLastTransId = tValue + 8191; - closeTransaction(tConnection); - return startTransactionLocal(aPriority, nodeId); - } - } - /** - * IntialReadSize = 0; - * InterpretedSize = incValue(1); - * FinalUpdateSize = 0; - * FinalReadSize = 1; // Read value - * SubroutineSize = 0; - */ -#endif - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Transaction execution request - * ------------------------------------------------------------------------ - * - * Handle requests to execute a prepared transaction - **************************************************************************/ - -void -DbUtil::execUTIL_EXECUTE_REQ(Signal* signal) -{ - jamEntry(); - - UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtr(); - const Uint32 clientRef = req->senderRef; - const Uint32 clientData = req->senderData; - const Uint32 prepareId = req->getPrepareId(); - const bool releaseFlag = req->getReleaseFlag(); - - if(signal->getNoOfSections() == 0) { - // Missing prepare data - jam(); - releaseSections(signal); - sendUtilExecuteRef(signal, UtilExecuteRef::MissingDataSection, - 0, clientRef, clientData); - return; - } - /******************************* - * Get PreparedOperation struct - *******************************/ - PreparedOperationPtr prepOpPtr; - c_preparedOperationPool.getPtr(prepOpPtr, prepareId); - - prepOpPtr.p->releaseFlag = releaseFlag; - - TransactionPtr transPtr; - OperationPtr opPtr; - SegmentedSectionPtr headerPtr, dataPtr; - - signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION); - SectionReader headerReader(headerPtr, getSectionSegmentPool()); - signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION); - SectionReader dataReader(dataPtr, getSectionSegmentPool()); - -#if 0 //def EVENT_DEBUG - // Debugging - printf("DbUtil::execUTIL_EXECUTEL_REQ: Headers (%u): ", headerPtr.sz); - Uint32 word; - while(headerReader.getWord(&word)) - printf("H'%.8x ", word); - printf("\n"); - printf("DbUtil::execUTIL_EXECUTEL_REQ: Data (%u): ", dataPtr.sz); - headerReader.reset(); - while(dataReader.getWord(&word)) - printf("H'%.8x ", word); - printf("\n"); - dataReader.reset(); -#endif - -// Uint32 totalDataLen = headerPtr.sz + dataPtr.sz; - - /************************************************************ - * Seize Transaction record - ************************************************************/ - ndbrequire(c_runningTransactions.seize(transPtr)); - transPtr.p->gsn = GSN_UTIL_EXECUTE_REQ; - transPtr.p->clientRef = clientRef; - transPtr.p->clientData = clientData; - ndbrequire(transPtr.p->operations.seize(opPtr)); - opPtr.p->prepOp = prepOpPtr.p; - opPtr.p->prepOp_i = prepOpPtr.i; - -#if 0 //def EVENT_DEBUG - printf("opPtr.p->rs.seize( %u )\n", prepOpPtr.p->rsLen); -#endif - ndbrequire(opPtr.p->rs.seize(prepOpPtr.p->rsLen)); - - /*********************************************************** - * Store signal data on linear memory in Transaction record - ***********************************************************/ - KeyInfoBuffer* keyInfo = &opPtr.p->keyInfo; - AttrInfoBuffer* attrInfo = &opPtr.p->attrInfo; - AttributeHeader header; - Uint32* tempBuf = signal->theData + 25; - bool dataComplete = true; - - while(headerReader.getWord((Uint32 *)&header)) { - Uint32* bufStart = tempBuf; - header.insertHeader(tempBuf++); - for(unsigned int i = 0; i < header.getDataSize(); i++) { - if (!dataReader.getWord(tempBuf++)) { - dataComplete = false; - break; - } - } - bool res = true; - -#if 0 //def EVENT_DEBUG - if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) == - TcKeyReq::Read) { - if(prepOpPtr.p->pkBitmask.get(header.getAttributeId())) - printf("PrimaryKey\n"); - } - printf("AttrId %u Hdrsz %d Datasz %u \n", - header.getAttributeId(), - header.getHeaderSize(), - header.getDataSize()); -#endif - - if(prepOpPtr.p->pkBitmask.get(header.getAttributeId())) - // A primary key attribute - res = keyInfo->append(bufStart + header.getHeaderSize(), - header.getDataSize()); - - switch (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo)) { - case ZREAD: - res &= attrInfo->append(bufStart, header.getHeaderSize()); - break; - case ZDELETE: - // no attrinfo for Delete - break; - default: - res &= attrInfo->append(bufStart, - header.getHeaderSize() + header.getDataSize()); - } - - if (!res) { - // Failed to allocate buffer data - jam(); - releaseSections(signal); - sendUtilExecuteRef(signal, UtilExecuteRef::AllocationError, - 0, clientRef, clientData); - releaseTransaction(transPtr); - return; - } - } - if (!dataComplete) { - // Missing data in data section - jam(); - releaseSections(signal); - sendUtilExecuteRef(signal, UtilExecuteRef::MissingData, - 0, clientRef, clientData); - releaseTransaction(transPtr); - return; - } - - // quick hack for hash index build - if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){ - prepOpPtr.p->tckey.attrLen = - prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize(); - TcKeyReq::setKeyLength(prepOpPtr.p->tckey.requestInfo, keyInfo->getSize()); - } - -#if 0 - const Uint32 l1 = prepOpPtr.p->tckey.attrLen; - const Uint32 l2 = - prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize(); - - if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){ - ndbrequire(l1 == l2); - } else { - ndbout_c("TcKeyReq::Read"); - } -#endif - - releaseSections(signal); - transPtr.p->noOfRetries = 3; - runTransaction(signal, transPtr); -} - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: General transaction machinery - * ------------------------------------------------------------------------ - * Executes a prepared transaction - **************************************************************************/ -void -DbUtil::runTransaction(Signal* signal, TransactionPtr transPtr){ - - /* Init transaction */ - transPtr.p->sent = 0; - transPtr.p->recv = 0; - transPtr.p->errorCode = 0; - getTransId(transPtr.p); - - OperationPtr opPtr; - ndbrequire(transPtr.p->operations.first(opPtr)); - - /* First operation */ - Uint32 start = 0; - TcKeyReq::setStartFlag(start, 1); - runOperation(signal, transPtr, opPtr, start); - transPtr.p->sent ++; - - /* Rest of operations */ - start = 0; - while(opPtr.i != RNIL){ - runOperation(signal, transPtr, opPtr, start); - transPtr.p->sent ++; - } - //transPtr.p->print(); -} - -void -DbUtil::runOperation(Signal* signal, TransactionPtr & transPtr, - OperationPtr & opPtr, Uint32 start) { - Uint32 opI = opPtr.i; - Operation * op = opPtr.p; - const PreparedOperation * pop = op->prepOp; - - if(!transPtr.p->operations.next(opPtr)){ - TcKeyReq::setCommitFlag(start, 1); // Last operation - TcKeyReq::setExecuteFlag(start, 1); - } - -#if 0 //def EVENT_DEBUG - if (TcKeyReq::getOperationType(pop->tckey.requestInfo) == - TcKeyReq::Read) { - printf("TcKeyReq::Read runOperation\n"); - } -#endif - - /** - * Init operation w.r.t result set - */ - initResultSet(op->rs, pop->rsInfo); - op->rs.first(op->rsIterator); - op->rsRecv = 0; -#if 0 //def EVENT_DEBUG - printf("pop->rsLen %u\n", pop->rsLen); -#endif - op->rsExpect = 0; - op->transPtrI = transPtr.i; - - TcKeyReq * tcKey = (TcKeyReq*)signal->getDataPtrSend(); - //ndbout << "*** 6 ***"<< endl; pop->print(); - memcpy(tcKey, &pop->tckey, pop->tckeyLenInBytes); - //ndbout << "*** 6b ***"<< endl; - //printTCKEYREQ(stdout, signal->getDataPtrSend(), - // pop->tckeyLenInBytes >> 2, 0); - tcKey->apiConnectPtr = transPtr.p->connectPtr; - tcKey->senderData = opI; - tcKey->transId1 = transPtr.p->transId[0]; - tcKey->transId2 = transPtr.p->transId[1]; - tcKey->requestInfo |= start; - -#if 0 //def EVENT_DEBUG - // Debugging - printf("DbUtil::runOperation: KEYINFO\n"); - op->keyInfo.print(stdout); - printf("DbUtil::runOperation: ATTRINFO\n"); - op->attrInfo.print(stdout); -#endif - - /** - * Key Info - */ - //KeyInfoBuffer::DataBufferIterator kit; - KeyInfoIterator kit; - op->keyInfo.first(kit); - Uint32 *keyDst = ((Uint32*)tcKey) + pop->keyDataPos; - for(Uint32 i = 0; i<8 && kit.curr.i != RNIL; i++, op->keyInfo.next(kit)){ - keyDst[i] = * kit.data; - } - //ndbout << "*** 7 ***" << endl; - //printTCKEYREQ(stdout, signal->getDataPtrSend(), - // pop->tckeyLenInBytes >> 2, 0); - -#if 0 //def EVENT_DEBUG - printf("DbUtil::runOperation: sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, %d , JBB)\n", pop->tckeyLenInBytes >> 2); - printTCKEYREQ(stdout, signal->getDataPtr(), pop->tckeyLenInBytes >> 2,0); -#endif - sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, pop->tckeyLenInBytes >> 2, JBB); - - /** - * More the 8 words of key info not implemented - */ - // ndbrequire(kit.curr.i == RNIL); // Yes it is - - /** - * KeyInfo - */ - KeyInfo* keyInfo = (KeyInfo *)signal->getDataPtrSend(); - keyInfo->connectPtr = transPtr.p->connectPtr; - keyInfo->transId[0] = transPtr.p->transId[0]; - keyInfo->transId[1] = transPtr.p->transId[1]; - sendKeyInfo(signal, keyInfo, op->keyInfo, kit); - - /** - * AttrInfo - */ - AttrInfo* attrInfo = (AttrInfo *)signal->getDataPtrSend(); - attrInfo->connectPtr = transPtr.p->connectPtr; - attrInfo->transId[0] = transPtr.p->transId[0]; - attrInfo->transId[1] = transPtr.p->transId[1]; - - AttrInfoIterator ait; - pop->attrInfo.first(ait); - sendAttrInfo(signal, attrInfo, pop->attrInfo, ait); - - op->attrInfo.first(ait); - sendAttrInfo(signal, attrInfo, op->attrInfo, ait); -} - -void -DbUtil::sendKeyInfo(Signal* signal, - KeyInfo* keyInfo, - const KeyInfoBuffer & keyBuf, - KeyInfoIterator & kit) -{ - while(kit.curr.i != RNIL) { - Uint32 *keyDst = keyInfo->keyData; - Uint32 keyDataLen = 0; - for(Uint32 i = 0; i<KeyInfo::DataLength && kit.curr.i != RNIL; - i++, keyBuf.next(kit)){ - keyDst[i] = * kit.data; - keyDataLen++; - } -#if 0 //def EVENT_DEBUG - printf("DbUtil::sendKeyInfo: sendSignal(DBTC_REF, GSN_KEYINFO, signal, %d , JBB)\n", KeyInfo::HeaderLength + keyDataLen); -#endif - sendSignal(DBTC_REF, GSN_KEYINFO, signal, - KeyInfo::HeaderLength + keyDataLen, JBB); - } -} - -void -DbUtil::sendAttrInfo(Signal* signal, - AttrInfo* attrInfo, - const AttrInfoBuffer & attrBuf, - AttrInfoIterator & ait) -{ - while(ait.curr.i != RNIL) { - Uint32 *attrDst = attrInfo->attrData; - Uint32 i = 0; - for(i = 0; i<AttrInfo::DataLength && ait.curr.i != RNIL; - i++, attrBuf.next(ait)){ - attrDst[i] = * ait.data; - } -#if 0 //def EVENT_DEBUG - printf("DbUtil::sendAttrInfo: sendSignal(DBTC_REF, GSN_ATTRINFO, signal, %d , JBB)\n", AttrInfo::HeaderLength + i); -#endif - sendSignal(DBTC_REF, GSN_ATTRINFO, signal, - AttrInfo::HeaderLength + i, JBB); - } -} - -void -DbUtil::initResultSet(ResultSetBuffer & rs, - const ResultSetInfoBuffer & rsi){ - - ResultSetBuffer::DataBufferIterator rsit; - rs.first(rsit); - - ResultSetInfoBuffer::ConstDataBufferIterator rsiit; - for(rsi.first(rsiit); rsiit.curr.i != RNIL; rsi.next(rsiit)){ - ndbrequire(rsit.curr.i != RNIL); - - rsit.data[0] = rsiit.data[0]; -#if 0 //def EVENT_DEBUG - printf("Init resultset %u, sz %d\n", - rsit.curr.i, - ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1); -#endif - rs.next(rsit, ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1); - } -} - -void -DbUtil::getTransId(Transaction * transP){ - - Uint32 tmp[2]; - tmp[0] = c_transId[0]; - tmp[1] = c_transId[1]; - - transP->transId[0] = tmp[0]; - transP->transId[1] = tmp[1]; - - c_transId[1] = tmp[1] + 1; -} - - - -/************************************************************************** - * ------------------------------------------------------------------------ - * MODULE: Post Execute - * ------------------------------------------------------------------------ - * - * Handles result from a sent transaction - **************************************************************************/ - -/** - * execTRANSID_AI - * - * Receive result from transaction - * - * NOTE: This codes assumes that - * TransidAI::DataLength = ResultSetBuffer::getSegmentSize() * n - */ -void -DbUtil::execTRANSID_AI(Signal* signal){ - jamEntry(); -#if 0 //def EVENT_DEBUG - ndbout_c("File: %s line: %u",__FILE__,__LINE__); -#endif - - const Uint32 opI = signal->theData[0]; - const Uint32 transId1 = signal->theData[1]; - const Uint32 transId2 = signal->theData[2]; - const Uint32 dataLen = signal->length() - 3; - - Operation * opP = c_operationPool.getPtr(opI); - TransactionPtr transPtr; - c_runningTransactions.getPtr(transPtr, opP->transPtrI); - - ndbrequire(transId1 == transPtr.p->transId[0] && - transId2 == transPtr.p->transId[1]); - opP->rsRecv += dataLen; - - /** - * Save result - */ - const Uint32 *src = &signal->theData[3]; - ResultSetBuffer::DataBufferIterator rs = opP->rsIterator; - - ndbrequire(opP->rs.import(rs,src,dataLen)); - opP->rs.next(rs, dataLen); - opP->rsIterator = rs; - - if(!opP->complete()){ - jam(); - return; - } - - transPtr.p->recv++; - if(!transPtr.p->complete()){ - jam(); - return; - } - - finishTransaction(signal, transPtr); -} - -void -DbUtil::execTCKEYCONF(Signal* signal){ - jamEntry(); -#if 0 //def EVENT_DEBUG - ndbout_c("File: %s line: %u",__FILE__,__LINE__); -#endif - - TcKeyConf * keyConf = (TcKeyConf*)signal->getDataPtr(); - - //const Uint32 gci = keyConf->gci; - const Uint32 transI = keyConf->apiConnectPtr >> 1; - const Uint32 confInfo = keyConf->confInfo; - const Uint32 transId1 = keyConf->transId1; - const Uint32 transId2 = keyConf->transId2; - - Uint32 recv = 0; - const Uint32 ops = TcKeyConf::getNoOfOperations(confInfo); - for(Uint32 i = 0; i<ops; i++){ - OperationPtr opPtr; - c_operationPool.getPtr(opPtr, keyConf->operations[i].apiOperationPtr); - - ndbrequire(opPtr.p->transPtrI == transI); - opPtr.p->rsExpect += keyConf->operations[i].attrInfoLen; - if(opPtr.p->complete()){ - recv++; - } - } - - /** - * Check commit ack marker flag - */ - if (TcKeyConf::getMarkerFlag(confInfo)){ - signal->theData[0] = transId1; - signal->theData[1] = transId2; - sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB); - }//if - - TransactionPtr transPtr; - c_runningTransactions.getPtr(transPtr, transI); - ndbrequire(transId1 == transPtr.p->transId[0] && - transId2 == transPtr.p->transId[1]); - - transPtr.p->recv += recv; - if(!transPtr.p->complete()){ - jam(); - return; - } - finishTransaction(signal, transPtr); -} - -void -DbUtil::execTCKEYREF(Signal* signal){ - jamEntry(); -#if 0 //def EVENT_DEBUG - ndbout_c("File: %s line: %u",__FILE__,__LINE__); -#endif - - const Uint32 transI = signal->theData[0] >> 1; - const Uint32 transId1 = signal->theData[1]; - const Uint32 transId2 = signal->theData[2]; - const Uint32 errCode = signal->theData[3]; - - TransactionPtr transPtr; - c_runningTransactions.getPtr(transPtr, transI); - ndbrequire(transId1 == transPtr.p->transId[0] && - transId2 == transPtr.p->transId[1]); - - //if(getClassification(errCode) == PermanentError){ - //} - - //ndbout << "Transaction error (code: " << errCode << ")" << endl; - - transPtr.p->errorCode = errCode; - finishTransaction(signal, transPtr); -} - -void -DbUtil::execTCROLLBACKREP(Signal* signal){ - jamEntry(); -#if 0 //def EVENT_DEBUG - ndbout_c("File: %s line: %u",__FILE__,__LINE__); -#endif - - const Uint32 transI = signal->theData[0] >> 1; - const Uint32 transId1 = signal->theData[1]; - const Uint32 transId2 = signal->theData[2]; - const Uint32 errCode = signal->theData[3]; - - TransactionPtr transPtr; - c_runningTransactions.getPtr(transPtr, transI); - ndbrequire(transId1 == transPtr.p->transId[0] && - transId2 == transPtr.p->transId[1]); - - //if(getClassification(errCode) == PermanentError){ - //} - -#if 0 //def EVENT_DEBUG - ndbout << "Transaction error (code: " << errCode << ")" << endl; -#endif - - if(transPtr.p->noOfRetries > 0){ - transPtr.p->noOfRetries--; - switch(errCode){ - case 266: - case 410: - case 1204: -#if 0 - ndbout_c("errCode: %d noOfRetries: %d -> retry", - errCode, transPtr.p->noOfRetries); -#endif - runTransaction(signal, transPtr); - return; - } - } - - transPtr.p->errorCode = errCode; - finishTransaction(signal, transPtr); -} - -void -DbUtil::finishTransaction(Signal* signal, TransactionPtr transPtr){ -#if 0 //def EVENT_DEBUG - ndbout_c("Transaction %x %x completed %s", - transPtr.p->transId[0], - transPtr.p->transId[1], - transPtr.p->errorCode == 0 ? "OK" : "FAILED"); -#endif - - /* - How to find the correct RS? Could we have multi-RS/transaction? - - Operation * opP = c_operationPool.getPtr(opI); - - ResultSetBuffer::DataBufferIterator rsit; - ndbrequire(opP->rs.first(rsit)); - ndbout << "F Result: " << rsit.data << endl; - - while (opP->rs.next(rsit)) { - ndbout << "R Result: " << rsit.data << endl; - } - */ - - switch(transPtr.p->gsn){ - case GSN_UTIL_SEQUENCE_REQ: - jam(); - reportSequence(signal, transPtr.p); - break; - case GSN_UTIL_EXECUTE_REQ: - if (transPtr.p->errorCode) { - UtilExecuteRef * ret = (UtilExecuteRef *)signal->getDataPtrSend(); - ret->senderData = transPtr.p->clientData; - ret->errorCode = UtilExecuteRef::TCError; - ret->TCErrorCode = transPtr.p->errorCode; - sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_REF, signal, - UtilExecuteRef::SignalLength, JBB); - } else { - struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections]; - UtilExecuteConf * ret = (UtilExecuteConf *)signal->getDataPtrSend(); - ret->senderData = transPtr.p->clientData; - if (getResultSet(signal, transPtr.p, sectionsPtr)) { -#if 0 //def EVENT_DEBUG - for (int j = 0; j < 2; j++) { - printf("Result set %u %u\n", j,sectionsPtr[j].sz); - for (int i=0; i < sectionsPtr[j].sz; i++) - printf("H'%.8x ", sectionsPtr[j].p[i]); - printf("\n"); - } -#endif - sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal, - UtilExecuteConf::SignalLength, JBB, - sectionsPtr, UtilExecuteReq::NoOfSections); - } else - sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal, - UtilExecuteConf::SignalLength, JBB); - } - break; - default: - ndbrequire(0); - break; - } - releaseTransaction(transPtr); -} - -void -DbUtil::execUTIL_LOCK_REQ(Signal * signal){ - jamEntry(); - UtilLockReq * req = (UtilLockReq*)signal->getDataPtr(); - const Uint32 lockId = req->lockId; - - LockQueuePtr lockQPtr; - if(!c_lockQueues.find(lockQPtr, lockId)){ - jam(); - sendLOCK_REF(signal, req, UtilLockRef::NoSuchLock); - return; - } - -// const Uint32 requestInfo = req->requestInfo; - const Uint32 senderNode = refToNode(req->senderRef); - if(senderNode != getOwnNodeId() && senderNode != 0){ - jam(); - sendLOCK_REF(signal, req, UtilLockRef::DistributedLockNotSupported); - return; - } - - LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, - lockQPtr.p->m_queue); - if(req->requestInfo & UtilLockReq::TryLock && !queue.isEmpty()){ - jam(); - sendLOCK_REF(signal, req, UtilLockRef::LockAlreadyHeld); - return; - } - - LockQueueElementPtr lockEPtr; - if(!c_lockElementPool.seize(lockEPtr)){ - jam(); - sendLOCK_REF(signal, req, UtilLockRef::OutOfLockRecords); - return; - } - - lockEPtr.p->m_senderRef = req->senderRef; - lockEPtr.p->m_senderData = req->senderData; - - if(queue.isEmpty()){ - jam(); - sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); - } - - queue.add(lockEPtr); -} - -void -DbUtil::execUTIL_UNLOCK_REQ(Signal* signal){ - jamEntry(); - - UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtr(); - const Uint32 lockId = req->lockId; - - LockQueuePtr lockQPtr; - if(!c_lockQueues.find(lockQPtr, lockId)){ - jam(); - sendUNLOCK_REF(signal, req, UtilUnlockRef::NoSuchLock); - return; - } - - LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, - lockQPtr.p->m_queue); - LockQueueElementPtr lockEPtr; - if(!queue.first(lockEPtr)){ - jam(); - sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner); - return; - } - - if(lockQPtr.p->m_lockKey != req->lockKey){ - jam(); - sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner); - return; - } - - sendUNLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); - queue.release(lockEPtr); - - if(queue.first(lockEPtr)){ - jam(); - sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); - return; - } -} - -void -DbUtil::sendLOCK_REF(Signal* signal, - const UtilLockReq * req, UtilLockRef::ErrorCode err){ - const Uint32 senderData = req->senderData; - const Uint32 senderRef = req->senderRef; - const Uint32 lockId = req->lockId; - - UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend(); - ref->senderData = senderData; - ref->senderRef = reference(); - ref->lockId = lockId; - ref->errorCode = err; - sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal, - UtilLockRef::SignalLength, JBB); -} - -void -DbUtil::sendLOCK_CONF(Signal* signal, - LockQueue * lockQP, - LockQueueElement * lockEP){ - const Uint32 senderData = lockEP->m_senderData; - const Uint32 senderRef = lockEP->m_senderRef; - const Uint32 lockId = lockQP->m_lockId; - const Uint32 lockKey = ++lockQP->m_lockKey; - - UtilLockConf * conf = (UtilLockConf*)signal->getDataPtrSend(); - conf->senderData = senderData; - conf->senderRef = reference(); - conf->lockId = lockId; - conf->lockKey = lockKey; - sendSignal(senderRef, GSN_UTIL_LOCK_CONF, signal, - UtilLockConf::SignalLength, JBB); -} - -void -DbUtil::sendUNLOCK_REF(Signal* signal, - const UtilUnlockReq* req, UtilUnlockRef::ErrorCode err){ - - const Uint32 senderData = req->senderData; - const Uint32 senderRef = req->senderRef; - const Uint32 lockId = req->lockId; - - UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtrSend(); - ref->senderData = senderData; - ref->senderRef = reference(); - ref->lockId = lockId; - ref->errorCode = err; - sendSignal(senderRef, GSN_UTIL_UNLOCK_REF, signal, - UtilUnlockRef::SignalLength, JBB); -} - -void -DbUtil::sendUNLOCK_CONF(Signal* signal, - LockQueue * lockQP, - LockQueueElement * lockEP){ - const Uint32 senderData = lockEP->m_senderData; - const Uint32 senderRef = lockEP->m_senderRef; - const Uint32 lockId = lockQP->m_lockId; - ++lockQP->m_lockKey; - - UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtrSend(); - conf->senderData = senderData; - conf->senderRef = reference(); - conf->lockId = lockId; - sendSignal(senderRef, GSN_UTIL_UNLOCK_CONF, signal, - UtilUnlockConf::SignalLength, JBB); -} - -void -DbUtil::execUTIL_CREATE_LOCK_REQ(Signal* signal){ - jamEntry(); - UtilCreateLockReq req = * (UtilCreateLockReq*)signal->getDataPtr(); - - UtilCreateLockRef::ErrorCode err = UtilCreateLockRef::OK; - - do { - LockQueuePtr lockQPtr; - if(c_lockQueues.find(lockQPtr, req.lockId)){ - jam(); - err = UtilCreateLockRef::LockIdAlreadyUsed; - break; - } - - if(req.lockType != UtilCreateLockReq::Mutex){ - jam(); - err = UtilCreateLockRef::UnsupportedLockType; - break; - } - - if(!c_lockQueues.seize(lockQPtr)){ - jam(); - err = UtilCreateLockRef::OutOfLockQueueRecords; - break; - } - - new (lockQPtr.p) LockQueue(req.lockId); - c_lockQueues.add(lockQPtr); - - UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtrSend(); - conf->senderData = req.senderData; - conf->senderRef = reference(); - conf->lockId = req.lockId; - - sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_CONF, signal, - UtilCreateLockConf::SignalLength, JBB); - return; - } while(false); - - UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtrSend(); - ref->senderData = req.senderData; - ref->senderRef = reference(); - ref->lockId = req.lockId; - ref->errorCode = err; - - sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_REF, signal, - UtilCreateLockRef::SignalLength, JBB); -} - -void -DbUtil::execUTIL_DESTORY_LOCK_REQ(Signal* signal){ - jamEntry(); - - UtilDestroyLockReq req = * (UtilDestroyLockReq*)signal->getDataPtr(); - UtilDestroyLockRef::ErrorCode err = UtilDestroyLockRef::OK; - do { - LockQueuePtr lockQPtr; - if(!c_lockQueues.find(lockQPtr, req.lockId)){ - jam(); - err = UtilDestroyLockRef::NoSuchLock; - break; - } - - LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, - lockQPtr.p->m_queue); - LockQueueElementPtr lockEPtr; - if(!queue.first(lockEPtr)){ - jam(); - err = UtilDestroyLockRef::NotLockOwner; - break; - } - - if(lockQPtr.p->m_lockKey != req.lockKey){ - jam(); - err = UtilDestroyLockRef::NotLockOwner; - break; - } - - /** - * OK - */ - - // Inform all in lock queue that queue has been destroyed - UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend(); - ref->lockId = req.lockId; - ref->errorCode = UtilLockRef::NoSuchLock; - ref->senderRef = reference(); - LockQueueElementPtr loopPtr = lockEPtr; - for(queue.next(loopPtr); !loopPtr.isNull(); queue.next(loopPtr)){ - jam(); - ref->senderData = loopPtr.p->m_senderData; - const Uint32 senderRef = loopPtr.p->m_senderRef; - sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal, - UtilLockRef::SignalLength, JBB); - } - queue.release(); - c_lockQueues.release(lockQPtr); - - // Send Destroy conf - UtilDestroyLockConf* conf=(UtilDestroyLockConf*)signal->getDataPtrSend(); - conf->senderData = req.senderData; - conf->senderRef = reference(); - conf->lockId = req.lockId; - sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_CONF, signal, - UtilDestroyLockConf::SignalLength, JBB); - return; - } while(false); - - UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtrSend(); - ref->senderData = req.senderData; - ref->senderRef = reference(); - ref->lockId = req.lockId; - ref->errorCode = err; - sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_REF, signal, - UtilDestroyLockRef::SignalLength, JBB); -} - -template class ArrayPool<DbUtil::Page32>; |