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