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