00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 00019 #include "DbUtil.hpp" 00020 00021 #include <ndb_version.h> 00022 00023 #include <signaldata/WaitGCP.hpp> 00024 #include <signaldata/KeyInfo.hpp> 00025 #include <signaldata/AttrInfo.hpp> 00026 #include <signaldata/TcKeyConf.hpp> 00027 #include <signaldata/TcKeyFailConf.hpp> 00028 #include <signaldata/GetTabInfo.hpp> 00029 #include <signaldata/DictTabInfo.hpp> 00030 00031 #include <signaldata/UtilSequence.hpp> 00032 #include <signaldata/UtilPrepare.hpp> 00033 #include <signaldata/UtilRelease.hpp> 00034 #include <signaldata/UtilExecute.hpp> 00035 #include <signaldata/UtilLock.hpp> 00036 00037 #include <SectionReader.hpp> 00038 #include <Interpreter.hpp> 00039 #include <AttributeHeader.hpp> 00040 00041 #include <NdbTick.h> 00042 00043 00044 /************************************************************************** 00045 * ------------------------------------------------------------------------ 00046 * MODULE: Startup 00047 * ------------------------------------------------------------------------ 00048 * 00049 * Constructors, startup, initializations 00050 **************************************************************************/ 00051 00052 DbUtil::DbUtil(Block_context& ctx) : 00053 SimulatedBlock(DBUTIL, ctx), 00054 c_runningPrepares(c_preparePool), 00055 c_seizingTransactions(c_transactionPool), 00056 c_runningTransactions(c_transactionPool), 00057 c_lockQueues(c_lockQueuePool) 00058 { 00059 BLOCK_CONSTRUCTOR(DbUtil); 00060 00061 // Add received signals 00062 addRecSignal(GSN_READ_CONFIG_REQ, &DbUtil::execREAD_CONFIG_REQ); 00063 addRecSignal(GSN_STTOR, &DbUtil::execSTTOR); 00064 addRecSignal(GSN_NDB_STTOR, &DbUtil::execNDB_STTOR); 00065 addRecSignal(GSN_DUMP_STATE_ORD, &DbUtil::execDUMP_STATE_ORD); 00066 addRecSignal(GSN_CONTINUEB, &DbUtil::execCONTINUEB); 00067 00068 //addRecSignal(GSN_TCSEIZEREF, &DbUtil::execTCSEIZEREF); 00069 addRecSignal(GSN_TCSEIZECONF, &DbUtil::execTCSEIZECONF); 00070 addRecSignal(GSN_TCKEYCONF, &DbUtil::execTCKEYCONF); 00071 addRecSignal(GSN_TCKEYREF, &DbUtil::execTCKEYREF); 00072 addRecSignal(GSN_TCROLLBACKREP, &DbUtil::execTCROLLBACKREP); 00073 00074 //addRecSignal(GSN_TCKEY_FAILCONF, &DbUtil::execTCKEY_FAILCONF); 00075 //addRecSignal(GSN_TCKEY_FAILREF, &DbUtil::execTCKEY_FAILREF); 00076 addRecSignal(GSN_TRANSID_AI, &DbUtil::execTRANSID_AI); 00077 00081 addRecSignal(GSN_UTIL_SEQUENCE_REQ, &DbUtil::execUTIL_SEQUENCE_REQ); 00082 // Debug 00083 addRecSignal(GSN_UTIL_SEQUENCE_REF, &DbUtil::execUTIL_SEQUENCE_REF); 00084 addRecSignal(GSN_UTIL_SEQUENCE_CONF, &DbUtil::execUTIL_SEQUENCE_CONF); 00085 00089 addRecSignal(GSN_UTIL_CREATE_LOCK_REQ, &DbUtil::execUTIL_CREATE_LOCK_REQ); 00090 addRecSignal(GSN_UTIL_DESTROY_LOCK_REQ, &DbUtil::execUTIL_DESTORY_LOCK_REQ); 00091 addRecSignal(GSN_UTIL_LOCK_REQ, &DbUtil::execUTIL_LOCK_REQ); 00092 addRecSignal(GSN_UTIL_UNLOCK_REQ, &DbUtil::execUTIL_UNLOCK_REQ); 00093 00097 addRecSignal(GSN_GET_TABINFOREF, &DbUtil::execGET_TABINFOREF); 00098 addRecSignal(GSN_GET_TABINFO_CONF, &DbUtil::execGET_TABINFO_CONF); 00099 00103 addRecSignal(GSN_UTIL_PREPARE_REQ, &DbUtil::execUTIL_PREPARE_REQ); 00104 addRecSignal(GSN_UTIL_PREPARE_CONF, &DbUtil::execUTIL_PREPARE_CONF); 00105 addRecSignal(GSN_UTIL_PREPARE_REF, &DbUtil::execUTIL_PREPARE_REF); 00106 00107 addRecSignal(GSN_UTIL_EXECUTE_REQ, &DbUtil::execUTIL_EXECUTE_REQ); 00108 addRecSignal(GSN_UTIL_EXECUTE_CONF, &DbUtil::execUTIL_EXECUTE_CONF); 00109 addRecSignal(GSN_UTIL_EXECUTE_REF, &DbUtil::execUTIL_EXECUTE_REF); 00110 00111 addRecSignal(GSN_UTIL_RELEASE_REQ, &DbUtil::execUTIL_RELEASE_REQ); 00112 addRecSignal(GSN_UTIL_RELEASE_CONF, &DbUtil::execUTIL_RELEASE_CONF); 00113 addRecSignal(GSN_UTIL_RELEASE_REF, &DbUtil::execUTIL_RELEASE_REF); 00114 } 00115 00116 DbUtil::~DbUtil() 00117 { 00118 } 00119 00120 BLOCK_FUNCTIONS(DbUtil) 00121 00122 void 00123 DbUtil::releasePrepare(PreparePtr prepPtr) { 00124 prepPtr.p->preparePages.release(); 00125 c_runningPrepares.release(prepPtr); // Automatic release in pool 00126 } 00127 00128 void 00129 DbUtil::releasePreparedOperation(PreparedOperationPtr prepOpPtr) { 00130 prepOpPtr.p->attrMapping.release(); 00131 prepOpPtr.p->attrInfo.release(); 00132 prepOpPtr.p->rsInfo.release(); 00133 prepOpPtr.p->pkBitmask.clear(); 00134 c_preparedOperationPool.release(prepOpPtr); // No list holding these structs 00135 } 00136 00137 void 00138 DbUtil::releaseTransaction(TransactionPtr transPtr){ 00139 transPtr.p->executePages.release(); 00140 OperationPtr opPtr; 00141 for(transPtr.p->operations.first(opPtr); opPtr.i != RNIL; 00142 transPtr.p->operations.next(opPtr)){ 00143 opPtr.p->attrInfo.release(); 00144 opPtr.p->keyInfo.release(); 00145 opPtr.p->rs.release(); 00146 if (opPtr.p->prepOp != 0 && opPtr.p->prepOp_i != RNIL) { 00147 if (opPtr.p->prepOp->releaseFlag) { 00148 PreparedOperationPtr prepOpPtr; 00149 prepOpPtr.i = opPtr.p->prepOp_i; 00150 prepOpPtr.p = opPtr.p->prepOp; 00151 releasePreparedOperation(prepOpPtr); 00152 } 00153 } 00154 } 00155 transPtr.p->operations.release(); 00156 c_runningTransactions.release(transPtr); 00157 } 00158 00159 void 00160 DbUtil::execREAD_CONFIG_REQ(Signal* signal) 00161 { 00162 jamEntry(); 00163 00164 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr(); 00165 00166 Uint32 ref = req->senderRef; 00167 Uint32 senderData = req->senderData; 00168 00169 const ndb_mgm_configuration_iterator * p = 00170 m_ctx.m_config.getOwnConfigIterator(); 00171 ndbrequire(p != 0); 00172 00173 c_pagePool.setSize(10); 00174 c_preparePool.setSize(1); // one parallel prepare at a time 00175 c_preparedOperationPool.setSize(5); // three hardcoded, two for test 00176 c_operationPool.setSize(64); // 64 parallel operations 00177 c_transactionPool.setSize(32); // 16 parallel transactions 00178 c_attrMappingPool.setSize(100); 00179 c_dataBufPool.setSize(6000); // 6000*11*4 = 264K > 8k+8k*16 = 256k 00180 { 00181 SLList<Prepare> tmp(c_preparePool); 00182 PreparePtr ptr; 00183 while(tmp.seize(ptr)) 00184 new (ptr.p) Prepare(c_pagePool); 00185 tmp.release(); 00186 } 00187 { 00188 SLList<Operation> tmp(c_operationPool); 00189 OperationPtr ptr; 00190 while(tmp.seize(ptr)) 00191 new (ptr.p) Operation(c_dataBufPool, c_dataBufPool, c_dataBufPool); 00192 tmp.release(); 00193 } 00194 { 00195 SLList<PreparedOperation> tmp(c_preparedOperationPool); 00196 PreparedOperationPtr ptr; 00197 while(tmp.seize(ptr)) 00198 new (ptr.p) PreparedOperation(c_attrMappingPool, 00199 c_dataBufPool, c_dataBufPool); 00200 tmp.release(); 00201 } 00202 { 00203 SLList<Transaction> tmp(c_transactionPool); 00204 TransactionPtr ptr; 00205 while(tmp.seize(ptr)) 00206 new (ptr.p) Transaction(c_pagePool, c_operationPool); 00207 tmp.release(); 00208 } 00209 00210 c_lockQueuePool.setSize(5); 00211 c_lockElementPool.setSize(5); 00212 c_lockQueues.setSize(8); 00213 00214 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); 00215 conf->senderRef = reference(); 00216 conf->senderData = senderData; 00217 sendSignal(ref, GSN_READ_CONFIG_CONF, signal, 00218 ReadConfigConf::SignalLength, JBB); 00219 } 00220 00221 void 00222 DbUtil::execSTTOR(Signal* signal) 00223 { 00224 jamEntry(); 00225 00226 const Uint32 startphase = signal->theData[1]; 00227 00228 if(startphase == 1){ 00229 c_transId[0] = (number() << 20) + (getOwnNodeId() << 8); 00230 c_transId[1] = 0; 00231 } 00232 00233 if(startphase == 6){ 00234 hardcodedPrepare(); 00235 connectTc(signal); 00236 } 00237 00238 signal->theData[0] = 0; 00239 signal->theData[3] = 1; 00240 signal->theData[4] = 6; 00241 signal->theData[5] = 255; 00242 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB); 00243 00244 return; 00245 } 00246 00247 void 00248 DbUtil::execNDB_STTOR(Signal* signal) 00249 { 00250 (void)signal; // Don't want compiler warning 00251 00252 jamEntry(); 00253 } 00254 00255 00256 /*************************** 00257 * Seize a number of TC records 00258 * to use for Util transactions 00259 */ 00260 00261 void 00262 DbUtil::connectTc(Signal* signal){ 00263 00264 TransactionPtr ptr; 00265 while(c_seizingTransactions.seize(ptr)){ 00266 signal->theData[0] = ptr.i << 1; // See TcCommitConf 00267 signal->theData[1] = reference(); 00268 sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB); 00269 } 00270 } 00271 00272 void 00273 DbUtil::execTCSEIZECONF(Signal* signal){ 00274 jamEntry(); 00275 00276 TransactionPtr ptr; 00277 ptr.i = signal->theData[0] >> 1; 00278 c_seizingTransactions.getPtr(ptr, signal->theData[0] >> 1); 00279 ptr.p->connectPtr = signal->theData[1]; 00280 00281 c_seizingTransactions.release(ptr); 00282 } 00283 00284 00285 /************************************************************************** 00286 * ------------------------------------------------------------------------ 00287 * MODULE: Misc 00288 * ------------------------------------------------------------------------ 00289 * 00290 * ContinueB, Dump 00291 **************************************************************************/ 00292 00293 void 00294 DbUtil::execCONTINUEB(Signal* signal){ 00295 jamEntry(); 00296 const Uint32 Tdata0 = signal->theData[0]; 00297 00298 switch(Tdata0){ 00299 default: 00300 ndbrequire(0); 00301 } 00302 } 00303 00304 void 00305 DbUtil::execDUMP_STATE_ORD(Signal* signal){ 00306 jamEntry(); 00307 00308 /**************************************************************************** 00309 * SEQUENCE SERVICE 00310 * 00311 * 200 : Simple test of Public Sequence Interface 00312 * ---------------------------------------------- 00313 * - Sends a SEQUENCE_REQ signal to Util (itself) 00314 */ 00315 const Uint32 tCase = signal->theData[0]; 00316 if(tCase == 200){ 00317 jam() 00318 ndbout << "--------------------------------------------------" << endl; 00319 UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend(); 00320 Uint32 seqId = 1; 00321 Uint32 reqTy = UtilSequenceReq::CurrVal; 00322 00323 if(signal->length() > 1) seqId = signal->theData[1]; 00324 if(signal->length() > 2) reqTy = signal->theData[2]; 00325 00326 req->senderData = 12; 00327 req->sequenceId = seqId; 00328 req->requestType = reqTy; 00329 00330 sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ, 00331 signal, UtilSequenceReq::SignalLength, JBB); 00332 } 00333 00334 /****************************************************************************/ 00335 /* // Obsolete tests, should be rewritten for long signals!! 00336 if(tCase == 210){ 00337 jam(); 00338 ndbout << "--------------------------------------------------" << endl; 00339 const Uint32 pageSizeInWords = 128; 00340 Uint32 propPage[pageSizeInWords]; 00341 LinearWriter w(&propPage[0], 128); 00342 w.first(); 00343 w.add(UtilPrepareReq::NoOfOperations, 1); 00344 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete); 00345 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); 00346 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 00347 Uint32 length = w.getWordsUsed(); 00348 ndbassert(length <= pageSizeInWords); 00349 00350 sendUtilPrepareReqSignals(signal, propPage, length); 00351 } 00352 if(tCase == 211){ 00353 jam(); 00354 ndbout << "--------------------------------------------------" << endl; 00355 const Uint32 pageSizeInWords = 128; 00356 Uint32 propPage[pageSizeInWords]; 00357 LinearWriter w(&propPage[0],128); 00358 w.first(); 00359 w.add(UtilPrepareReq::NoOfOperations, 1); 00360 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert); 00361 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); 00362 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 00363 w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1 00364 Uint32 length = w.getWordsUsed(); 00365 ndbassert(length <= pageSizeInWords); 00366 00367 sendUtilPrepareReqSignals(signal, propPage, length); 00368 } 00369 if(tCase == 212){ 00370 jam(); 00371 ndbout << "--------------------------------------------------" << endl; 00372 const Uint32 pageSizeInWords = 128; 00373 Uint32 propPage[pageSizeInWords]; 00374 LinearWriter w(&propPage[0],128); 00375 w.first(); 00376 w.add(UtilPrepareReq::NoOfOperations, 1); 00377 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update); 00378 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); 00379 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 00380 w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1 00381 Uint32 length = w.getWordsUsed(); 00382 ndbassert(length <= pageSizeInWords); 00383 00384 sendUtilPrepareReqSignals(signal, propPage, length); 00385 } 00386 if(tCase == 213){ 00387 jam(); 00388 ndbout << "--------------------------------------------------" << endl; 00389 const Uint32 pageSizeInWords = 128; 00390 Uint32 propPage[pageSizeInWords]; 00391 LinearWriter w(&propPage[0],128); 00392 w.first(); 00393 w.add(UtilPrepareReq::NoOfOperations, 1); 00394 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read); 00395 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0"); 00396 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0 00397 Uint32 length = w.getWordsUsed(); 00398 ndbassert(length <= pageSizeInWords); 00399 00400 sendUtilPrepareReqSignals(signal, propPage, length); 00401 } 00402 if(tCase == 214){ 00403 jam(); 00404 ndbout << "--------------------------------------------------" << endl; 00405 const Uint32 pageSizeInWords = 128; 00406 Uint32 propPage[pageSizeInWords]; 00407 LinearWriter w(&propPage[0], 128); 00408 w.first(); 00409 w.add(UtilPrepareReq::NoOfOperations, 1); 00410 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete); 00411 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 00412 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 00413 Uint32 length = w.getWordsUsed(); 00414 ndbassert(length <= pageSizeInWords); 00415 00416 sendUtilPrepareReqSignals(signal, propPage, length); 00417 } 00418 if(tCase == 215){ 00419 jam(); 00420 ndbout << "--------------------------------------------------" << endl; 00421 const Uint32 pageSizeInWords = 128; 00422 Uint32 propPage[pageSizeInWords]; 00423 LinearWriter w(&propPage[0],128); 00424 w.first(); 00425 w.add(UtilPrepareReq::NoOfOperations, 1); 00426 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert); 00427 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 00428 w.add(UtilPrepareReq::AttributeId, (unsigned int)0); // SYSKEY_0 00429 w.add(UtilPrepareReq::AttributeId, 1); // NEXTID 00430 Uint32 length = w.getWordsUsed(); 00431 ndbassert(length <= pageSizeInWords); 00432 00433 sendUtilPrepareReqSignals(signal, propPage, length); 00434 } 00435 if(tCase == 216){ 00436 jam(); 00437 ndbout << "--------------------------------------------------" << endl; 00438 const Uint32 pageSizeInWords = 128; 00439 Uint32 propPage[pageSizeInWords]; 00440 LinearWriter w(&propPage[0],128); 00441 w.first(); 00442 w.add(UtilPrepareReq::NoOfOperations, 1); 00443 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update); 00444 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 00445 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 00446 w.add(UtilPrepareReq::AttributeId, 1); // NEXTID 00447 Uint32 length = w.getWordsUsed(); 00448 ndbassert(length <= pageSizeInWords); 00449 00450 sendUtilPrepareReqSignals(signal, propPage, length); 00451 } 00452 if(tCase == 217){ 00453 jam(); 00454 ndbout << "--------------------------------------------------" << endl; 00455 const Uint32 pageSizeInWords = 128; 00456 Uint32 propPage[pageSizeInWords]; 00457 LinearWriter w(&propPage[0],128); 00458 w.first(); 00459 w.add(UtilPrepareReq::NoOfOperations, 1); 00460 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read); 00461 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0 00462 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0 00463 Uint32 length = w.getWordsUsed(); 00464 ndbassert(length <= pageSizeInWords); 00465 00466 sendUtilPrepareReqSignals(signal, propPage, length); 00467 } 00468 */ 00469 /****************************************************************************/ 00470 /* // Obsolete tests, should be rewritten for long signals!! 00471 if(tCase == 220){ 00472 jam(); 00473 ndbout << "--------------------------------------------------" << endl; 00474 Uint32 prepI = signal->theData[1]; 00475 Uint32 length = signal->theData[2]; 00476 Uint32 attributeValue0 = signal->theData[3]; 00477 Uint32 attributeValue1a = signal->theData[4]; 00478 Uint32 attributeValue1b = signal->theData[5]; 00479 ndbrequire(prepI != 0); 00480 00481 UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtrSend(); 00482 00483 req->senderData = 221; 00484 req->prepareId = prepI; 00485 req->totalDataLen = length; // Including headers 00486 req->offset = 0; 00487 00488 AttributeHeader::init(&req->attrData[0], 0, 1); // AttrNo 0, DataSize 00489 req->attrData[1] = attributeValue0; // AttrValue 00490 AttributeHeader::init(&req->attrData[2], 1, 2); // AttrNo 1, DataSize 00491 req->attrData[3] = attributeValue1a; // AttrValue 00492 req->attrData[4] = attributeValue1b; // AttrValue 00493 00494 printUTIL_EXECUTE_REQ(stdout, signal->getDataPtrSend(), 3 + 5,0); 00495 sendSignal(DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal, 3 + 5, JBB); 00496 } 00497 */ 00498 /**************************************************************************** 00499 * 230 : PRINT STATE 00500 */ 00501 #ifdef ARRAY_GUARD 00502 if(tCase == 230){ 00503 jam(); 00504 00505 ndbout << "--------------------------------------------------" << endl; 00506 if (signal->length() <= 1) { 00507 ndbout << "Usage: DUMP 230 <recordType> <recordNo>" << endl 00508 << "[1] Print Prepare (running) records" << endl 00509 << "[2] Print PreparedOperation records" << endl 00510 << "[3] Print Transaction records" << endl 00511 << "[4] Print Operation records" << endl 00512 << "Ex. \"dump 230 1 2\" prints Prepare record no 2." << endl 00513 << endl 00514 << "210 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0" << endl 00515 << "211 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID" << endl 00516 << "212 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID" << endl 00517 << "213 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0" << endl 00518 << "214 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0 using id" << endl 00519 << "215 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID using id" << endl 00520 << "216 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID using id" << endl 00521 << "217 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0 using id" << endl 00522 << "220 : EXECUTE_REQ <PrepId> <Len> <Val1> <Val2a> <Val2b>" <<endl 00523 << "299 : Crash system (using ndbrequire(0))" 00524 << endl 00525 << "Ex. \"dump 220 3 5 1 0 17 \" prints Prepare record no 2." 00526 << endl; 00527 return; 00528 } 00529 00530 switch (signal->theData[1]) { 00531 case 1: 00532 // ** Print a specific record ** 00533 if (signal->length() >= 3) { 00534 PreparePtr prepPtr; 00535 if (!c_preparePool.isSeized(signal->theData[2])) { 00536 ndbout << "Prepare Id: " << signal->theData[2] 00537 << " (Not seized!)" << endl; 00538 } else { 00539 c_preparePool.getPtr(prepPtr, signal->theData[2]); 00540 prepPtr.p->print(); 00541 } 00542 return; 00543 } 00544 00545 // ** Print all records ** 00546 PreparePtr prepPtr; 00547 if (!c_runningPrepares.first(prepPtr)) { 00548 ndbout << "No Prepare records exist" << endl; 00549 return; 00550 } 00551 00552 while (!prepPtr.isNull()) { 00553 prepPtr.p->print(); 00554 c_runningPrepares.next(prepPtr); 00555 } 00556 return; 00557 00558 case 2: 00559 // ** Print a specific record ** 00560 if (signal->length() >= 3) { 00561 if (!c_preparedOperationPool.isSeized(signal->theData[2])) { 00562 ndbout << "PreparedOperation Id: " << signal->theData[2] 00563 << " (Not seized!)" << endl; 00564 return; 00565 } 00566 ndbout << "PreparedOperation Id: " << signal->theData[2] << endl; 00567 PreparedOperationPtr prepOpPtr; 00568 c_preparedOperationPool.getPtr(prepOpPtr, signal->theData[2]); 00569 prepOpPtr.p->print(); 00570 return; 00571 } 00572 00573 // ** Print all records ** 00574 #if 0 // not implemented 00575 PreparedOperationPtr prepOpPtr; 00576 if (!c_runningPreparedOperations.first(prepOpPtr)) { 00577 ndbout << "No PreparedOperations exist" << endl; 00578 return; 00579 } 00580 while (!prepOpPtr.isNull()) { 00581 ndbout << "[-PreparedOperation no " << prepOpPtr.i << ":"; 00582 prepOpPtr.p->print(); 00583 ndbout << "]"; 00584 c_runningPreparedOperations.next(prepOpPtr); 00585 } 00586 #endif 00587 return; 00588 00589 case 3: 00590 // ** Print a specific record ** 00591 if (signal->length() >= 3) { 00592 ndbout << "Print specific record not implemented." << endl; 00593 return; 00594 } 00595 00596 // ** Print all records ** 00597 ndbout << "Print all records not implemented, specify an Id." << endl; 00598 return; 00599 00600 case 4: 00601 ndbout << "Not implemented" << endl; 00602 return; 00603 00604 default: 00605 ndbout << "Unknown input (try without any data)" << endl; 00606 return; 00607 } 00608 } 00609 #endif 00610 if(tCase == 240 && signal->getLength() == 2){ 00611 MutexManager::ActiveMutexPtr ptr; 00612 ndbrequire(c_mutexMgr.seize(ptr)); 00613 ptr.p->m_mutexId = signal->theData[1]; 00614 Callback c = { safe_cast(&DbUtil::mutex_created), ptr.i }; 00615 ptr.p->m_callback = c; 00616 c_mutexMgr.create(signal, ptr); 00617 ndbout_c("c_mutexMgr.create ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); 00618 } 00619 00620 if(tCase == 241 && signal->getLength() == 2){ 00621 MutexManager::ActiveMutexPtr ptr; 00622 ndbrequire(c_mutexMgr.seize(ptr)); 00623 ptr.p->m_mutexId = signal->theData[1]; 00624 Callback c = { safe_cast(&DbUtil::mutex_locked), ptr.i }; 00625 ptr.p->m_callback = c; 00626 c_mutexMgr.lock(signal, ptr); 00627 ndbout_c("c_mutexMgr.lock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); 00628 } 00629 00630 if(tCase == 242 && signal->getLength() == 2){ 00631 MutexManager::ActiveMutexPtr ptr; 00632 ptr.i = signal->theData[1]; 00633 c_mutexMgr.getPtr(ptr); 00634 Callback c = { safe_cast(&DbUtil::mutex_unlocked), ptr.i }; 00635 ptr.p->m_callback = c; 00636 c_mutexMgr.unlock(signal, ptr); 00637 ndbout_c("c_mutexMgr.unlock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId); 00638 } 00639 00640 if(tCase == 243 && signal->getLength() == 3){ 00641 MutexManager::ActiveMutexPtr ptr; 00642 ndbrequire(c_mutexMgr.seize(ptr)); 00643 ptr.p->m_mutexId = signal->theData[1]; 00644 ptr.p->m_mutexKey = signal->theData[2]; 00645 Callback c = { safe_cast(&DbUtil::mutex_destroyed), ptr.i }; 00646 ptr.p->m_callback = c; 00647 c_mutexMgr.destroy(signal, ptr); 00648 ndbout_c("c_mutexMgr.destroy ptrI=%d mutexId=%d key=%d", 00649 ptr.i, ptr.p->m_mutexId, ptr.p->m_mutexKey); 00650 } 00651 } 00652 00653 void 00654 DbUtil::mutex_created(Signal* signal, Uint32 ptrI, Uint32 retVal){ 00655 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; 00656 c_mutexMgr.getPtr(ptr); 00657 ndbout_c("mutex_created - mutexId=%d, retVal=%d", 00658 ptr.p->m_mutexId, retVal); 00659 c_mutexMgr.release(ptrI); 00660 } 00661 00662 void 00663 DbUtil::mutex_destroyed(Signal* signal, Uint32 ptrI, Uint32 retVal){ 00664 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; 00665 c_mutexMgr.getPtr(ptr); 00666 ndbout_c("mutex_destroyed - mutexId=%d, retVal=%d", 00667 ptr.p->m_mutexId, retVal); 00668 c_mutexMgr.release(ptrI); 00669 } 00670 00671 void 00672 DbUtil::mutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){ 00673 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; 00674 c_mutexMgr.getPtr(ptr); 00675 ndbout_c("mutex_locked - mutexId=%d, retVal=%d key=%d ptrI=%d", 00676 ptr.p->m_mutexId, retVal, ptr.p->m_mutexKey, ptrI); 00677 if(retVal) 00678 c_mutexMgr.release(ptrI); 00679 } 00680 00681 void 00682 DbUtil::mutex_unlocked(Signal* signal, Uint32 ptrI, Uint32 retVal){ 00683 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI; 00684 c_mutexMgr.getPtr(ptr); 00685 ndbout_c("mutex_unlocked - mutexId=%d, retVal=%d", 00686 ptr.p->m_mutexId, retVal); 00687 if(!retVal) 00688 c_mutexMgr.release(ptrI); 00689 } 00690 00691 void 00692 DbUtil::execUTIL_SEQUENCE_REF(Signal* signal){ 00693 jamEntry(); 00694 ndbout << "UTIL_SEQUENCE_REF" << endl; 00695 printUTIL_SEQUENCE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); 00696 } 00697 00698 void 00699 DbUtil::execUTIL_SEQUENCE_CONF(Signal* signal){ 00700 jamEntry(); 00701 ndbout << "UTIL_SEQUENCE_CONF" << endl; 00702 printUTIL_SEQUENCE_CONF(stdout, signal->getDataPtrSend(), signal->length(),0); 00703 } 00704 00705 void 00706 DbUtil::execUTIL_PREPARE_CONF(Signal* signal){ 00707 jamEntry(); 00708 ndbout << "UTIL_PREPARE_CONF" << endl; 00709 printUTIL_PREPARE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0); 00710 } 00711 00712 void 00713 DbUtil::execUTIL_PREPARE_REF(Signal* signal){ 00714 jamEntry(); 00715 ndbout << "UTIL_PREPARE_REF" << endl; 00716 printUTIL_PREPARE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); 00717 } 00718 00719 void 00720 DbUtil::execUTIL_EXECUTE_CONF(Signal* signal) { 00721 jamEntry(); 00722 ndbout << "UTIL_EXECUTE_CONF" << endl; 00723 printUTIL_EXECUTE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0); 00724 } 00725 00726 void 00727 DbUtil::execUTIL_EXECUTE_REF(Signal* signal) { 00728 jamEntry(); 00729 00730 ndbout << "UTIL_EXECUTE_REF" << endl; 00731 printUTIL_EXECUTE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0); 00732 } 00733 00734 void 00735 DbUtil::execUTIL_RELEASE_CONF(Signal* signal) { 00736 jamEntry(); 00737 ndbout << "UTIL_RELEASE_CONF" << endl; 00738 } 00739 00740 void 00741 DbUtil::execUTIL_RELEASE_REF(Signal* signal) { 00742 jamEntry(); 00743 00744 ndbout << "UTIL_RELEASE_REF" << endl; 00745 } 00746 00747 void 00748 DbUtil::sendUtilPrepareRef(Signal* signal, UtilPrepareRef::ErrorCode error, 00749 Uint32 recipient, Uint32 senderData){ 00750 UtilPrepareRef * ref = (UtilPrepareRef *)signal->getDataPtrSend(); 00751 ref->errorCode = error; 00752 ref->senderData = senderData; 00753 00754 sendSignal(recipient, GSN_UTIL_PREPARE_REF, signal, 00755 UtilPrepareRef::SignalLength, JBB); 00756 } 00757 00758 void 00759 DbUtil::sendUtilExecuteRef(Signal* signal, UtilExecuteRef::ErrorCode error, 00760 Uint32 TCerror, Uint32 recipient, Uint32 senderData){ 00761 00762 UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend(); 00763 ref->senderData = senderData; 00764 ref->errorCode = error; 00765 ref->TCErrorCode = TCerror; 00766 00767 sendSignal(recipient, GSN_UTIL_EXECUTE_REF, signal, 00768 UtilPrepareRef::SignalLength, JBB); 00769 } 00770 00771 00772 /************************************************************************** 00773 * ------------------------------------------------------------------------ 00774 * MODULE: Prepare service 00775 * ------------------------------------------------------------------------ 00776 * 00777 * Prepares a transaction by storing info in some structs 00778 **************************************************************************/ 00779 00780 void 00781 DbUtil::execUTIL_PREPARE_REQ(Signal* signal) 00782 { 00783 jamEntry(); 00784 00785 /**************** 00786 * Decode Signal 00787 ****************/ 00788 UtilPrepareReq * req = (UtilPrepareReq *)signal->getDataPtr(); 00789 const Uint32 senderRef = req->senderRef; 00790 const Uint32 senderData = req->senderData; 00791 00792 if(signal->getNoOfSections() == 0) { 00793 // Missing prepare data 00794 jam(); 00795 releaseSections(signal); 00796 sendUtilPrepareRef(signal, UtilPrepareRef::MISSING_PROPERTIES_SECTION, 00797 senderRef, senderData); 00798 return; 00799 } 00800 00801 PreparePtr prepPtr; 00802 SegmentedSectionPtr ptr; 00803 00804 jam(); 00805 if(!c_runningPrepares.seize(prepPtr)) { 00806 jam(); 00807 releaseSections(signal); 00808 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR, 00809 senderRef, senderData); 00810 return; 00811 }; 00812 signal->getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION); 00813 const Uint32 noPages = (ptr.sz + sizeof(Page32)) / sizeof(Page32); 00814 ndbassert(noPages > 0); 00815 if (!prepPtr.p->preparePages.seize(noPages)) { 00816 jam(); 00817 releaseSections(signal); 00818 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR, 00819 senderRef, senderData); 00820 c_preparePool.release(prepPtr); 00821 return; 00822 } 00823 // Save SimpleProperties 00824 Uint32* target = &prepPtr.p->preparePages.getPtr(0)->data[0]; 00825 copy(target, ptr); 00826 prepPtr.p->prepDataLen = ptr.sz; 00827 // Release long signal sections 00828 releaseSections(signal); 00829 // Check table properties with DICT 00830 SimplePropertiesSectionReader reader(ptr, getSectionSegmentPool()); 00831 prepPtr.p->clientRef = senderRef; 00832 prepPtr.p->clientData = senderData; 00833 // Release long signal sections 00834 releaseSections(signal); 00835 readPrepareProps(signal, &reader, prepPtr.i); 00836 } 00837 00838 void DbUtil::readPrepareProps(Signal* signal, 00839 SimpleProperties::Reader* reader, 00840 Uint32 senderData) 00841 { 00842 jam(); 00843 #if 0 00844 printf("DbUtil::readPrepareProps: Received SimpleProperties:\n"); 00845 reader->printAll(ndbout); 00846 #endif 00847 ndbrequire(reader->first()); 00848 ndbrequire(reader->getKey() == UtilPrepareReq::NoOfOperations); 00849 ndbrequire(reader->getUint32() == 1); // Only one op/trans implemented 00850 00851 ndbrequire(reader->next()); 00852 ndbrequire(reader->getKey() == UtilPrepareReq::OperationType); 00853 00854 ndbrequire(reader->next()); 00855 UtilPrepareReq::KeyValue tableKey = 00856 (UtilPrepareReq::KeyValue) reader->getKey(); 00857 ndbrequire((tableKey == UtilPrepareReq::TableName) || 00858 (tableKey == UtilPrepareReq::TableId)); 00859 00860 /************************ 00861 * Ask Dict for metadata 00862 ************************/ 00863 { 00864 GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend(); 00865 req->senderRef = reference(); 00866 req->senderData = senderData; 00867 if (tableKey == UtilPrepareReq::TableName) { 00868 jam(); 00869 char tableName[MAX_TAB_NAME_SIZE]; 00870 req->requestType = GetTabInfoReq::RequestByName | 00871 GetTabInfoReq::LongSignalConf; 00872 00873 req->tableNameLen = reader->getValueLen(); // Including trailing \0 00874 00875 /******************************************** 00876 * Code signal data and send signals to DICT 00877 ********************************************/ 00878 00879 ndbrequire(req->tableNameLen < MAX_TAB_NAME_SIZE); 00880 reader->getString((char*)tableName); 00881 LinearSectionPtr ptr[1]; 00882 ptr[0].p = (Uint32*)tableName; 00883 ptr[0].sz = req->tableNameLen; 00884 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, 00885 GetTabInfoReq::SignalLength, JBB, ptr,1); 00886 00887 } 00888 else { // (tableKey == UtilPrepareReq::TableId) 00889 jam(); 00890 req->requestType = GetTabInfoReq::RequestById | 00891 GetTabInfoReq::LongSignalConf; 00892 req->tableId = reader->getUint32(); 00893 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, 00894 GetTabInfoReq::SignalLength, JBB); 00895 } 00896 00897 } 00898 } 00899 00905 void 00906 DbUtil::execGET_TABINFO_CONF(Signal* signal){ 00907 jamEntry(); 00908 00909 if(!assembleFragments(signal)){ 00910 jam(); 00911 return; 00912 } 00913 00914 /**************** 00915 * Decode signal 00916 ****************/ 00917 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr(); 00918 const Uint32 prepI = conf->senderData; 00919 const Uint32 totalLen = conf->totalLen; 00920 00921 SegmentedSectionPtr dictTabInfoPtr; 00922 signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO); 00923 ndbrequire(dictTabInfoPtr.sz == totalLen); 00924 00925 PreparePtr prepPtr; 00926 c_runningPrepares.getPtr(prepPtr, prepI); 00927 prepareOperation(signal, prepPtr); 00928 } 00929 00930 void 00931 DbUtil::execGET_TABINFOREF(Signal* signal){ 00932 jamEntry(); 00933 00934 GetTabInfoRef * ref = (GetTabInfoRef *)signal->getDataPtr(); 00935 Uint32 prepI = ref->senderData; 00936 #define EVENT_DEBUG 00937 #if 0 //def EVENT_DEBUG 00938 ndbout << "Signal GET_TABINFOREF received." << endl; 00939 ndbout << "Error Code: " << ref->errorCode << endl; 00940 00941 switch (ref->errorCode) { 00942 case GetTabInfoRef::InvalidTableId: 00943 ndbout << " Msg: Invalid table id" << endl; 00944 break; 00945 case GetTabInfoRef::TableNotDefined: 00946 ndbout << " Msg: Table not defined" << endl; 00947 break; 00948 case GetTabInfoRef::TableNameToLong: 00949 ndbout << " Msg: Table node too long" << endl; 00950 break; 00951 default: 00952 ndbout << " Msg: Unknown error returned from Dict" << endl; 00953 break; 00954 } 00955 #endif 00956 00957 PreparePtr prepPtr; 00958 c_runningPrepares.getPtr(prepPtr, prepI); 00959 00960 sendUtilPrepareRef(signal, UtilPrepareRef::DICT_TAB_INFO_ERROR, 00961 prepPtr.p->clientRef, prepPtr.p->clientData); 00962 00963 releasePrepare(prepPtr); 00964 } 00965 00966 00967 /****************************************************************************** 00968 * Prepare Operation 00969 * 00970 * Using a prepare record, prepare an operation (i.e. create PreparedOperation). 00971 * Info from both Pepare request (PreparePages) and DictTabInfo is used. 00972 * 00973 * Algorithm: 00974 * -# Seize AttrbuteMapping 00975 * - Lookup in preparePages how many attributes should be prepared 00976 * - Seize AttributeMapping 00977 * -# For each attributes in preparePages 00978 * - Lookup id and isPK in dictInfoPages 00979 * - Store "no -> (AttributeId, Position)" in AttributeMapping 00980 * -# For each map in AttributeMapping 00981 * - if (isPK) then assign offset 00982 ******************************************************************************/ 00983 void 00984 DbUtil::prepareOperation(Signal* signal, PreparePtr prepPtr) 00985 { 00986 jam(); 00987 00988 /******************************************* 00989 * Seize and store PreparedOperation struct 00990 *******************************************/ 00991 PreparedOperationPtr prepOpPtr; 00992 if(!c_preparedOperationPool.seize(prepOpPtr)) { 00993 jam(); 00994 releaseSections(signal); 00995 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR, 00996 prepPtr.p->clientRef, prepPtr.p->clientData); 00997 releasePrepare(prepPtr); 00998 return; 00999 } 01000 prepPtr.p->prepOpPtr = prepOpPtr; 01001 01002 /******************** 01003 * Read request info 01004 ********************/ 01005 SimplePropertiesLinearReader prepPagesReader(&prepPtr.p->preparePages.getPtr(0)->data[0], 01006 prepPtr.p->prepDataLen); 01007 01008 ndbrequire(prepPagesReader.first()); 01009 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::NoOfOperations); 01010 const Uint32 noOfOperations = prepPagesReader.getUint32(); 01011 ndbrequire(noOfOperations == 1); 01012 01013 ndbrequire(prepPagesReader.next()); 01014 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::OperationType); 01015 const Uint32 operationType = prepPagesReader.getUint32(); 01016 01017 ndbrequire(prepPagesReader.next()); 01018 01019 char tableName[MAX_TAB_NAME_SIZE]; 01020 Uint32 tableId; 01021 UtilPrepareReq::KeyValue tableKey = 01022 (UtilPrepareReq::KeyValue) prepPagesReader.getKey(); 01023 if (tableKey == UtilPrepareReq::TableId) { 01024 jam(); 01025 tableId = prepPagesReader.getUint32(); 01026 } 01027 else { 01028 jam(); 01029 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::TableName); 01030 ndbrequire(prepPagesReader.getValueLen() <= MAX_TAB_NAME_SIZE); 01031 prepPagesReader.getString(tableName); 01032 } 01033 /****************************************************************** 01034 * Seize AttributeMapping (by counting no of attribs in prepPages) 01035 ******************************************************************/ 01036 Uint32 noOfAttributes = 0; // No of attributes in PreparePages (used later) 01037 while(prepPagesReader.next()) { 01038 if (tableKey == UtilPrepareReq::TableName) { 01039 jam(); 01040 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeName); 01041 } else { 01042 jam(); 01043 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeId); 01044 } 01045 noOfAttributes++; 01046 } 01047 ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.seize(noOfAttributes)); 01048 if (operationType == UtilPrepareReq::Read) { 01049 ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.seize(noOfAttributes)); 01050 } 01051 /*************************************** 01052 * For each attribute name, lookup info 01053 ***************************************/ 01054 // Goto start of attribute names 01055 ndbrequire(prepPagesReader.first() && prepPagesReader.next() && 01056 prepPagesReader.next()); 01057 01058 DictTabInfo::Table tableDesc; tableDesc.init(); 01059 AttrMappingBuffer::DataBufferIterator attrMappingIt; 01060 ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.first(attrMappingIt)); 01061 01062 ResultSetBuffer::DataBufferIterator rsInfoIt; 01063 if (operationType == UtilPrepareReq::Read) { 01064 ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.first(rsInfoIt)); 01065 } 01066 01067 Uint32 noOfPKAttribsStored = 0; 01068 Uint32 noOfNonPKAttribsStored = 0; 01069 Uint32 attrLength = 0; 01070 Uint32 pkAttrLength = 0; 01071 char attrNameRequested[MAX_ATTR_NAME_SIZE]; 01072 Uint32 attrIdRequested; 01073 01074 while(prepPagesReader.next()) { 01075 UtilPrepareReq::KeyValue attributeKey = 01076 (UtilPrepareReq::KeyValue) prepPagesReader.getKey(); 01077 01078 ndbrequire((attributeKey == UtilPrepareReq::AttributeName) || 01079 (attributeKey == UtilPrepareReq::AttributeId)); 01080 if (attributeKey == UtilPrepareReq::AttributeName) { 01081 jam(); 01082 ndbrequire(prepPagesReader.getValueLen() <= MAX_ATTR_NAME_SIZE); 01083 01084 prepPagesReader.getString(attrNameRequested); 01085 attrIdRequested= ~0u; 01086 } else { 01087 jam(); 01088 attrIdRequested = prepPagesReader.getUint32(); 01089 } 01090 /***************************************** 01091 * Copy DictTabInfo into tableDesc struct 01092 *****************************************/ 01093 01094 SegmentedSectionPtr ptr; 01095 signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO); 01096 SimplePropertiesSectionReader dictInfoReader(ptr, getSectionSegmentPool()); 01097 01098 SimpleProperties::UnpackStatus unpackStatus; 01099 unpackStatus = SimpleProperties::unpack(dictInfoReader, &tableDesc, 01100 DictTabInfo::TableMapping, 01101 DictTabInfo::TableMappingSize, 01102 true, true); 01103 ndbrequire(unpackStatus == SimpleProperties::Break); 01104 01105 /************************ 01106 * Lookup in DictTabInfo 01107 ************************/ 01108 DictTabInfo::Attribute attrDesc; attrDesc.init(); 01109 char attrName[MAX_ATTR_NAME_SIZE]; 01110 Uint32 attrId= ~(Uint32)0; 01111 bool attributeFound = false; 01112 Uint32 noOfKeysFound = 0; // # PK attrs found before attr in DICTdata 01113 Uint32 noOfNonKeysFound = 0; // # nonPK attrs found before attr in DICTdata 01114 for (Uint32 i=0; i<tableDesc.NoOfAttributes; i++) { 01115 if (tableKey == UtilPrepareReq::TableName) { 01116 jam(); 01117 ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeName); 01118 ndbrequire(dictInfoReader.getValueLen() <= MAX_ATTR_NAME_SIZE); 01119 dictInfoReader.getString(attrName); 01120 attrId= ~(Uint32)0; // attrId not used 01121 } else { // (tableKey == UtilPrepareReq::TableId) 01122 jam(); 01123 dictInfoReader.next(); // Skip name 01124 ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeId); 01125 attrId = dictInfoReader.getUint32(); 01126 attrName[0]= '\0'; // attrName not used 01127 } 01128 unpackStatus = SimpleProperties::unpack(dictInfoReader, &attrDesc, 01129 DictTabInfo::AttributeMapping, 01130 DictTabInfo::AttributeMappingSize, 01131 true, true); 01132 ndbrequire(unpackStatus == SimpleProperties::Break); 01133 //attrDesc.print(stdout); 01134 01135 if (attrDesc.AttributeKeyFlag) { jam(); noOfKeysFound++; } 01136 else { jam(); noOfNonKeysFound++; } 01137 if (attributeKey == UtilPrepareReq::AttributeName) { 01138 if (strcmp(attrName, attrNameRequested) == 0) { 01139 attributeFound = true; 01140 break; 01141 } 01142 } 01143 else // (attributeKey == UtilPrepareReq::AttributeId) 01144 if (attrId == attrIdRequested) { 01145 attributeFound = true; 01146 break; 01147 } 01148 01149 // Move to next attribute 01150 ndbassert(dictInfoReader.getKey() == DictTabInfo::AttributeEnd); 01151 dictInfoReader.next(); 01152 } 01153 01154 /********************** 01155 * Attribute not found 01156 **********************/ 01157 if (!attributeFound) { 01158 jam(); 01159 releaseSections(signal); 01160 sendUtilPrepareRef(signal, 01161 UtilPrepareRef::DICT_TAB_INFO_ERROR, 01162 prepPtr.p->clientRef, prepPtr.p->clientData); 01163 infoEvent("UTIL: Unknown attribute requested: %s in table: %s", 01164 attrNameRequested, tableName); 01165 releasePreparedOperation(prepOpPtr); 01166 releasePrepare(prepPtr); 01167 return; 01168 } 01169 01170 /************************************************************** 01171 * Attribute found - store in mapping (AttributeId, Position) 01172 **************************************************************/ 01173 AttributeHeader & attrMap = 01174 AttributeHeader::init(attrMappingIt.data, 01175 attrDesc.AttributeId, // 1. Store AttrId 01176 0); 01177 01178 if (attrDesc.AttributeKeyFlag) { 01179 // ** Attribute belongs to PK ** 01180 prepOpPtr.p->pkBitmask.set(attrDesc.AttributeId); 01181 attrMap.setDataSize(noOfKeysFound - 1); // 2. Store Position 01182 noOfPKAttribsStored++; 01183 } else { 01184 attrMap.setDataSize(0x3fff); // 2. Store Position (fake) 01185 noOfNonPKAttribsStored++; 01186 01187 /*********************************************************** 01188 * Error: Read nonPK Attr before all PK attr have been read 01189 ***********************************************************/ 01190 if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) { 01191 jam(); 01192 releaseSections(signal); 01193 sendUtilPrepareRef(signal, 01194 UtilPrepareRef::DICT_TAB_INFO_ERROR, 01195 prepPtr.p->clientRef, prepPtr.p->clientData); 01196 infoEvent("UTIL: Non-PK attr not allowed before " 01197 "all PK attrs have been defined, table: %s", 01198 tableName); 01199 releasePreparedOperation(prepOpPtr); 01200 releasePrepare(prepPtr); 01201 return; 01202 } 01203 } 01204 #if 0 01205 ndbout << "BEFORE: attrLength: " << attrLength << endl; 01206 #endif 01207 { 01208 int len = 0; 01209 switch (attrDesc.AttributeSize) { 01210 case DictTabInfo::an8Bit: 01211 len = (attrDesc.AttributeArraySize + 3)/ 4; 01212 break; 01213 case DictTabInfo::a16Bit: 01214 len = (attrDesc.AttributeArraySize + 1) / 2; 01215 break; 01216 case DictTabInfo::a32Bit: 01217 len = attrDesc.AttributeArraySize; 01218 break; 01219 case DictTabInfo::a64Bit: 01220 len = attrDesc.AttributeArraySize * 2; 01221 break; 01222 case DictTabInfo::a128Bit: 01223 len = attrDesc.AttributeArraySize * 4; 01224 break; 01225 } 01226 attrLength += len; 01227 if (attrDesc.AttributeKeyFlag) 01228 pkAttrLength += len; 01229 01230 if (operationType == UtilPrepareReq::Read) { 01231 AttributeHeader::init(rsInfoIt.data, 01232 attrDesc.AttributeId, // 1. Store AttrId 01233 len << 2); 01234 prepOpPtr.p->rsInfo.next(rsInfoIt, 1); 01235 } 01236 } 01237 #if 0 01238 ndbout << ": AttributeSize: " << attrDesc.AttributeSize << endl; 01239 ndbout << ": AttributeArraySize: " << attrDesc.AttributeArraySize << endl; 01240 ndbout << "AFTER: attrLength: " << attrLength << endl; 01241 #endif 01242 //attrMappingIt.print(stdout); 01243 //prepPtr.p->prepOpPtr.p->attrMapping.print(stdout); 01244 prepPtr.p->prepOpPtr.p->attrMapping.next(attrMappingIt, 1); 01245 } 01246 01247 /*************************** 01248 * Error: Not all PKs found 01249 ***************************/ 01250 if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) { 01251 jam(); 01252 releaseSections(signal); 01253 sendUtilPrepareRef(signal, 01254 UtilPrepareRef::DICT_TAB_INFO_ERROR, 01255 prepPtr.p->clientRef, prepPtr.p->clientData); 01256 infoEvent("UTIL: Not all primary key attributes requested for table: %s", 01257 tableName); 01258 releasePreparedOperation(prepOpPtr); 01259 releasePrepare(prepPtr); 01260 return; 01261 } 01262 01263 #if 0 01264 AttrMappingBuffer::ConstDataBufferIterator tmpIt; 01265 for (prepPtr.p->prepOpPtr.p->attrMapping.first(tmpIt); tmpIt.curr.i != RNIL; 01266 prepPtr.p->prepOpPtr.p->attrMapping.next(tmpIt)) { 01267 AttributeHeader* ah = (AttributeHeader *) tmpIt.data; 01268 ah->print(stdout); 01269 } 01270 #endif 01271 01272 /********************************************** 01273 * Preparing of PreparedOperation signal train 01274 **********************************************/ 01275 Uint32 static_len = TcKeyReq::StaticLength; 01276 prepOpPtr.p->tckey.tableId = tableDesc.TableId; 01277 prepOpPtr.p->tckey.tableSchemaVersion = tableDesc.TableVersion; 01278 prepOpPtr.p->noOfKeyAttr = tableDesc.NoOfKeyAttr; 01279 prepOpPtr.p->keyLen = tableDesc.KeyLength; // Total no of words in PK 01280 if (prepOpPtr.p->keyLen > TcKeyReq::MaxKeyInfo) { 01281 jam(); 01282 prepOpPtr.p->tckeyLenInBytes = (static_len + TcKeyReq::MaxKeyInfo) * 4; 01283 } else { 01284 jam(); 01285 prepOpPtr.p->tckeyLenInBytes = (static_len + prepOpPtr.p->keyLen) * 4; 01286 } 01287 prepOpPtr.p->keyDataPos = static_len; // Start of keyInfo[] in tckeyreq 01288 01289 Uint32 requestInfo = 0; 01290 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::AbortOnError); 01291 TcKeyReq::setKeyLength(requestInfo, tableDesc.KeyLength); 01292 switch(operationType) { 01293 case(UtilPrepareReq::Read): 01294 prepOpPtr.p->rsLen = 01295 attrLength + 01296 tableDesc.NoOfKeyAttr + 01297 noOfNonPKAttribsStored; // Read needs a resultset 01298 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; 01299 prepOpPtr.p->tckey.attrLen = prepOpPtr.p->noOfAttr; 01300 TcKeyReq::setOperationType(requestInfo, ZREAD); 01301 break; 01302 case(UtilPrepareReq::Update): 01303 prepOpPtr.p->rsLen = 0; 01304 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; 01305 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; 01306 TcKeyReq::setOperationType(requestInfo, ZUPDATE); 01307 break; 01308 case(UtilPrepareReq::Insert): 01309 prepOpPtr.p->rsLen = 0; 01310 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; 01311 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; 01312 TcKeyReq::setOperationType(requestInfo, ZINSERT); 01313 break; 01314 case(UtilPrepareReq::Delete): 01315 // The number of attributes should equal the size of the primary key 01316 ndbrequire(tableDesc.KeyLength == attrLength); 01317 prepOpPtr.p->rsLen = 0; 01318 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr; 01319 prepOpPtr.p->tckey.attrLen = 0; 01320 TcKeyReq::setOperationType(requestInfo, ZDELETE); 01321 break; 01322 case(UtilPrepareReq::Write): 01323 prepOpPtr.p->rsLen = 0; 01324 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored; 01325 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr; 01326 TcKeyReq::setOperationType(requestInfo, ZWRITE); 01327 break; 01328 } 01329 TcKeyReq::setAIInTcKeyReq(requestInfo, 0); // Attrinfo sent separately 01330 prepOpPtr.p->tckey.requestInfo = requestInfo; 01331 01332 /**************************** 01333 * Confirm completed prepare 01334 ****************************/ 01335 UtilPrepareConf * conf = (UtilPrepareConf *)signal->getDataPtr(); 01336 conf->senderData = prepPtr.p->clientData; 01337 conf->prepareId = prepPtr.p->prepOpPtr.i; 01338 01339 releaseSections(signal); 01340 sendSignal(prepPtr.p->clientRef, GSN_UTIL_PREPARE_CONF, signal, 01341 UtilPrepareConf::SignalLength, JBB); 01342 01343 #if 0 01344 prepPtr.p->prepOpPtr.p->print(); 01345 #endif 01346 releasePrepare(prepPtr); 01347 } 01348 01349 01350 void 01351 DbUtil::execUTIL_RELEASE_REQ(Signal* signal){ 01352 jamEntry(); 01353 01354 UtilReleaseReq * req = (UtilReleaseReq *)signal->getDataPtr(); 01355 const Uint32 clientRef = signal->senderBlockRef(); 01356 const Uint32 prepareId = req->prepareId; 01357 const Uint32 senderData = req->senderData; 01358 01359 #if 0 01360 01363 if (!c_preparedOperationPool.isSeized(prepareId)) { 01364 UtilReleaseRef * ref = (UtilReleaseRef *)signal->getDataPtr(); 01365 ref->prepareId = prepareId; 01366 ref->errorCode = UtilReleaseRef::NO_SUCH_PREPARE_SEIZED; 01367 sendSignal(clientRef, GSN_UTIL_RELEASE_REF, signal, 01368 UtilReleaseRef::SignalLength, JBB); 01369 } 01370 #endif 01371 PreparedOperationPtr prepOpPtr; 01372 c_preparedOperationPool.getPtr(prepOpPtr, prepareId); 01373 01374 releasePreparedOperation(prepOpPtr); 01375 01376 UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend(); 01377 conf->senderData = senderData; 01378 sendSignal(clientRef, GSN_UTIL_RELEASE_CONF, signal, 01379 UtilReleaseConf::SignalLength, JBB); 01380 } 01381 01382 01383 /************************************************************************** 01384 * ------------------------------------------------------------------------ 01385 * MODULE: Sequence Service 01386 * ------------------------------------------------------------------------ 01387 * 01388 * A service with a stored incrementable number 01389 **************************************************************************/ 01390 01391 void 01392 DbUtil::hardcodedPrepare() { 01396 { 01397 PreparedOperationPtr ptr; 01398 ndbrequire(c_preparedOperationPool.seizeId(ptr, 0)); 01399 ptr.p->keyLen = 1; 01400 ptr.p->tckey.attrLen = 1; 01401 ptr.p->rsLen = 3; 01402 ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + 01403 ptr.p->keyLen + ptr.p->tckey.attrLen) * 4; 01404 ptr.p->keyDataPos = TcKeyReq::StaticLength; 01405 ptr.p->tckey.tableId = 0; 01406 Uint32 requestInfo = 0; 01407 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); 01408 TcKeyReq::setOperationType(requestInfo, ZREAD); 01409 TcKeyReq::setKeyLength(requestInfo, 1); 01410 TcKeyReq::setAIInTcKeyReq(requestInfo, 1); 01411 ptr.p->tckey.requestInfo = requestInfo; 01412 ptr.p->tckey.tableSchemaVersion = 1; 01413 01414 // This is actually attr data 01415 AttributeHeader::init(&ptr.p->tckey.distrGroupHashValue, 1, 0); 01416 01417 ndbrequire(ptr.p->rsInfo.seize(1)); 01418 ResultSetInfoBuffer::DataBufferIterator it; 01419 ptr.p->rsInfo.first(it); 01420 AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words 01421 } 01422 01426 { 01427 PreparedOperationPtr ptr; 01428 ndbrequire(c_preparedOperationPool.seizeId(ptr, 1)); 01429 ptr.p->keyLen = 1; 01430 ptr.p->rsLen = 3; 01431 ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + ptr.p->keyLen + 5) * 4; 01432 ptr.p->keyDataPos = TcKeyReq::StaticLength; 01433 ptr.p->tckey.attrLen = 11; 01434 ptr.p->tckey.tableId = 0; 01435 Uint32 requestInfo = 0; 01436 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); 01437 TcKeyReq::setOperationType(requestInfo, ZUPDATE); 01438 TcKeyReq::setKeyLength(requestInfo, 1); 01439 TcKeyReq::setAIInTcKeyReq(requestInfo, 5); 01440 TcKeyReq::setInterpretedFlag(requestInfo, 1); 01441 ptr.p->tckey.requestInfo = requestInfo; 01442 ptr.p->tckey.tableSchemaVersion = 1; 01443 01444 // Signal is packed, which is why attrInfo is at distrGroupHashValue 01445 // position 01446 Uint32 * attrInfo = &ptr.p->tckey.distrGroupHashValue; 01447 attrInfo[0] = 0; // IntialReadSize 01448 attrInfo[1] = 5; // InterpretedSize 01449 attrInfo[2] = 0; // FinalUpdateSize 01450 attrInfo[3] = 1; // FinalReadSize 01451 attrInfo[4] = 0; // SubroutineSize 01452 01453 { // AttrInfo 01454 ndbrequire(ptr.p->attrInfo.seize(6)); 01455 AttrInfoBuffer::DataBufferIterator it; 01456 ptr.p->attrInfo.first(it); 01457 * it.data = Interpreter::Read(1, 6); 01458 ndbrequire(ptr.p->attrInfo.next(it)); 01459 * it.data = Interpreter::LoadConst16(7, 1); 01460 ndbrequire(ptr.p->attrInfo.next(it)); 01461 * it.data = Interpreter::Add(7, 6, 7); 01462 ndbrequire(ptr.p->attrInfo.next(it)); 01463 * it.data = Interpreter::Write(1, 7); 01464 ndbrequire(ptr.p->attrInfo.next(it)); 01465 * it.data = Interpreter::ExitOK(); 01466 01467 ndbrequire(ptr.p->attrInfo.next(it)); 01468 AttributeHeader::init(it.data, 1, 0); 01469 } 01470 01471 { // ResultSet 01472 ndbrequire(ptr.p->rsInfo.seize(1)); 01473 ResultSetInfoBuffer::DataBufferIterator it; 01474 ptr.p->rsInfo.first(it); 01475 AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words 01476 } 01477 } 01478 01482 { 01483 PreparedOperationPtr ptr; 01484 ndbrequire(c_preparedOperationPool.seizeId(ptr, 2)); 01485 ptr.p->keyLen = 1; 01486 ptr.p->tckey.attrLen = 5; 01487 ptr.p->rsLen = 0; 01488 ptr.p->tckeyLenInBytes = (TcKeyReq::StaticLength + 01489 ptr.p->keyLen + ptr.p->tckey.attrLen) * 4; 01490 ptr.p->keyDataPos = TcKeyReq::StaticLength; 01491 ptr.p->tckey.tableId = 0; 01492 Uint32 requestInfo = 0; 01493 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree); 01494 TcKeyReq::setOperationType(requestInfo, ZINSERT); 01495 TcKeyReq::setKeyLength(requestInfo, 1); 01496 TcKeyReq::setAIInTcKeyReq(requestInfo, 0); 01497 ptr.p->tckey.requestInfo = requestInfo; 01498 ptr.p->tckey.tableSchemaVersion = 1; 01499 } 01500 } 01501 01502 void 01503 DbUtil::execUTIL_SEQUENCE_REQ(Signal* signal){ 01504 jamEntry(); 01505 01506 UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtr(); 01507 01508 PreparedOperation * prepOp; 01509 01510 switch(req->requestType){ 01511 case UtilSequenceReq::CurrVal: 01512 prepOp = c_preparedOperationPool.getPtr(0); //c_SequenceCurrVal 01513 break; 01514 case UtilSequenceReq::NextVal: 01515 prepOp = c_preparedOperationPool.getPtr(1); //c_SequenceNextVal 01516 break; 01517 case UtilSequenceReq::Create: 01518 prepOp = c_preparedOperationPool.getPtr(2); //c_CreateSequence 01519 break; 01520 default: 01521 ndbrequire(false); 01522 prepOp = 0; // remove warning 01523 } 01524 01528 TransactionPtr transPtr; 01529 ndbrequire(c_runningTransactions.seize(transPtr)); 01530 01531 OperationPtr opPtr; 01532 ndbrequire(transPtr.p->operations.seize(opPtr)); 01533 01534 ndbrequire(opPtr.p->rs.seize(prepOp->rsLen)); 01535 ndbrequire(opPtr.p->keyInfo.seize(prepOp->keyLen)); 01536 01537 transPtr.p->gsn = GSN_UTIL_SEQUENCE_REQ; 01538 transPtr.p->clientRef = signal->senderBlockRef(); 01539 transPtr.p->clientData = req->senderData; 01540 transPtr.p->sequence.sequenceId = req->sequenceId; 01541 transPtr.p->sequence.requestType = req->requestType; 01542 01543 opPtr.p->prepOp = prepOp; 01544 opPtr.p->prepOp_i = RNIL; 01545 01546 KeyInfoBuffer::DataBufferIterator it; 01547 opPtr.p->keyInfo.first(it); 01548 it.data[0] = transPtr.p->sequence.sequenceId; 01549 01550 if(req->requestType == UtilSequenceReq::Create){ 01551 ndbrequire(opPtr.p->attrInfo.seize(5)); 01552 AttrInfoBuffer::DataBufferIterator it; 01553 01554 opPtr.p->attrInfo.first(it); 01555 AttributeHeader::init(it.data, 0, 1 << 2); 01556 01557 ndbrequire(opPtr.p->attrInfo.next(it)); 01558 * it.data = transPtr.p->sequence.sequenceId; 01559 01560 ndbrequire(opPtr.p->attrInfo.next(it)); 01561 AttributeHeader::init(it.data, 1, 2 << 2); 01562 01563 ndbrequire(opPtr.p->attrInfo.next(it)); 01564 * it.data = 0; 01565 01566 ndbrequire(opPtr.p->attrInfo.next(it)); 01567 * it.data = 0; 01568 } 01569 01570 runTransaction(signal, transPtr); 01571 } 01572 01573 int 01574 DbUtil::getResultSet(Signal* signal, const Transaction * transP, 01575 struct LinearSectionPtr sectionsPtr[]) { 01576 OperationPtr opPtr; 01577 ndbrequire(transP->operations.first(opPtr)); 01578 ndbrequire(transP->operations.hasNext(opPtr) == false); 01579 01580 int noAttr = 0; 01581 int dataSz = 0; 01582 Uint32* tmpBuf = signal->theData + 25; 01583 const Uint32* headerBuffer = tmpBuf; 01584 01585 const ResultSetBuffer & rs = opPtr.p->rs; 01586 ResultSetInfoBuffer::ConstDataBufferIterator it; 01587 01588 // extract headers 01589 for(rs.first(it); it.curr.i != RNIL; ) { 01590 *tmpBuf++ = it.data[0]; 01591 rs.next(it, ((AttributeHeader*)&it.data[0])->getDataSize() + 1); 01592 noAttr++; 01593 } 01594 01595 if (noAttr == 0) 01596 return 0; 01597 01598 const Uint32* dataBuffer = tmpBuf; 01599 01600 // extract data 01601 for(rs.first(it); it.curr.i != RNIL; ) { 01602 int sz = ((AttributeHeader*)&it.data[0])->getDataSize(); 01603 rs.next(it,1); 01604 for (int i = 0; i < sz; i++) { 01605 *tmpBuf++ = *it.data; 01606 rs.next(it,1); 01607 dataSz++; 01608 } 01609 } 01610 01611 sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = (Uint32 *)headerBuffer; 01612 sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr; 01613 sectionsPtr[UtilExecuteReq::DATA_SECTION].p = (Uint32 *)dataBuffer; 01614 sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataSz; 01615 01616 return 1; 01617 } 01618 01619 void 01620 DbUtil::reportSequence(Signal* signal, const Transaction * transP){ 01621 OperationPtr opPtr; 01622 ndbrequire(transP->operations.first(opPtr)); 01623 ndbrequire(transP->operations.hasNext(opPtr) == false); 01624 01625 if(transP->errorCode == 0){ 01626 jam(); // OK 01627 01628 UtilSequenceConf * ret = (UtilSequenceConf *)signal->getDataPtrSend(); 01629 ret->senderData = transP->clientData; 01630 ret->sequenceId = transP->sequence.sequenceId; 01631 ret->requestType = transP->sequence.requestType; 01632 01633 bool ok = false; 01634 switch(transP->sequence.requestType){ 01635 case UtilSequenceReq::CurrVal: 01636 case UtilSequenceReq::NextVal:{ 01637 ok = true; 01638 ndbrequire(opPtr.p->rsRecv == 3); 01639 01640 ResultSetBuffer::DataBufferIterator rsit; 01641 ndbrequire(opPtr.p->rs.first(rsit)); 01642 01643 ret->sequenceValue[0] = rsit.data[1]; 01644 ret->sequenceValue[1] = rsit.data[2]; 01645 break; 01646 } 01647 case UtilSequenceReq::Create: 01648 ok = true; 01649 ret->sequenceValue[0] = 0; 01650 ret->sequenceValue[1] = 0; 01651 break; 01652 } 01653 ndbrequire(ok); 01654 sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_CONF, signal, 01655 UtilSequenceConf::SignalLength, JBB); 01656 return; 01657 } 01658 01659 UtilSequenceRef::ErrorCode errCode = UtilSequenceRef::TCError; 01660 01661 switch(transP->sequence.requestType) 01662 { 01663 case UtilSequenceReq::CurrVal: 01664 case UtilSequenceReq::NextVal:{ 01665 if (transP->errorCode == 626) 01666 errCode = UtilSequenceRef::NoSuchSequence; 01667 break; 01668 } 01669 case UtilSequenceReq::Create: 01670 break; 01671 } 01672 01673 UtilSequenceRef * ret = (UtilSequenceRef *)signal->getDataPtrSend(); 01674 ret->senderData = transP->clientData; 01675 ret->sequenceId = transP->sequence.sequenceId; 01676 ret->requestType = transP->sequence.requestType; 01677 ret->errorCode = (Uint32)errCode; 01678 sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_REF, signal, 01679 UtilSequenceRef::SignalLength, JBB); 01680 } 01681 #if 0 01682 Ndb ndb("ndb","def"); 01683 NdbConnection* tConnection = ndb.startTransaction(); 01684 NdbOperation* tOperation = tConnection->getNdbOperation("SYSTAB_0"); 01685 01686 //#if 0 && API_CODE 01687 if( tOperation != NULL ) { 01688 tOperation->interpretedUpdateTuple(); 01689 tOperation->equal((U_Int32)0, keyValue ); 01690 tNextId_Result = tOperation->getValue((U_Int32)1); 01691 tOperation->incValue((U_Int32)1, (U_Int32)8192); 01692 01693 if (tConnection->execute( Commit ) != -1 ) { 01694 U_Int64 tValue = tNextId_Result->u_64_value(); // Read result value 01695 theFirstTransId = tValue; 01696 theLastTransId = tValue + 8191; 01697 closeTransaction(tConnection); 01698 return startTransactionLocal(aPriority, nodeId); 01699 } 01700 } 01708 #endif 01709 01710 01711 /************************************************************************** 01712 * ------------------------------------------------------------------------ 01713 * MODULE: Transaction execution request 01714 * ------------------------------------------------------------------------ 01715 * 01716 * Handle requests to execute a prepared transaction 01717 **************************************************************************/ 01718 01719 void 01720 DbUtil::execUTIL_EXECUTE_REQ(Signal* signal) 01721 { 01722 jamEntry(); 01723 01724 UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtr(); 01725 const Uint32 clientRef = req->senderRef; 01726 const Uint32 clientData = req->senderData; 01727 const Uint32 prepareId = req->getPrepareId(); 01728 const bool releaseFlag = req->getReleaseFlag(); 01729 01730 if(signal->getNoOfSections() == 0) { 01731 // Missing prepare data 01732 jam(); 01733 releaseSections(signal); 01734 sendUtilExecuteRef(signal, UtilExecuteRef::MissingDataSection, 01735 0, clientRef, clientData); 01736 return; 01737 } 01738 /******************************* 01739 * Get PreparedOperation struct 01740 *******************************/ 01741 PreparedOperationPtr prepOpPtr; 01742 c_preparedOperationPool.getPtr(prepOpPtr, prepareId); 01743 01744 prepOpPtr.p->releaseFlag = releaseFlag; 01745 01746 TransactionPtr transPtr; 01747 OperationPtr opPtr; 01748 SegmentedSectionPtr headerPtr, dataPtr; 01749 01750 signal->getSection(headerPtr, UtilExecuteReq::HEADER_SECTION); 01751 SectionReader headerReader(headerPtr, getSectionSegmentPool()); 01752 signal->getSection(dataPtr, UtilExecuteReq::DATA_SECTION); 01753 SectionReader dataReader(dataPtr, getSectionSegmentPool()); 01754 01755 #if 0 //def EVENT_DEBUG 01756 // Debugging 01757 printf("DbUtil::execUTIL_EXECUTEL_REQ: Headers (%u): ", headerPtr.sz); 01758 Uint32 word; 01759 while(headerReader.getWord(&word)) 01760 printf("H'%.8x ", word); 01761 printf("\n"); 01762 printf("DbUtil::execUTIL_EXECUTEL_REQ: Data (%u): ", dataPtr.sz); 01763 headerReader.reset(); 01764 while(dataReader.getWord(&word)) 01765 printf("H'%.8x ", word); 01766 printf("\n"); 01767 dataReader.reset(); 01768 #endif 01769 01770 // Uint32 totalDataLen = headerPtr.sz + dataPtr.sz; 01771 01772 /************************************************************ 01773 * Seize Transaction record 01774 ************************************************************/ 01775 ndbrequire(c_runningTransactions.seize(transPtr)); 01776 transPtr.p->gsn = GSN_UTIL_EXECUTE_REQ; 01777 transPtr.p->clientRef = clientRef; 01778 transPtr.p->clientData = clientData; 01779 ndbrequire(transPtr.p->operations.seize(opPtr)); 01780 opPtr.p->prepOp = prepOpPtr.p; 01781 opPtr.p->prepOp_i = prepOpPtr.i; 01782 01783 #if 0 //def EVENT_DEBUG 01784 printf("opPtr.p->rs.seize( %u )\n", prepOpPtr.p->rsLen); 01785 #endif 01786 ndbrequire(opPtr.p->rs.seize(prepOpPtr.p->rsLen)); 01787 01788 /*********************************************************** 01789 * Store signal data on linear memory in Transaction record 01790 ***********************************************************/ 01791 KeyInfoBuffer* keyInfo = &opPtr.p->keyInfo; 01792 AttrInfoBuffer* attrInfo = &opPtr.p->attrInfo; 01793 AttributeHeader header; 01794 Uint32* tempBuf = signal->theData + 25; 01795 bool dataComplete = true; 01796 01797 while(headerReader.getWord((Uint32 *)&header)) { 01798 Uint32* bufStart = tempBuf; 01799 header.insertHeader(tempBuf++); 01800 for(unsigned int i = 0; i < header.getDataSize(); i++) { 01801 if (!dataReader.getWord(tempBuf++)) { 01802 dataComplete = false; 01803 break; 01804 } 01805 } 01806 bool res = true; 01807 01808 #if 0 //def EVENT_DEBUG 01809 if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) == 01810 TcKeyReq::Read) { 01811 if(prepOpPtr.p->pkBitmask.get(header.getAttributeId())) 01812 printf("PrimaryKey\n"); 01813 } 01814 printf("AttrId %u Hdrsz %d Datasz %u \n", 01815 header.getAttributeId(), 01816 header.getHeaderSize(), 01817 header.getDataSize()); 01818 #endif 01819 01820 if(prepOpPtr.p->pkBitmask.get(header.getAttributeId())) 01821 // A primary key attribute 01822 res = keyInfo->append(bufStart + header.getHeaderSize(), 01823 header.getDataSize()); 01824 01825 switch (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo)) { 01826 case ZREAD: 01827 res &= attrInfo->append(bufStart, header.getHeaderSize()); 01828 break; 01829 case ZDELETE: 01830 // no attrinfo for Delete 01831 break; 01832 default: 01833 res &= attrInfo->append(bufStart, 01834 header.getHeaderSize() + header.getDataSize()); 01835 } 01836 01837 if (!res) { 01838 // Failed to allocate buffer data 01839 jam(); 01840 releaseSections(signal); 01841 sendUtilExecuteRef(signal, UtilExecuteRef::AllocationError, 01842 0, clientRef, clientData); 01843 releaseTransaction(transPtr); 01844 return; 01845 } 01846 } 01847 if (!dataComplete) { 01848 // Missing data in data section 01849 jam(); 01850 releaseSections(signal); 01851 sendUtilExecuteRef(signal, UtilExecuteRef::MissingData, 01852 0, clientRef, clientData); 01853 releaseTransaction(transPtr); 01854 return; 01855 } 01856 01857 // quick hack for hash index build 01858 if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){ 01859 prepOpPtr.p->tckey.attrLen = 01860 prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize(); 01861 TcKeyReq::setKeyLength(prepOpPtr.p->tckey.requestInfo, keyInfo->getSize()); 01862 } 01863 01864 #if 0 01865 const Uint32 l1 = prepOpPtr.p->tckey.attrLen; 01866 const Uint32 l2 = 01867 prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize(); 01868 01869 if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){ 01870 ndbrequire(l1 == l2); 01871 } else { 01872 ndbout_c("TcKeyReq::Read"); 01873 } 01874 #endif 01875 01876 releaseSections(signal); 01877 transPtr.p->noOfRetries = 3; 01878 runTransaction(signal, transPtr); 01879 } 01880 01881 /************************************************************************** 01882 * ------------------------------------------------------------------------ 01883 * MODULE: General transaction machinery 01884 * ------------------------------------------------------------------------ 01885 * Executes a prepared transaction 01886 **************************************************************************/ 01887 void 01888 DbUtil::runTransaction(Signal* signal, TransactionPtr transPtr){ 01889 01890 /* Init transaction */ 01891 transPtr.p->sent = 0; 01892 transPtr.p->recv = 0; 01893 transPtr.p->errorCode = 0; 01894 getTransId(transPtr.p); 01895 01896 OperationPtr opPtr; 01897 ndbrequire(transPtr.p->operations.first(opPtr)); 01898 01899 /* First operation */ 01900 Uint32 start = 0; 01901 TcKeyReq::setStartFlag(start, 1); 01902 runOperation(signal, transPtr, opPtr, start); 01903 transPtr.p->sent ++; 01904 01905 /* Rest of operations */ 01906 start = 0; 01907 while(opPtr.i != RNIL){ 01908 runOperation(signal, transPtr, opPtr, start); 01909 transPtr.p->sent ++; 01910 } 01911 //transPtr.p->print(); 01912 } 01913 01914 void 01915 DbUtil::runOperation(Signal* signal, TransactionPtr & transPtr, 01916 OperationPtr & opPtr, Uint32 start) { 01917 Uint32 opI = opPtr.i; 01918 Operation * op = opPtr.p; 01919 const PreparedOperation * pop = op->prepOp; 01920 01921 if(!transPtr.p->operations.next(opPtr)){ 01922 TcKeyReq::setCommitFlag(start, 1); // Last operation 01923 TcKeyReq::setExecuteFlag(start, 1); 01924 } 01925 01926 #if 0 //def EVENT_DEBUG 01927 if (TcKeyReq::getOperationType(pop->tckey.requestInfo) == 01928 TcKeyReq::Read) { 01929 printf("TcKeyReq::Read runOperation\n"); 01930 } 01931 #endif 01932 01936 initResultSet(op->rs, pop->rsInfo); 01937 op->rs.first(op->rsIterator); 01938 op->rsRecv = 0; 01939 #if 0 //def EVENT_DEBUG 01940 printf("pop->rsLen %u\n", pop->rsLen); 01941 #endif 01942 op->rsExpect = 0; 01943 op->transPtrI = transPtr.i; 01944 01945 TcKeyReq * tcKey = (TcKeyReq*)signal->getDataPtrSend(); 01946 //ndbout << "*** 6 ***"<< endl; pop->print(); 01947 memcpy(tcKey, &pop->tckey, pop->tckeyLenInBytes); 01948 //ndbout << "*** 6b ***"<< endl; 01949 //printTCKEYREQ(stdout, signal->getDataPtrSend(), 01950 // pop->tckeyLenInBytes >> 2, 0); 01951 tcKey->apiConnectPtr = transPtr.p->connectPtr; 01952 tcKey->senderData = opI; 01953 tcKey->transId1 = transPtr.p->transId[0]; 01954 tcKey->transId2 = transPtr.p->transId[1]; 01955 tcKey->requestInfo |= start; 01956 01957 #if 0 //def EVENT_DEBUG 01958 // Debugging 01959 printf("DbUtil::runOperation: KEYINFO\n"); 01960 op->keyInfo.print(stdout); 01961 printf("DbUtil::runOperation: ATTRINFO\n"); 01962 op->attrInfo.print(stdout); 01963 #endif 01964 01968 //KeyInfoBuffer::DataBufferIterator kit; 01969 KeyInfoIterator kit; 01970 op->keyInfo.first(kit); 01971 Uint32 *keyDst = ((Uint32*)tcKey) + pop->keyDataPos; 01972 for(Uint32 i = 0; i<8 && kit.curr.i != RNIL; i++, op->keyInfo.next(kit)){ 01973 keyDst[i] = * kit.data; 01974 } 01975 //ndbout << "*** 7 ***" << endl; 01976 //printTCKEYREQ(stdout, signal->getDataPtrSend(), 01977 // pop->tckeyLenInBytes >> 2, 0); 01978 01979 #if 0 //def EVENT_DEBUG 01980 printf("DbUtil::runOperation: sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, %d , JBB)\n", pop->tckeyLenInBytes >> 2); 01981 printTCKEYREQ(stdout, signal->getDataPtr(), pop->tckeyLenInBytes >> 2,0); 01982 #endif 01983 sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, pop->tckeyLenInBytes >> 2, JBB); 01984 01988 // ndbrequire(kit.curr.i == RNIL); // Yes it is 01989 01993 KeyInfo* keyInfo = (KeyInfo *)signal->getDataPtrSend(); 01994 keyInfo->connectPtr = transPtr.p->connectPtr; 01995 keyInfo->transId[0] = transPtr.p->transId[0]; 01996 keyInfo->transId[1] = transPtr.p->transId[1]; 01997 sendKeyInfo(signal, keyInfo, op->keyInfo, kit); 01998 02002 AttrInfo* attrInfo = (AttrInfo *)signal->getDataPtrSend(); 02003 attrInfo->connectPtr = transPtr.p->connectPtr; 02004 attrInfo->transId[0] = transPtr.p->transId[0]; 02005 attrInfo->transId[1] = transPtr.p->transId[1]; 02006 02007 AttrInfoIterator ait; 02008 pop->attrInfo.first(ait); 02009 sendAttrInfo(signal, attrInfo, pop->attrInfo, ait); 02010 02011 op->attrInfo.first(ait); 02012 sendAttrInfo(signal, attrInfo, op->attrInfo, ait); 02013 } 02014 02015 void 02016 DbUtil::sendKeyInfo(Signal* signal, 02017 KeyInfo* keyInfo, 02018 const KeyInfoBuffer & keyBuf, 02019 KeyInfoIterator & kit) 02020 { 02021 while(kit.curr.i != RNIL) { 02022 Uint32 *keyDst = keyInfo->keyData; 02023 Uint32 keyDataLen = 0; 02024 for(Uint32 i = 0; i<KeyInfo::DataLength && kit.curr.i != RNIL; 02025 i++, keyBuf.next(kit)){ 02026 keyDst[i] = * kit.data; 02027 keyDataLen++; 02028 } 02029 #if 0 //def EVENT_DEBUG 02030 printf("DbUtil::sendKeyInfo: sendSignal(DBTC_REF, GSN_KEYINFO, signal, %d , JBB)\n", KeyInfo::HeaderLength + keyDataLen); 02031 #endif 02032 sendSignal(DBTC_REF, GSN_KEYINFO, signal, 02033 KeyInfo::HeaderLength + keyDataLen, JBB); 02034 } 02035 } 02036 02037 void 02038 DbUtil::sendAttrInfo(Signal* signal, 02039 AttrInfo* attrInfo, 02040 const AttrInfoBuffer & attrBuf, 02041 AttrInfoIterator & ait) 02042 { 02043 while(ait.curr.i != RNIL) { 02044 Uint32 *attrDst = attrInfo->attrData; 02045 Uint32 i = 0; 02046 for(i = 0; i<AttrInfo::DataLength && ait.curr.i != RNIL; 02047 i++, attrBuf.next(ait)){ 02048 attrDst[i] = * ait.data; 02049 } 02050 #if 0 //def EVENT_DEBUG 02051 printf("DbUtil::sendAttrInfo: sendSignal(DBTC_REF, GSN_ATTRINFO, signal, %d , JBB)\n", AttrInfo::HeaderLength + i); 02052 #endif 02053 sendSignal(DBTC_REF, GSN_ATTRINFO, signal, 02054 AttrInfo::HeaderLength + i, JBB); 02055 } 02056 } 02057 02058 void 02059 DbUtil::initResultSet(ResultSetBuffer & rs, 02060 const ResultSetInfoBuffer & rsi){ 02061 02062 ResultSetBuffer::DataBufferIterator rsit; 02063 rs.first(rsit); 02064 02065 ResultSetInfoBuffer::ConstDataBufferIterator rsiit; 02066 for(rsi.first(rsiit); rsiit.curr.i != RNIL; rsi.next(rsiit)){ 02067 ndbrequire(rsit.curr.i != RNIL); 02068 02069 rsit.data[0] = rsiit.data[0]; 02070 #if 0 //def EVENT_DEBUG 02071 printf("Init resultset %u, sz %d\n", 02072 rsit.curr.i, 02073 ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1); 02074 #endif 02075 rs.next(rsit, ((AttributeHeader*)&rsit.data[0])->getDataSize() + 1); 02076 } 02077 } 02078 02079 void 02080 DbUtil::getTransId(Transaction * transP){ 02081 02082 Uint32 tmp[2]; 02083 tmp[0] = c_transId[0]; 02084 tmp[1] = c_transId[1]; 02085 02086 transP->transId[0] = tmp[0]; 02087 transP->transId[1] = tmp[1]; 02088 02089 c_transId[1] = tmp[1] + 1; 02090 } 02091 02092 02093 02094 /************************************************************************** 02095 * ------------------------------------------------------------------------ 02096 * MODULE: Post Execute 02097 * ------------------------------------------------------------------------ 02098 * 02099 * Handles result from a sent transaction 02100 **************************************************************************/ 02101 02110 void 02111 DbUtil::execTRANSID_AI(Signal* signal){ 02112 jamEntry(); 02113 #if 0 //def EVENT_DEBUG 02114 ndbout_c("File: %s line: %u",__FILE__,__LINE__); 02115 #endif 02116 02117 const Uint32 opI = signal->theData[0]; 02118 const Uint32 transId1 = signal->theData[1]; 02119 const Uint32 transId2 = signal->theData[2]; 02120 const Uint32 dataLen = signal->length() - 3; 02121 02122 Operation * opP = c_operationPool.getPtr(opI); 02123 TransactionPtr transPtr; 02124 c_runningTransactions.getPtr(transPtr, opP->transPtrI); 02125 02126 ndbrequire(transId1 == transPtr.p->transId[0] && 02127 transId2 == transPtr.p->transId[1]); 02128 opP->rsRecv += dataLen; 02129 02133 const Uint32 *src = &signal->theData[3]; 02134 ResultSetBuffer::DataBufferIterator rs = opP->rsIterator; 02135 02136 ndbrequire(opP->rs.import(rs,src,dataLen)); 02137 opP->rs.next(rs, dataLen); 02138 opP->rsIterator = rs; 02139 02140 if(!opP->complete()){ 02141 jam(); 02142 return; 02143 } 02144 02145 transPtr.p->recv++; 02146 if(!transPtr.p->complete()){ 02147 jam(); 02148 return; 02149 } 02150 02151 finishTransaction(signal, transPtr); 02152 } 02153 02154 void 02155 DbUtil::execTCKEYCONF(Signal* signal){ 02156 jamEntry(); 02157 #if 0 //def EVENT_DEBUG 02158 ndbout_c("File: %s line: %u",__FILE__,__LINE__); 02159 #endif 02160 02161 TcKeyConf * keyConf = (TcKeyConf*)signal->getDataPtr(); 02162 02163 //const Uint32 gci = keyConf->gci; 02164 const Uint32 transI = keyConf->apiConnectPtr >> 1; 02165 const Uint32 confInfo = keyConf->confInfo; 02166 const Uint32 transId1 = keyConf->transId1; 02167 const Uint32 transId2 = keyConf->transId2; 02168 02169 Uint32 recv = 0; 02170 const Uint32 ops = TcKeyConf::getNoOfOperations(confInfo); 02171 for(Uint32 i = 0; i<ops; i++){ 02172 OperationPtr opPtr; 02173 c_operationPool.getPtr(opPtr, keyConf->operations[i].apiOperationPtr); 02174 02175 ndbrequire(opPtr.p->transPtrI == transI); 02176 opPtr.p->rsExpect += keyConf->operations[i].attrInfoLen; 02177 if(opPtr.p->complete()){ 02178 recv++; 02179 } 02180 } 02181 02185 if (TcKeyConf::getMarkerFlag(confInfo)){ 02186 signal->theData[0] = transId1; 02187 signal->theData[1] = transId2; 02188 sendSignal(DBTC_REF, GSN_TC_COMMIT_ACK, signal, 2, JBB); 02189 }//if 02190 02191 TransactionPtr transPtr; 02192 c_runningTransactions.getPtr(transPtr, transI); 02193 ndbrequire(transId1 == transPtr.p->transId[0] && 02194 transId2 == transPtr.p->transId[1]); 02195 02196 transPtr.p->recv += recv; 02197 if(!transPtr.p->complete()){ 02198 jam(); 02199 return; 02200 } 02201 finishTransaction(signal, transPtr); 02202 } 02203 02204 void 02205 DbUtil::execTCKEYREF(Signal* signal){ 02206 jamEntry(); 02207 #if 0 //def EVENT_DEBUG 02208 ndbout_c("File: %s line: %u",__FILE__,__LINE__); 02209 #endif 02210 02211 const Uint32 transI = signal->theData[0] >> 1; 02212 const Uint32 transId1 = signal->theData[1]; 02213 const Uint32 transId2 = signal->theData[2]; 02214 const Uint32 errCode = signal->theData[3]; 02215 02216 TransactionPtr transPtr; 02217 c_runningTransactions.getPtr(transPtr, transI); 02218 ndbrequire(transId1 == transPtr.p->transId[0] && 02219 transId2 == transPtr.p->transId[1]); 02220 02221 //if(getClassification(errCode) == PermanentError){ 02222 //} 02223 02224 //ndbout << "Transaction error (code: " << errCode << ")" << endl; 02225 02226 transPtr.p->errorCode = errCode; 02227 finishTransaction(signal, transPtr); 02228 } 02229 02230 void 02231 DbUtil::execTCROLLBACKREP(Signal* signal){ 02232 jamEntry(); 02233 #if 0 //def EVENT_DEBUG 02234 ndbout_c("File: %s line: %u",__FILE__,__LINE__); 02235 #endif 02236 02237 const Uint32 transI = signal->theData[0] >> 1; 02238 const Uint32 transId1 = signal->theData[1]; 02239 const Uint32 transId2 = signal->theData[2]; 02240 const Uint32 errCode = signal->theData[3]; 02241 02242 TransactionPtr transPtr; 02243 c_runningTransactions.getPtr(transPtr, transI); 02244 ndbrequire(transId1 == transPtr.p->transId[0] && 02245 transId2 == transPtr.p->transId[1]); 02246 02247 //if(getClassification(errCode) == PermanentError){ 02248 //} 02249 02250 #if 0 //def EVENT_DEBUG 02251 ndbout << "Transaction error (code: " << errCode << ")" << endl; 02252 #endif 02253 02254 if(transPtr.p->noOfRetries > 0){ 02255 transPtr.p->noOfRetries--; 02256 switch(errCode){ 02257 case 266: 02258 case 410: 02259 case 1204: 02260 #if 0 02261 ndbout_c("errCode: %d noOfRetries: %d -> retry", 02262 errCode, transPtr.p->noOfRetries); 02263 #endif 02264 runTransaction(signal, transPtr); 02265 return; 02266 } 02267 } 02268 02269 transPtr.p->errorCode = errCode; 02270 finishTransaction(signal, transPtr); 02271 } 02272 02273 void 02274 DbUtil::finishTransaction(Signal* signal, TransactionPtr transPtr){ 02275 #if 0 //def EVENT_DEBUG 02276 ndbout_c("Transaction %x %x completed %s", 02277 transPtr.p->transId[0], 02278 transPtr.p->transId[1], 02279 transPtr.p->errorCode == 0 ? "OK" : "FAILED"); 02280 #endif 02281 02282 /* 02283 How to find the correct RS? Could we have multi-RS/transaction? 02284 02285 Operation * opP = c_operationPool.getPtr(opI); 02286 02287 ResultSetBuffer::DataBufferIterator rsit; 02288 ndbrequire(opP->rs.first(rsit)); 02289 ndbout << "F Result: " << rsit.data << endl; 02290 02291 while (opP->rs.next(rsit)) { 02292 ndbout << "R Result: " << rsit.data << endl; 02293 } 02294 */ 02295 02296 switch(transPtr.p->gsn){ 02297 case GSN_UTIL_SEQUENCE_REQ: 02298 jam(); 02299 reportSequence(signal, transPtr.p); 02300 break; 02301 case GSN_UTIL_EXECUTE_REQ: 02302 if (transPtr.p->errorCode) { 02303 UtilExecuteRef * ret = (UtilExecuteRef *)signal->getDataPtrSend(); 02304 ret->senderData = transPtr.p->clientData; 02305 ret->errorCode = UtilExecuteRef::TCError; 02306 ret->TCErrorCode = transPtr.p->errorCode; 02307 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_REF, signal, 02308 UtilExecuteRef::SignalLength, JBB); 02309 } else { 02310 struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections]; 02311 UtilExecuteConf * ret = (UtilExecuteConf *)signal->getDataPtrSend(); 02312 ret->senderData = transPtr.p->clientData; 02313 if (getResultSet(signal, transPtr.p, sectionsPtr)) { 02314 #if 0 //def EVENT_DEBUG 02315 for (int j = 0; j < 2; j++) { 02316 printf("Result set %u %u\n", j,sectionsPtr[j].sz); 02317 for (int i=0; i < sectionsPtr[j].sz; i++) 02318 printf("H'%.8x ", sectionsPtr[j].p[i]); 02319 printf("\n"); 02320 } 02321 #endif 02322 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal, 02323 UtilExecuteConf::SignalLength, JBB, 02324 sectionsPtr, UtilExecuteReq::NoOfSections); 02325 } else 02326 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal, 02327 UtilExecuteConf::SignalLength, JBB); 02328 } 02329 break; 02330 default: 02331 ndbrequire(0); 02332 break; 02333 } 02334 releaseTransaction(transPtr); 02335 } 02336 02337 void 02338 DbUtil::execUTIL_LOCK_REQ(Signal * signal){ 02339 jamEntry(); 02340 UtilLockReq * req = (UtilLockReq*)signal->getDataPtr(); 02341 const Uint32 lockId = req->lockId; 02342 02343 LockQueuePtr lockQPtr; 02344 if(!c_lockQueues.find(lockQPtr, lockId)){ 02345 jam(); 02346 sendLOCK_REF(signal, req, UtilLockRef::NoSuchLock); 02347 return; 02348 } 02349 02350 // const Uint32 requestInfo = req->requestInfo; 02351 const Uint32 senderNode = refToNode(req->senderRef); 02352 if(senderNode != getOwnNodeId() && senderNode != 0){ 02353 jam(); 02354 sendLOCK_REF(signal, req, UtilLockRef::DistributedLockNotSupported); 02355 return; 02356 } 02357 02358 LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, 02359 lockQPtr.p->m_queue); 02360 if(req->requestInfo & UtilLockReq::TryLock && !queue.isEmpty()){ 02361 jam(); 02362 sendLOCK_REF(signal, req, UtilLockRef::LockAlreadyHeld); 02363 return; 02364 } 02365 02366 LockQueueElementPtr lockEPtr; 02367 if(!c_lockElementPool.seize(lockEPtr)){ 02368 jam(); 02369 sendLOCK_REF(signal, req, UtilLockRef::OutOfLockRecords); 02370 return; 02371 } 02372 02373 lockEPtr.p->m_senderRef = req->senderRef; 02374 lockEPtr.p->m_senderData = req->senderData; 02375 02376 if(queue.isEmpty()){ 02377 jam(); 02378 sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); 02379 } 02380 02381 queue.add(lockEPtr); 02382 } 02383 02384 void 02385 DbUtil::execUTIL_UNLOCK_REQ(Signal* signal){ 02386 jamEntry(); 02387 02388 UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtr(); 02389 const Uint32 lockId = req->lockId; 02390 02391 LockQueuePtr lockQPtr; 02392 if(!c_lockQueues.find(lockQPtr, lockId)){ 02393 jam(); 02394 sendUNLOCK_REF(signal, req, UtilUnlockRef::NoSuchLock); 02395 return; 02396 } 02397 02398 LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, 02399 lockQPtr.p->m_queue); 02400 LockQueueElementPtr lockEPtr; 02401 if(!queue.first(lockEPtr)){ 02402 jam(); 02403 sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner); 02404 return; 02405 } 02406 02407 if(lockQPtr.p->m_lockKey != req->lockKey){ 02408 jam(); 02409 sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner); 02410 return; 02411 } 02412 02413 sendUNLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); 02414 queue.release(lockEPtr); 02415 02416 if(queue.first(lockEPtr)){ 02417 jam(); 02418 sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p); 02419 return; 02420 } 02421 } 02422 02423 void 02424 DbUtil::sendLOCK_REF(Signal* signal, 02425 const UtilLockReq * req, UtilLockRef::ErrorCode err){ 02426 const Uint32 senderData = req->senderData; 02427 const Uint32 senderRef = req->senderRef; 02428 const Uint32 lockId = req->lockId; 02429 02430 UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend(); 02431 ref->senderData = senderData; 02432 ref->senderRef = reference(); 02433 ref->lockId = lockId; 02434 ref->errorCode = err; 02435 sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal, 02436 UtilLockRef::SignalLength, JBB); 02437 } 02438 02439 void 02440 DbUtil::sendLOCK_CONF(Signal* signal, 02441 LockQueue * lockQP, 02442 LockQueueElement * lockEP){ 02443 const Uint32 senderData = lockEP->m_senderData; 02444 const Uint32 senderRef = lockEP->m_senderRef; 02445 const Uint32 lockId = lockQP->m_lockId; 02446 const Uint32 lockKey = ++lockQP->m_lockKey; 02447 02448 UtilLockConf * conf = (UtilLockConf*)signal->getDataPtrSend(); 02449 conf->senderData = senderData; 02450 conf->senderRef = reference(); 02451 conf->lockId = lockId; 02452 conf->lockKey = lockKey; 02453 sendSignal(senderRef, GSN_UTIL_LOCK_CONF, signal, 02454 UtilLockConf::SignalLength, JBB); 02455 } 02456 02457 void 02458 DbUtil::sendUNLOCK_REF(Signal* signal, 02459 const UtilUnlockReq* req, UtilUnlockRef::ErrorCode err){ 02460 02461 const Uint32 senderData = req->senderData; 02462 const Uint32 senderRef = req->senderRef; 02463 const Uint32 lockId = req->lockId; 02464 02465 UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtrSend(); 02466 ref->senderData = senderData; 02467 ref->senderRef = reference(); 02468 ref->lockId = lockId; 02469 ref->errorCode = err; 02470 sendSignal(senderRef, GSN_UTIL_UNLOCK_REF, signal, 02471 UtilUnlockRef::SignalLength, JBB); 02472 } 02473 02474 void 02475 DbUtil::sendUNLOCK_CONF(Signal* signal, 02476 LockQueue * lockQP, 02477 LockQueueElement * lockEP){ 02478 const Uint32 senderData = lockEP->m_senderData; 02479 const Uint32 senderRef = lockEP->m_senderRef; 02480 const Uint32 lockId = lockQP->m_lockId; 02481 ++lockQP->m_lockKey; 02482 02483 UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtrSend(); 02484 conf->senderData = senderData; 02485 conf->senderRef = reference(); 02486 conf->lockId = lockId; 02487 sendSignal(senderRef, GSN_UTIL_UNLOCK_CONF, signal, 02488 UtilUnlockConf::SignalLength, JBB); 02489 } 02490 02491 void 02492 DbUtil::execUTIL_CREATE_LOCK_REQ(Signal* signal){ 02493 jamEntry(); 02494 UtilCreateLockReq req = * (UtilCreateLockReq*)signal->getDataPtr(); 02495 02496 UtilCreateLockRef::ErrorCode err = UtilCreateLockRef::OK; 02497 02498 do { 02499 LockQueuePtr lockQPtr; 02500 if(c_lockQueues.find(lockQPtr, req.lockId)){ 02501 jam(); 02502 err = UtilCreateLockRef::LockIdAlreadyUsed; 02503 break; 02504 } 02505 02506 if(req.lockType != UtilCreateLockReq::Mutex){ 02507 jam(); 02508 err = UtilCreateLockRef::UnsupportedLockType; 02509 break; 02510 } 02511 02512 if(!c_lockQueues.seize(lockQPtr)){ 02513 jam(); 02514 err = UtilCreateLockRef::OutOfLockQueueRecords; 02515 break; 02516 } 02517 02518 new (lockQPtr.p) LockQueue(req.lockId); 02519 c_lockQueues.add(lockQPtr); 02520 02521 UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtrSend(); 02522 conf->senderData = req.senderData; 02523 conf->senderRef = reference(); 02524 conf->lockId = req.lockId; 02525 02526 sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_CONF, signal, 02527 UtilCreateLockConf::SignalLength, JBB); 02528 return; 02529 } while(false); 02530 02531 UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtrSend(); 02532 ref->senderData = req.senderData; 02533 ref->senderRef = reference(); 02534 ref->lockId = req.lockId; 02535 ref->errorCode = err; 02536 02537 sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_REF, signal, 02538 UtilCreateLockRef::SignalLength, JBB); 02539 } 02540 02541 void 02542 DbUtil::execUTIL_DESTORY_LOCK_REQ(Signal* signal){ 02543 jamEntry(); 02544 02545 UtilDestroyLockReq req = * (UtilDestroyLockReq*)signal->getDataPtr(); 02546 UtilDestroyLockRef::ErrorCode err = UtilDestroyLockRef::OK; 02547 do { 02548 LockQueuePtr lockQPtr; 02549 if(!c_lockQueues.find(lockQPtr, req.lockId)){ 02550 jam(); 02551 err = UtilDestroyLockRef::NoSuchLock; 02552 break; 02553 } 02554 02555 LocalDLFifoList<LockQueueElement> queue(c_lockElementPool, 02556 lockQPtr.p->m_queue); 02557 LockQueueElementPtr lockEPtr; 02558 if(!queue.first(lockEPtr)){ 02559 jam(); 02560 err = UtilDestroyLockRef::NotLockOwner; 02561 break; 02562 } 02563 02564 if(lockQPtr.p->m_lockKey != req.lockKey){ 02565 jam(); 02566 err = UtilDestroyLockRef::NotLockOwner; 02567 break; 02568 } 02569 02574 // Inform all in lock queue that queue has been destroyed 02575 UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend(); 02576 ref->lockId = req.lockId; 02577 ref->errorCode = UtilLockRef::NoSuchLock; 02578 ref->senderRef = reference(); 02579 LockQueueElementPtr loopPtr = lockEPtr; 02580 for(queue.next(loopPtr); !loopPtr.isNull(); queue.next(loopPtr)){ 02581 jam(); 02582 ref->senderData = loopPtr.p->m_senderData; 02583 const Uint32 senderRef = loopPtr.p->m_senderRef; 02584 sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal, 02585 UtilLockRef::SignalLength, JBB); 02586 } 02587 queue.release(); 02588 c_lockQueues.release(lockQPtr); 02589 02590 // Send Destroy conf 02591 UtilDestroyLockConf* conf=(UtilDestroyLockConf*)signal->getDataPtrSend(); 02592 conf->senderData = req.senderData; 02593 conf->senderRef = reference(); 02594 conf->lockId = req.lockId; 02595 sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_CONF, signal, 02596 UtilDestroyLockConf::SignalLength, JBB); 02597 return; 02598 } while(false); 02599 02600 UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtrSend(); 02601 ref->senderData = req.senderData; 02602 ref->senderRef = reference(); 02603 ref->lockId = req.lockId; 02604 ref->errorCode = err; 02605 sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_REF, signal, 02606 UtilDestroyLockRef::SignalLength, JBB); 02607 } 02608 02609 template class ArrayPool<DbUtil::Page32>;
1.4.7

