DbUtil.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:79k
源码类别:

MySQL数据库

开发平台:

Visual C++

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