1 /*
2 Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <ndb_global.h>
26
27 #include "DbUtil.hpp"
28
29 #include <ndb_version.h>
30
31 #include <signaldata/WaitGCP.hpp>
32 #include <signaldata/KeyInfo.hpp>
33 #include <signaldata/AttrInfo.hpp>
34 #include <signaldata/TcKeyConf.hpp>
35 #include <signaldata/TcKeyFailConf.hpp>
36 #include <signaldata/GetTabInfo.hpp>
37 #include <signaldata/DictTabInfo.hpp>
38 #include <signaldata/NodeFailRep.hpp>
39
40 #include <signaldata/UtilSequence.hpp>
41 #include <signaldata/UtilPrepare.hpp>
42 #include <signaldata/UtilRelease.hpp>
43 #include <signaldata/UtilExecute.hpp>
44 #include <signaldata/UtilLock.hpp>
45
46 #include <SectionReader.hpp>
47 #include <Interpreter.hpp>
48 #include <AttributeHeader.hpp>
49
50 #include <NdbTick.h>
51
52 #include <signaldata/DbinfoScan.hpp>
53 #include <signaldata/TransIdAI.hpp>
54
55 /**************************************************************************
56 * ------------------------------------------------------------------------
57 * MODULE: Startup
58 * ------------------------------------------------------------------------
59 *
60 * Constructors, startup, initializations
61 **************************************************************************/
62
DbUtil(Block_context & ctx)63 DbUtil::DbUtil(Block_context& ctx) :
64 SimulatedBlock(DBUTIL, ctx),
65 c_runningPrepares(c_preparePool),
66 c_seizingTransactions(c_transactionPool),
67 c_runningTransactions(c_transactionPool),
68 c_lockQueues(c_lockQueuePool)
69 {
70 BLOCK_CONSTRUCTOR(DbUtil);
71
72 // Add received signals
73 addRecSignal(GSN_READ_CONFIG_REQ, &DbUtil::execREAD_CONFIG_REQ);
74 addRecSignal(GSN_STTOR, &DbUtil::execSTTOR);
75 addRecSignal(GSN_NDB_STTOR, &DbUtil::execNDB_STTOR);
76 addRecSignal(GSN_DUMP_STATE_ORD, &DbUtil::execDUMP_STATE_ORD);
77 addRecSignal(GSN_DBINFO_SCANREQ, &DbUtil::execDBINFO_SCANREQ);
78 addRecSignal(GSN_CONTINUEB, &DbUtil::execCONTINUEB);
79 addRecSignal(GSN_NODE_FAILREP, &DbUtil::execNODE_FAILREP);
80
81 //addRecSignal(GSN_TCSEIZEREF, &DbUtil::execTCSEIZEREF);
82 addRecSignal(GSN_TCSEIZECONF, &DbUtil::execTCSEIZECONF);
83 addRecSignal(GSN_TCKEYCONF, &DbUtil::execTCKEYCONF);
84 addRecSignal(GSN_TCKEYREF, &DbUtil::execTCKEYREF);
85 addRecSignal(GSN_TCROLLBACKREP, &DbUtil::execTCROLLBACKREP);
86
87 //addRecSignal(GSN_TCKEY_FAILCONF, &DbUtil::execTCKEY_FAILCONF);
88 //addRecSignal(GSN_TCKEY_FAILREF, &DbUtil::execTCKEY_FAILREF);
89 addRecSignal(GSN_TRANSID_AI, &DbUtil::execTRANSID_AI);
90
91 /**
92 * Sequence Service
93 */
94 addRecSignal(GSN_UTIL_SEQUENCE_REQ, &DbUtil::execUTIL_SEQUENCE_REQ);
95 // Debug
96 addRecSignal(GSN_UTIL_SEQUENCE_REF, &DbUtil::execUTIL_SEQUENCE_REF);
97 addRecSignal(GSN_UTIL_SEQUENCE_CONF, &DbUtil::execUTIL_SEQUENCE_CONF);
98
99 /**
100 * Locking
101 */
102 addRecSignal(GSN_UTIL_CREATE_LOCK_REQ, &DbUtil::execUTIL_CREATE_LOCK_REQ);
103 addRecSignal(GSN_UTIL_DESTROY_LOCK_REQ, &DbUtil::execUTIL_DESTORY_LOCK_REQ);
104 addRecSignal(GSN_UTIL_LOCK_REQ, &DbUtil::execUTIL_LOCK_REQ);
105 addRecSignal(GSN_UTIL_UNLOCK_REQ, &DbUtil::execUTIL_UNLOCK_REQ);
106
107 /**
108 * Backend towards Dict
109 */
110 addRecSignal(GSN_GET_TABINFOREF, &DbUtil::execGET_TABINFOREF);
111 addRecSignal(GSN_GET_TABINFO_CONF, &DbUtil::execGET_TABINFO_CONF);
112
113 /**
114 * Prepare / Execute / Release Services
115 */
116 addRecSignal(GSN_UTIL_PREPARE_REQ, &DbUtil::execUTIL_PREPARE_REQ);
117 addRecSignal(GSN_UTIL_PREPARE_CONF, &DbUtil::execUTIL_PREPARE_CONF);
118 addRecSignal(GSN_UTIL_PREPARE_REF, &DbUtil::execUTIL_PREPARE_REF);
119
120 addRecSignal(GSN_UTIL_EXECUTE_REQ, &DbUtil::execUTIL_EXECUTE_REQ);
121 addRecSignal(GSN_UTIL_EXECUTE_CONF, &DbUtil::execUTIL_EXECUTE_CONF);
122 addRecSignal(GSN_UTIL_EXECUTE_REF, &DbUtil::execUTIL_EXECUTE_REF);
123
124 addRecSignal(GSN_UTIL_RELEASE_REQ, &DbUtil::execUTIL_RELEASE_REQ);
125 addRecSignal(GSN_UTIL_RELEASE_CONF, &DbUtil::execUTIL_RELEASE_CONF);
126 addRecSignal(GSN_UTIL_RELEASE_REF, &DbUtil::execUTIL_RELEASE_REF);
127 }
128
~DbUtil()129 DbUtil::~DbUtil()
130 {
131 }
132
BLOCK_FUNCTIONS(DbUtil)133 BLOCK_FUNCTIONS(DbUtil)
134
135 void
136 DbUtil::releasePrepare(PreparePtr prepPtr) {
137 prepPtr.p->preparePages.release();
138 c_runningPrepares.release(prepPtr); // Automatic release in pool
139 }
140
141 void
releasePreparedOperation(PreparedOperationPtr prepOpPtr)142 DbUtil::releasePreparedOperation(PreparedOperationPtr prepOpPtr) {
143 prepOpPtr.p->attrMapping.release();
144 prepOpPtr.p->attrInfo.release();
145 prepOpPtr.p->rsInfo.release();
146 prepOpPtr.p->pkBitmask.clear();
147 c_preparedOperationPool.release(prepOpPtr); // No list holding these structs
148 }
149
150 void
releaseTransaction(TransactionPtr transPtr)151 DbUtil::releaseTransaction(TransactionPtr transPtr){
152 transPtr.p->executePages.release();
153 OperationPtr opPtr;
154 for(transPtr.p->operations.first(opPtr); opPtr.i != RNIL;
155 transPtr.p->operations.next(opPtr)){
156 opPtr.p->attrInfo.release();
157 opPtr.p->keyInfo.release();
158 opPtr.p->rs.release();
159 if (opPtr.p->prepOp != 0 && opPtr.p->prepOp_i != RNIL) {
160 if (opPtr.p->prepOp->releaseFlag) {
161 PreparedOperationPtr prepOpPtr;
162 prepOpPtr.i = opPtr.p->prepOp_i;
163 prepOpPtr.p = opPtr.p->prepOp;
164 releasePreparedOperation(prepOpPtr);
165 }
166 }
167 }
168 transPtr.p->operations.release();
169 c_runningTransactions.release(transPtr);
170 }
171
172 void
execREAD_CONFIG_REQ(Signal * signal)173 DbUtil::execREAD_CONFIG_REQ(Signal* signal)
174 {
175 jamEntry();
176
177 const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
178
179 Uint32 ref = req->senderRef;
180 Uint32 senderData = req->senderData;
181
182 const ndb_mgm_configuration_iterator * p =
183 m_ctx.m_config.getOwnConfigIterator();
184 ndbrequire(p != 0);
185
186 c_pagePool.setSize(10);
187 c_preparePool.setSize(1); // one parallel prepare at a time
188 c_preparedOperationPool.setSize(6); // three hardcoded, one for setval, two for test
189 c_operationPool.setSize(64); // 64 parallel operations
190 c_transactionPool.setSize(32); // 16 parallel transactions
191 c_attrMappingPool.setSize(100);
192 c_dataBufPool.setSize(6000); // 6000*11*4 = 264K > 8k+8k*16 = 256k
193 {
194 SLList<Prepare> tmp(c_preparePool);
195 PreparePtr ptr;
196 while(tmp.seize(ptr))
197 new (ptr.p) Prepare(c_pagePool);
198 tmp.release();
199 }
200 {
201 SLList<Operation> tmp(c_operationPool);
202 OperationPtr ptr;
203 while(tmp.seize(ptr))
204 new (ptr.p) Operation(c_dataBufPool, c_dataBufPool, c_dataBufPool);
205 tmp.release();
206 }
207 {
208 SLList<PreparedOperation> tmp(c_preparedOperationPool);
209 PreparedOperationPtr ptr;
210 while(tmp.seize(ptr))
211 new (ptr.p) PreparedOperation(c_attrMappingPool,
212 c_dataBufPool, c_dataBufPool);
213 tmp.release();
214 }
215 {
216 SLList<Transaction> tmp(c_transactionPool);
217 TransactionPtr ptr;
218 while(tmp.seize(ptr))
219 new (ptr.p) Transaction(c_pagePool, c_operationPool);
220 tmp.release();
221 }
222
223 c_lockQueuePool.setSize(5);
224 c_lockElementPool.setSize(4*MAX_NDB_NODES);
225 c_lockQueues.setSize(8);
226
227 ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
228 conf->senderRef = reference();
229 conf->senderData = senderData;
230 sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
231 ReadConfigConf::SignalLength, JBB);
232 }
233
234 void
execSTTOR(Signal * signal)235 DbUtil::execSTTOR(Signal* signal)
236 {
237 jamEntry();
238
239 const Uint32 startphase = signal->theData[1];
240
241 if(startphase == 1){
242 c_transId[0] = (number() << 20) + (getOwnNodeId() << 8);
243 c_transId[1] = 0;
244 }
245
246 if(startphase == 6)
247 {
248 jam();
249
250 /**
251 * 1) get systab_0 table-id
252 * 2) run hardcodedPrepare (for sequences)
253 * 3) connectTc()
254 * 4) STTORRY
255 */
256
257 /**
258 * We need to find table-id of SYSTAB_0, as it can be after upgrade
259 * we don't know what it will be...
260 */
261 get_systab_tableid(signal);
262
263 return;
264 }
265
266 signal->theData[0] = 0;
267 signal->theData[3] = 1;
268 signal->theData[4] = 6;
269 signal->theData[5] = 255;
270 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
271
272 return;
273 }
274
275 void
get_systab_tableid(Signal * signal)276 DbUtil::get_systab_tableid(Signal* signal)
277 {
278 static char NAME[] = "sys/def/SYSTAB_0";
279
280 GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
281 req->senderRef = reference();
282 req->senderData = RNIL;
283 req->schemaTransId = 0;
284 req->requestType = GetTabInfoReq::RequestByName |
285 GetTabInfoReq::LongSignalConf;
286
287 req->tableNameLen = sizeof(NAME);
288
289 /********************************************
290 * Code signal data and send signals to DICT
291 ********************************************/
292
293 Uint32 buf[(sizeof(NAME)+3)/4];
294 ndbrequire(sizeof(buf) >= sizeof(NAME));
295 memcpy(buf, NAME, sizeof(NAME));
296
297 LinearSectionPtr ptr[1];
298 ptr[0].p = buf;
299 ptr[0].sz = sizeof(NAME);
300 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
301 GetTabInfoReq::SignalLength, JBB, ptr,1);
302 }
303
304 void
execNDB_STTOR(Signal * signal)305 DbUtil::execNDB_STTOR(Signal* signal)
306 {
307 (void)signal; // Don't want compiler warning
308
309 jamEntry();
310 }
311
312
313 /***************************
314 * Seize a number of TC records
315 * to use for Util transactions
316 */
317
318 void
connectTc(Signal * signal)319 DbUtil::connectTc(Signal* signal){
320
321 TransactionPtr ptr;
322 while(c_seizingTransactions.seize(ptr)){
323 signal->theData[0] = ptr.i << 1; // See TcCommitConf
324 signal->theData[1] = reference();
325 sendSignal(DBTC_REF, GSN_TCSEIZEREQ, signal, 2, JBB);
326 }
327 }
328
329 void
execTCSEIZECONF(Signal * signal)330 DbUtil::execTCSEIZECONF(Signal* signal){
331 jamEntry();
332
333 TransactionPtr ptr;
334 ptr.i = signal->theData[0] >> 1;
335 c_seizingTransactions.getPtr(ptr, signal->theData[0] >> 1);
336 ptr.p->connectPtr = signal->theData[1];
337 ptr.p->connectRef = signal->theData[2];
338
339 c_seizingTransactions.release(ptr);
340
341 if (c_seizingTransactions.isEmpty())
342 {
343 jam();
344 signal->theData[0] = 0;
345 signal->theData[3] = 1;
346 signal->theData[4] = 6;
347 signal->theData[5] = 255;
348 sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 6, JBB);
349 }
350 }
351
352
353 /**************************************************************************
354 * ------------------------------------------------------------------------
355 * MODULE: Misc
356 * ------------------------------------------------------------------------
357 *
358 * ContinueB, Dump
359 **************************************************************************/
360
361 void
execCONTINUEB(Signal * signal)362 DbUtil::execCONTINUEB(Signal* signal){
363 jamEntry();
364 //const Uint32 Tdata0 = signal->theData[0];
365
366 ndbrequire(0);
367 }
368
369 void
execNODE_FAILREP(Signal * signal)370 DbUtil::execNODE_FAILREP(Signal* signal){
371 jamEntry();
372 const NodeFailRep * rep = (NodeFailRep*)signal->getDataPtr();
373 NdbNodeBitmask failed;
374 failed.assign(NdbNodeBitmask::Size, rep->theNodes);
375
376 /* Block level cleanup */
377 for(unsigned i = 1; i < MAX_NDB_NODES; i++) {
378 jam();
379 if(failed.get(i)) {
380 jam();
381 Uint32 elementsCleaned = simBlockNodeFailure(signal, i); // No callback
382 ndbassert(elementsCleaned == 0); // No distributed fragmented signals
383 (void) elementsCleaned; // Remove compiler warning
384 }//if
385 }//for
386 }
387
388 void
execDUMP_STATE_ORD(Signal * signal)389 DbUtil::execDUMP_STATE_ORD(Signal* signal){
390 jamEntry();
391
392 /****************************************************************************
393 * SEQUENCE SERVICE
394 *
395 * 200 : Simple test of Public Sequence Interface
396 * ----------------------------------------------
397 * - Sends a SEQUENCE_REQ signal to Util (itself)
398 */
399 const Uint32 tCase = signal->theData[0];
400 if(tCase == 200){
401 jam();
402 ndbout << "--------------------------------------------------" << endl;
403 UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtrSend();
404 Uint32 seqId = 1;
405 Uint32 reqTy = UtilSequenceReq::CurrVal;
406
407 if(signal->length() > 1) seqId = signal->theData[1];
408 if(signal->length() > 2) reqTy = signal->theData[2];
409
410 req->senderData = 12;
411 req->sequenceId = seqId;
412 req->requestType = reqTy;
413
414 sendSignal(DBUTIL_REF, GSN_UTIL_SEQUENCE_REQ,
415 signal, UtilSequenceReq::SignalLength, JBB);
416 }
417
418 /****************************************************************************/
419 /* // Obsolete tests, should be rewritten for long signals!!
420 if(tCase == 210){
421 jam();
422 ndbout << "--------------------------------------------------" << endl;
423 const Uint32 pageSizeInWords = 128;
424 Uint32 propPage[pageSizeInWords];
425 LinearWriter w(&propPage[0], 128);
426 w.first();
427 w.add(UtilPrepareReq::NoOfOperations, 1);
428 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete);
429 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
430 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
431 Uint32 length = w.getWordsUsed();
432 ndbassert(length <= pageSizeInWords);
433
434 sendUtilPrepareReqSignals(signal, propPage, length);
435 }
436 if(tCase == 211){
437 jam();
438 ndbout << "--------------------------------------------------" << endl;
439 const Uint32 pageSizeInWords = 128;
440 Uint32 propPage[pageSizeInWords];
441 LinearWriter w(&propPage[0],128);
442 w.first();
443 w.add(UtilPrepareReq::NoOfOperations, 1);
444 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert);
445 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
446 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
447 w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1
448 Uint32 length = w.getWordsUsed();
449 ndbassert(length <= pageSizeInWords);
450
451 sendUtilPrepareReqSignals(signal, propPage, length);
452 }
453 if(tCase == 212){
454 jam();
455 ndbout << "--------------------------------------------------" << endl;
456 const Uint32 pageSizeInWords = 128;
457 Uint32 propPage[pageSizeInWords];
458 LinearWriter w(&propPage[0],128);
459 w.first();
460 w.add(UtilPrepareReq::NoOfOperations, 1);
461 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update);
462 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
463 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
464 w.add(UtilPrepareReq::AttributeName, "NEXTID"); // AttrNo = 1
465 Uint32 length = w.getWordsUsed();
466 ndbassert(length <= pageSizeInWords);
467
468 sendUtilPrepareReqSignals(signal, propPage, length);
469 }
470 if(tCase == 213){
471 jam();
472 ndbout << "--------------------------------------------------" << endl;
473 const Uint32 pageSizeInWords = 128;
474 Uint32 propPage[pageSizeInWords];
475 LinearWriter w(&propPage[0],128);
476 w.first();
477 w.add(UtilPrepareReq::NoOfOperations, 1);
478 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read);
479 w.add(UtilPrepareReq::TableName, "sys/def/SYSTAB_0");
480 w.add(UtilPrepareReq::AttributeName, "SYSKEY_0"); // AttrNo = 0
481 Uint32 length = w.getWordsUsed();
482 ndbassert(length <= pageSizeInWords);
483
484 sendUtilPrepareReqSignals(signal, propPage, length);
485 }
486 if(tCase == 214){
487 jam();
488 ndbout << "--------------------------------------------------" << endl;
489 const Uint32 pageSizeInWords = 128;
490 Uint32 propPage[pageSizeInWords];
491 LinearWriter w(&propPage[0], 128);
492 w.first();
493 w.add(UtilPrepareReq::NoOfOperations, 1);
494 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Delete);
495 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
496 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
497 Uint32 length = w.getWordsUsed();
498 ndbassert(length <= pageSizeInWords);
499
500 sendUtilPrepareReqSignals(signal, propPage, length);
501 }
502 if(tCase == 215){
503 jam();
504 ndbout << "--------------------------------------------------" << endl;
505 const Uint32 pageSizeInWords = 128;
506 Uint32 propPage[pageSizeInWords];
507 LinearWriter w(&propPage[0],128);
508 w.first();
509 w.add(UtilPrepareReq::NoOfOperations, 1);
510 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Insert);
511 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
512 w.add(UtilPrepareReq::AttributeId, (unsigned int)0); // SYSKEY_0
513 w.add(UtilPrepareReq::AttributeId, 1); // NEXTID
514 Uint32 length = w.getWordsUsed();
515 ndbassert(length <= pageSizeInWords);
516
517 sendUtilPrepareReqSignals(signal, propPage, length);
518 }
519 if(tCase == 216){
520 jam();
521 ndbout << "--------------------------------------------------" << endl;
522 const Uint32 pageSizeInWords = 128;
523 Uint32 propPage[pageSizeInWords];
524 LinearWriter w(&propPage[0],128);
525 w.first();
526 w.add(UtilPrepareReq::NoOfOperations, 1);
527 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Update);
528 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
529 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
530 w.add(UtilPrepareReq::AttributeId, 1); // NEXTID
531 Uint32 length = w.getWordsUsed();
532 ndbassert(length <= pageSizeInWords);
533
534 sendUtilPrepareReqSignals(signal, propPage, length);
535 }
536 if(tCase == 217){
537 jam();
538 ndbout << "--------------------------------------------------" << endl;
539 const Uint32 pageSizeInWords = 128;
540 Uint32 propPage[pageSizeInWords];
541 LinearWriter w(&propPage[0],128);
542 w.first();
543 w.add(UtilPrepareReq::NoOfOperations, 1);
544 w.add(UtilPrepareReq::OperationType, UtilPrepareReq::Read);
545 w.add(UtilPrepareReq::TableId, (unsigned int)0); // SYSTAB_0
546 w.add(UtilPrepareReq::AttributeId, (unsigned int)0);// SYSKEY_0
547 Uint32 length = w.getWordsUsed();
548 ndbassert(length <= pageSizeInWords);
549
550 sendUtilPrepareReqSignals(signal, propPage, length);
551 }
552 */
553 /****************************************************************************/
554 /* // Obsolete tests, should be rewritten for long signals!!
555 if(tCase == 220){
556 jam();
557 ndbout << "--------------------------------------------------" << endl;
558 Uint32 prepI = signal->theData[1];
559 Uint32 length = signal->theData[2];
560 Uint32 attributeValue0 = signal->theData[3];
561 Uint32 attributeValue1a = signal->theData[4];
562 Uint32 attributeValue1b = signal->theData[5];
563 ndbrequire(prepI != 0);
564
565 UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtrSend();
566
567 req->senderData = 221;
568 req->prepareId = prepI;
569 req->totalDataLen = length; // Including headers
570 req->offset = 0;
571
572 AttributeHeader::init(&req->attrData[0], 0, 1); // AttrNo 0, DataSize
573 req->attrData[1] = attributeValue0; // AttrValue
574 AttributeHeader::init(&req->attrData[2], 1, 2); // AttrNo 1, DataSize
575 req->attrData[3] = attributeValue1a; // AttrValue
576 req->attrData[4] = attributeValue1b; // AttrValue
577
578 printUTIL_EXECUTE_REQ(stdout, signal->getDataPtrSend(), 3 + 5,0);
579 sendSignal(DBUTIL_REF, GSN_UTIL_EXECUTE_REQ, signal, 3 + 5, JBB);
580 }
581 */
582 /****************************************************************************
583 * 230 : PRINT STATE
584 */
585 #ifdef ARRAY_GUARD
586 if(tCase == 230){
587 jam();
588
589 ndbout << "--------------------------------------------------" << endl;
590 if (signal->length() <= 1) {
591 ndbout << "Usage: DUMP 230 <recordType> <recordNo>" << endl
592 << "[1] Print Prepare (running) records" << endl
593 << "[2] Print PreparedOperation records" << endl
594 << "[3] Print Transaction records" << endl
595 << "[4] Print Operation records" << endl
596 << "Ex. \"dump 230 1 2\" prints Prepare record no 2." << endl
597 << endl
598 << "210 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0" << endl
599 << "211 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID" << endl
600 << "212 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID" << endl
601 << "213 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0" << endl
602 << "214 : PREPARE_REQ DELETE SYSTAB_0 SYSKEY_0 using id" << endl
603 << "215 : PREPARE_REQ INSERT SYSTAB_0 SYSKEY_0 NEXTID using id" << endl
604 << "216 : PREPARE_REQ UPDATE SYSTAB_0 SYSKEY_0 NEXTID using id" << endl
605 << "217 : PREPARE_REQ READ SYSTAB_0 SYSKEY_0 using id" << endl
606 << "220 : EXECUTE_REQ <PrepId> <Len> <Val1> <Val2a> <Val2b>" <<endl
607 << "299 : Crash system (using ndbrequire(0))"
608 << endl
609 << "Ex. \"dump 220 3 5 1 0 17 \" prints Prepare record no 2."
610 << endl;
611 return;
612 }
613
614 switch (signal->theData[1]) {
615 case 1:
616 // ** Print a specific record **
617 if (signal->length() >= 3) {
618 PreparePtr prepPtr;
619 if (!c_preparePool.isSeized(signal->theData[2])) {
620 ndbout << "Prepare Id: " << signal->theData[2]
621 << " (Not seized!)" << endl;
622 } else {
623 c_preparePool.getPtr(prepPtr, signal->theData[2]);
624 prepPtr.p->print();
625 }
626 return;
627 }
628
629 // ** Print all records **
630 PreparePtr prepPtr;
631 if (!c_runningPrepares.first(prepPtr)) {
632 ndbout << "No Prepare records exist" << endl;
633 return;
634 }
635
636 while (!prepPtr.isNull()) {
637 prepPtr.p->print();
638 c_runningPrepares.next(prepPtr);
639 }
640 return;
641
642 case 2:
643 // ** Print a specific record **
644 if (signal->length() >= 3) {
645 if (!c_preparedOperationPool.isSeized(signal->theData[2])) {
646 ndbout << "PreparedOperation Id: " << signal->theData[2]
647 << " (Not seized!)" << endl;
648 return;
649 }
650 ndbout << "PreparedOperation Id: " << signal->theData[2] << endl;
651 PreparedOperationPtr prepOpPtr;
652 c_preparedOperationPool.getPtr(prepOpPtr, signal->theData[2]);
653 prepOpPtr.p->print();
654 return;
655 }
656
657 // ** Print all records **
658 #if 0 // not implemented
659 PreparedOperationPtr prepOpPtr;
660 if (!c_runningPreparedOperations.first(prepOpPtr)) {
661 ndbout << "No PreparedOperations exist" << endl;
662 return;
663 }
664 while (!prepOpPtr.isNull()) {
665 ndbout << "[-PreparedOperation no " << prepOpPtr.i << ":";
666 prepOpPtr.p->print();
667 ndbout << "]";
668 c_runningPreparedOperations.next(prepOpPtr);
669 }
670 #endif
671 return;
672
673 case 3:
674 // ** Print a specific record **
675 if (signal->length() >= 3) {
676 ndbout << "Print specific record not implemented." << endl;
677 return;
678 }
679
680 // ** Print all records **
681 ndbout << "Print all records not implemented, specify an Id." << endl;
682 return;
683
684 case 4:
685 ndbout << "Not implemented" << endl;
686 return;
687
688 default:
689 ndbout << "Unknown input (try without any data)" << endl;
690 return;
691 }
692 }
693 #endif
694 if(tCase == 240 && signal->getLength() == 2){
695 MutexManager::ActiveMutexPtr ptr;
696 ndbrequire(c_mutexMgr.seize(ptr));
697 ptr.p->m_mutexId = signal->theData[1];
698 Callback c = { safe_cast(&DbUtil::mutex_created), ptr.i };
699 ptr.p->m_callback = c;
700 c_mutexMgr.create(signal, ptr);
701 ndbout_c("c_mutexMgr.create ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
702 }
703
704 if(tCase == 241 && signal->getLength() == 2){
705 MutexManager::ActiveMutexPtr ptr;
706 ndbrequire(c_mutexMgr.seize(ptr));
707 ptr.p->m_mutexId = signal->theData[1];
708 Callback c = { safe_cast(&DbUtil::mutex_locked), ptr.i };
709 ptr.p->m_callback = c;
710 c_mutexMgr.lock(signal, ptr, true);
711 ndbout_c("c_mutexMgr.lock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
712 }
713
714 if(tCase == 242 && signal->getLength() == 2){
715 MutexManager::ActiveMutexPtr ptr;
716 ptr.i = signal->theData[1];
717 c_mutexMgr.getPtr(ptr);
718 Callback c = { safe_cast(&DbUtil::mutex_unlocked), ptr.i };
719 ptr.p->m_callback = c;
720 c_mutexMgr.unlock(signal, ptr);
721 ndbout_c("c_mutexMgr.unlock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
722 }
723
724 if(tCase == 243 && signal->getLength() == 3){
725 MutexManager::ActiveMutexPtr ptr;
726 ndbrequire(c_mutexMgr.seize(ptr));
727 ptr.p->m_mutexId = signal->theData[1];
728 Callback c = { safe_cast(&DbUtil::mutex_destroyed), ptr.i };
729 ptr.p->m_callback = c;
730 c_mutexMgr.destroy(signal, ptr);
731 ndbout_c("c_mutexMgr.destroy ptrI=%d mutexId=%d",
732 ptr.i, ptr.p->m_mutexId);
733 }
734
735 if (tCase == 244)
736 {
737 jam();
738 DLHashTable<LockQueueInstance>::Iterator iter;
739 Uint32 bucket = signal->theData[1];
740 if (signal->getLength() == 1)
741 {
742 bucket = 0;
743 infoEvent("Starting dumping of DbUtil::Locks");
744 }
745 c_lockQueues.next(bucket, iter);
746
747 for (Uint32 i = 0; i<32 || iter.bucket == bucket; i++)
748 {
749 if (iter.curr.isNull())
750 {
751 infoEvent("Dumping of DbUtil::Locks - done");
752 return;
753 }
754
755 infoEvent("LockQueue %u", iter.curr.p->m_lockId);
756 iter.curr.p->m_queue.dump_queue(c_lockElementPool, this);
757 c_lockQueues.next(iter);
758 }
759 signal->theData[0] = 244;
760 signal->theData[1] = iter.bucket;
761 sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
762 return;
763 }
764 }
765
execDBINFO_SCANREQ(Signal * signal)766 void DbUtil::execDBINFO_SCANREQ(Signal *signal)
767 {
768 DbinfoScanReq req= *(DbinfoScanReq*)signal->theData;
769 const Ndbinfo::ScanCursor* cursor =
770 CAST_CONSTPTR(Ndbinfo::ScanCursor, DbinfoScan::getCursorPtr(&req));
771 Ndbinfo::Ratelimit rl;
772
773 jamEntry();
774
775 switch(req.tableId){
776 case Ndbinfo::POOLS_TABLEID:
777 {
778 Ndbinfo::pool_entry pools[] =
779 {
780 { "Page",
781 c_pagePool.getUsed(),
782 c_pagePool.getSize(),
783 c_pagePool.getEntrySize(),
784 c_pagePool.getUsedHi(),
785 { 0,0,0,0 }},
786 { "Prepare",
787 c_preparePool.getUsed(),
788 c_preparePool.getSize(),
789 c_preparePool.getEntrySize(),
790 c_preparePool.getUsedHi(),
791 { 0,0,0,0 }},
792 { "Prepared Operation",
793 c_preparedOperationPool.getUsed(),
794 c_preparedOperationPool.getSize(),
795 c_preparedOperationPool.getEntrySize(),
796 c_preparedOperationPool.getUsedHi(),
797 { 0,0,0,0 }},
798 { "Operation",
799 c_operationPool.getUsed(),
800 c_operationPool.getSize(),
801 c_operationPool.getEntrySize(),
802 c_operationPool.getUsedHi(),
803 { 0,0,0,0 }},
804 { "Transaction",
805 c_transactionPool.getUsed(),
806 c_transactionPool.getSize(),
807 c_transactionPool.getEntrySize(),
808 c_transactionPool.getUsedHi(),
809 { 0,0,0,0 }},
810 { "Attribute Mapping",
811 c_attrMappingPool.getUsed(),
812 c_attrMappingPool.getSize(),
813 c_attrMappingPool.getEntrySize(),
814 c_attrMappingPool.getUsedHi(),
815 { 0,0,0,0 }},
816 { "Data Buffer",
817 c_dataBufPool.getUsed(),
818 c_dataBufPool.getSize(),
819 c_dataBufPool.getEntrySize(),
820 c_dataBufPool.getUsedHi(),
821 { 0,0,0,0 }},
822 { NULL, 0,0,0,0, { 0,0,0,0 }}
823 };
824
825 const size_t num_config_params =
826 sizeof(pools[0].config_params) / sizeof(pools[0].config_params[0]);
827 Uint32 pool = cursor->data[0];
828 BlockNumber bn = blockToMain(number());
829 while(pools[pool].poolname)
830 {
831 jam();
832 Ndbinfo::Row row(signal, req);
833 row.write_uint32(getOwnNodeId());
834 row.write_uint32(bn); // block number
835 row.write_uint32(instance()); // block instance
836 row.write_string(pools[pool].poolname);
837 row.write_uint64(pools[pool].used);
838 row.write_uint64(pools[pool].total);
839 row.write_uint64(pools[pool].used_hi);
840 row.write_uint64(pools[pool].entry_size);
841 for (size_t i = 0; i < num_config_params; i++)
842 row.write_uint32(pools[pool].config_params[i]);
843 ndbinfo_send_row(signal, req, row, rl);
844 pool++;
845 if (rl.need_break(req))
846 {
847 jam();
848 ndbinfo_send_scan_break(signal, req, rl, pool);
849 return;
850 }
851 }
852 break;
853 }
854 default:
855 break;
856 }
857
858 ndbinfo_send_scan_conf(signal, req, rl);
859 }
860
861 void
mutex_created(Signal * signal,Uint32 ptrI,Uint32 retVal)862 DbUtil::mutex_created(Signal* signal, Uint32 ptrI, Uint32 retVal){
863 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
864 c_mutexMgr.getPtr(ptr);
865 ndbout_c("mutex_created - mutexId=%d, retVal=%d",
866 ptr.p->m_mutexId, retVal);
867 c_mutexMgr.release(ptrI);
868 }
869
870 void
mutex_destroyed(Signal * signal,Uint32 ptrI,Uint32 retVal)871 DbUtil::mutex_destroyed(Signal* signal, Uint32 ptrI, Uint32 retVal){
872 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
873 c_mutexMgr.getPtr(ptr);
874 ndbout_c("mutex_destroyed - mutexId=%d, retVal=%d",
875 ptr.p->m_mutexId, retVal);
876 c_mutexMgr.release(ptrI);
877 }
878
879 void
mutex_locked(Signal * signal,Uint32 ptrI,Uint32 retVal)880 DbUtil::mutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
881 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
882 c_mutexMgr.getPtr(ptr);
883 ndbout_c("mutex_locked - mutexId=%d, retVal=%d ptrI=%d",
884 ptr.p->m_mutexId, retVal, ptrI);
885 if(retVal)
886 c_mutexMgr.release(ptrI);
887 }
888
889 void
mutex_unlocked(Signal * signal,Uint32 ptrI,Uint32 retVal)890 DbUtil::mutex_unlocked(Signal* signal, Uint32 ptrI, Uint32 retVal){
891 MutexManager::ActiveMutexPtr ptr; ptr.i = ptrI;
892 c_mutexMgr.getPtr(ptr);
893 ndbout_c("mutex_unlocked - mutexId=%d, retVal=%d",
894 ptr.p->m_mutexId, retVal);
895 if(!retVal)
896 c_mutexMgr.release(ptrI);
897 }
898
899 void
execUTIL_SEQUENCE_REF(Signal * signal)900 DbUtil::execUTIL_SEQUENCE_REF(Signal* signal){
901 jamEntry();
902 ndbout << "UTIL_SEQUENCE_REF" << endl;
903 printUTIL_SEQUENCE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
904 }
905
906 void
execUTIL_SEQUENCE_CONF(Signal * signal)907 DbUtil::execUTIL_SEQUENCE_CONF(Signal* signal){
908 jamEntry();
909 ndbout << "UTIL_SEQUENCE_CONF" << endl;
910 printUTIL_SEQUENCE_CONF(stdout, signal->getDataPtrSend(), signal->length(),0);
911 }
912
913 void
execUTIL_PREPARE_CONF(Signal * signal)914 DbUtil::execUTIL_PREPARE_CONF(Signal* signal){
915 jamEntry();
916 ndbout << "UTIL_PREPARE_CONF" << endl;
917 printUTIL_PREPARE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0);
918 }
919
920 void
execUTIL_PREPARE_REF(Signal * signal)921 DbUtil::execUTIL_PREPARE_REF(Signal* signal){
922 jamEntry();
923 ndbout << "UTIL_PREPARE_REF" << endl;
924 printUTIL_PREPARE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
925 }
926
927 void
execUTIL_EXECUTE_CONF(Signal * signal)928 DbUtil::execUTIL_EXECUTE_CONF(Signal* signal) {
929 jamEntry();
930 ndbout << "UTIL_EXECUTE_CONF" << endl;
931 printUTIL_EXECUTE_CONF(stdout, signal->getDataPtrSend(), signal->length(), 0);
932 }
933
934 void
execUTIL_EXECUTE_REF(Signal * signal)935 DbUtil::execUTIL_EXECUTE_REF(Signal* signal) {
936 jamEntry();
937
938 ndbout << "UTIL_EXECUTE_REF" << endl;
939 printUTIL_EXECUTE_REF(stdout, signal->getDataPtrSend(), signal->length(), 0);
940 }
941
942 void
execUTIL_RELEASE_CONF(Signal * signal)943 DbUtil::execUTIL_RELEASE_CONF(Signal* signal) {
944 jamEntry();
945 ndbout << "UTIL_RELEASE_CONF" << endl;
946 }
947
948 void
execUTIL_RELEASE_REF(Signal * signal)949 DbUtil::execUTIL_RELEASE_REF(Signal* signal) {
950 jamEntry();
951
952 ndbout << "UTIL_RELEASE_REF" << endl;
953 }
954
955 void
sendUtilPrepareRef(Signal * signal,UtilPrepareRef::ErrorCode error,Uint32 recipient,Uint32 senderData,Uint32 errCode2)956 DbUtil::sendUtilPrepareRef(Signal* signal, UtilPrepareRef::ErrorCode error,
957 Uint32 recipient, Uint32 senderData,
958 Uint32 errCode2){
959 UtilPrepareRef * ref = (UtilPrepareRef *)signal->getDataPtrSend();
960 ref->errorCode = error;
961 ref->senderData = senderData;
962 ref->dictErrCode = errCode2;
963
964 sendSignal(recipient, GSN_UTIL_PREPARE_REF, signal,
965 UtilPrepareRef::SignalLength, JBB);
966 }
967
968 void
sendUtilExecuteRef(Signal * signal,UtilExecuteRef::ErrorCode error,Uint32 TCerror,Uint32 recipient,Uint32 senderData)969 DbUtil::sendUtilExecuteRef(Signal* signal, UtilExecuteRef::ErrorCode error,
970 Uint32 TCerror, Uint32 recipient, Uint32 senderData){
971
972 UtilExecuteRef * ref = (UtilExecuteRef *)signal->getDataPtrSend();
973 ref->senderData = senderData;
974 ref->errorCode = error;
975 ref->TCErrorCode = TCerror;
976
977 sendSignal(recipient, GSN_UTIL_EXECUTE_REF, signal,
978 UtilPrepareRef::SignalLength, JBB);
979 }
980
981
982 /**************************************************************************
983 * ------------------------------------------------------------------------
984 * MODULE: Prepare service
985 * ------------------------------------------------------------------------
986 *
987 * Prepares a transaction by storing info in some structs
988 **************************************************************************/
989
990 void
execUTIL_PREPARE_REQ(Signal * signal)991 DbUtil::execUTIL_PREPARE_REQ(Signal* signal)
992 {
993 jamEntry();
994
995 /****************
996 * Decode Signal
997 ****************/
998 UtilPrepareReq * req = (UtilPrepareReq *)signal->getDataPtr();
999 const Uint32 senderRef = req->senderRef;
1000 const Uint32 senderData = req->senderData;
1001 const Uint32 schemaTransId= req->schemaTransId;
1002
1003 if(signal->getNoOfSections() == 0) {
1004 // Missing prepare data
1005 jam();
1006 sendUtilPrepareRef(signal, UtilPrepareRef::MISSING_PROPERTIES_SECTION,
1007 senderRef, senderData);
1008 return;
1009 }
1010
1011 PreparePtr prepPtr;
1012 SegmentedSectionPtr ptr;
1013 SectionHandle handle(this, signal);
1014
1015 jam();
1016 if(!c_runningPrepares.seize(prepPtr)) {
1017 jam();
1018 releaseSections(handle);
1019 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_SEIZE_ERROR,
1020 senderRef, senderData);
1021 return;
1022 };
1023 handle.getSection(ptr, UtilPrepareReq::PROPERTIES_SECTION);
1024 const Uint32 noPages = (ptr.sz + sizeof(Page32)) / sizeof(Page32);
1025 ndbassert(noPages > 0);
1026 if (!prepPtr.p->preparePages.seize(noPages)) {
1027 jam();
1028 releaseSections(handle);
1029 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARE_PAGES_SEIZE_ERROR,
1030 senderRef, senderData);
1031 c_preparePool.release(prepPtr);
1032 return;
1033 }
1034 // Save SimpleProperties
1035 Uint32* target = &prepPtr.p->preparePages.getPtr(0)->data[0];
1036 copy(target, ptr);
1037 prepPtr.p->prepDataLen = ptr.sz;
1038 // Release long signal sections
1039 releaseSections(handle);
1040 // Check table properties with DICT
1041 SimplePropertiesSectionReader reader(ptr, getSectionSegmentPool());
1042 prepPtr.p->clientRef = senderRef;
1043 prepPtr.p->clientData = senderData;
1044 prepPtr.p->schemaTransId = schemaTransId;
1045 // Release long signal sections
1046 readPrepareProps(signal, &reader, prepPtr);
1047 }
1048
readPrepareProps(Signal * signal,SimpleProperties::Reader * reader,PreparePtr prepPtr)1049 void DbUtil::readPrepareProps(Signal* signal,
1050 SimpleProperties::Reader* reader,
1051 PreparePtr prepPtr)
1052 {
1053 jam();
1054 #if 0
1055 printf("DbUtil::readPrepareProps: Received SimpleProperties:\n");
1056 reader->printAll(ndbout);
1057 #endif
1058 ndbrequire(reader->first());
1059 ndbrequire(reader->getKey() == UtilPrepareReq::NoOfOperations);
1060 ndbrequire(reader->getUint32() == 1); // Only one op/trans implemented
1061
1062 ndbrequire(reader->next());
1063 ndbrequire(reader->getKey() == UtilPrepareReq::OperationType);
1064
1065 ndbrequire(reader->next());
1066 UtilPrepareReq::KeyValue tableKey =
1067 (UtilPrepareReq::KeyValue) reader->getKey();
1068 if (tableKey == UtilPrepareReq::ScanTakeOverInd)
1069 {
1070 reader->next();
1071 tableKey = (UtilPrepareReq::KeyValue) reader->getKey();
1072 }
1073 if (tableKey == UtilPrepareReq::ReorgInd)
1074 {
1075 reader->next();
1076 tableKey = (UtilPrepareReq::KeyValue) reader->getKey();
1077 }
1078
1079 ndbrequire((tableKey == UtilPrepareReq::TableName) ||
1080 (tableKey == UtilPrepareReq::TableId));
1081
1082 /************************
1083 * Ask Dict for metadata
1084 ************************/
1085 {
1086 GetTabInfoReq * req = (GetTabInfoReq *)signal->getDataPtrSend();
1087 req->senderRef = reference();
1088 req->senderData = prepPtr.i;
1089 req->schemaTransId = prepPtr.p->schemaTransId;
1090 if (tableKey == UtilPrepareReq::TableName) {
1091 jam();
1092 char tableName[MAX_TAB_NAME_SIZE];
1093 req->requestType = GetTabInfoReq::RequestByName |
1094 GetTabInfoReq::LongSignalConf;
1095
1096 req->tableNameLen = reader->getValueLen(); // Including trailing \0
1097
1098 /********************************************
1099 * Code signal data and send signals to DICT
1100 ********************************************/
1101
1102 ndbrequire(req->tableNameLen < MAX_TAB_NAME_SIZE);
1103 reader->getString((char*)tableName);
1104 LinearSectionPtr ptr[1];
1105 ptr[0].p = (Uint32*)tableName;
1106 ptr[0].sz = req->tableNameLen;
1107 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
1108 GetTabInfoReq::SignalLength, JBB, ptr,1);
1109
1110 }
1111 else { // (tableKey == UtilPrepareReq::TableId)
1112 jam();
1113 req->requestType = GetTabInfoReq::RequestById |
1114 GetTabInfoReq::LongSignalConf;
1115 req->tableId = reader->getUint32();
1116 sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal,
1117 GetTabInfoReq::SignalLength, JBB);
1118 }
1119
1120 }
1121 }
1122
1123 /**
1124 * @note We assume that this signal comes due to a request related
1125 * to a Prepare struct. DictTabInfo:s 'senderData' denotes
1126 * the Prepare struct related to the request.
1127 */
1128 void
execGET_TABINFO_CONF(Signal * signal)1129 DbUtil::execGET_TABINFO_CONF(Signal* signal){
1130 jamEntry();
1131
1132 if(!assembleFragments(signal)){
1133 jam();
1134 return;
1135 }
1136
1137 /****************
1138 * Decode signal
1139 ****************/
1140 GetTabInfoConf * const conf = (GetTabInfoConf*)signal->getDataPtr();
1141 const Uint32 prepI = conf->senderData;
1142 const Uint32 totalLen = conf->totalLen;
1143
1144 SectionHandle handle(this, signal);
1145 SegmentedSectionPtr dictTabInfoPtr;
1146 handle.getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
1147 ndbrequire(dictTabInfoPtr.sz == totalLen);
1148
1149 if (prepI != RNIL)
1150 {
1151 jam();
1152 PreparePtr prepPtr;
1153 c_runningPrepares.getPtr(prepPtr, prepI);
1154 prepareOperation(signal, prepPtr, dictTabInfoPtr);
1155 releaseSections(handle);
1156 return;
1157 }
1158 else
1159 {
1160 jam();
1161 // get_systab_tableid
1162 releaseSections(handle);
1163 hardcodedPrepare(signal, conf->tableId);
1164 return;
1165 }
1166 }
1167
1168 void
execGET_TABINFOREF(Signal * signal)1169 DbUtil::execGET_TABINFOREF(Signal* signal){
1170 jamEntry();
1171
1172 GetTabInfoRef * ref = (GetTabInfoRef *)signal->getDataPtr();
1173 Uint32 prepI = ref->senderData;
1174 #define EVENT_DEBUG
1175 #if 0 //def EVENT_DEBUG
1176 ndbout << "Signal GET_TABINFOREF received." << endl;
1177 ndbout << "Error Code: " << ref->errorCode << endl;
1178
1179 switch (ref->errorCode) {
1180 case GetTabInfoRef::InvalidTableId:
1181 ndbout << " Msg: Invalid table id" << endl;
1182 break;
1183 case GetTabInfoRef::TableNotDefined:
1184 ndbout << " Msg: Table not defined" << endl;
1185 break;
1186 case GetTabInfoRef::TableNameToLong:
1187 ndbout << " Msg: Table node too long" << endl;
1188 break;
1189 default:
1190 ndbout << " Msg: Unknown error returned from Dict" << endl;
1191 break;
1192 }
1193 #endif
1194
1195 PreparePtr prepPtr;
1196 c_runningPrepares.getPtr(prepPtr, prepI);
1197
1198 sendUtilPrepareRef(signal, UtilPrepareRef::DICT_TAB_INFO_ERROR,
1199 prepPtr.p->clientRef, prepPtr.p->clientData,
1200 ref->errorCode);
1201
1202 releasePrepare(prepPtr);
1203 }
1204
1205
1206 /******************************************************************************
1207 * Prepare Operation
1208 *
1209 * Using a prepare record, prepare an operation (i.e. create PreparedOperation).
1210 * Info from both Pepare request (PreparePages) and DictTabInfo is used.
1211 *
1212 * Algorithm:
1213 * -# Seize AttrbuteMapping
1214 * - Lookup in preparePages how many attributes should be prepared
1215 * - Seize AttributeMapping
1216 * -# For each attributes in preparePages
1217 * - Lookup id and isPK in dictInfoPages
1218 * - Store "no -> (AttributeId, Position)" in AttributeMapping
1219 * -# For each map in AttributeMapping
1220 * - if (isPK) then assign offset
1221 ******************************************************************************/
1222 void
prepareOperation(Signal * signal,PreparePtr prepPtr,SegmentedSectionPtr ptr)1223 DbUtil::prepareOperation(Signal* signal,
1224 PreparePtr prepPtr,
1225 SegmentedSectionPtr ptr)
1226 {
1227 jam();
1228
1229 /*******************************************
1230 * Seize and store PreparedOperation struct
1231 *******************************************/
1232 PreparedOperationPtr prepOpPtr;
1233 if(!c_preparedOperationPool.seize(prepOpPtr)) {
1234 jam();
1235 sendUtilPrepareRef(signal, UtilPrepareRef::PREPARED_OPERATION_SEIZE_ERROR,
1236 prepPtr.p->clientRef, prepPtr.p->clientData);
1237 releasePrepare(prepPtr);
1238 return;
1239 }
1240 prepPtr.p->prepOpPtr = prepOpPtr;
1241
1242 /********************
1243 * Read request info
1244 ********************/
1245 SimplePropertiesLinearReader prepPagesReader(&prepPtr.p->preparePages.getPtr(0)->data[0],
1246 prepPtr.p->prepDataLen);
1247
1248 ndbrequire(prepPagesReader.first());
1249 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::NoOfOperations);
1250 const Uint32 noOfOperations = prepPagesReader.getUint32();
1251 ndbrequire(noOfOperations == 1);
1252
1253 ndbrequire(prepPagesReader.next());
1254 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::OperationType);
1255 const Uint32 operationType = prepPagesReader.getUint32();
1256
1257 ndbrequire(prepPagesReader.next());
1258
1259 char tableName[MAX_TAB_NAME_SIZE];
1260 Uint32 tableId;
1261 UtilPrepareReq::KeyValue tableKey =
1262 (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
1263
1264 bool scanTakeOver = false;
1265 bool reorg = false;
1266 if (tableKey == UtilPrepareReq::ScanTakeOverInd)
1267 {
1268 scanTakeOver = true;
1269 prepPagesReader.next();
1270 tableKey = (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
1271 }
1272
1273 if (tableKey == UtilPrepareReq::ReorgInd)
1274 {
1275 reorg = true;
1276 prepPagesReader.next();
1277 tableKey = (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
1278 }
1279
1280 if (tableKey == UtilPrepareReq::TableId) {
1281 jam();
1282 tableId = prepPagesReader.getUint32();
1283 }
1284 else {
1285 jam();
1286 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::TableName);
1287 ndbrequire(prepPagesReader.getValueLen() <= MAX_TAB_NAME_SIZE);
1288 prepPagesReader.getString(tableName);
1289 }
1290 /******************************************************************
1291 * Seize AttributeMapping (by counting no of attribs in prepPages)
1292 ******************************************************************/
1293 Uint32 noOfAttributes = 0; // No of attributes in PreparePages (used later)
1294 while(prepPagesReader.next()) {
1295 if (tableKey == UtilPrepareReq::TableName) {
1296 jam();
1297 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeName);
1298 } else {
1299 jam();
1300 ndbrequire(prepPagesReader.getKey() == UtilPrepareReq::AttributeId);
1301 }
1302 noOfAttributes++;
1303 }
1304 ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.seize(noOfAttributes));
1305 if (operationType == UtilPrepareReq::Read) {
1306 ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.seize(noOfAttributes));
1307 }
1308 /***************************************
1309 * For each attribute name, lookup info
1310 ***************************************/
1311 // Goto start of attribute names
1312 ndbrequire(prepPagesReader.first() && prepPagesReader.next() &&
1313 prepPagesReader.next());
1314
1315 if (scanTakeOver)
1316 prepPagesReader.next();
1317
1318 if (reorg)
1319 prepPagesReader.next();
1320
1321 DictTabInfo::Table tableDesc; tableDesc.init();
1322 AttrMappingBuffer::DataBufferIterator attrMappingIt;
1323 ndbrequire(prepPtr.p->prepOpPtr.p->attrMapping.first(attrMappingIt));
1324
1325 ResultSetBuffer::DataBufferIterator rsInfoIt;
1326 if (operationType == UtilPrepareReq::Read) {
1327 ndbrequire(prepPtr.p->prepOpPtr.p->rsInfo.first(rsInfoIt));
1328 }
1329
1330 Uint32 noOfPKAttribsStored = 0;
1331 Uint32 noOfNonPKAttribsStored = 0;
1332 Uint32 attrLength = 0;
1333 char attrNameRequested[MAX_ATTR_NAME_SIZE];
1334 Uint32 attrIdRequested;
1335
1336 while(prepPagesReader.next()) {
1337 UtilPrepareReq::KeyValue attributeKey =
1338 (UtilPrepareReq::KeyValue) prepPagesReader.getKey();
1339
1340 ndbrequire((attributeKey == UtilPrepareReq::AttributeName) ||
1341 (attributeKey == UtilPrepareReq::AttributeId));
1342 if (attributeKey == UtilPrepareReq::AttributeName) {
1343 jam();
1344 ndbrequire(prepPagesReader.getValueLen() <= MAX_ATTR_NAME_SIZE);
1345
1346 prepPagesReader.getString(attrNameRequested);
1347 attrIdRequested= ~0u;
1348 } else {
1349 jam();
1350 attrIdRequested = prepPagesReader.getUint32();
1351 }
1352 /*****************************************
1353 * Copy DictTabInfo into tableDesc struct
1354 *****************************************/
1355
1356 SimplePropertiesSectionReader dictInfoReader(ptr, getSectionSegmentPool());
1357 SimpleProperties::UnpackStatus unpackStatus;
1358 unpackStatus = SimpleProperties::unpack(dictInfoReader, &tableDesc,
1359 DictTabInfo::TableMapping,
1360 DictTabInfo::TableMappingSize,
1361 true, true);
1362 ndbrequire(unpackStatus == SimpleProperties::Break);
1363
1364 /************************
1365 * Lookup in DictTabInfo
1366 ************************/
1367 DictTabInfo::Attribute attrDesc; attrDesc.init();
1368 char attrName[MAX_ATTR_NAME_SIZE];
1369 Uint32 attrId= ~(Uint32)0;
1370 bool attributeFound = false;
1371 Uint32 noOfKeysFound = 0; // # PK attrs found before attr in DICTdata
1372 Uint32 noOfNonKeysFound = 0; // # nonPK attrs found before attr in DICTdata
1373 for (Uint32 i=0; i<tableDesc.NoOfAttributes; i++) {
1374 if (tableKey == UtilPrepareReq::TableName) {
1375 jam();
1376 ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeName);
1377 ndbrequire(dictInfoReader.getValueLen() <= MAX_ATTR_NAME_SIZE);
1378 dictInfoReader.getString(attrName);
1379 attrId= ~(Uint32)0; // attrId not used
1380 } else { // (tableKey == UtilPrepareReq::TableId)
1381 jam();
1382 dictInfoReader.next(); // Skip name
1383 ndbrequire(dictInfoReader.getKey() == DictTabInfo::AttributeId);
1384 attrId = dictInfoReader.getUint32();
1385 attrName[0]= '\0'; // attrName not used
1386 }
1387 unpackStatus = SimpleProperties::unpack(dictInfoReader, &attrDesc,
1388 DictTabInfo::AttributeMapping,
1389 DictTabInfo::AttributeMappingSize,
1390 true, true);
1391 ndbrequire(unpackStatus == SimpleProperties::Break);
1392 //attrDesc.print(stdout);
1393
1394 if (attrDesc.AttributeKeyFlag) { jam(); noOfKeysFound++; }
1395 else { jam(); noOfNonKeysFound++; }
1396 if (attributeKey == UtilPrepareReq::AttributeName) {
1397 if (strcmp(attrName, attrNameRequested) == 0) {
1398 attributeFound = true;
1399 break;
1400 }
1401 }
1402 else // (attributeKey == UtilPrepareReq::AttributeId)
1403 if (attrId == attrIdRequested) {
1404 attributeFound = true;
1405 break;
1406 }
1407
1408 // Move to next attribute
1409 ndbassert(dictInfoReader.getKey() == DictTabInfo::AttributeEnd);
1410 dictInfoReader.next();
1411 }
1412
1413 /**********************
1414 * Attribute not found
1415 **********************/
1416 if (!attributeFound) {
1417 jam();
1418 sendUtilPrepareRef(signal,
1419 UtilPrepareRef::DICT_TAB_INFO_ERROR,
1420 prepPtr.p->clientRef, prepPtr.p->clientData);
1421 infoEvent("UTIL: Unknown attribute requested: %s in table: %s",
1422 attrNameRequested, tableName);
1423 releasePreparedOperation(prepOpPtr);
1424 releasePrepare(prepPtr);
1425 return;
1426 }
1427
1428 /**************************************************************
1429 * Attribute found - store in mapping (AttributeId, Position)
1430 **************************************************************/
1431 AttributeHeader attrMap(attrDesc.AttributeId, // 1. Store AttrId
1432 0);
1433
1434 if (attrDesc.AttributeKeyFlag) {
1435 // ** Attribute belongs to PK **
1436 prepOpPtr.p->pkBitmask.set(attrDesc.AttributeId);
1437 attrMap.setDataSize(noOfKeysFound - 1); // 2. Store Position
1438 noOfPKAttribsStored++;
1439 } else {
1440 attrMap.setDataSize(0x3fff); // 2. Store Position (fake)
1441 noOfNonPKAttribsStored++;
1442
1443 /***********************************************************
1444 * Error: Read nonPK Attr before all PK attr have been read
1445 ***********************************************************/
1446 if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
1447 jam();
1448 sendUtilPrepareRef(signal,
1449 UtilPrepareRef::DICT_TAB_INFO_ERROR,
1450 prepPtr.p->clientRef, prepPtr.p->clientData);
1451 infoEvent("UTIL: Non-PK attr not allowed before "
1452 "all PK attrs have been defined, table: %s",
1453 tableName);
1454 releasePreparedOperation(prepOpPtr);
1455 releasePrepare(prepPtr);
1456 return;
1457 }
1458 }
1459 *(attrMappingIt.data) = attrMap.m_value;
1460 #if 0
1461 ndbout << "BEFORE: attrLength: " << attrLength << endl;
1462 #endif
1463 {
1464 int len = 0;
1465 switch (attrDesc.AttributeSize) {
1466 case DictTabInfo::an8Bit:
1467 len = (attrDesc.AttributeArraySize + 3)/ 4;
1468 break;
1469 case DictTabInfo::a16Bit:
1470 len = (attrDesc.AttributeArraySize + 1) / 2;
1471 break;
1472 case DictTabInfo::a32Bit:
1473 len = attrDesc.AttributeArraySize;
1474 break;
1475 case DictTabInfo::a64Bit:
1476 len = attrDesc.AttributeArraySize * 2;
1477 break;
1478 case DictTabInfo::a128Bit:
1479 len = attrDesc.AttributeArraySize * 4;
1480 break;
1481 }
1482 attrLength += len;
1483
1484 if (operationType == UtilPrepareReq::Read) {
1485 AttributeHeader::init(rsInfoIt.data,
1486 attrDesc.AttributeId, // 1. Store AttrId
1487 len << 2);
1488 prepOpPtr.p->rsInfo.next(rsInfoIt, 1);
1489 }
1490 }
1491 #if 0
1492 ndbout << ": AttributeSize: " << attrDesc.AttributeSize << endl;
1493 ndbout << ": AttributeArraySize: " << attrDesc.AttributeArraySize << endl;
1494 ndbout << "AFTER: attrLength: " << attrLength << endl;
1495 #endif
1496 //attrMappingIt.print(stdout);
1497 //prepPtr.p->prepOpPtr.p->attrMapping.print(stdout);
1498 prepPtr.p->prepOpPtr.p->attrMapping.next(attrMappingIt, 1);
1499 }
1500
1501 /***************************
1502 * Error: Not all PKs found
1503 ***************************/
1504 if (noOfPKAttribsStored != tableDesc.NoOfKeyAttr) {
1505 jam();
1506 sendUtilPrepareRef(signal,
1507 UtilPrepareRef::DICT_TAB_INFO_ERROR,
1508 prepPtr.p->clientRef, prepPtr.p->clientData);
1509 infoEvent("UTIL: Not all primary key attributes requested for table: %s",
1510 tableName);
1511 releasePreparedOperation(prepOpPtr);
1512 releasePrepare(prepPtr);
1513 return;
1514 }
1515
1516 #if 0
1517 AttrMappingBuffer::ConstDataBufferIterator tmpIt;
1518 for (prepPtr.p->prepOpPtr.p->attrMapping.first(tmpIt); tmpIt.curr.i != RNIL;
1519 prepPtr.p->prepOpPtr.p->attrMapping.next(tmpIt)) {
1520 AttributeHeader* ah = (AttributeHeader *) tmpIt.data;
1521 ah->print(stdout);
1522 }
1523 #endif
1524
1525 /**********************************************
1526 * Preparing of PreparedOperation signal train
1527 **********************************************/
1528 Uint32 static_len = TcKeyReq::StaticLength;
1529 Uint32 requestInfo = 0;
1530 if (scanTakeOver)
1531 {
1532 static_len ++;
1533 TcKeyReq::setScanIndFlag(requestInfo, 1);
1534 }
1535 if (reorg)
1536 {
1537 TcKeyReq::setReorgFlag(requestInfo, 1);
1538 }
1539 prepOpPtr.p->tckey.tableId = tableDesc.TableId;
1540 prepOpPtr.p->tckey.tableSchemaVersion = tableDesc.TableVersion;
1541 prepOpPtr.p->noOfKeyAttr = tableDesc.NoOfKeyAttr;
1542 prepOpPtr.p->tckeyLen = static_len;
1543 prepOpPtr.p->keyDataPos = static_len; // Start of keyInfo[] in tckeyreq
1544
1545 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::AbortOnError);
1546 TcKeyReq::setKeyLength(requestInfo, tableDesc.KeyLength);
1547 switch(operationType) {
1548 case(UtilPrepareReq::Read):
1549 prepOpPtr.p->rsLen =
1550 attrLength +
1551 tableDesc.NoOfKeyAttr +
1552 noOfNonPKAttribsStored; // Read needs a resultset
1553 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
1554 prepOpPtr.p->tckey.attrLen = prepOpPtr.p->noOfAttr;
1555 TcKeyReq::setOperationType(requestInfo, ZREAD);
1556 break;
1557 case(UtilPrepareReq::Update):
1558 prepOpPtr.p->rsLen = 0;
1559 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
1560 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
1561 TcKeyReq::setOperationType(requestInfo, ZUPDATE);
1562 break;
1563 case(UtilPrepareReq::Insert):
1564 prepOpPtr.p->rsLen = 0;
1565 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
1566 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
1567 TcKeyReq::setOperationType(requestInfo, ZINSERT);
1568 break;
1569 case(UtilPrepareReq::Delete):
1570 // The number of attributes should equal the size of the primary key
1571 ndbrequire(tableDesc.KeyLength == attrLength);
1572 prepOpPtr.p->rsLen = 0;
1573 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr;
1574 prepOpPtr.p->tckey.attrLen = 0;
1575 TcKeyReq::setOperationType(requestInfo, ZDELETE);
1576 break;
1577 case(UtilPrepareReq::Write):
1578 prepOpPtr.p->rsLen = 0;
1579 prepOpPtr.p->noOfAttr = tableDesc.NoOfKeyAttr + noOfNonPKAttribsStored;
1580 prepOpPtr.p->tckey.attrLen = attrLength + prepOpPtr.p->noOfAttr;
1581 TcKeyReq::setOperationType(requestInfo, ZWRITE);
1582 break;
1583 }
1584 TcKeyReq::setAIInTcKeyReq(requestInfo, 0); // Attrinfo sent separately
1585 prepOpPtr.p->tckey.requestInfo = requestInfo;
1586
1587 /****************************
1588 * Confirm completed prepare
1589 ****************************/
1590 UtilPrepareConf * conf = (UtilPrepareConf *)signal->getDataPtr();
1591 conf->senderData = prepPtr.p->clientData;
1592 conf->prepareId = prepPtr.p->prepOpPtr.i;
1593
1594 sendSignal(prepPtr.p->clientRef, GSN_UTIL_PREPARE_CONF, signal,
1595 UtilPrepareConf::SignalLength, JBB);
1596
1597 #if 0
1598 prepPtr.p->prepOpPtr.p->print();
1599 #endif
1600 releasePrepare(prepPtr);
1601 }
1602
1603
1604 void
execUTIL_RELEASE_REQ(Signal * signal)1605 DbUtil::execUTIL_RELEASE_REQ(Signal* signal){
1606 jamEntry();
1607
1608 UtilReleaseReq * req = (UtilReleaseReq *)signal->getDataPtr();
1609 const Uint32 clientRef = signal->senderBlockRef();
1610 const Uint32 prepareId = req->prepareId;
1611 const Uint32 senderData = req->senderData;
1612
1613 #if 0
1614 /**
1615 * This only works in when ARRAY_GUARD is defined (debug-mode)
1616 */
1617 if (!c_preparedOperationPool.isSeized(prepareId)) {
1618 UtilReleaseRef * ref = (UtilReleaseRef *)signal->getDataPtr();
1619 ref->prepareId = prepareId;
1620 ref->errorCode = UtilReleaseRef::NO_SUCH_PREPARE_SEIZED;
1621 sendSignal(clientRef, GSN_UTIL_RELEASE_REF, signal,
1622 UtilReleaseRef::SignalLength, JBB);
1623 }
1624 #endif
1625 PreparedOperationPtr prepOpPtr;
1626 c_preparedOperationPool.getPtr(prepOpPtr, prepareId);
1627
1628 releasePreparedOperation(prepOpPtr);
1629
1630 UtilReleaseConf * const conf = (UtilReleaseConf*)signal->getDataPtrSend();
1631 conf->senderData = senderData;
1632 sendSignal(clientRef, GSN_UTIL_RELEASE_CONF, signal,
1633 UtilReleaseConf::SignalLength, JBB);
1634 }
1635
1636
1637 /**************************************************************************
1638 * ------------------------------------------------------------------------
1639 * MODULE: Sequence Service
1640 * ------------------------------------------------------------------------
1641 *
1642 * A service with a stored incrementable number
1643 **************************************************************************/
1644 void
hardcodedPrepare(Signal * signal,Uint32 SYSTAB_0)1645 DbUtil::hardcodedPrepare(Signal* signal, Uint32 SYSTAB_0)
1646 {
1647 /**
1648 * Prepare SequenceCurrVal (READ)
1649 */
1650 Uint32 keyLen = 1;
1651 {
1652 PreparedOperationPtr ptr;
1653 ndbrequire(c_preparedOperationPool.seizeId(ptr, 0));
1654 ptr.p->tckey.attrLen = 1;
1655 ptr.p->rsLen = 3;
1656 ptr.p->tckeyLen = TcKeyReq::StaticLength + keyLen + ptr.p->tckey.attrLen;
1657 ptr.p->keyDataPos = TcKeyReq::StaticLength;
1658 ptr.p->tckey.tableId = SYSTAB_0;
1659 Uint32 requestInfo = 0;
1660 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
1661 TcKeyReq::setOperationType(requestInfo, ZREAD);
1662 TcKeyReq::setKeyLength(requestInfo, 1);
1663 TcKeyReq::setAIInTcKeyReq(requestInfo, 1);
1664 ptr.p->tckey.requestInfo = requestInfo;
1665 ptr.p->tckey.tableSchemaVersion = 1;
1666
1667 // This is actually attr data
1668 AttributeHeader::init(&ptr.p->tckey.distrGroupHashValue, 1, 0);
1669
1670 ndbrequire(ptr.p->rsInfo.seize(1));
1671 ResultSetInfoBuffer::DataBufferIterator it;
1672 ptr.p->rsInfo.first(it);
1673 AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words
1674 }
1675
1676 /**
1677 * Prepare SequenceNextVal (UPDATE)
1678 */
1679 {
1680 PreparedOperationPtr ptr;
1681 ndbrequire(c_preparedOperationPool.seizeId(ptr, 1));
1682 ptr.p->rsLen = 3;
1683 ptr.p->tckeyLen = TcKeyReq::StaticLength + keyLen + 5;
1684 ptr.p->keyDataPos = TcKeyReq::StaticLength;
1685 ptr.p->tckey.attrLen = 11;
1686 ptr.p->tckey.tableId = SYSTAB_0;
1687 Uint32 requestInfo = 0;
1688 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
1689 TcKeyReq::setOperationType(requestInfo, ZUPDATE);
1690 TcKeyReq::setKeyLength(requestInfo, 1);
1691 TcKeyReq::setAIInTcKeyReq(requestInfo, 5);
1692 TcKeyReq::setInterpretedFlag(requestInfo, 1);
1693 ptr.p->tckey.requestInfo = requestInfo;
1694 ptr.p->tckey.tableSchemaVersion = 1;
1695
1696 // Signal is packed, which is why attrInfo is at distrGroupHashValue
1697 // position
1698 Uint32 * attrInfo = &ptr.p->tckey.distrGroupHashValue;
1699 attrInfo[0] = 0; // IntialReadSize
1700 attrInfo[1] = 5; // InterpretedSize
1701 attrInfo[2] = 0; // FinalUpdateSize
1702 attrInfo[3] = 1; // FinalReadSize
1703 attrInfo[4] = 0; // SubroutineSize
1704
1705 { // AttrInfo
1706 ndbrequire(ptr.p->attrInfo.seize(6));
1707 AttrInfoBuffer::DataBufferIterator it;
1708 ptr.p->attrInfo.first(it);
1709 * it.data = Interpreter::Read(1, 6);
1710 ndbrequire(ptr.p->attrInfo.next(it));
1711 * it.data = Interpreter::LoadConst16(7, 1);
1712 ndbrequire(ptr.p->attrInfo.next(it));
1713 * it.data = Interpreter::Add(7, 6, 7);
1714 ndbrequire(ptr.p->attrInfo.next(it));
1715 * it.data = Interpreter::Write(1, 7);
1716 ndbrequire(ptr.p->attrInfo.next(it));
1717 * it.data = Interpreter::ExitOK();
1718
1719 ndbrequire(ptr.p->attrInfo.next(it));
1720 AttributeHeader::init(it.data, 1, 0);
1721 }
1722
1723 { // ResultSet
1724 ndbrequire(ptr.p->rsInfo.seize(1));
1725 ResultSetInfoBuffer::DataBufferIterator it;
1726 ptr.p->rsInfo.first(it);
1727 AttributeHeader::init(it.data, 1, 2 << 2); // Attribute 1 - 2 data words
1728 }
1729 }
1730
1731 /**
1732 * Prepare CreateSequence (INSERT)
1733 */
1734 {
1735 PreparedOperationPtr ptr;
1736 ndbrequire(c_preparedOperationPool.seizeId(ptr, 2));
1737 ptr.p->tckey.attrLen = 5;
1738 ptr.p->rsLen = 0;
1739 ptr.p->tckeyLen = TcKeyReq::StaticLength + keyLen + ptr.p->tckey.attrLen;
1740 ptr.p->keyDataPos = TcKeyReq::StaticLength;
1741 ptr.p->tckey.tableId = SYSTAB_0;
1742 Uint32 requestInfo = 0;
1743 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
1744 TcKeyReq::setOperationType(requestInfo, ZINSERT);
1745 TcKeyReq::setKeyLength(requestInfo, 1);
1746 TcKeyReq::setAIInTcKeyReq(requestInfo, 0);
1747 ptr.p->tckey.requestInfo = requestInfo;
1748 ptr.p->tckey.tableSchemaVersion = 1;
1749 }
1750
1751 /**
1752 * Prepare SetSequence (UPDATE)
1753 */
1754 {
1755 PreparedOperationPtr ptr;
1756 ndbrequire(c_preparedOperationPool.seizeId(ptr, 3));
1757 ptr.p->rsLen = 0;
1758 ptr.p->tckeyLen = TcKeyReq::StaticLength + keyLen + 5;
1759 ptr.p->keyDataPos = TcKeyReq::StaticLength;
1760 ptr.p->tckey.attrLen = 9;
1761 ptr.p->tckey.tableId = SYSTAB_0;
1762 Uint32 requestInfo = 0;
1763 TcKeyReq::setAbortOption(requestInfo, TcKeyReq::CommitIfFailFree);
1764 TcKeyReq::setOperationType(requestInfo, ZUPDATE);
1765 TcKeyReq::setKeyLength(requestInfo, 1);
1766 TcKeyReq::setAIInTcKeyReq(requestInfo, 5);
1767 TcKeyReq::setInterpretedFlag(requestInfo, 1);
1768 ptr.p->tckey.requestInfo = requestInfo;
1769 ptr.p->tckey.tableSchemaVersion = 1;
1770
1771 Uint32 * attrInfo = &ptr.p->tckey.distrGroupHashValue;
1772 attrInfo[0] = 0; // IntialReadSize
1773 attrInfo[1] = 4; // InterpretedSize
1774 attrInfo[2] = 0; // FinalUpdateSize
1775 attrInfo[3] = 0; // FinalReadSize
1776 attrInfo[4] = 0; // SubroutineSize
1777 }
1778
1779 connectTc(signal);
1780 }
1781
1782 void
execUTIL_SEQUENCE_REQ(Signal * signal)1783 DbUtil::execUTIL_SEQUENCE_REQ(Signal* signal){
1784 jamEntry();
1785
1786 UtilSequenceReq * req = (UtilSequenceReq*)signal->getDataPtr();
1787
1788 PreparedOperation * prepOp;
1789
1790 switch(req->requestType){
1791 case UtilSequenceReq::CurrVal:
1792 prepOp = c_preparedOperationPool.getPtr(0); //c_SequenceCurrVal
1793 break;
1794 case UtilSequenceReq::NextVal:
1795 prepOp = c_preparedOperationPool.getPtr(1); //c_SequenceNextVal
1796 break;
1797 case UtilSequenceReq::Create:
1798 prepOp = c_preparedOperationPool.getPtr(2); //c_CreateSequence
1799 break;
1800 case UtilSequenceReq::SetVal:{
1801 prepOp = c_preparedOperationPool.getPtr(3);
1802 break;
1803 }
1804 default:
1805 ndbrequire(false);
1806 prepOp = 0; // remove warning
1807 }
1808
1809 /**
1810 * 1 Transaction with 1 operation
1811 */
1812 TransactionPtr transPtr;
1813 ndbrequire(c_runningTransactions.seize(transPtr));
1814
1815 OperationPtr opPtr;
1816 ndbrequire(transPtr.p->operations.seize(opPtr));
1817
1818 ndbrequire(opPtr.p->keyInfo.seize(1));
1819
1820 transPtr.p->gci_hi = 0;
1821 transPtr.p->gci_lo = 0;
1822 transPtr.p->gsn = GSN_UTIL_SEQUENCE_REQ;
1823 transPtr.p->clientRef = signal->senderBlockRef();
1824 transPtr.p->clientData = req->senderData;
1825 transPtr.p->sequence.sequenceId = req->sequenceId;
1826 transPtr.p->sequence.requestType = req->requestType;
1827
1828 opPtr.p->prepOp = prepOp;
1829 opPtr.p->prepOp_i = RNIL;
1830
1831 KeyInfoBuffer::DataBufferIterator it;
1832 opPtr.p->keyInfo.first(it);
1833 it.data[0] = transPtr.p->sequence.sequenceId;
1834
1835 if(req->requestType == UtilSequenceReq::Create){
1836 ndbrequire(opPtr.p->attrInfo.seize(5));
1837 AttrInfoBuffer::DataBufferIterator it;
1838
1839 opPtr.p->attrInfo.first(it);
1840 AttributeHeader::init(it.data, 0, 1 << 2);
1841
1842 ndbrequire(opPtr.p->attrInfo.next(it));
1843 * it.data = transPtr.p->sequence.sequenceId;
1844
1845 ndbrequire(opPtr.p->attrInfo.next(it));
1846 AttributeHeader::init(it.data, 1, 2 << 2);
1847
1848 ndbrequire(opPtr.p->attrInfo.next(it));
1849 * it.data = 0;
1850
1851 ndbrequire(opPtr.p->attrInfo.next(it));
1852 * it.data = 0;
1853 }
1854
1855 if(req->requestType == UtilSequenceReq::SetVal)
1856 { // AttrInfo
1857 ndbrequire(opPtr.p->attrInfo.seize(4));
1858 AttrInfoBuffer::DataBufferIterator it;
1859 opPtr.p->attrInfo.first(it);
1860 * it.data = Interpreter::LoadConst32(7);
1861 ndbrequire(opPtr.p->attrInfo.next(it));
1862 * it.data = req->value;
1863 ndbrequire(opPtr.p->attrInfo.next(it));
1864 * it.data = Interpreter::Write(1, 7);
1865 ndbrequire(opPtr.p->attrInfo.next(it))
1866 * it.data = Interpreter::ExitOK();
1867 }
1868
1869 transPtr.p->noOfRetries = 3;
1870 runTransaction(signal, transPtr);
1871 }
1872
1873 int
getResultSet(Signal * signal,const Transaction * transP,struct LinearSectionPtr sectionsPtr[])1874 DbUtil::getResultSet(Signal* signal, const Transaction * transP,
1875 struct LinearSectionPtr sectionsPtr[]) {
1876 OperationPtr opPtr;
1877 ndbrequire(transP->operations.first(opPtr));
1878 ndbrequire(transP->operations.hasNext(opPtr) == false);
1879
1880 int noAttr = 0;
1881 int dataSz = 0;
1882 Uint32* tmpBuf = signal->theData + 25;
1883 const Uint32* headerBuffer = tmpBuf;
1884
1885 const ResultSetBuffer & rs = opPtr.p->rs;
1886 ResultSetInfoBuffer::ConstDataBufferIterator it;
1887
1888 // extract headers
1889 for(rs.first(it); it.curr.i != RNIL; ) {
1890 *tmpBuf++ = it.data[0];
1891 rs.next(it, AttributeHeader::getDataSize(it.data[0]) + 1);
1892 noAttr++;
1893 }
1894
1895 if (noAttr == 0)
1896 return 0;
1897
1898 const Uint32* dataBuffer = tmpBuf;
1899
1900 // extract data
1901 for(rs.first(it); it.curr.i != RNIL; )
1902 {
1903 jam();
1904 int sz = AttributeHeader::getDataSize(it.data[0]);
1905 rs.next(it,1);
1906 for (int i = 0; i < sz; i++)
1907 {
1908 *tmpBuf++ = *it.data;
1909 rs.next(it,1);
1910 dataSz++;
1911 }
1912 }
1913
1914 sectionsPtr[UtilExecuteReq::HEADER_SECTION].p = (Uint32 *)headerBuffer;
1915 sectionsPtr[UtilExecuteReq::HEADER_SECTION].sz = noAttr;
1916 sectionsPtr[UtilExecuteReq::DATA_SECTION].p = (Uint32 *)dataBuffer;
1917 sectionsPtr[UtilExecuteReq::DATA_SECTION].sz = dataSz;
1918
1919 return 1;
1920 }
1921
1922 void
reportSequence(Signal * signal,const Transaction * transP)1923 DbUtil::reportSequence(Signal* signal, const Transaction * transP){
1924 OperationPtr opPtr;
1925 ndbrequire(transP->operations.first(opPtr));
1926 ndbrequire(transP->operations.hasNext(opPtr) == false);
1927
1928 if(transP->errorCode == 0){
1929 jam(); // OK
1930
1931 UtilSequenceConf * ret = (UtilSequenceConf *)signal->getDataPtrSend();
1932 ret->senderData = transP->clientData;
1933 ret->sequenceId = transP->sequence.sequenceId;
1934 ret->requestType = transP->sequence.requestType;
1935
1936 bool ok = false;
1937 switch(transP->sequence.requestType){
1938 case UtilSequenceReq::CurrVal:
1939 case UtilSequenceReq::NextVal:{
1940 ok = true;
1941 ndbrequire(opPtr.p->rsRecv == 3);
1942
1943 ResultSetBuffer::DataBufferIterator rsit;
1944 ndbrequire(opPtr.p->rs.first(rsit));
1945
1946 ret->sequenceValue[0] = rsit.data[1];
1947 ret->sequenceValue[1] = rsit.data[2];
1948 break;
1949 }
1950 case UtilSequenceReq::SetVal:
1951 ok = true;
1952 case UtilSequenceReq::Create:
1953 ok = true;
1954 ret->sequenceValue[0] = 0;
1955 ret->sequenceValue[1] = 0;
1956 break;
1957 }
1958 ndbrequire(ok);
1959 sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_CONF, signal,
1960 UtilSequenceConf::SignalLength, JBB);
1961 return;
1962 }
1963
1964 UtilSequenceRef::ErrorCode errCode = UtilSequenceRef::TCError;
1965
1966 switch(transP->sequence.requestType)
1967 {
1968 case UtilSequenceReq::SetVal:
1969 case UtilSequenceReq::CurrVal:
1970 case UtilSequenceReq::NextVal:{
1971 if (transP->errorCode == 626)
1972 errCode = UtilSequenceRef::NoSuchSequence;
1973 break;
1974 }
1975 case UtilSequenceReq::Create:
1976 break;
1977 }
1978
1979 UtilSequenceRef * ret = (UtilSequenceRef *)signal->getDataPtrSend();
1980 ret->senderData = transP->clientData;
1981 ret->sequenceId = transP->sequence.sequenceId;
1982 ret->requestType = transP->sequence.requestType;
1983 ret->errorCode = (Uint32)errCode;
1984 ret->TCErrorCode = transP->errorCode;
1985 sendSignal(transP->clientRef, GSN_UTIL_SEQUENCE_REF, signal,
1986 UtilSequenceRef::SignalLength, JBB);
1987 }
1988 #if 0
1989 Ndb ndb("ndb","def");
1990 NdbConnection* tConnection = ndb.startTransaction();
1991 NdbOperation* tOperation = tConnection->getNdbOperation("SYSTAB_0");
1992
1993 //#if 0 && API_CODE
1994 if( tOperation != NULL ) {
1995 tOperation->interpretedUpdateTuple();
1996 tOperation->equal((U_Int32)0, keyValue );
1997 tNextId_Result = tOperation->getValue((U_Int32)1);
1998 tOperation->incValue((U_Int32)1, (U_Int32)8192);
1999
2000 if (tConnection->execute( Commit ) != -1 ) {
2001 U_Int64 tValue = tNextId_Result->u_64_value(); // Read result value
2002 theFirstTransId = tValue;
2003 theLastTransId = tValue + 8191;
2004 closeTransaction(tConnection);
2005 return startTransactionLocal(aPriority, nodeId);
2006 }
2007 }
2008 /**
2009 * IntialReadSize = 0;
2010 * InterpretedSize = incValue(1);
2011 * FinalUpdateSize = 0;
2012 * FinalReadSize = 1; // Read value
2013 * SubroutineSize = 0;
2014 */
2015 #endif
2016
2017
2018 /**************************************************************************
2019 * ------------------------------------------------------------------------
2020 * MODULE: Transaction execution request
2021 * ------------------------------------------------------------------------
2022 *
2023 * Handle requests to execute a prepared transaction
2024 **************************************************************************/
2025
2026 void
execUTIL_EXECUTE_REQ(Signal * signal)2027 DbUtil::execUTIL_EXECUTE_REQ(Signal* signal)
2028 {
2029 jamEntry();
2030
2031 UtilExecuteReq * req = (UtilExecuteReq *)signal->getDataPtr();
2032 const Uint32 clientRef = req->senderRef;
2033 const Uint32 clientData = req->senderData;
2034 const Uint32 prepareId = req->getPrepareId();
2035 const bool releaseFlag = req->getReleaseFlag();
2036 const Uint32 scanTakeOver = req->scanTakeOver;
2037
2038 if(signal->getNoOfSections() == 0) {
2039 // Missing prepare data
2040 jam();
2041 sendUtilExecuteRef(signal, UtilExecuteRef::MissingDataSection,
2042 0, clientRef, clientData);
2043 return;
2044 }
2045 /*******************************
2046 * Get PreparedOperation struct
2047 *******************************/
2048 PreparedOperationPtr prepOpPtr;
2049 c_preparedOperationPool.getPtr(prepOpPtr, prepareId);
2050
2051 prepOpPtr.p->releaseFlag = releaseFlag;
2052
2053 TransactionPtr transPtr;
2054 OperationPtr opPtr;
2055 SectionHandle handle(this, signal);
2056 SegmentedSectionPtr headerPtr, dataPtr;
2057
2058 handle.getSection(headerPtr, UtilExecuteReq::HEADER_SECTION);
2059 SectionReader headerReader(headerPtr, getSectionSegmentPool());
2060 handle.getSection(dataPtr, UtilExecuteReq::DATA_SECTION);
2061 SectionReader dataReader(dataPtr, getSectionSegmentPool());
2062
2063 #if 0 //def EVENT_DEBUG
2064 // Debugging
2065 printf("DbUtil::execUTIL_EXECUTEL_REQ: Headers (%u): ", headerPtr.sz);
2066 Uint32 word;
2067 while(headerReader.getWord(&word))
2068 printf("H'%.8x ", word);
2069 printf("\n");
2070 printf("DbUtil::execUTIL_EXECUTEL_REQ: Data (%u): ", dataPtr.sz);
2071 headerReader.reset();
2072 while(dataReader.getWord(&word))
2073 printf("H'%.8x ", word);
2074 printf("\n");
2075 dataReader.reset();
2076 #endif
2077
2078 // Uint32 totalDataLen = headerPtr.sz + dataPtr.sz;
2079
2080 /************************************************************
2081 * Seize Transaction record
2082 ************************************************************/
2083 ndbrequire(c_runningTransactions.seize(transPtr));
2084 transPtr.p->gci_hi = 0;
2085 transPtr.p->gci_lo = 0;
2086 transPtr.p->gsn = GSN_UTIL_EXECUTE_REQ;
2087 transPtr.p->clientRef = clientRef;
2088 transPtr.p->clientData = clientData;
2089 ndbrequire(transPtr.p->operations.seize(opPtr));
2090 opPtr.p->prepOp = prepOpPtr.p;
2091 opPtr.p->prepOp_i = prepOpPtr.i;
2092 opPtr.p->m_scanTakeOver = scanTakeOver;
2093
2094 /***********************************************************
2095 * Store signal data on linear memory in Transaction record
2096 ***********************************************************/
2097 KeyInfoBuffer* keyInfo = &opPtr.p->keyInfo;
2098 AttrInfoBuffer* attrInfo = &opPtr.p->attrInfo;
2099 AttributeHeader header;
2100 Uint32* tempBuf = signal->theData + 25;
2101 bool dataComplete = true;
2102
2103 while(headerReader.getWord((Uint32 *)&header)) {
2104 Uint32* bufStart = tempBuf;
2105 header.insertHeader(tempBuf++);
2106 for(unsigned int i = 0; i < header.getDataSize(); i++) {
2107 if (!dataReader.getWord(tempBuf++)) {
2108 dataComplete = false;
2109 break;
2110 }
2111 }
2112 bool res = true;
2113
2114 #if 0 //def EVENT_DEBUG
2115 if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) ==
2116 TcKeyReq::Read) {
2117 if(prepOpPtr.p->pkBitmask.get(header.getAttributeId()))
2118 printf("PrimaryKey\n");
2119 }
2120 printf("AttrId %u Hdrsz %d Datasz %u \n",
2121 header.getAttributeId(),
2122 header.getHeaderSize(),
2123 header.getDataSize());
2124 #endif
2125
2126 if(prepOpPtr.p->pkBitmask.get(header.getAttributeId()))
2127 // A primary key attribute
2128 res = keyInfo->append(bufStart + header.getHeaderSize(),
2129 header.getDataSize());
2130
2131 switch (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo)) {
2132 case ZREAD:
2133 res &= attrInfo->append(bufStart, header.getHeaderSize());
2134 break;
2135 case ZDELETE:
2136 // no attrinfo for Delete
2137 break;
2138 default:
2139 res &= attrInfo->append(bufStart,
2140 header.getHeaderSize() + header.getDataSize());
2141 }
2142
2143 if (!res) {
2144 // Failed to allocate buffer data
2145 jam();
2146 releaseSections(handle);
2147 sendUtilExecuteRef(signal, UtilExecuteRef::AllocationError,
2148 0, clientRef, clientData);
2149 releaseTransaction(transPtr);
2150 return;
2151 }
2152 }
2153 if (!dataComplete) {
2154 // Missing data in data section
2155 jam();
2156 releaseSections(handle);
2157 sendUtilExecuteRef(signal, UtilExecuteRef::MissingData,
2158 0, clientRef, clientData);
2159 releaseTransaction(transPtr);
2160 return;
2161 }
2162
2163 #if 0
2164 const Uint32 l1 = prepOpPtr.p->tckey.attrLen;
2165 const Uint32 l2 =
2166 prepOpPtr.p->attrInfo.getSize() + opPtr.p->attrInfo.getSize();
2167
2168 if (TcKeyReq::getOperationType(prepOpPtr.p->tckey.requestInfo) != ZREAD){
2169 ndbrequire(l1 == l2);
2170 } else {
2171 ndbout_c("TcKeyReq::Read");
2172 }
2173 #endif
2174
2175 releaseSections(handle);
2176 transPtr.p->noOfRetries = 3;
2177 runTransaction(signal, transPtr);
2178 }
2179
2180 /**************************************************************************
2181 * ------------------------------------------------------------------------
2182 * MODULE: General transaction machinery
2183 * ------------------------------------------------------------------------
2184 * Executes a prepared transaction
2185 **************************************************************************/
2186 void
runTransaction(Signal * signal,TransactionPtr transPtr)2187 DbUtil::runTransaction(Signal* signal, TransactionPtr transPtr){
2188
2189 /* Init transaction */
2190 transPtr.p->sent = 0;
2191 transPtr.p->recv = 0;
2192 transPtr.p->errorCode = 0;
2193 getTransId(transPtr.p);
2194
2195 OperationPtr opPtr;
2196 ndbrequire(transPtr.p->operations.first(opPtr));
2197
2198 /* First operation */
2199 Uint32 start = 0;
2200 TcKeyReq::setStartFlag(start, 1);
2201 runOperation(signal, transPtr, opPtr, start);
2202 transPtr.p->sent ++;
2203
2204 /* Rest of operations */
2205 start = 0;
2206 while(opPtr.i != RNIL){
2207 runOperation(signal, transPtr, opPtr, start);
2208 transPtr.p->sent ++;
2209 }
2210 //transPtr.p->print();
2211 }
2212
2213 void
runOperation(Signal * signal,TransactionPtr & transPtr,OperationPtr & opPtr,Uint32 start)2214 DbUtil::runOperation(Signal* signal, TransactionPtr & transPtr,
2215 OperationPtr & opPtr, Uint32 start) {
2216 Uint32 opI = opPtr.i;
2217 Operation * op = opPtr.p;
2218 const PreparedOperation * pop = op->prepOp;
2219
2220 if(!transPtr.p->operations.next(opPtr)){
2221 TcKeyReq::setCommitFlag(start, 1); // Last operation
2222 TcKeyReq::setExecuteFlag(start, 1);
2223 }
2224
2225 #if 0 //def EVENT_DEBUG
2226 if (TcKeyReq::getOperationType(pop->tckey.requestInfo) ==
2227 TcKeyReq::Read) {
2228 printf("TcKeyReq::Read runOperation\n");
2229 }
2230 #endif
2231
2232 /**
2233 * Init operation w.r.t result set
2234 */
2235 op->rsRecv = 0;
2236 #if 0 //def EVENT_DEBUG
2237 printf("pop->rsLen %u\n", pop->rsLen);
2238 #endif
2239 op->rsExpect = 0;
2240 op->transPtrI = transPtr.i;
2241
2242 TcKeyReq * tcKey = (TcKeyReq*)signal->getDataPtrSend();
2243 //ndbout << "*** 6 ***"<< endl; pop->print();
2244 memcpy(tcKey, &pop->tckey, 4*pop->tckeyLen);
2245 //ndbout << "*** 6b ***"<< endl;
2246 //printTCKEYREQ(stdout, signal->getDataPtrSend(),
2247 // pop->tckeyLenInBytes >> 2, 0);
2248 tcKey->apiConnectPtr = transPtr.p->connectPtr;
2249 tcKey->senderData = opI;
2250 tcKey->transId1 = transPtr.p->transId[0];
2251 tcKey->transId2 = transPtr.p->transId[1];
2252 tcKey->requestInfo |= start;
2253
2254 if (TcKeyReq::getScanIndFlag(tcKey->requestInfo))
2255 {
2256 tcKey->scanInfo = op->m_scanTakeOver;
2257 }
2258
2259 #if 0 //def EVENT_DEBUG
2260 // Debugging
2261 printf("DbUtil::runOperation: KEYINFO\n");
2262 op->keyInfo.print(stdout);
2263 printf("DbUtil::runOperation: ATTRINFO\n");
2264 op->attrInfo.print(stdout);
2265 #endif
2266
2267 Uint32 attrLen = pop->attrInfo.getSize() + op->attrInfo.getSize();
2268 Uint32 keyLen = op->keyInfo.getSize();
2269 tcKey->attrLen = attrLen + TcKeyReq::getAIInTcKeyReq(tcKey->requestInfo);
2270 TcKeyReq::setKeyLength(tcKey->requestInfo, keyLen);
2271
2272 /**
2273 * Key Info
2274 */
2275 //KeyInfoBuffer::DataBufferIterator kit;
2276 KeyInfoIterator kit;
2277 op->keyInfo.first(kit);
2278 Uint32 *keyDst = ((Uint32*)tcKey) + pop->keyDataPos;
2279 for(Uint32 i = 0; i<8 && kit.curr.i != RNIL; i++, op->keyInfo.next(kit)){
2280 keyDst[i] = * kit.data;
2281 }
2282 //ndbout << "*** 7 ***" << endl;
2283 //printTCKEYREQ(stdout, signal->getDataPtrSend(),
2284 // pop->tckeyLenInBytes >> 2, 0);
2285
2286 #if 0 //def EVENT_DEBUG
2287 printf("DbUtil::runOperation: sendSignal(DBTC_REF, GSN_TCKEYREQ, signal, %d , JBB)\n", pop->tckeyLenInBytes >> 2);
2288 printTCKEYREQ(stdout, signal->getDataPtr(), pop->tckeyLenInBytes >> 2,0);
2289 #endif
2290 Uint32 sigLen = pop->tckeyLen + (keyLen > 8 ? 8 : keyLen);
2291 sendSignal(transPtr.p->connectRef, GSN_TCKEYREQ, signal, sigLen, JBB);
2292
2293 /**
2294 * More the 8 words of key info not implemented
2295 */
2296 // ndbrequire(kit.curr.i == RNIL); // Yes it is
2297
2298 /**
2299 * KeyInfo
2300 */
2301 KeyInfo* keyInfo = (KeyInfo *)signal->getDataPtrSend();
2302 keyInfo->connectPtr = transPtr.p->connectPtr;
2303 keyInfo->transId[0] = transPtr.p->transId[0];
2304 keyInfo->transId[1] = transPtr.p->transId[1];
2305 sendKeyInfo(signal, transPtr.p->connectRef,
2306 keyInfo, op->keyInfo, kit);
2307
2308 /**
2309 * AttrInfo
2310 */
2311 AttrInfo* attrInfo = (AttrInfo *)signal->getDataPtrSend();
2312 attrInfo->connectPtr = transPtr.p->connectPtr;
2313 attrInfo->transId[0] = transPtr.p->transId[0];
2314 attrInfo->transId[1] = transPtr.p->transId[1];
2315
2316 AttrInfoIterator ait;
2317 pop->attrInfo.first(ait);
2318 sendAttrInfo(signal, transPtr.p->connectRef,
2319 attrInfo, pop->attrInfo, ait);
2320
2321 op->attrInfo.first(ait);
2322 sendAttrInfo(signal, transPtr.p->connectRef,
2323 attrInfo, op->attrInfo, ait);
2324 }
2325
2326 void
sendKeyInfo(Signal * signal,Uint32 tcRef,KeyInfo * keyInfo,const KeyInfoBuffer & keyBuf,KeyInfoIterator & kit)2327 DbUtil::sendKeyInfo(Signal* signal,
2328 Uint32 tcRef,
2329 KeyInfo* keyInfo,
2330 const KeyInfoBuffer & keyBuf,
2331 KeyInfoIterator & kit)
2332 {
2333 while(kit.curr.i != RNIL) {
2334 Uint32 *keyDst = keyInfo->keyData;
2335 Uint32 keyDataLen = 0;
2336 for(Uint32 i = 0; i<KeyInfo::DataLength && kit.curr.i != RNIL;
2337 i++, keyBuf.next(kit)){
2338 keyDst[i] = * kit.data;
2339 keyDataLen++;
2340 }
2341 #if 0 //def EVENT_DEBUG
2342 printf("DbUtil::sendKeyInfo: sendSignal(DBTC_REF, GSN_KEYINFO, signal, %d , JBB)\n", KeyInfo::HeaderLength + keyDataLen);
2343 #endif
2344 sendSignal(tcRef, GSN_KEYINFO, signal,
2345 KeyInfo::HeaderLength + keyDataLen, JBB);
2346 }
2347 }
2348
2349 void
sendAttrInfo(Signal * signal,Uint32 tcRef,AttrInfo * attrInfo,const AttrInfoBuffer & attrBuf,AttrInfoIterator & ait)2350 DbUtil::sendAttrInfo(Signal* signal,
2351 Uint32 tcRef,
2352 AttrInfo* attrInfo,
2353 const AttrInfoBuffer & attrBuf,
2354 AttrInfoIterator & ait)
2355 {
2356 while(ait.curr.i != RNIL) {
2357 Uint32 *attrDst = attrInfo->attrData;
2358 Uint32 i = 0;
2359 for(i = 0; i<AttrInfo::DataLength && ait.curr.i != RNIL;
2360 i++, attrBuf.next(ait)){
2361 attrDst[i] = * ait.data;
2362 }
2363 #if 0 //def EVENT_DEBUG
2364 printf("DbUtil::sendAttrInfo: sendSignal(DBTC_REF, GSN_ATTRINFO, signal, %d , JBB)\n", AttrInfo::HeaderLength + i);
2365 #endif
2366 sendSignal(tcRef, GSN_ATTRINFO, signal,
2367 AttrInfo::HeaderLength + i, JBB);
2368 }
2369 }
2370
2371 void
getTransId(Transaction * transP)2372 DbUtil::getTransId(Transaction * transP){
2373
2374 Uint32 tmp[2];
2375 tmp[0] = c_transId[0];
2376 tmp[1] = c_transId[1];
2377
2378 transP->transId[0] = tmp[0];
2379 transP->transId[1] = tmp[1];
2380
2381 c_transId[1] = tmp[1] + 1;
2382 }
2383
2384
2385
2386 /**************************************************************************
2387 * ------------------------------------------------------------------------
2388 * MODULE: Post Execute
2389 * ------------------------------------------------------------------------
2390 *
2391 * Handles result from a sent transaction
2392 **************************************************************************/
2393
2394 /**
2395 * execTRANSID_AI
2396 *
2397 * Receive result from transaction
2398 *
2399 * NOTE: This codes assumes that
2400 * TransidAI::DataLength = ResultSetBuffer::getSegmentSize() * n
2401 */
2402 void
execTRANSID_AI(Signal * signal)2403 DbUtil::execTRANSID_AI(Signal* signal){
2404 jamEntry();
2405 #if 0 //def EVENT_DEBUG
2406 ndbout_c("File: %s line: %u",__FILE__,__LINE__);
2407 #endif
2408
2409 const Uint32 opI = signal->theData[0];
2410 const Uint32 transId1 = signal->theData[1];
2411 const Uint32 transId2 = signal->theData[2];
2412 SectionHandle handle(this, signal);
2413 SegmentedSectionPtr dataPtr;
2414 bool longSignal = (handle.m_cnt == 1);
2415 Uint32 dataLen;
2416
2417 if (longSignal)
2418 {
2419 ndbrequire(handle.getSection(dataPtr, 0));
2420 dataLen = dataPtr.sz;
2421 }
2422 else
2423 {
2424 dataLen = signal->length() - 3;
2425 }
2426
2427 Operation * opP = c_operationPool.getPtr(opI);
2428 TransactionPtr transPtr;
2429 c_runningTransactions.getPtr(transPtr, opP->transPtrI);
2430
2431 ndbrequire(transId1 == transPtr.p->transId[0] &&
2432 transId2 == transPtr.p->transId[1]);
2433 opP->rsRecv += dataLen;
2434
2435 /**
2436 * Save result
2437 */
2438 if (longSignal)
2439 {
2440 SectionSegment * ptrP = dataPtr.p;
2441 while (dataLen > NDB_SECTION_SEGMENT_SZ)
2442 {
2443 ndbrequire(opP->rs.append(ptrP->theData, NDB_SECTION_SEGMENT_SZ));
2444 dataLen -= NDB_SECTION_SEGMENT_SZ;
2445 ptrP = g_sectionSegmentPool.getPtr(ptrP->m_nextSegment);
2446 }
2447 ndbrequire(opP->rs.append(ptrP->theData, dataLen));
2448
2449 releaseSections(handle);
2450 }
2451 else
2452 {
2453 const Uint32 *src = &signal->theData[3];
2454 ndbrequire(opP->rs.append(src, dataLen));
2455 }
2456
2457 if(!opP->complete()){
2458 jam();
2459 return;
2460 }
2461
2462 transPtr.p->recv++;
2463 if(!transPtr.p->complete()){
2464 jam();
2465 return;
2466 }
2467
2468 finishTransaction(signal, transPtr);
2469 }
2470
2471 void
execTCKEYCONF(Signal * signal)2472 DbUtil::execTCKEYCONF(Signal* signal){
2473 jamEntry();
2474 #if 0 //def EVENT_DEBUG
2475 ndbout_c("File: %s line: %u",__FILE__,__LINE__);
2476 #endif
2477
2478 TcKeyConf * keyConf = (TcKeyConf*)signal->getDataPtr();
2479
2480 Uint32 gci_lo = 0;
2481 const Uint32 gci_hi = keyConf->gci_hi;
2482 const Uint32 transI = keyConf->apiConnectPtr >> 1;
2483 const Uint32 confInfo = keyConf->confInfo;
2484 const Uint32 transId1 = keyConf->transId1;
2485 const Uint32 transId2 = keyConf->transId2;
2486
2487 Uint32 recv = 0;
2488 const Uint32 ops = TcKeyConf::getNoOfOperations(confInfo);
2489 for(Uint32 i = 0; i<ops; i++){
2490 OperationPtr opPtr;
2491 c_operationPool.getPtr(opPtr, keyConf->operations[i].apiOperationPtr);
2492
2493 ndbrequire(opPtr.p->transPtrI == transI);
2494 opPtr.p->rsExpect += keyConf->operations[i].attrInfoLen;
2495 if(opPtr.p->complete()){
2496 recv++;
2497 }
2498 }
2499
2500 if (TcKeyConf::getCommitFlag(confInfo))
2501 {
2502 jam();
2503 gci_lo = keyConf->operations[ops].apiOperationPtr;
2504 }
2505
2506 TransactionPtr transPtr;
2507 c_runningTransactions.getPtr(transPtr, transI);
2508
2509 /**
2510 * Check commit ack marker flag
2511 */
2512 if (TcKeyConf::getMarkerFlag(confInfo))
2513 {
2514 jam();
2515 signal->theData[0] = transId1;
2516 signal->theData[1] = transId2;
2517 sendSignal(transPtr.p->connectRef, GSN_TC_COMMIT_ACK, signal, 2, JBB);
2518 }//if
2519
2520 ndbrequire(transId1 == transPtr.p->transId[0] &&
2521 transId2 == transPtr.p->transId[1]);
2522
2523 if (TcKeyConf::getCommitFlag(confInfo))
2524 {
2525 jam();
2526 transPtr.p->gci_hi = gci_hi;
2527 transPtr.p->gci_lo = gci_lo;
2528 }
2529
2530 transPtr.p->recv += recv;
2531 if(!transPtr.p->complete()){
2532 jam();
2533 return;
2534 }
2535 finishTransaction(signal, transPtr);
2536 }
2537
2538 void
execTCKEYREF(Signal * signal)2539 DbUtil::execTCKEYREF(Signal* signal){
2540 jamEntry();
2541 #if 0 //def EVENT_DEBUG
2542 ndbout_c("File: %s line: %u",__FILE__,__LINE__);
2543 #endif
2544
2545 const Uint32 transI = signal->theData[0] >> 1;
2546 const Uint32 transId1 = signal->theData[1];
2547 const Uint32 transId2 = signal->theData[2];
2548 const Uint32 errCode = signal->theData[3];
2549
2550 TransactionPtr transPtr;
2551 c_runningTransactions.getPtr(transPtr, transI);
2552 ndbrequire(transId1 == transPtr.p->transId[0] &&
2553 transId2 == transPtr.p->transId[1]);
2554
2555 //if(getClassification(errCode) == PermanentError){
2556 //}
2557
2558 //ndbout << "Transaction error (code: " << errCode << ")" << endl;
2559
2560 transPtr.p->errorCode = errCode;
2561 finishTransaction(signal, transPtr);
2562 }
2563
2564 void
execTCROLLBACKREP(Signal * signal)2565 DbUtil::execTCROLLBACKREP(Signal* signal){
2566 jamEntry();
2567 #if 0 //def EVENT_DEBUG
2568 ndbout_c("File: %s line: %u",__FILE__,__LINE__);
2569 #endif
2570
2571 const Uint32 transI = signal->theData[0] >> 1;
2572 const Uint32 transId1 = signal->theData[1];
2573 const Uint32 transId2 = signal->theData[2];
2574 const Uint32 errCode = signal->theData[3];
2575
2576 TransactionPtr transPtr;
2577 c_runningTransactions.getPtr(transPtr, transI);
2578 ndbrequire(transId1 == transPtr.p->transId[0] &&
2579 transId2 == transPtr.p->transId[1]);
2580
2581 //if(getClassification(errCode) == PermanentError){
2582 //}
2583
2584 #if 0 //def EVENT_DEBUG
2585 ndbout << "Transaction error (code: " << errCode << ")" << endl;
2586 #endif
2587
2588 if(transPtr.p->noOfRetries > 0){
2589 transPtr.p->noOfRetries--;
2590 switch(errCode){
2591 case 266:
2592 case 410:
2593 case 1204:
2594 #if 0
2595 ndbout_c("errCode: %d noOfRetries: %d -> retry",
2596 errCode, transPtr.p->noOfRetries);
2597 #endif
2598 runTransaction(signal, transPtr);
2599 return;
2600 }
2601 }
2602
2603 transPtr.p->errorCode = errCode;
2604 finishTransaction(signal, transPtr);
2605 }
2606
2607 void
finishTransaction(Signal * signal,TransactionPtr transPtr)2608 DbUtil::finishTransaction(Signal* signal, TransactionPtr transPtr){
2609 #if 0 //def EVENT_DEBUG
2610 ndbout_c("Transaction %x %x completed %s",
2611 transPtr.p->transId[0],
2612 transPtr.p->transId[1],
2613 transPtr.p->errorCode == 0 ? "OK" : "FAILED");
2614 #endif
2615
2616 /*
2617 How to find the correct RS? Could we have multi-RS/transaction?
2618
2619 Operation * opP = c_operationPool.getPtr(opI);
2620
2621 ResultSetBuffer::DataBufferIterator rsit;
2622 ndbrequire(opP->rs.first(rsit));
2623 ndbout << "F Result: " << rsit.data << endl;
2624
2625 while (opP->rs.next(rsit)) {
2626 ndbout << "R Result: " << rsit.data << endl;
2627 }
2628 */
2629
2630 switch(transPtr.p->gsn){
2631 case GSN_UTIL_SEQUENCE_REQ:
2632 jam();
2633 reportSequence(signal, transPtr.p);
2634 break;
2635 case GSN_UTIL_EXECUTE_REQ:
2636 if (transPtr.p->errorCode) {
2637 UtilExecuteRef * ret = (UtilExecuteRef *)signal->getDataPtrSend();
2638 ret->senderData = transPtr.p->clientData;
2639 ret->errorCode = UtilExecuteRef::TCError;
2640 ret->TCErrorCode = transPtr.p->errorCode;
2641 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_REF, signal,
2642 UtilExecuteRef::SignalLength, JBB);
2643 } else {
2644 struct LinearSectionPtr sectionsPtr[UtilExecuteReq::NoOfSections];
2645 UtilExecuteConf * ret = (UtilExecuteConf *)signal->getDataPtrSend();
2646 ret->senderData = transPtr.p->clientData;
2647 ret->gci_hi = transPtr.p->gci_hi;
2648 ret->gci_lo = transPtr.p->gci_lo;
2649 if (getResultSet(signal, transPtr.p, sectionsPtr)) {
2650 #if 0 //def EVENT_DEBUG
2651 for (int j = 0; j < 2; j++) {
2652 printf("Result set %u %u\n", j,sectionsPtr[j].sz);
2653 for (int i=0; i < sectionsPtr[j].sz; i++)
2654 printf("H'%.8x ", sectionsPtr[j].p[i]);
2655 printf("\n");
2656 }
2657 #endif
2658 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal,
2659 UtilExecuteConf::SignalLength, JBB,
2660 sectionsPtr, UtilExecuteReq::NoOfSections);
2661 } else
2662 sendSignal(transPtr.p->clientRef, GSN_UTIL_EXECUTE_CONF, signal,
2663 UtilExecuteConf::SignalLength, JBB);
2664 }
2665 break;
2666 default:
2667 ndbrequire(0);
2668 break;
2669 }
2670 releaseTransaction(transPtr);
2671 }
2672
2673 void
execUTIL_LOCK_REQ(Signal * signal)2674 DbUtil::execUTIL_LOCK_REQ(Signal * signal){
2675 jamEntry();
2676
2677 UtilLockReq req = *(UtilLockReq*)signal->getDataPtr();
2678
2679 LockQueuePtr lockQPtr;
2680 if(!c_lockQueues.find(lockQPtr, req.lockId))
2681 {
2682 jam();
2683 sendLOCK_REF(signal, &req, UtilLockRef::NoSuchLock);
2684 return;
2685 }
2686
2687 const Uint32 senderNode = refToNode(req.senderRef);
2688 if(senderNode != getOwnNodeId() && senderNode != 0)
2689 {
2690 jam();
2691 sendLOCK_REF(signal, &req, UtilLockRef::DistributedLockNotSupported);
2692 return;
2693 }
2694
2695 Uint32 res = lockQPtr.p->m_queue.lock(this, c_lockElementPool, &req);
2696 switch(res){
2697 case UtilLockRef::OK:
2698 jam();
2699 sendLOCK_CONF(signal, &req);
2700 return;
2701 case UtilLockRef::OutOfLockRecords:
2702 jam();
2703 sendLOCK_REF(signal, &req, UtilLockRef::OutOfLockRecords);
2704 return;
2705 case UtilLockRef::InLockQueue:
2706 jam();
2707 if (req.requestInfo & UtilLockReq::Notify)
2708 {
2709 jam();
2710 sendLOCK_REF(signal, &req, UtilLockRef::InLockQueue);
2711 }
2712 return;
2713 case UtilLockRef::LockAlreadyHeld:
2714 jam();
2715 ndbassert(req.requestInfo & UtilLockReq::TryLock);
2716 sendLOCK_REF(signal, &req, UtilLockRef::LockAlreadyHeld);
2717 return;
2718 default:
2719 jam();
2720 ndbassert(false);
2721 sendLOCK_REF(signal, &req, (UtilLockRef::ErrorCode)res);
2722 return;
2723 }
2724 }
2725
2726 void
execUTIL_UNLOCK_REQ(Signal * signal)2727 DbUtil::execUTIL_UNLOCK_REQ(Signal* signal)
2728 {
2729 jamEntry();
2730
2731 UtilUnlockReq req = *(UtilUnlockReq*)signal->getDataPtr();
2732
2733 LockQueuePtr lockQPtr;
2734 if(!c_lockQueues.find(lockQPtr, req.lockId))
2735 {
2736 jam();
2737 sendUNLOCK_REF(signal, &req, UtilUnlockRef::NoSuchLock);
2738 return;
2739 }
2740
2741 Uint32 res = lockQPtr.p->m_queue.unlock(this, c_lockElementPool, &req);
2742 switch(res){
2743 case UtilUnlockRef::OK:
2744 jam();
2745 case UtilUnlockRef::NotLockOwner: {
2746 jam();
2747 UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtrSend();
2748 conf->senderData = req.senderData;
2749 conf->senderRef = reference();
2750 conf->lockId = req.lockId;
2751 sendSignal(req.senderRef, GSN_UTIL_UNLOCK_CONF, signal,
2752 UtilUnlockConf::SignalLength, JBB);
2753 break;
2754 }
2755 case UtilUnlockRef::NotInLockQueue:
2756 jam();
2757 default:
2758 jam();
2759 ndbassert(false);
2760 sendUNLOCK_REF(signal, &req, (UtilUnlockRef::ErrorCode)res);
2761 break;
2762 }
2763
2764 /**
2765 * Unlock can make other(s) acquie lock
2766 */
2767 UtilLockReq lockReq;
2768 LockQueue::Iterator iter;
2769 if (lockQPtr.p->m_queue.first(this, c_lockElementPool, iter))
2770 {
2771 int res;
2772 while ((res = lockQPtr.p->m_queue.checkLockGrant(iter, &lockReq)) > 0)
2773 {
2774 jam();
2775 /**
2776 *
2777 */
2778 if (res == 2)
2779 {
2780 jam();
2781 sendLOCK_CONF(signal, &lockReq);
2782 }
2783
2784 if (!lockQPtr.p->m_queue.next(iter))
2785 break;
2786 }
2787 }
2788 }
2789
2790 void
sendLOCK_REF(Signal * signal,const UtilLockReq * req,UtilLockRef::ErrorCode err)2791 DbUtil::sendLOCK_REF(Signal* signal,
2792 const UtilLockReq * req, UtilLockRef::ErrorCode err)
2793 {
2794 const Uint32 senderData = req->senderData;
2795 const Uint32 senderRef = req->senderRef;
2796 const Uint32 lockId = req->lockId;
2797 const Uint32 extra = req->extra;
2798
2799 UtilLockRef * ref = (UtilLockRef*)signal->getDataPtrSend();
2800 ref->senderData = senderData;
2801 ref->senderRef = reference();
2802 ref->lockId = lockId;
2803 ref->errorCode = err;
2804 ref->extra = extra;
2805 sendSignal(senderRef, GSN_UTIL_LOCK_REF, signal,
2806 UtilLockRef::SignalLength, JBB);
2807 }
2808
2809 void
sendLOCK_CONF(Signal * signal,const UtilLockReq * req)2810 DbUtil::sendLOCK_CONF(Signal* signal, const UtilLockReq * req)
2811 {
2812 const Uint32 senderData = req->senderData;
2813 const Uint32 senderRef = req->senderRef;
2814 const Uint32 lockId = req->lockId;
2815 const Uint32 extra = req->extra;
2816
2817 UtilLockConf * conf = (UtilLockConf*)signal->getDataPtrSend();
2818 conf->senderData = senderData;
2819 conf->senderRef = reference();
2820 conf->lockId = lockId;
2821 conf->extra = extra;
2822 sendSignal(senderRef, GSN_UTIL_LOCK_CONF, signal,
2823 UtilLockConf::SignalLength, JBB);
2824 }
2825
2826 void
sendUNLOCK_REF(Signal * signal,const UtilUnlockReq * req,UtilUnlockRef::ErrorCode err)2827 DbUtil::sendUNLOCK_REF(Signal* signal,
2828 const UtilUnlockReq* req, UtilUnlockRef::ErrorCode err){
2829
2830 const Uint32 senderData = req->senderData;
2831 const Uint32 senderRef = req->senderRef;
2832 const Uint32 lockId = req->lockId;
2833
2834 UtilUnlockRef * ref = (UtilUnlockRef*)signal->getDataPtrSend();
2835 ref->senderData = senderData;
2836 ref->senderRef = reference();
2837 ref->lockId = lockId;
2838 ref->errorCode = err;
2839 sendSignal(senderRef, GSN_UTIL_UNLOCK_REF, signal,
2840 UtilUnlockRef::SignalLength, JBB);
2841 }
2842
2843 void
execUTIL_CREATE_LOCK_REQ(Signal * signal)2844 DbUtil::execUTIL_CREATE_LOCK_REQ(Signal* signal){
2845 jamEntry();
2846 UtilCreateLockReq req = * (UtilCreateLockReq*)signal->getDataPtr();
2847
2848 UtilCreateLockRef::ErrorCode err = UtilCreateLockRef::OK;
2849
2850 do {
2851 LockQueuePtr lockQPtr;
2852 if(c_lockQueues.find(lockQPtr, req.lockId)){
2853 jam();
2854 err = UtilCreateLockRef::LockIdAlreadyUsed;
2855 break;
2856 }
2857
2858 if(req.lockType != UtilCreateLockReq::Mutex){
2859 jam();
2860 err = UtilCreateLockRef::UnsupportedLockType;
2861 break;
2862 }
2863
2864 if(!c_lockQueues.seize(lockQPtr)){
2865 jam();
2866 err = UtilCreateLockRef::OutOfLockQueueRecords;
2867 break;
2868 }
2869
2870 new (lockQPtr.p) LockQueueInstance(req.lockId);
2871 c_lockQueues.add(lockQPtr);
2872
2873 UtilCreateLockConf * conf = (UtilCreateLockConf*)signal->getDataPtrSend();
2874 conf->senderData = req.senderData;
2875 conf->senderRef = reference();
2876 conf->lockId = req.lockId;
2877
2878 sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_CONF, signal,
2879 UtilCreateLockConf::SignalLength, JBB);
2880 return;
2881 } while(false);
2882
2883 UtilCreateLockRef * ref = (UtilCreateLockRef*)signal->getDataPtrSend();
2884 ref->senderData = req.senderData;
2885 ref->senderRef = reference();
2886 ref->lockId = req.lockId;
2887 ref->errorCode = err;
2888
2889 sendSignal(req.senderRef, GSN_UTIL_CREATE_LOCK_REF, signal,
2890 UtilCreateLockRef::SignalLength, JBB);
2891 }
2892
2893 void
execUTIL_DESTORY_LOCK_REQ(Signal * signal)2894 DbUtil::execUTIL_DESTORY_LOCK_REQ(Signal* signal){
2895 jamEntry();
2896
2897 UtilDestroyLockReq req = * (UtilDestroyLockReq*)signal->getDataPtr();
2898 UtilDestroyLockRef::ErrorCode err = UtilDestroyLockRef::OK;
2899 do {
2900 LockQueuePtr lockQPtr;
2901 if(!c_lockQueues.find(lockQPtr, req.lockId))
2902 {
2903 jam();
2904 err = UtilDestroyLockRef::NoSuchLock;
2905 break;
2906 }
2907
2908 LockQueue::Iterator iter;
2909 if (lockQPtr.p->m_queue.first(this, c_lockElementPool, iter) == false)
2910 {
2911 jam();
2912 err = UtilDestroyLockRef::NotLockOwner;
2913 break;
2914 }
2915
2916 if (! (iter.m_curr.p->m_req.senderData == req.senderData &&
2917 iter.m_curr.p->m_req.senderRef == req.senderRef &&
2918 (! (iter.m_curr.p->m_req.requestInfo & UtilLockReq::SharedLock)) &&
2919 iter.m_curr.p->m_req.requestInfo & UtilLockReq::Granted))
2920 {
2921 jam();
2922 err = UtilDestroyLockRef::NotLockOwner;
2923 break;
2924 }
2925
2926 /**
2927 * OK
2928 */
2929
2930 while (lockQPtr.p->m_queue.next(iter))
2931 {
2932 jam();
2933 sendLOCK_REF(signal, &iter.m_curr.p->m_req, UtilLockRef::NoSuchLock);
2934 }
2935
2936 lockQPtr.p->m_queue.clear(c_lockElementPool);
2937 c_lockQueues.release(lockQPtr);
2938
2939 // Send Destroy conf
2940 UtilDestroyLockConf* conf=(UtilDestroyLockConf*)signal->getDataPtrSend();
2941 conf->senderData = req.senderData;
2942 conf->senderRef = reference();
2943 conf->lockId = req.lockId;
2944 sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_CONF, signal,
2945 UtilDestroyLockConf::SignalLength, JBB);
2946 return;
2947 } while(false);
2948
2949 UtilDestroyLockRef * ref = (UtilDestroyLockRef*)signal->getDataPtrSend();
2950 ref->senderData = req.senderData;
2951 ref->senderRef = reference();
2952 ref->lockId = req.lockId;
2953 ref->errorCode = err;
2954 sendSignal(req.senderRef, GSN_UTIL_DESTROY_LOCK_REF, signal,
2955 UtilDestroyLockRef::SignalLength, JBB);
2956 }
2957
2958 template class ArrayPool<DbUtil::Page32>;
2959