summaryrefslogtreecommitdiff
path: root/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp')
-rw-r--r--storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp2608
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>;