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