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

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. #define DBLQH_C
  14. #include "Dblqh.hpp"
  15. #include <ndb_limits.h>
  16. #include <md5_hash.hpp>
  17. #include <ndb_version.h>
  18. #include <signaldata/TuxBound.hpp>
  19. #include <signaldata/AccScan.hpp>
  20. #include <signaldata/CopyActive.hpp>
  21. #include <signaldata/CopyFrag.hpp>
  22. #include <signaldata/CreateTrig.hpp>
  23. #include <signaldata/DropTrig.hpp>
  24. #include <signaldata/EmptyLcp.hpp>
  25. #include <signaldata/EventReport.hpp>
  26. #include <signaldata/ExecFragReq.hpp>
  27. #include <signaldata/GCPSave.hpp>
  28. #include <signaldata/TcKeyRef.hpp>
  29. #include <signaldata/LqhKey.hpp>
  30. #include <signaldata/NextScan.hpp>
  31. #include <signaldata/NFCompleteRep.hpp>
  32. #include <signaldata/NodeFailRep.hpp>
  33. #include <signaldata/ReadNodesConf.hpp>
  34. #include <signaldata/RelTabMem.hpp>
  35. #include <signaldata/ScanFrag.hpp>
  36. #include <signaldata/SrFragidConf.hpp>
  37. #include <signaldata/StartFragReq.hpp>
  38. #include <signaldata/StartRec.hpp>
  39. #include <signaldata/TupKey.hpp>
  40. #include <signaldata/TupCommit.hpp>
  41. #include <signaldata/LqhFrag.hpp>
  42. #include <signaldata/AccFrag.hpp>
  43. #include <signaldata/TupFrag.hpp>
  44. #include <signaldata/DumpStateOrd.hpp>
  45. #include <signaldata/PackedSignal.hpp>
  46. #include <signaldata/PrepDropTab.hpp>
  47. #include <signaldata/DropTab.hpp>
  48. #include <signaldata/AlterTab.hpp>
  49. #include <signaldata/LCP.hpp>
  50. // Use DEBUG to print messages that should be
  51. // seen only when we debug the product
  52. #ifdef VM_TRACE
  53. #define DEBUG(x) ndbout << "DBLQH: "<< x << endl;
  54. NdbOut &
  55. operator<<(NdbOut& out, Dblqh::TcConnectionrec::TransactionState state){
  56.   out << (int)state;
  57.   return out;
  58. }
  59. NdbOut &
  60. operator<<(NdbOut& out, Dblqh::TcConnectionrec::LogWriteState state){
  61.   out << (int)state;
  62.   return out;
  63. }
  64. NdbOut &
  65. operator<<(NdbOut& out, Dblqh::TcConnectionrec::ListState state){
  66.   out << (int)state;
  67.   return out;
  68. }
  69. NdbOut &
  70. operator<<(NdbOut& out, Dblqh::TcConnectionrec::AbortState state){
  71.   out << (int)state;
  72.   return out;
  73. }
  74. NdbOut &
  75. operator<<(NdbOut& out, Dblqh::ScanRecord::ScanState state){
  76.   out << (int)state;
  77.   return out;
  78. }
  79. NdbOut &
  80. operator<<(NdbOut& out, Dblqh::LogFileOperationRecord::LfoState state){
  81.   out << (int)state;
  82.   return out;
  83. }
  84. NdbOut &
  85. operator<<(NdbOut& out, Dblqh::ScanRecord::ScanType state){
  86.   out << (int)state;
  87.   return out;
  88. }
  89. #else
  90. #define DEBUG(x)
  91. #endif
  92. //#define MARKER_TRACE 1
  93. //#define TRACE_SCAN_TAKEOVER 1
  94. const Uint32 NR_ScanNo = 0;
  95. void Dblqh::execACC_COM_BLOCK(Signal* signal)
  96. {
  97.   jamEntry();
  98. /* ------------------------------------------------------------------------- */
  99. // Undo log buffer in ACC is in critical sector of being full.
  100. /* ------------------------------------------------------------------------- */
  101.   cCounterAccCommitBlocked++;
  102.   caccCommitBlocked = true;
  103.   cCommitBlocked = true;
  104.   return;
  105. }//Dblqh::execACC_COM_BLOCK()
  106. void Dblqh::execACC_COM_UNBLOCK(Signal* signal)
  107. {
  108.   jamEntry();
  109. /* ------------------------------------------------------------------------- */
  110. // Undo log buffer in ACC ok again.
  111. /* ------------------------------------------------------------------------- */
  112.   caccCommitBlocked = false;
  113.   if (ctupCommitBlocked == false) {
  114.     jam();
  115.     cCommitBlocked = false;
  116.   }//if
  117.   return;
  118. }//Dblqh::execACC_COM_UNBLOCK()
  119. void Dblqh::execTUP_COM_BLOCK(Signal* signal)
  120. {
  121.   jamEntry();
  122. /* ------------------------------------------------------------------------- */
  123. // Undo log buffer in TUP is in critical sector of being full.
  124. /* ------------------------------------------------------------------------- */
  125.   cCounterTupCommitBlocked++;
  126.   ctupCommitBlocked = true;
  127.   cCommitBlocked = true;
  128.   return;
  129. }//Dblqh::execTUP_COM_BLOCK()
  130. void Dblqh::execTUP_COM_UNBLOCK(Signal* signal)
  131. {
  132.   jamEntry();
  133. /* ------------------------------------------------------------------------- */
  134. // Undo log buffer in TUP ok again.
  135. /* ------------------------------------------------------------------------- */
  136.   ctupCommitBlocked = false;
  137.   if (caccCommitBlocked == false) {
  138.     jam();
  139.     cCommitBlocked = false;
  140.   }//if
  141.   return;
  142. }//Dblqh::execTUP_COM_UNBLOCK()
  143. /* ------------------------------------------------------------------------- */
  144. /* -------               SEND SYSTEM ERROR                           ------- */
  145. /*                                                                           */
  146. /* ------------------------------------------------------------------------- */
  147. void Dblqh::systemError(Signal* signal) 
  148. {
  149.   progError(0, 0);
  150. }//Dblqh::systemError()
  151. /* *************** */
  152. /*  ACCSEIZEREF  > */
  153. /* *************** */
  154. void Dblqh::execACCSEIZEREF(Signal* signal) 
  155. {
  156.   jamEntry();
  157.   ndbrequire(false);
  158. }//Dblqh::execACCSEIZEREF()
  159. /* ******************************************************>> */
  160. /* THIS SIGNAL IS USED TO HANDLE REAL-TIME                  */
  161. /* BREAKS THAT ARE NECESSARY TO ENSURE REAL-TIME            */
  162. /* OPERATION OF LQH.                                        */
  163. /* This signal is also used for signal loops, for example   */
  164. /* the timeout handling for writing logs every second.      */
  165. /* ******************************************************>> */
  166. void Dblqh::execCONTINUEB(Signal* signal) 
  167. {
  168.   jamEntry();
  169.   Uint32 tcase = signal->theData[0];
  170.   Uint32 data0 = signal->theData[1];
  171.   Uint32 data1 = signal->theData[2];
  172.   Uint32 data2 = signal->theData[3];
  173. #if 0
  174.   if (tcase == RNIL) {
  175.     tcConnectptr.i = data0;
  176.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  177.     ndbout << "State = " << tcConnectptr.p->transactionState;
  178.     ndbout << " seqNoReplica = " << tcConnectptr.p->seqNoReplica;
  179.     ndbout << " tcNodeFailrec = " << tcConnectptr.p->tcNodeFailrec;
  180.     ndbout << " activeCreat = " << tcConnectptr.p->activeCreat;
  181.     ndbout << endl;
  182.     ndbout << "tupkeyData0 = " << tcConnectptr.p->tupkeyData[0];
  183.     ndbout << "tupkeyData1 = " << tcConnectptr.p->tupkeyData[1];
  184.     ndbout << "tupkeyData2 = " << tcConnectptr.p->tupkeyData[2];
  185.     ndbout << "tupkeyData3 = " << tcConnectptr.p->tupkeyData[3];
  186.     ndbout << endl;
  187.     ndbout << "abortState = " << tcConnectptr.p->abortState;
  188.     ndbout << "listState = " << tcConnectptr.p->listState;
  189.     ndbout << endl;
  190.     return;
  191.   }//if
  192. #endif
  193.   switch (tcase) {
  194.   case ZLOG_LQHKEYREQ:
  195.     if (cnoOfLogPages == 0) {
  196.       jam();
  197.       sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
  198.       return;
  199.     }//if
  200.     logPartPtr.i = data0;
  201.     ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
  202.     logFilePtr.i = logPartPtr.p->currentLogfile;
  203.     ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
  204.     logPagePtr.i = logFilePtr.p->currentLogpage;
  205.     ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
  206.     tcConnectptr.i = logPartPtr.p->firstLogQueue;
  207.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  208.     fragptr.i = tcConnectptr.p->fragmentptr;
  209.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  210.     if ((cCommitBlocked == true) &&
  211.         (fragptr.p->fragActiveStatus == ZTRUE)) {
  212.       jam();
  213.       sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
  214.       return;
  215.     }//if
  216.     logPartPtr.p->LogLqhKeyReqSent = ZFALSE;
  217.     getFirstInLogQueue(signal);
  218.     switch (tcConnectptr.p->transactionState) {
  219.     case TcConnectionrec::LOG_QUEUED:
  220.       if (tcConnectptr.p->abortState != TcConnectionrec::ABORT_IDLE) {
  221.         jam();
  222.         logNextStart(signal);
  223.         abortCommonLab(signal);
  224.         return;
  225.       } else {
  226.         jam();
  227. /*------------------------------------------------------------*/
  228. /*       WE MUST SET THE STATE OF THE LOG PART TO IDLE TO     */
  229. /*       ENSURE THAT WE ARE NOT QUEUED AGAIN ON THE LOG PART  */
  230. /*       WE WILL SET THE LOG PART STATE TO ACTIVE IMMEDIATELY */
  231. /*       SO NO OTHER PROCESS WILL SEE THIS STATE. IT IS MERELY*/
  232. /*       USED TO ENABLE REUSE OF CODE.                        */
  233. /*------------------------------------------------------------*/
  234.         if (logPartPtr.p->logPartState == LogPartRecord::ACTIVE) {
  235.           jam();
  236.           logPartPtr.p->logPartState = LogPartRecord::IDLE;
  237.         }//if
  238.         logLqhkeyreqLab(signal);
  239.         return;
  240.       }//if
  241.       break;
  242.     case TcConnectionrec::LOG_ABORT_QUEUED:
  243.       jam();
  244.       writeAbortLog(signal);
  245.       removeLogTcrec(signal);
  246.       logNextStart(signal);
  247.       continueAfterLogAbortWriteLab(signal);
  248.       return;
  249.       break;
  250.     case TcConnectionrec::LOG_COMMIT_QUEUED:
  251.     case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
  252.       jam();
  253.       writeCommitLog(signal, logPartPtr);
  254.       logNextStart(signal);
  255.       if (tcConnectptr.p->transactionState == TcConnectionrec::LOG_COMMIT_QUEUED) {
  256.         if (tcConnectptr.p->seqNoReplica != 0) {
  257.           jam();
  258.           commitReplyLab(signal);
  259.         } else {
  260.           jam();
  261.           localCommitLab(signal);
  262.         }//if
  263.         return;
  264.       } else {
  265.         jam();
  266.         tcConnectptr.p->transactionState = TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL;
  267.         return;
  268.       }//if
  269.       break;
  270.     case TcConnectionrec::COMMIT_QUEUED:
  271.       jam();
  272.       logNextStart(signal);
  273.       localCommitLab(signal);
  274.       break;
  275.     case TcConnectionrec::ABORT_QUEUED:
  276.       jam();
  277.       logNextStart(signal);
  278.       abortCommonLab(signal);
  279.       break;
  280.     default:
  281.       ndbrequire(false);
  282.       break;
  283.     }//switch
  284.     return;
  285.     break;
  286.   case ZSR_GCI_LIMITS:
  287.     jam();
  288.     signal->theData[0] = data0;
  289.     srGciLimits(signal);
  290.     return;
  291.     break;
  292.   case ZSR_LOG_LIMITS:
  293.     jam();
  294.     signal->theData[0] = data0;
  295.     signal->theData[1] = data1;
  296.     signal->theData[2] = data2;
  297.     srLogLimits(signal);
  298.     return;
  299.     break;
  300.   case ZSEND_EXEC_CONF:
  301.     jam();
  302.     signal->theData[0] = data0;
  303.     sendExecConf(signal);
  304.     return;
  305.     break;
  306.   case ZEXEC_SR:
  307.     jam();
  308.     signal->theData[0] = data0;
  309.     execSr(signal);
  310.     return;
  311.     break;
  312.   case ZSR_FOURTH_COMP:
  313.     jam();
  314.     signal->theData[0] = data0;
  315.     srFourthComp(signal);
  316.     return;
  317.     break;
  318.   case ZINIT_FOURTH:
  319.     jam();
  320.     signal->theData[0] = data0;
  321.     initFourth(signal);
  322.     return;
  323.     break;
  324.   case ZTIME_SUPERVISION:
  325.     jam();
  326.     signal->theData[0] = data0;
  327.     timeSup(signal);
  328.     return;
  329.     break;
  330.   case ZSR_PHASE3_START:
  331.     jam();
  332.     signal->theData[0] = data0;
  333.     srPhase3Start(signal);
  334.     return;
  335.     break;
  336.   case ZLQH_TRANS_NEXT:
  337.     jam();
  338.     tcNodeFailptr.i = data0;
  339.     ptrCheckGuard(tcNodeFailptr, ctcNodeFailrecFileSize, tcNodeFailRecord);
  340.     lqhTransNextLab(signal);
  341.     return;
  342.     break;
  343.   case ZSCAN_TC_CONNECT:
  344.     jam();
  345.     tabptr.i = data1;
  346.     ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  347.     scanTcConnectLab(signal, data0, data2);
  348.     return;
  349.     break;
  350.   case ZINITIALISE_RECORDS:
  351.     jam();
  352.     initialiseRecordsLab(signal, data0, data2, signal->theData[4]);
  353.     return;
  354.     break;
  355.   case ZINIT_GCP_REC:
  356.     jam();
  357.     gcpPtr.i = 0;
  358.     ptrAss(gcpPtr, gcpRecord);
  359.     initGcpRecLab(signal);
  360.     return;
  361.     break;
  362.   case ZRESTART_OPERATIONS_AFTER_STOP:
  363.     jam();
  364.     tcConnectptr.i = data0;
  365.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  366.     if (tcConnectptr.p->listState != TcConnectionrec::WAIT_QUEUE_LIST) {
  367.       jam();
  368.       return;
  369.     }//if
  370.     releaseWaitQueue(signal);
  371.     linkActiveFrag(signal);
  372.     restartOperationsAfterStopLab(signal);
  373.     return;
  374.     break;
  375.   case ZCHECK_LCP_STOP_BLOCKED:
  376.     jam();
  377.     c_scanRecordPool.getPtr(scanptr, data0);
  378.     tcConnectptr.i = scanptr.p->scanTcrec;
  379.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  380.     fragptr.i = tcConnectptr.p->fragmentptr;
  381.     ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  382.     checkLcpStopBlockedLab(signal);
  383.     return;
  384.   case ZSCAN_MARKERS:
  385.     jam();
  386.     scanMarkers(signal, data0, data1, data2);
  387.     return;
  388.     break;
  389.   case ZOPERATION_EVENT_REP:
  390.     jam();
  391.     /* --------------------------------------------------------------------- */
  392.     // Report information about transaction activity once per second.
  393.     /* --------------------------------------------------------------------- */
  394.     if (signal->theData[1] == 0) {
  395.       signal->theData[0] = EventReport::OperationReportCounters;
  396.       signal->theData[1] = c_Counters.operations;
  397.       sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
  398.     }//if
  399.     c_Counters.clear();
  400.     signal->theData[0] = ZOPERATION_EVENT_REP;
  401.     signal->theData[1] = 0;
  402.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 5000, 2);
  403.     break;
  404.   case ZPREP_DROP_TABLE:
  405.     jam();
  406.     checkDropTab(signal);
  407.     return;
  408.     break;
  409.   default:
  410.     ndbrequire(false);
  411.     break;
  412.   }//switch
  413. }//Dblqh::execCONTINUEB()
  414. /* *********************************************************> */
  415. /*  Request from DBDIH to include a new node in the node list */
  416. /*  and so forth.                                             */
  417. /* *********************************************************> */
  418. void Dblqh::execINCL_NODEREQ(Signal* signal) 
  419. {
  420.   jamEntry();
  421.   BlockReference retRef = signal->theData[0];
  422.   Uint32 nodeId = signal->theData[1];
  423.   cnewestGci = signal->theData[2];
  424.   cnewestCompletedGci = signal->theData[2] - 1;
  425.   ndbrequire(cnoOfNodes < MAX_NDB_NODES);
  426.   for (Uint32 i = 0; i < cnoOfNodes; i++) {
  427.     jam();
  428.     if (cnodeData[i] == nodeId) {
  429.       jam();
  430.       cnodeStatus[i] = ZNODE_UP;
  431.     }//if
  432.   }//for
  433.   signal->theData[0] = cownref; 
  434.   sendSignal(retRef, GSN_INCL_NODECONF, signal, 1, JBB);
  435.   return;
  436. }//Dblqh::execINCL_NODEREQ()
  437. void Dblqh::execTUPSEIZEREF(Signal* signal) 
  438. {
  439.   jamEntry();
  440.   ndbrequire(false);
  441. }//Dblqh::execTUPSEIZEREF()
  442. /* ########################################################################## */
  443. /* #######                  START / RESTART MODULE                    ####### */
  444. /* ########################################################################## */
  445. /* ************************************************************************>> */
  446. /*  This is first signal that arrives in a start / restart. Sender is NDBCNTR_REF. */
  447. /* ************************************************************************>> */
  448. void Dblqh::execSTTOR(Signal* signal) 
  449. {
  450.   UintR tstartPhase;
  451.   jamEntry();
  452.                                                   /* START CASE */
  453.   tstartPhase = signal->theData[1];
  454.                                                   /* SYSTEM RESTART RANK */
  455.   csignalKey = signal->theData[6];
  456.   switch (tstartPhase) {
  457.   case ZSTART_PHASE1:
  458.     jam();
  459.     cstartPhase = tstartPhase;
  460.     sttorStartphase1Lab(signal);
  461.     return;
  462.     break;
  463.   default:
  464.     jam();
  465.     /*empty*/;
  466.     sendsttorryLab(signal);
  467.     return;
  468.     break;
  469.   }//switch
  470. }//Dblqh::execSTTOR()
  471. /* ***************************************> */
  472. /*  Restart phases 1 - 6, sender is Ndbcntr */
  473. /* ***************************************> */
  474. void Dblqh::execNDB_STTOR(Signal* signal) 
  475. {
  476.   jamEntry();
  477.   Uint32 ownNodeId = signal->theData[1];   /* START PHASE*/
  478.   cstartPhase = signal->theData[2];  /* MY NODE ID */
  479.   cstartType = signal->theData[3];   /* START TYPE */
  480.   switch (cstartPhase) {
  481.   case ZSTART_PHASE1:
  482.     jam();
  483.     preComputedRequestInfoMask = 0;
  484.     LqhKeyReq::setKeyLen(preComputedRequestInfoMask, RI_KEYLEN_MASK);
  485.     LqhKeyReq::setLastReplicaNo(preComputedRequestInfoMask, RI_LAST_REPL_MASK);
  486.     LqhKeyReq::setLockType(preComputedRequestInfoMask, RI_LOCK_TYPE_MASK);
  487.     // Dont LqhKeyReq::setApplicationAddressFlag
  488.     LqhKeyReq::setDirtyFlag(preComputedRequestInfoMask, 1);
  489.     // Dont LqhKeyReq::setInterpretedFlag
  490.     LqhKeyReq::setSimpleFlag(preComputedRequestInfoMask, 1);
  491.     LqhKeyReq::setOperation(preComputedRequestInfoMask, RI_OPERATION_MASK);
  492.     // Dont setAIInLqhKeyReq
  493.     // Dont setSeqNoReplica
  494.     // Dont setSameClientAndTcFlag
  495.     // Dont setReturnedReadLenAIFlag
  496.     // Dont setAPIVersion
  497.     LqhKeyReq::setMarkerFlag(preComputedRequestInfoMask, 1);
  498.     //preComputedRequestInfoMask = 0x003d7fff;
  499.     startphase1Lab(signal, /* dummy */ ~0, ownNodeId);
  500.     signal->theData[0] = ZOPERATION_EVENT_REP;
  501.     signal->theData[1] = 1;
  502.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 2);
  503.     return;
  504.     break;
  505.   case ZSTART_PHASE2:
  506.     jam();
  507.     startphase2Lab(signal, /* dummy */ ~0);
  508.     return;
  509.     break;
  510.   case ZSTART_PHASE3:
  511.     jam();
  512.     startphase3Lab(signal);
  513.     return;
  514.     break;
  515.   case ZSTART_PHASE4:
  516.     jam();
  517.     startphase4Lab(signal);
  518.     return;
  519.     break;
  520.   case ZSTART_PHASE6:
  521.     jam();
  522.     startphase6Lab(signal);
  523.     return;
  524.     break;
  525.   default:
  526.     jam();
  527.     /*empty*/;
  528.     sendNdbSttorryLab(signal);
  529.     return;
  530.     break;
  531.   }//switch
  532. }//Dblqh::execNDB_STTOR()
  533. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  534. /* +++++++                     START PHASE 1                          +++++++ */
  535. /*               LOAD OUR BLOCK REFERENCE AND OUR PROCESSOR ID                */
  536. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  537. void Dblqh::sttorStartphase1Lab(Signal* signal) 
  538. {
  539.   sendsttorryLab(signal);
  540.   return;
  541. }//Dblqh::sttorStartphase1Lab()
  542. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  543. /* +++++++                           START PHASE 2                    +++++++ */
  544. /*                                                                            */
  545. /*               INITIATE ALL RECORDS WITHIN THE BLOCK                        */
  546. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  547. void Dblqh::startphase1Lab(Signal* signal, Uint32 _dummy, Uint32 ownNodeId) 
  548. {
  549.   UintR Ti;
  550.   HostRecordPtr ThostPtr;
  551. /* ------- INITIATE ALL RECORDS ------- */
  552.   cownNodeid    = ownNodeId;
  553.   caccBlockref  = calcAccBlockRef (cownNodeid);
  554.   ctupBlockref  = calcTupBlockRef (cownNodeid);
  555.   ctuxBlockref  = calcTuxBlockRef (cownNodeid);
  556.   cownref       = calcLqhBlockRef (cownNodeid);
  557.   for (Ti = 0; Ti < chostFileSize; Ti++) {
  558.     ThostPtr.i = Ti;
  559.     ptrCheckGuard(ThostPtr, chostFileSize, hostRecord);
  560.     ThostPtr.p->hostLqhBlockRef = calcLqhBlockRef(ThostPtr.i);
  561.     ThostPtr.p->hostTcBlockRef  = calcTcBlockRef(ThostPtr.i);
  562.     ThostPtr.p->inPackedList = false;
  563.     ThostPtr.p->noOfPackedWordsLqh = 0;
  564.     ThostPtr.p->noOfPackedWordsTc  = 0;
  565.   }//for
  566.   cpackedListIndex = 0;
  567.   sendNdbSttorryLab(signal);
  568.   return;
  569. }//Dblqh::startphase1Lab()
  570. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  571. /* +++++++                           START PHASE 2                    +++++++ */
  572. /*                                                                            */
  573. /* CONNECT LQH WITH ACC AND TUP.                                              */
  574. /* EVERY CONNECTION RECORD IN LQH IS ASSIGNED TO ONE ACC CONNECTION RECORD    */
  575. /*       AND ONE TUP CONNECTION RECORD.                                       */
  576. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  577. void Dblqh::startphase2Lab(Signal* signal, Uint32 _dummy) 
  578. {
  579.   cmaxWordsAtNodeRec = MAX_NO_WORDS_OUTSTANDING_COPY_FRAGMENT;
  580. /* -- ACC AND TUP CONNECTION PROCESS -- */
  581.   tcConnectptr.i = 0;
  582.   ptrAss(tcConnectptr, tcConnectionrec);
  583.   moreconnectionsLab(signal);
  584.   return;
  585. }//Dblqh::startphase2Lab()
  586. void Dblqh::moreconnectionsLab(Signal* signal) 
  587. {
  588.   tcConnectptr.p->tcAccBlockref = caccBlockref;
  589.   // set TUX block here (no operation is seized in TUX)
  590.   tcConnectptr.p->tcTuxBlockref = ctuxBlockref;
  591. /* NO STATE CHECKING IS PERFORMED, ASSUMED TO WORK */
  592. /* *************** */
  593. /*  ACCSEIZEREQ  < */
  594. /* *************** */
  595.   signal->theData[0] = tcConnectptr.i;
  596.   signal->theData[1] = cownref;
  597.   sendSignal(caccBlockref, GSN_ACCSEIZEREQ, signal, 2, JBB);
  598.   return;
  599. }//Dblqh::moreconnectionsLab()
  600. /* ***************> */
  601. /*  ACCSEIZECONF  > */
  602. /* ***************> */
  603. void Dblqh::execACCSEIZECONF(Signal* signal) 
  604. {
  605.   jamEntry();
  606.   tcConnectptr.i = signal->theData[0];
  607.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  608.   tcConnectptr.p->accConnectrec = signal->theData[1];
  609. /* *************** */
  610. /*  TUPSEIZEREQ  < */
  611. /* *************** */
  612.   tcConnectptr.p->tcTupBlockref = ctupBlockref;
  613.   signal->theData[0] = tcConnectptr.i;
  614.   signal->theData[1] = cownref;
  615.   sendSignal(ctupBlockref, GSN_TUPSEIZEREQ, signal, 2, JBB);
  616.   return;
  617. }//Dblqh::execACCSEIZECONF()
  618. /* ***************> */
  619. /*  TUPSEIZECONF  > */
  620. /* ***************> */
  621. void Dblqh::execTUPSEIZECONF(Signal* signal) 
  622. {
  623.   jamEntry();
  624.   tcConnectptr.i = signal->theData[0];
  625.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  626.   tcConnectptr.p->tupConnectrec = signal->theData[1];
  627. /* ------- CHECK IF THERE ARE MORE CONNECTIONS TO BE CONNECTED ------- */
  628.   tcConnectptr.i = tcConnectptr.p->nextTcConnectrec;
  629.   if (tcConnectptr.i != RNIL) {
  630.     jam();
  631.     ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  632.     moreconnectionsLab(signal);
  633.     return;
  634.   }//if
  635. /* ALL LQH_CONNECT RECORDS ARE CONNECTED TO ACC AND TUP ---- */
  636.   sendNdbSttorryLab(signal);
  637.   return;
  638. }//Dblqh::execTUPSEIZECONF()
  639. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  640. /* +++++++                    START PHASE 4                          +++++++ */
  641. /*                                                                           */
  642. /*       CONNECT LQH WITH LQH.                                               */
  643. /*       CONNECT EACH LQH WITH EVERY LQH IN THE DATABASE SYSTEM.             */
  644. /*       IF INITIAL START THEN CREATE THE FRAGMENT LOG FILES                 */
  645. /*IF SYSTEM RESTART OR NODE RESTART THEN OPEN THE FRAGMENT LOG FILES AND     */
  646. /*FIND THE END OF THE LOG FILES.                                             */
  647. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  648. /*        WAIT UNTIL ADD NODE PROCESSES ARE COMPLETED                        */
  649. /*        IF INITIAL START ALSO WAIT FOR LOG FILES TO INITIALISED            */
  650. /*START TIME SUPERVISION OF LOG FILES. WE HAVE TO WRITE LOG PAGES TO DISK    */
  651. /*EVEN IF THE PAGES ARE NOT FULL TO ENSURE THAT THEY COME TO DISK ASAP.      */
  652. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  653. void Dblqh::startphase3Lab(Signal* signal) 
  654. {
  655.   LogFileRecordPtr prevLogFilePtr;
  656.   LogFileRecordPtr zeroLogFilePtr;
  657.   caddNodeState = ZTRUE;
  658. /* ***************<< */
  659. /*  READ_NODESREQ  < */
  660. /* ***************<< */
  661.   cinitialStartOngoing = ZTRUE;
  662.   ndbrequire(cnoLogFiles != 0);
  663.   for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  664.     jam();
  665.     ptrAss(logPartPtr, logPartRecord);
  666.     initLogpart(signal);
  667.     for (Uint32 fileNo = 0; fileNo < cnoLogFiles; fileNo++) {
  668.       seizeLogfile(signal);
  669.       if (fileNo != 0) {
  670.         jam();
  671.         prevLogFilePtr.p->nextLogFile = logFilePtr.i;
  672.         logFilePtr.p->prevLogFile = prevLogFilePtr.i;
  673.       } else {
  674.         jam();
  675.         logPartPtr.p->firstLogfile = logFilePtr.i;
  676.         logPartPtr.p->currentLogfile = logFilePtr.i;
  677.         zeroLogFilePtr.i = logFilePtr.i;
  678.         zeroLogFilePtr.p = logFilePtr.p;
  679.       }//if
  680.       prevLogFilePtr.i = logFilePtr.i;
  681.       prevLogFilePtr.p = logFilePtr.p;
  682.       initLogfile(signal, fileNo);
  683.       if ((cstartType == NodeState::ST_INITIAL_START) ||
  684.   (cstartType == NodeState::ST_INITIAL_NODE_RESTART)) {
  685.         if (logFilePtr.i == zeroLogFilePtr.i) {
  686.           jam();
  687. /* ------------------------------------------------------------------------- */
  688. /*IN AN INITIAL START WE START BY CREATING ALL LOG FILES AND SETTING THEIR   */
  689. /*PROPER SIZE AND INITIALISING PAGE ZERO IN ALL FILES.                       */
  690. /*WE START BY CREATING FILE ZERO IN EACH LOG PART AND THEN PROCEED           */
  691. /*SEQUENTIALLY THROUGH ALL LOG FILES IN THE LOG PART.                        */
  692. /* ------------------------------------------------------------------------- */
  693.           openLogfileInit(signal);
  694.         }//if
  695.       }//if
  696.     }//for
  697.     zeroLogFilePtr.p->prevLogFile = logFilePtr.i;
  698.     logFilePtr.p->nextLogFile = zeroLogFilePtr.i;
  699.   }//for
  700.   if (cstartType != NodeState::ST_INITIAL_START && 
  701.       cstartType != NodeState::ST_INITIAL_NODE_RESTART) {
  702.     jam();
  703.     ndbrequire(cstartType == NodeState::ST_NODE_RESTART || 
  704.        cstartType == NodeState::ST_SYSTEM_RESTART);
  705.     /** --------------------------------------------------------------------
  706.      * THIS CODE KICKS OFF THE SYSTEM RESTART AND NODE RESTART. IT STARTS UP 
  707.      * THE RESTART BY FINDING THE END OF THE LOG AND FROM THERE FINDING THE 
  708.      * INFO ABOUT THE GLOBAL CHECKPOINTS IN THE FRAGMENT LOG. 
  709.      --------------------------------------------------------------------- */
  710.     for (logPartPtr.i = 0; logPartPtr.i < 4; logPartPtr.i++) {
  711.       jam();
  712.       LogFileRecordPtr locLogFilePtr;
  713.       ptrAss(logPartPtr, logPartRecord);
  714.       locLogFilePtr.i = logPartPtr.p->firstLogfile;
  715.       ptrCheckGuard(locLogFilePtr, clogFileFileSize, logFileRecord);
  716.       locLogFilePtr.p->logFileStatus = LogFileRecord::OPEN_SR_FRONTPAGE;
  717.       openFileRw(signal, locLogFilePtr);
  718.     }//for
  719.   }//if
  720.   signal->theData[0] = cownref;
  721.   sendSignal(NDBCNTR_REF, GSN_READ_NODESREQ, signal, 1, JBB);
  722.   return;
  723. }//Dblqh::startphase3Lab()
  724. /* ****************** */
  725. /*  READ_NODESCONF  > */
  726. /* ****************** */
  727. void Dblqh::execREAD_NODESCONF(Signal* signal) 
  728. {
  729.   jamEntry();
  730.   ReadNodesConf * const readNodes = (ReadNodesConf *)&signal->theData[0];
  731.   cnoOfNodes = readNodes->noOfNodes;
  732.   unsigned ind = 0;
  733.   unsigned i = 0;
  734.   for (i = 1; i < MAX_NDB_NODES; i++) {
  735.     jam();
  736.     if (NodeBitmask::get(readNodes->allNodes, i)) {
  737.       jam();
  738.       cnodeData[ind]    = i;
  739.       cnodeStatus[ind]  = NodeBitmask::get(readNodes->inactiveNodes, i);
  740.       //readNodes->getVersionId(i, readNodes->theVersionIds) not used
  741.       ind++;
  742.     }//if
  743.   }//for
  744.   ndbrequire(ind == cnoOfNodes);
  745.   ndbrequire(cnoOfNodes >= 1 && cnoOfNodes < MAX_NDB_NODES);
  746.   ndbrequire(!(cnoOfNodes == 1 && cstartType == NodeState::ST_NODE_RESTART));
  747.   
  748.   caddNodeState = ZFALSE;
  749.   if (cstartType == NodeState::ST_SYSTEM_RESTART) {
  750.     jam();
  751.     sendNdbSttorryLab(signal);
  752.     return;
  753.   }//if
  754.   checkStartCompletedLab(signal);
  755.   return;
  756. }//Dblqh::execREAD_NODESCONF()
  757. void Dblqh::checkStartCompletedLab(Signal* signal) 
  758. {
  759.   if (caddNodeState == ZFALSE) {
  760.     if (cinitialStartOngoing == ZFALSE) {
  761.       jam();
  762.       sendNdbSttorryLab(signal);
  763.       return;
  764.     }//if
  765.   }//if
  766.   return;
  767. }//Dblqh::checkStartCompletedLab()
  768. void Dblqh::startphase4Lab(Signal* signal) 
  769. {
  770.   sendNdbSttorryLab(signal);
  771.   return;
  772. }//Dblqh::startphase4Lab()
  773. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  774. /* SET CONCURRENCY OF LOCAL CHECKPOINTS TO BE USED AFTER SYSTEM RESTART.      */
  775. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  776. void Dblqh::startphase6Lab(Signal* signal) 
  777. {
  778.   cstartPhase = ZNIL;
  779.   cstartType = ZNIL;
  780.   sendNdbSttorryLab(signal);
  781.   return;
  782. }//Dblqh::startphase6Lab()
  783. void Dblqh::sendNdbSttorryLab(Signal* signal) 
  784. {
  785.   signal->theData[0] = cownref;
  786.   sendSignal(NDBCNTR_REF, GSN_NDB_STTORRY, signal, 1, JBB);
  787.   return;
  788. }//Dblqh::sendNdbSttorryLab()
  789. void Dblqh::sendsttorryLab(Signal* signal) 
  790. {
  791. /* *********<< */
  792. /*  STTORRY  < */
  793. /* *********<< */
  794.   signal->theData[0] = csignalKey; /* SIGNAL KEY */
  795.   signal->theData[1] = 3;          /* BLOCK CATEGORY */
  796.   signal->theData[2] = 2;          /* SIGNAL VERSION NUMBER */
  797.   signal->theData[3] = ZSTART_PHASE1;
  798.   signal->theData[4] = 255;
  799.   sendSignal(NDBCNTR_REF, GSN_STTORRY, signal, 5, JBB);
  800.   return;
  801. }//Dblqh::sendsttorryLab()
  802. /* ***************>> */
  803. /*  READ_NODESREF  > */
  804. /* ***************>> */
  805. void Dblqh::execREAD_NODESREF(Signal* signal) 
  806. {
  807.   jamEntry();
  808.   ndbrequire(false);
  809. }//Dblqh::execREAD_NODESREF()
  810. /* *************** */
  811. /*  SIZEALT_REP  > */
  812. /* *************** */
  813. void Dblqh::execREAD_CONFIG_REQ(Signal* signal) 
  814. {
  815.   const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
  816.   Uint32 ref = req->senderRef;
  817.   Uint32 senderData = req->senderData;
  818.   ndbrequire(req->noOfParameters == 0);
  819.   jamEntry();
  820.   const ndb_mgm_configuration_iterator * p = 
  821.     theConfiguration.getOwnConfigIterator();
  822.   ndbrequire(p != 0);
  823.   
  824.   cnoLogFiles = 8;
  825.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_NO_REDOLOG_FILES, 
  826. &cnoLogFiles));
  827.   ndbrequire(cnoLogFiles > 0);
  828.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_FRAG, &cfragrecFileSize));
  829.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TABLE, &ctabrecFileSize));
  830.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_TC_CONNECT, 
  831. &ctcConnectrecFileSize));
  832.   clogFileFileSize       = 4 * cnoLogFiles;
  833.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_LQH_SCAN, &cscanrecFileSize));
  834.   cmaxAccOps = cscanrecFileSize * MAX_PARALLEL_OP_PER_SCAN;
  835.   ndbrequire(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &c_diskless));
  836.   
  837.   initRecords();
  838.   initialiseRecordsLab(signal, 0, ref, senderData);
  839.   
  840.   return;
  841. }//Dblqh::execSIZEALT_REP()
  842. /* ########################################################################## */
  843. /* #######                          ADD/DELETE FRAGMENT MODULE        ####### */
  844. /*       THIS MODULE IS USED BY DICTIONARY TO CREATE NEW FRAGMENTS AND DELETE */
  845. /*       OLD FRAGMENTS.                                                       */
  846. /*                                                                            */
  847. /* ########################################################################## */
  848. /* -------------------------------------------------------------- */
  849. /*            FRAG REQ                                            */
  850. /* -------------------------------------------------------------- */
  851. /* *********************************************************> */
  852. /*  LQHFRAGREQ: Create new fragments for a table. Sender DICT */
  853. /* *********************************************************> */
  854. // this unbelievable mess could be replaced by one signal to LQH
  855. // and execute direct to local DICT to get everything at once
  856. void Dblqh::execLQHFRAGREQ(Signal* signal) 
  857. {
  858.   jamEntry();
  859.   LqhFragReq * req = (LqhFragReq*)signal->getDataPtr();
  860.   
  861.   Uint32 retPtr = req->senderData;
  862.   BlockReference retRef = req->senderRef;
  863.   Uint32 fragId = req->fragmentId;
  864.   Uint32 reqinfo = req->requestInfo;
  865.   tabptr.i = req->tableId;
  866.   Uint16 tlocalKeylen = req->localKeyLength;
  867.   Uint32 tmaxLoadFactor = req->maxLoadFactor;
  868.   Uint32 tminLoadFactor = req->minLoadFactor;
  869.   Uint8 tk = req->kValue;
  870.   Uint8 tlhstar = req->lh3DistrBits;
  871.   Uint8 tlh = req->lh3PageBits;
  872.   Uint32 tnoOfAttr = req->noOfAttributes;
  873.   Uint32 tnoOfNull = req->noOfNullAttributes;
  874.   Uint32 noOfAlloc = req->noOfPagesToPreAllocate;
  875.   Uint32 tschemaVersion = req->schemaVersion;
  876.   Uint32 ttupKeyLength = req->keyLength;
  877.   Uint32 nextLcp = req->nextLCP;
  878.   Uint32 noOfKeyAttr = req->noOfKeyAttr;
  879.   Uint32 noOfNewAttr = req->noOfNewAttr;
  880.   Uint32 checksumIndicator = req->checksumIndicator;
  881.   Uint32 noOfAttributeGroups = req->noOfAttributeGroups;
  882.   Uint32 gcpIndicator = req->GCPIndicator;
  883.   Uint32 startGci = req->startGci;
  884.   Uint32 tableType = req->tableType;
  885.   Uint32 primaryTableId = req->primaryTableId;
  886.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  887.   bool tempTable = ((reqinfo & LqhFragReq::TemporaryTable) != 0);
  888.   /* Temporary tables set to defined in system restart */
  889.   if (tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
  890.     tabptr.p->tableStatus = Tablerec::ADD_TABLE_ONGOING;
  891.     tabptr.p->tableType = tableType;
  892.     tabptr.p->primaryTableId = primaryTableId;
  893.     tabptr.p->schemaVersion = tschemaVersion;
  894.   }//if
  895.   
  896.   if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING){
  897.     jam();
  898.     fragrefLab(signal, retRef, retPtr, ZTAB_STATE_ERROR);
  899.     return;
  900.   }//if
  901.   //--------------------------------------------------------------------
  902.   // We could arrive here if we create the fragment as part of a take
  903.   // over by a hot spare node. The table is then is already created
  904.   // and bit 31 is set, thus indicating that we are creating a fragment
  905.   // by copy creation. Also since the node has already been started we
  906.   // know that it is not a node restart ongoing.
  907.   //--------------------------------------------------------------------
  908.   if (getFragmentrec(signal, fragId)) {
  909.     jam();
  910.     fragrefLab(signal, retRef, retPtr, terrorCode);
  911.     return;
  912.   }//if
  913.   if (!insertFragrec(signal, fragId)) {
  914.     jam();
  915.     fragrefLab(signal, retRef, retPtr, terrorCode);
  916.     return;
  917.   }//if
  918.   Uint32 copyType = reqinfo & 3;
  919.   initFragrec(signal, tabptr.i, fragId, copyType);
  920.   fragptr.p->startGci = startGci;
  921.   fragptr.p->newestGci = startGci;
  922.   fragptr.p->tableType = tableType;
  923.   if (DictTabInfo::isOrderedIndex(tableType)) {
  924.     jam();
  925.     // find corresponding primary table fragment
  926.     TablerecPtr tTablePtr;
  927.     tTablePtr.i = primaryTableId;
  928.     ptrCheckGuard(tTablePtr, ctabrecFileSize, tablerec);
  929.     FragrecordPtr tFragPtr;
  930.     tFragPtr.i = RNIL;
  931.     for (Uint32 i = 0; i < MAX_FRAG_PER_NODE; i++) {
  932.       if (tTablePtr.p->fragid[i] == fragptr.p->fragId) {
  933.         jam();
  934.         tFragPtr.i = tTablePtr.p->fragrec[i];
  935.         break;
  936.       }
  937.     }
  938.     ndbrequire(tFragPtr.i != RNIL);
  939.     // store it
  940.     fragptr.p->tableFragptr = tFragPtr.i;
  941.   } else {
  942.     fragptr.p->tableFragptr = fragptr.i;
  943.   }
  944.   if (tempTable) {
  945. //--------------------------------------------
  946. // reqinfo bit 3-4 = 2 means temporary table
  947. // without logging or checkpointing.
  948. //--------------------------------------------
  949.     jam();
  950.     fragptr.p->logFlag = Fragrecord::STATE_FALSE;
  951.     fragptr.p->lcpFlag = Fragrecord::LCP_STATE_FALSE;
  952.   }//if
  953.   
  954.   fragptr.p->nextLcp = nextLcp; 
  955. //----------------------------------------------
  956. // For node restarts it is not necessarily zero 
  957. //----------------------------------------------
  958.   if (cfirstfreeAddfragrec == RNIL) {
  959.     jam();
  960.     deleteFragrec(fragId);
  961.     fragrefLab(signal, retRef, retPtr, ZNO_ADD_FRAGREC);
  962.     return;
  963.   }//if
  964.   seizeAddfragrec(signal);
  965.   addfragptr.p->addFragid = fragId;
  966.   addfragptr.p->fragmentPtr = fragptr.i;
  967.   addfragptr.p->dictBlockref = retRef;
  968.   addfragptr.p->dictConnectptr = retPtr;
  969.   addfragptr.p->m_senderAttrPtr = RNIL;
  970.   addfragptr.p->noOfAttr = tnoOfAttr;
  971.   addfragptr.p->noOfNull = tnoOfNull;
  972.   addfragptr.p->noOfAllocPages = noOfAlloc;
  973.   addfragptr.p->tabId = tabptr.i;
  974.   addfragptr.p->totalAttrReceived = 0;
  975.   addfragptr.p->attrSentToTup = ZNIL;/* TO FIND PROGRAMMING ERRORS QUICKLY */
  976.   addfragptr.p->schemaVer = tschemaVersion;
  977.   Uint32 tmp = (reqinfo & LqhFragReq::CreateInRunning);
  978.   addfragptr.p->fragCopyCreation = (tmp == 0 ? 0 : 1);
  979.   addfragptr.p->addfragErrorCode = 0;
  980.   addfragptr.p->noOfKeyAttr = noOfKeyAttr;
  981.   addfragptr.p->noOfNewAttr = noOfNewAttr;
  982.   addfragptr.p->checksumIndicator = checksumIndicator;
  983.   addfragptr.p->noOfAttributeGroups = noOfAttributeGroups;
  984.   addfragptr.p->GCPIndicator = gcpIndicator;
  985.   addfragptr.p->lh3DistrBits = tlhstar;
  986.   addfragptr.p->tableType = tableType;
  987.   addfragptr.p->primaryTableId = primaryTableId;
  988.   //
  989.   addfragptr.p->tup1Connectptr = RNIL;
  990.   addfragptr.p->tup2Connectptr = RNIL;
  991.   addfragptr.p->tux1Connectptr = RNIL;
  992.   addfragptr.p->tux2Connectptr = RNIL;
  993.   if (DictTabInfo::isTable(tableType) ||
  994.       DictTabInfo::isHashIndex(tableType)) {
  995.     jam();
  996.     AccFragReq* const accreq = (AccFragReq*)signal->getDataPtrSend();
  997.     accreq->userPtr = addfragptr.i;
  998.     accreq->userRef = cownref;
  999.     accreq->tableId = tabptr.i;
  1000.     accreq->reqInfo = copyType << 4;
  1001.     accreq->fragId = fragId;
  1002.     accreq->localKeyLen = tlocalKeylen;
  1003.     accreq->maxLoadFactor = tmaxLoadFactor;
  1004.     accreq->minLoadFactor = tminLoadFactor;
  1005.     accreq->kValue = tk;
  1006.     accreq->lhFragBits = tlhstar;
  1007.     accreq->lhDirBits = tlh;
  1008.     accreq->keyLength = ttupKeyLength;
  1009.     /* ----------------------------------------------------------------------- */
  1010.     /* Send ACCFRAGREQ, when confirmation is received send 2 * TUPFRAGREQ to   */
  1011.     /* create 2 tuple fragments on this node.                                  */
  1012.     /* ----------------------------------------------------------------------- */
  1013.     addfragptr.p->addfragStatus = AddFragRecord::ACC_ADDFRAG;
  1014.     sendSignal(fragptr.p->accBlockref, GSN_ACCFRAGREQ,
  1015.         signal, AccFragReq::SignalLength, JBB);
  1016.     return;
  1017.   }
  1018.   if (DictTabInfo::isOrderedIndex(tableType)) {
  1019.     jam();
  1020.     // NOTE: next 2 lines stolen from ACC
  1021.     addfragptr.p->fragid1 = (0 << tlhstar) | fragId;
  1022.     addfragptr.p->fragid2 = (1 << tlhstar) | fragId;
  1023.     addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
  1024.     sendAddFragReq(signal);
  1025.     return;
  1026.   }
  1027.   ndbrequire(false);
  1028. }//Dblqh::execLQHFRAGREQ()
  1029. /* *************** */
  1030. /*  ACCFRAGCONF  > */
  1031. /* *************** */
  1032. void Dblqh::execACCFRAGCONF(Signal* signal) 
  1033. {
  1034.   jamEntry();
  1035.   addfragptr.i = signal->theData[0];
  1036.   Uint32 taccConnectptr = signal->theData[1];
  1037.   Uint32 fragId1 = signal->theData[2];
  1038.   Uint32 fragId2 = signal->theData[3];
  1039.   Uint32 accFragPtr1 = signal->theData[4];
  1040.   Uint32 accFragPtr2 = signal->theData[5];
  1041.   Uint32 hashCheckBit = signal->theData[6];
  1042.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1043.   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
  1044.   addfragptr.p->accConnectptr = taccConnectptr;
  1045.   addfragptr.p->fragid1 = fragId1;
  1046.   addfragptr.p->fragid2 = fragId2;
  1047.   fragptr.i = addfragptr.p->fragmentPtr;
  1048.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1049.   fragptr.p->accFragptr[0] = accFragPtr1;
  1050.   fragptr.p->accFragptr[1] = accFragPtr2;
  1051.   fragptr.p->hashCheckBit = hashCheckBit;
  1052.   addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
  1053.   sendAddFragReq(signal);
  1054. }//Dblqh::execACCFRAGCONF()
  1055. /* *************** */
  1056. /*  TUPFRAGCONF  > */
  1057. /* *************** */
  1058. void Dblqh::execTUPFRAGCONF(Signal* signal) 
  1059. {
  1060.   jamEntry();
  1061.   addfragptr.i = signal->theData[0];
  1062.   Uint32 tupConnectptr = signal->theData[1];
  1063.   Uint32 tupFragPtr = signal->theData[2];  /* TUP FRAGMENT POINTER */
  1064.   Uint32 localFragId = signal->theData[3];  /* LOCAL FRAGMENT ID    */
  1065.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1066.   fragptr.i = addfragptr.p->fragmentPtr;
  1067.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1068.   if (localFragId == addfragptr.p->fragid1) {
  1069.     jam();
  1070.     fragptr.p->tupFragptr[0] = tupFragPtr;
  1071.   } else if (localFragId == addfragptr.p->fragid2) {
  1072.     jam();
  1073.     fragptr.p->tupFragptr[1] = tupFragPtr;
  1074.   } else {
  1075.     ndbrequire(false);
  1076.     return;
  1077.   }//if
  1078.   switch (addfragptr.p->addfragStatus) {
  1079.   case AddFragRecord::WAIT_TWO_TUP:
  1080.     jam();
  1081.     fragptr.p->tupFragptr[0] = tupFragPtr;
  1082.     addfragptr.p->tup1Connectptr = tupConnectptr;
  1083.     addfragptr.p->addfragStatus = AddFragRecord::WAIT_ONE_TUP;
  1084.     sendAddFragReq(signal);
  1085.     break;
  1086.   case AddFragRecord::WAIT_ONE_TUP:
  1087.     jam();
  1088.     fragptr.p->tupFragptr[1] = tupFragPtr;
  1089.     addfragptr.p->tup2Connectptr = tupConnectptr;
  1090.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
  1091.       addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUX;
  1092.       sendAddFragReq(signal);
  1093.       break;
  1094.     }
  1095.     goto done_with_frag;
  1096.     break;
  1097.   case AddFragRecord::WAIT_TWO_TUX:
  1098.     jam();
  1099.     fragptr.p->tuxFragptr[0] = tupFragPtr;
  1100.     addfragptr.p->tux1Connectptr = tupConnectptr;
  1101.     addfragptr.p->addfragStatus = AddFragRecord::WAIT_ONE_TUX;
  1102.     sendAddFragReq(signal);
  1103.     break;
  1104.   case AddFragRecord::WAIT_ONE_TUX:
  1105.     jam();
  1106.     fragptr.p->tuxFragptr[1] = tupFragPtr;
  1107.     addfragptr.p->tux2Connectptr = tupConnectptr;
  1108.     goto done_with_frag;
  1109.     break;
  1110.   done_with_frag:
  1111.     /* ---------------------------------------------------------------- */
  1112.     /* Finished create of fragments. Now ready for creating attributes. */
  1113.     /* ---------------------------------------------------------------- */
  1114.     addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
  1115.     {
  1116.       LqhFragConf* conf = (LqhFragConf*)signal->getDataPtrSend();
  1117.       conf->senderData = addfragptr.p->dictConnectptr;
  1118.       conf->lqhFragPtr = addfragptr.i;
  1119.       sendSignal(addfragptr.p->dictBlockref, GSN_LQHFRAGCONF,
  1120.           signal, LqhFragConf::SignalLength, JBB);
  1121.     }
  1122.     break;
  1123.   default:
  1124.     ndbrequire(false);
  1125.     break;
  1126.   }
  1127. }//Dblqh::execTUPFRAGCONF()
  1128. /* *************** */
  1129. /*  TUXFRAGCONF  > */
  1130. /* *************** */
  1131. void Dblqh::execTUXFRAGCONF(Signal* signal) 
  1132. {
  1133.   jamEntry();
  1134.   execTUPFRAGCONF(signal);
  1135. }//Dblqh::execTUXFRAGCONF
  1136. /*
  1137.  * Add fragment in TUP or TUX.  Called up to 4 times.
  1138.  */
  1139. void
  1140. Dblqh::sendAddFragReq(Signal* signal)
  1141. {
  1142.   fragptr.i = addfragptr.p->fragmentPtr;
  1143.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1144.   if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP ||
  1145.       addfragptr.p->addfragStatus == AddFragRecord::WAIT_ONE_TUP) {
  1146.     if (DictTabInfo::isTable(addfragptr.p->tableType) ||
  1147.         DictTabInfo::isHashIndex(addfragptr.p->tableType)) {
  1148.       jam();
  1149.       signal->theData[0] = addfragptr.i;
  1150.       signal->theData[1] = cownref;
  1151.       signal->theData[2] = 0; /* ADD TABLE */
  1152.       signal->theData[3] = addfragptr.p->tabId;
  1153.       signal->theData[4] = addfragptr.p->noOfAttr;
  1154.       signal->theData[5] =
  1155.         addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP
  1156.         ? addfragptr.p->fragid1 : addfragptr.p->fragid2;
  1157.       signal->theData[6] = (addfragptr.p->noOfAllocPages >> 1) + 1;
  1158.       signal->theData[7] = addfragptr.p->noOfNull;
  1159.       signal->theData[8] = addfragptr.p->schemaVer;
  1160.       signal->theData[9] = addfragptr.p->noOfKeyAttr;
  1161.       signal->theData[10] = addfragptr.p->noOfNewAttr;
  1162.       signal->theData[11] = addfragptr.p->checksumIndicator;
  1163.       signal->theData[12] = addfragptr.p->noOfAttributeGroups;
  1164.       signal->theData[13] = addfragptr.p->GCPIndicator;
  1165.       sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
  1166.           signal, TupFragReq::SignalLength, JBB);
  1167.       return;
  1168.     }
  1169.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
  1170.       jam();
  1171.       signal->theData[0] = addfragptr.i;
  1172.       signal->theData[1] = cownref;
  1173.       signal->theData[2] = 0; /* ADD TABLE */
  1174.       signal->theData[3] = addfragptr.p->tabId;
  1175.       signal->theData[4] = 1; /* ordered index: one array attr */
  1176.       signal->theData[5] =
  1177.         addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUP
  1178.         ? addfragptr.p->fragid1 : addfragptr.p->fragid2;
  1179.       signal->theData[6] = (addfragptr.p->noOfAllocPages >> 1) + 1;
  1180.       signal->theData[7] = 0; /* ordered index: no nullable */
  1181.       signal->theData[8] = addfragptr.p->schemaVer;
  1182.       signal->theData[9] = 1; /* ordered index: one key */
  1183.       signal->theData[10] = addfragptr.p->noOfNewAttr;
  1184.       signal->theData[11] = addfragptr.p->checksumIndicator;
  1185.       signal->theData[12] = addfragptr.p->noOfAttributeGroups;
  1186.       signal->theData[13] = addfragptr.p->GCPIndicator;
  1187.       sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ,
  1188.           signal, TupFragReq::SignalLength, JBB);
  1189.       return;
  1190.     }
  1191.   }
  1192.   if (addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ||
  1193.       addfragptr.p->addfragStatus == AddFragRecord::WAIT_ONE_TUX) {
  1194.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
  1195.       jam();
  1196.       TuxFragReq* const tuxreq = (TuxFragReq*)signal->getDataPtrSend();
  1197.       tuxreq->userPtr = addfragptr.i;
  1198.       tuxreq->userRef = cownref;
  1199.       tuxreq->reqInfo = 0; /* ADD TABLE */
  1200.       tuxreq->tableId = addfragptr.p->tabId;
  1201.       ndbrequire(addfragptr.p->noOfAttr >= 2);
  1202.       tuxreq->noOfAttr = addfragptr.p->noOfAttr - 1; /* skip NDB$TNODE */
  1203.       tuxreq->fragId =
  1204.         addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX
  1205.         ? addfragptr.p->fragid1 : addfragptr.p->fragid2;
  1206.       tuxreq->fragOff = addfragptr.p->lh3DistrBits;
  1207.       tuxreq->tableType = addfragptr.p->tableType;
  1208.       tuxreq->primaryTableId = addfragptr.p->primaryTableId;
  1209.       // pointer to index fragment in TUP
  1210.       tuxreq->tupIndexFragPtrI =
  1211.         addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX ?
  1212.         fragptr.p->tupFragptr[0] : fragptr.p->tupFragptr[1];
  1213.       // pointers to table fragments in TUP and ACC
  1214.       FragrecordPtr tFragPtr;
  1215.       tFragPtr.i = fragptr.p->tableFragptr;
  1216.       ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
  1217.       tuxreq->tupTableFragPtrI[0] = tFragPtr.p->tupFragptr[0];
  1218.       tuxreq->tupTableFragPtrI[1] = tFragPtr.p->tupFragptr[1];
  1219.       tuxreq->accTableFragPtrI[0] = tFragPtr.p->accFragptr[0];
  1220.       tuxreq->accTableFragPtrI[1] = tFragPtr.p->accFragptr[1];
  1221.       sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ,
  1222.           signal, TuxFragReq::SignalLength, JBB);
  1223.       return;
  1224.     }
  1225.   }
  1226.   ndbrequire(false);
  1227. }//Dblqh::sendAddFragReq
  1228. /* ************************************************************************> */
  1229. /*  LQHADDATTRREQ: Request from DICT to create attributes for the new table. */
  1230. /* ************************************************************************> */
  1231. void Dblqh::execLQHADDATTREQ(Signal* signal) 
  1232. {
  1233.   jamEntry();
  1234.   LqhAddAttrReq * const req = (LqhAddAttrReq*)signal->getDataPtr();
  1235.   
  1236.   addfragptr.i = req->lqhFragPtr;
  1237.   const Uint32 tnoOfAttr = req->noOfAttributes;
  1238.   const Uint32 senderData = req->senderData;
  1239.   const Uint32 senderAttrPtr = req->senderAttrPtr;
  1240.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1241.   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::WAIT_ADD_ATTR);
  1242.   ndbrequire((tnoOfAttr != 0) && (tnoOfAttr <= LqhAddAttrReq::MAX_ATTRIBUTES));
  1243.   addfragptr.p->totalAttrReceived += tnoOfAttr;
  1244.   ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
  1245.   addfragptr.p->attrReceived = tnoOfAttr;
  1246.   for (Uint32 i = 0; i < tnoOfAttr; i++) {
  1247.     addfragptr.p->attributes[i] = req->attributes[i];
  1248.   }//for
  1249.   addfragptr.p->attrSentToTup = 0;
  1250.   ndbrequire(addfragptr.p->dictConnectptr == senderData);
  1251.   addfragptr.p->m_senderAttrPtr = senderAttrPtr;
  1252.   addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT1;
  1253.   sendAddAttrReq(signal);
  1254. }//Dblqh::execLQHADDATTREQ()
  1255. /* *********************>> */
  1256. /*  TUP_ADD_ATTCONF      > */
  1257. /* *********************>> */
  1258. void Dblqh::execTUP_ADD_ATTCONF(Signal* signal) 
  1259. {
  1260.   jamEntry();
  1261.   addfragptr.i = signal->theData[0];
  1262.   // implies that operation was released on the other side
  1263.   const bool lastAttr = signal->theData[1];
  1264.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1265.   switch (addfragptr.p->addfragStatus) {
  1266.   case AddFragRecord::TUP_ATTR_WAIT1:
  1267.     jam();
  1268.     if (lastAttr)
  1269.       addfragptr.p->tup1Connectptr = RNIL;
  1270.     addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT2;
  1271.     sendAddAttrReq(signal);
  1272.     break;
  1273.   case AddFragRecord::TUP_ATTR_WAIT2:
  1274.     jam();
  1275.     if (lastAttr)
  1276.       addfragptr.p->tup2Connectptr = RNIL;
  1277.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType)) {
  1278.       addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT1;
  1279.       sendAddAttrReq(signal);
  1280.       break;
  1281.     }
  1282.     goto done_with_attr;
  1283.     break;
  1284.   case AddFragRecord::TUX_ATTR_WAIT1:
  1285.     jam();
  1286.     if (lastAttr)
  1287.       addfragptr.p->tux1Connectptr = RNIL;
  1288.     addfragptr.p->addfragStatus = AddFragRecord::TUX_ATTR_WAIT2;
  1289.     sendAddAttrReq(signal);
  1290.     break;
  1291.   case AddFragRecord::TUX_ATTR_WAIT2:
  1292.     jam();
  1293.     if (lastAttr)
  1294.       addfragptr.p->tux2Connectptr = RNIL;
  1295.     goto done_with_attr;
  1296.     break;
  1297.   done_with_attr:
  1298.     addfragptr.p->attrSentToTup = addfragptr.p->attrSentToTup + 1;
  1299.     ndbrequire(addfragptr.p->attrSentToTup <= addfragptr.p->attrReceived);
  1300.     ndbrequire(addfragptr.p->totalAttrReceived <= addfragptr.p->noOfAttr);
  1301.     if (addfragptr.p->attrSentToTup < addfragptr.p->attrReceived) {
  1302.       // more in this batch
  1303.       jam();
  1304.       addfragptr.p->addfragStatus = AddFragRecord::TUP_ATTR_WAIT1;
  1305.       sendAddAttrReq(signal);
  1306.     } else if (addfragptr.p->totalAttrReceived < addfragptr.p->noOfAttr) {
  1307.       // more batches to receive
  1308.       jam();
  1309.       addfragptr.p->addfragStatus = AddFragRecord::WAIT_ADD_ATTR;
  1310.       LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
  1311.       conf->senderData = addfragptr.p->dictConnectptr;
  1312.       conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
  1313.       conf->fragId = addfragptr.p->addFragid;
  1314.       sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF,
  1315.           signal, LqhAddAttrConf::SignalLength, JBB);
  1316.     } else {
  1317.       fragptr.i = addfragptr.p->fragmentPtr;
  1318.       ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1319.       /* ------------------------------------------------------------------ 
  1320.        * WE HAVE NOW COMPLETED ADDING THIS FRAGMENT. WE NOW NEED TO SET THE 
  1321.        * PROPER STATE IN FRAG_STATUS DEPENDENT ON IF WE ARE CREATING A NEW 
  1322.        * REPLICA OR IF WE ARE CREATING A TABLE. FOR FRAGMENTS IN COPY
  1323.        * PROCESS WE DO NOT WANT LOGGING ACTIVATED.      
  1324.        * ----------------------------------------------------------------- */
  1325.       if (addfragptr.p->fragCopyCreation == 1) {
  1326.         jam();
  1327.         if (! DictTabInfo::isOrderedIndex(addfragptr.p->tableType))
  1328.           fragptr.p->fragStatus = Fragrecord::ACTIVE_CREATION;
  1329.         else
  1330.           fragptr.p->fragStatus = Fragrecord::FSACTIVE;
  1331.         fragptr.p->logFlag = Fragrecord::STATE_FALSE;
  1332.       } else {
  1333.         jam();
  1334.         fragptr.p->fragStatus = Fragrecord::FSACTIVE;
  1335.       }//if
  1336.       LqhAddAttrConf *const conf = (LqhAddAttrConf*)signal->getDataPtrSend();
  1337.       conf->senderData = addfragptr.p->dictConnectptr;
  1338.       conf->senderAttrPtr = addfragptr.p->m_senderAttrPtr;
  1339.       conf->fragId = addfragptr.p->addFragid;
  1340.       sendSignal(addfragptr.p->dictBlockref, GSN_LQHADDATTCONF, signal, 
  1341.                  LqhAddAttrConf::SignalLength, JBB);
  1342.       releaseAddfragrec(signal);
  1343.     }//if
  1344.     break;
  1345.   default:
  1346.     ndbrequire(false);
  1347.     break;
  1348.   }
  1349. }
  1350. /* **********************>> */
  1351. /*  TUX_ADD_ATTRCONF      > */
  1352. /* **********************>> */
  1353. void Dblqh::execTUX_ADD_ATTRCONF(Signal* signal) 
  1354. {
  1355.   jamEntry();
  1356.   execTUP_ADD_ATTCONF(signal);
  1357. }//Dblqh::execTUX_ADD_ATTRCONF
  1358. /*
  1359.  * Add attribute in TUP or TUX.  Called up to 4 times.
  1360.  */
  1361. void
  1362. Dblqh::sendAddAttrReq(Signal* signal)
  1363. {
  1364.   arrGuard(addfragptr.p->attrSentToTup, LqhAddAttrReq::MAX_ATTRIBUTES);
  1365.   LqhAddAttrReq::Entry& entry =
  1366.     addfragptr.p->attributes[addfragptr.p->attrSentToTup];
  1367.   const Uint32 attrId = entry.attrId & 0xffff;
  1368.   const Uint32 primaryAttrId = entry.attrId >> 16;
  1369.   fragptr.i = addfragptr.p->fragmentPtr;
  1370.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1371.   if (addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT1 ||
  1372.       addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT2) {
  1373.     if (DictTabInfo::isTable(addfragptr.p->tableType) ||
  1374.         DictTabInfo::isHashIndex(addfragptr.p->tableType) ||
  1375.         (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
  1376.          primaryAttrId == ZNIL)) {
  1377.       jam();
  1378.       TupAddAttrReq* const tupreq = (TupAddAttrReq*)signal->getDataPtrSend();
  1379.       tupreq->tupConnectPtr =
  1380.         addfragptr.p->addfragStatus == AddFragRecord::TUP_ATTR_WAIT1
  1381.         ? addfragptr.p->tup1Connectptr : addfragptr.p->tup2Connectptr;
  1382.       tupreq->notused1 = 0;
  1383.       tupreq->attrId = attrId;
  1384.       tupreq->attrDescriptor = entry.attrDescriptor;
  1385.       tupreq->extTypeInfo = entry.extTypeInfo;
  1386.       sendSignal(fragptr.p->tupBlockref, GSN_TUP_ADD_ATTRREQ,
  1387.           signal, TupAddAttrReq::SignalLength, JBB);
  1388.       return;
  1389.     }
  1390.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
  1391.         primaryAttrId != ZNIL) {
  1392.       // this attribute is not for TUP
  1393.       jam();
  1394.       TupAddAttrConf* tupconf = (TupAddAttrConf*)signal->getDataPtrSend();
  1395.       tupconf->userPtr = addfragptr.i;
  1396.       tupconf->lastAttr = false;
  1397.       sendSignal(reference(), GSN_TUP_ADD_ATTCONF,
  1398.           signal, TupAddAttrConf::SignalLength, JBB);
  1399.       return;
  1400.     }
  1401.   }
  1402.   if (addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT1 ||
  1403.       addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT2) {
  1404.     jam();
  1405.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
  1406.         primaryAttrId != ZNIL) {
  1407.       jam();
  1408.       TuxAddAttrReq* const tuxreq = (TuxAddAttrReq*)signal->getDataPtrSend();
  1409.       tuxreq->tuxConnectPtr =
  1410.         addfragptr.p->addfragStatus == AddFragRecord::TUX_ATTR_WAIT1
  1411.         ? addfragptr.p->tux1Connectptr : addfragptr.p->tux2Connectptr;
  1412.       tuxreq->notused1 = 0;
  1413.       tuxreq->attrId = attrId;
  1414.       tuxreq->attrDescriptor = entry.attrDescriptor;
  1415.       tuxreq->extTypeInfo = entry.extTypeInfo;
  1416.       tuxreq->primaryAttrId = primaryAttrId;
  1417.       sendSignal(fragptr.p->tuxBlockref, GSN_TUX_ADD_ATTRREQ,
  1418.           signal, TuxAddAttrReq::SignalLength, JBB);
  1419.       return;
  1420.     }
  1421.     if (DictTabInfo::isOrderedIndex(addfragptr.p->tableType) &&
  1422.         primaryAttrId == ZNIL) {
  1423.       // this attribute is not for TUX
  1424.       jam();
  1425.       TuxAddAttrConf* tuxconf = (TuxAddAttrConf*)signal->getDataPtrSend();
  1426.       tuxconf->userPtr = addfragptr.i;
  1427.       tuxconf->lastAttr = false;
  1428.       sendSignal(reference(), GSN_TUX_ADD_ATTRCONF,
  1429.           signal, TuxAddAttrConf::SignalLength, JBB);
  1430.       return;
  1431.     }
  1432.   }
  1433.   ndbrequire(false);
  1434. }//Dblqh::sendAddAttrReq
  1435. /* ************************************************************************>> */
  1436. /*  TAB_COMMITREQ: Commit the new table for use in transactions. Sender DICT. */
  1437. /* ************************************************************************>> */
  1438. void Dblqh::execTAB_COMMITREQ(Signal* signal) 
  1439. {
  1440.   jamEntry();
  1441.   Uint32 dihPtr = signal->theData[0];
  1442.   BlockReference dihBlockref = signal->theData[1];
  1443.   tabptr.i = signal->theData[2];
  1444.   if (tabptr.i >= ctabrecFileSize) {
  1445.     jam();
  1446.     terrorCode = ZTAB_FILE_SIZE;
  1447.     signal->theData[0] = dihPtr;
  1448.     signal->theData[1] = cownNodeid;
  1449.     signal->theData[2] = tabptr.i;
  1450.     signal->theData[3] = terrorCode;
  1451.     sendSignal(dihBlockref, GSN_TAB_COMMITREF, signal, 4, JBB);
  1452.     return;
  1453.   }//if
  1454.   ptrAss(tabptr, tablerec);
  1455.   if (tabptr.p->tableStatus != Tablerec::ADD_TABLE_ONGOING) {
  1456.     jam();
  1457.     terrorCode = ZTAB_STATE_ERROR;
  1458.     signal->theData[0] = dihPtr;
  1459.     signal->theData[1] = cownNodeid;
  1460.     signal->theData[2] = tabptr.i;
  1461.     signal->theData[3] = terrorCode;
  1462.     signal->theData[4] = tabptr.p->tableStatus;
  1463.     sendSignal(dihBlockref, GSN_TAB_COMMITREF, signal, 5, JBB);
  1464.     ndbrequire(false);
  1465.     return;
  1466.   }//if
  1467.   tabptr.p->usageCount = 0;
  1468.   tabptr.p->tableStatus = Tablerec::TABLE_DEFINED;
  1469.   signal->theData[0] = dihPtr;
  1470.   signal->theData[1] = cownNodeid;
  1471.   signal->theData[2] = tabptr.i;
  1472.   sendSignal(dihBlockref, GSN_TAB_COMMITCONF, signal, 3, JBB);
  1473.   return;
  1474. }//Dblqh::execTAB_COMMITREQ()
  1475. void Dblqh::fragrefLab(Signal* signal,
  1476.                        BlockReference fragBlockRef,
  1477.                        Uint32 fragConPtr,
  1478.                        Uint32 errorCode) 
  1479. {
  1480.   LqhFragRef * ref = (LqhFragRef*)signal->getDataPtrSend();
  1481.   ref->senderData = fragConPtr;
  1482.   ref->errorCode = errorCode;
  1483.   sendSignal(fragBlockRef, GSN_LQHFRAGREF, signal, 
  1484.      LqhFragRef::SignalLength, JBB);
  1485.   return;
  1486. }//Dblqh::fragrefLab()
  1487. /*
  1488.  * Abort on-going ops.
  1489.  */
  1490. void Dblqh::abortAddFragOps(Signal* signal)
  1491. {
  1492.   fragptr.i = addfragptr.p->fragmentPtr;
  1493.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1494.   signal->theData[0] = (Uint32)-1;
  1495.   if (addfragptr.p->tup1Connectptr != RNIL) {
  1496.     jam();
  1497.     signal->theData[1] = addfragptr.p->tup1Connectptr;
  1498.     sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
  1499.     addfragptr.p->tup1Connectptr = RNIL;
  1500.   }
  1501.   if (addfragptr.p->tup2Connectptr != RNIL) {
  1502.     jam();
  1503.     signal->theData[1] = addfragptr.p->tup2Connectptr;
  1504.     sendSignal(fragptr.p->tupBlockref, GSN_TUPFRAGREQ, signal, 2, JBB);
  1505.     addfragptr.p->tup2Connectptr = RNIL;
  1506.   }
  1507.   if (addfragptr.p->tux1Connectptr != RNIL) {
  1508.     jam();
  1509.     signal->theData[1] = addfragptr.p->tux1Connectptr;
  1510.     sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
  1511.     addfragptr.p->tux1Connectptr = RNIL;
  1512.   }
  1513.   if (addfragptr.p->tux2Connectptr != RNIL) {
  1514.     jam();
  1515.     signal->theData[1] = addfragptr.p->tux2Connectptr;
  1516.     sendSignal(fragptr.p->tuxBlockref, GSN_TUXFRAGREQ, signal, 2, JBB);
  1517.     addfragptr.p->tux2Connectptr = RNIL;
  1518.   }
  1519. }
  1520. /* ************>> */
  1521. /*  ACCFRAGREF  > */
  1522. /* ************>> */
  1523. void Dblqh::execACCFRAGREF(Signal* signal) 
  1524. {
  1525.   jamEntry();
  1526.   addfragptr.i = signal->theData[0];
  1527.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1528.   terrorCode = signal->theData[1];
  1529.   ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
  1530.   addfragptr.p->addfragErrorCode = terrorCode;
  1531.   const Uint32 ref = addfragptr.p->dictBlockref;
  1532.   const Uint32 senderData = addfragptr.p->dictConnectptr;
  1533.   const Uint32 errorCode = addfragptr.p->addfragErrorCode;
  1534.   releaseAddfragrec(signal);
  1535.   fragrefLab(signal, ref, senderData, errorCode);
  1536.   return;
  1537. }//Dblqh::execACCFRAGREF()
  1538. /* ************>> */
  1539. /*  TUPFRAGREF  > */
  1540. /* ************>> */
  1541. void Dblqh::execTUPFRAGREF(Signal* signal) 
  1542. {
  1543.   jamEntry();
  1544.   addfragptr.i = signal->theData[0];
  1545.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1546.   terrorCode = signal->theData[1];
  1547.   fragptr.i = addfragptr.p->fragmentPtr;
  1548.   ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
  1549.   addfragptr.p->addfragErrorCode = terrorCode;
  1550.   // no operation to release, just add some jams
  1551.   switch (addfragptr.p->addfragStatus) {
  1552.   case AddFragRecord::WAIT_TWO_TUP:
  1553.     jam();
  1554.     break;
  1555.   case AddFragRecord::WAIT_ONE_TUP:
  1556.     jam();
  1557.     break;
  1558.   case AddFragRecord::WAIT_TWO_TUX:
  1559.     jam();
  1560.     break;
  1561.   case AddFragRecord::WAIT_ONE_TUX:
  1562.     jam();
  1563.     break;
  1564.   default:
  1565.     ndbrequire(false);
  1566.     break;
  1567.   }
  1568.   abortAddFragOps(signal);
  1569.   const Uint32 ref = addfragptr.p->dictBlockref;
  1570.   const Uint32 senderData = addfragptr.p->dictConnectptr;
  1571.   const Uint32 errorCode = addfragptr.p->addfragErrorCode;
  1572.   releaseAddfragrec(signal);
  1573.   fragrefLab(signal, ref, senderData, errorCode);
  1574. }//Dblqh::execTUPFRAGREF()
  1575. /* ************>> */
  1576. /*  TUXFRAGREF  > */
  1577. /* ************>> */
  1578. void Dblqh::execTUXFRAGREF(Signal* signal) 
  1579. {
  1580.   jamEntry();
  1581.   execTUPFRAGREF(signal);
  1582. }//Dblqh::execTUXFRAGREF
  1583. /* *********************> */
  1584. /*  TUP_ADD_ATTREF      > */
  1585. /* *********************> */
  1586. void Dblqh::execTUP_ADD_ATTRREF(Signal* signal) 
  1587. {
  1588.   jamEntry();
  1589.   addfragptr.i = signal->theData[0];
  1590.   ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
  1591.   terrorCode = signal->theData[1];
  1592.   addfragptr.p->addfragErrorCode = terrorCode;
  1593.   // operation was released on the other side
  1594.   switch (addfragptr.p->addfragStatus) {
  1595.   case AddFragRecord::TUP_ATTR_WAIT1:
  1596.     jam();
  1597.     ndbrequire(addfragptr.p->tup1Connectptr != RNIL);
  1598.     addfragptr.p->tup1Connectptr = RNIL;
  1599.     break;
  1600.   case AddFragRecord::TUP_ATTR_WAIT2:
  1601.     jam();
  1602.     ndbrequire(addfragptr.p->tup2Connectptr != RNIL);
  1603.     addfragptr.p->tup2Connectptr = RNIL;
  1604.     break;
  1605.   case AddFragRecord::TUX_ATTR_WAIT1:
  1606.     jam();
  1607.     ndbrequire(addfragptr.p->tux1Connectptr != RNIL);
  1608.     addfragptr.p->tux1Connectptr = RNIL;
  1609.     break;
  1610.   case AddFragRecord::TUX_ATTR_WAIT2:
  1611.     jam();
  1612.     ndbrequire(addfragptr.p->tux2Connectptr != RNIL);
  1613.     addfragptr.p->tux2Connectptr = RNIL;
  1614.     break;
  1615.   default:
  1616.     ndbrequire(false);
  1617.     break;
  1618.   }
  1619.   abortAddFragOps(signal);
  1620.   
  1621.   const Uint32 Ref = addfragptr.p->dictBlockref;
  1622.   const Uint32 senderData = addfragptr.p->dictConnectptr;
  1623.   const Uint32 errorCode = addfragptr.p->addfragErrorCode;
  1624.   releaseAddfragrec(signal);
  1625.   
  1626.   LqhAddAttrRef *const ref = (LqhAddAttrRef*)signal->getDataPtrSend();
  1627.   ref->senderData = senderData;
  1628.   ref->errorCode = errorCode;
  1629.   sendSignal(Ref, GSN_LQHADDATTREF, signal, 
  1630.      LqhAddAttrRef::SignalLength, JBB);
  1631.   
  1632. }//Dblqh::execTUP_ADD_ATTRREF()
  1633. /* **********************> */
  1634. /*  TUX_ADD_ATTRREF      > */
  1635. /* **********************> */
  1636. void Dblqh::execTUX_ADD_ATTRREF(Signal* signal) 
  1637. {
  1638.   jamEntry();
  1639.   execTUP_ADD_ATTRREF(signal);
  1640. }//Dblqh::execTUX_ADD_ATTRREF
  1641. void
  1642. Dblqh::execPREP_DROP_TAB_REQ(Signal* signal){
  1643.   jamEntry();
  1644.   PrepDropTabReq* req = (PrepDropTabReq*)signal->getDataPtr();
  1645.   
  1646.   Uint32 senderRef = req->senderRef;
  1647.   Uint32 senderData = req->senderData;
  1648.   
  1649.   TablerecPtr tabPtr;
  1650.   tabPtr.i = req->tableId;
  1651.   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
  1652.   
  1653.   Uint32 errCode = 0;
  1654.   errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_PREP_DROP_TAB_REQ);
  1655.   if(errCode != 0){
  1656.     jam();
  1657.     PrepDropTabRef* ref = (PrepDropTabRef*)signal->getDataPtrSend();
  1658.     ref->senderRef = reference();
  1659.     ref->senderData = senderData;
  1660.     ref->tableId = tabPtr.i;
  1661.     ref->errorCode = errCode;
  1662.     sendSignal(senderRef, GSN_PREP_DROP_TAB_REF, signal,
  1663.        PrepDropTabRef::SignalLength, JBB);
  1664.     return;
  1665.   }
  1666.   
  1667.   tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_ONGOING;
  1668.   tabPtr.p->waitingTC.clear();
  1669.   tabPtr.p->waitingDIH.clear();
  1670.   
  1671.   PrepDropTabConf * conf = (PrepDropTabConf*)signal->getDataPtrSend();
  1672.   conf->tableId = tabPtr.i;
  1673.   conf->senderRef = reference();
  1674.   conf->senderData = senderData;
  1675.   sendSignal(senderRef, GSN_PREP_DROP_TAB_CONF, signal,
  1676.      PrepDropTabConf::SignalLength, JBB);
  1677.   
  1678.   signal->theData[0] = ZPREP_DROP_TABLE;
  1679.   signal->theData[1] = tabPtr.i;
  1680.   signal->theData[2] = senderRef;
  1681.   signal->theData[3] = senderData;
  1682.   checkDropTab(signal);
  1683. }
  1684. void
  1685. Dblqh::checkDropTab(Signal* signal){
  1686.   TablerecPtr tabPtr;
  1687.   tabPtr.i = signal->theData[1];
  1688.   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
  1689.   
  1690.   ndbrequire(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING);
  1691.   
  1692.   if(tabPtr.p->usageCount > 0){
  1693.     jam();
  1694.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
  1695.     return;
  1696.   }
  1697.   bool lcpDone = true;
  1698.   lcpPtr.i = 0;
  1699.   ptrAss(lcpPtr, lcpRecord);
  1700.   if(lcpPtr.p->lcpState != LcpRecord::LCP_IDLE){
  1701.     jam();
  1702.     if(lcpPtr.p->currentFragment.lcpFragOrd.tableId == tabPtr.i){
  1703.       jam();
  1704.       lcpDone = false;
  1705.     }
  1706.     
  1707.     if(lcpPtr.p->lcpQueued && 
  1708.        lcpPtr.p->queuedFragment.lcpFragOrd.tableId == tabPtr.i){
  1709.       jam();
  1710.       lcpDone = false;
  1711.     }
  1712.   }
  1713.   
  1714.   if(!lcpDone){
  1715.     jam();
  1716.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 100, 4);
  1717.     return;
  1718.   }
  1719.   
  1720.   tabPtr.p->tableStatus = Tablerec::PREP_DROP_TABLE_DONE;
  1721.   WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtrSend();
  1722.   conf->tableId = tabPtr.i;
  1723.   conf->senderRef = reference();
  1724.   for(Uint32 i = 1; i<MAX_NDB_NODES; i++){
  1725.     if(tabPtr.p->waitingTC.get(i)){
  1726.       tabPtr.p->waitingTC.clear(i);
  1727.       sendSignal(calcTcBlockRef(i), GSN_WAIT_DROP_TAB_CONF, signal,
  1728.  WaitDropTabConf::SignalLength, JBB);
  1729.     }
  1730.     if(tabPtr.p->waitingDIH.get(i)){
  1731.       tabPtr.p->waitingDIH.clear(i);
  1732.       sendSignal(calcDihBlockRef(i), GSN_WAIT_DROP_TAB_CONF, signal,
  1733.  WaitDropTabConf::SignalLength, JBB);
  1734.     }
  1735.   }
  1736. }
  1737. void
  1738. Dblqh::execWAIT_DROP_TAB_REQ(Signal* signal){
  1739.   jamEntry();
  1740.   WaitDropTabReq * req = (WaitDropTabReq*)signal->getDataPtr();
  1741.   
  1742.   TablerecPtr tabPtr;
  1743.   tabPtr.i = req->tableId;
  1744.   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
  1745.   
  1746.   Uint32 senderRef = req->senderRef;
  1747.   Uint32 nodeId = refToNode(senderRef);
  1748.   Uint32 blockNo = refToBlock(senderRef);
  1749.   if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING){
  1750.     jam();
  1751.     switch(blockNo){
  1752.     case DBTC:
  1753.       tabPtr.p->waitingTC.set(nodeId);
  1754.       break;
  1755.     case DBDIH:
  1756.       tabPtr.p->waitingDIH.set(nodeId);
  1757.       break;
  1758.     default:
  1759.       ndbrequire(false);
  1760.     }
  1761.     return;
  1762.   }
  1763.   if(tabPtr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
  1764.     jam();
  1765.     WaitDropTabConf * conf = (WaitDropTabConf*)signal->getDataPtrSend();
  1766.     conf->tableId = tabPtr.i;
  1767.     conf->senderRef = reference();
  1768.     sendSignal(senderRef, GSN_WAIT_DROP_TAB_CONF, signal,
  1769.        WaitDropTabConf::SignalLength, JBB);
  1770.     return;
  1771.   }
  1772.   WaitDropTabRef * ref = (WaitDropTabRef*)signal->getDataPtrSend();
  1773.   ref->tableId = tabPtr.i;
  1774.   ref->senderRef = reference();
  1775.   bool ok = false;
  1776.   switch(tabPtr.p->tableStatus){
  1777.   case Tablerec::TABLE_DEFINED:
  1778.     ok = true;
  1779.     ref->errorCode = WaitDropTabRef::IllegalTableState;
  1780.     break;
  1781.   case Tablerec::NOT_DEFINED:
  1782.     ok = true;
  1783.     ref->errorCode = WaitDropTabRef::NoSuchTable;
  1784.     break;
  1785.   case Tablerec::ADD_TABLE_ONGOING:
  1786.     ok = true;
  1787.     ref->errorCode = WaitDropTabRef::IllegalTableState;
  1788.     break;
  1789.   case Tablerec::PREP_DROP_TABLE_ONGOING:
  1790.   case Tablerec::PREP_DROP_TABLE_DONE:
  1791.     // Should have been take care of above
  1792.     ndbrequire(false);
  1793.   }
  1794.   ndbrequire(ok);
  1795.   ref->tableStatus = tabPtr.p->tableStatus;
  1796.   sendSignal(senderRef, GSN_WAIT_DROP_TAB_REF, signal,
  1797.      WaitDropTabRef::SignalLength, JBB);
  1798.   return;
  1799. }
  1800. void
  1801. Dblqh::execDROP_TAB_REQ(Signal* signal){
  1802.   jamEntry();
  1803.   DropTabReq* req = (DropTabReq*)signal->getDataPtr();
  1804.   
  1805.   Uint32 senderRef = req->senderRef;
  1806.   Uint32 senderData = req->senderData;
  1807.   
  1808.   TablerecPtr tabPtr;
  1809.   tabPtr.i = req->tableId;
  1810.   ptrCheckGuard(tabPtr, ctabrecFileSize, tablerec);
  1811.   
  1812.   do {
  1813.     if(req->requestType == DropTabReq::RestartDropTab){
  1814.       jam();
  1815.       break;
  1816.     }
  1817.     
  1818.     if(req->requestType == DropTabReq::OnlineDropTab){
  1819.       jam();
  1820.       Uint32 errCode = 0;
  1821.       errCode = checkDropTabState(tabPtr.p->tableStatus, GSN_DROP_TAB_REQ);
  1822.       if(errCode != 0){
  1823. jam();
  1824. DropTabRef* ref = (DropTabRef*)signal->getDataPtrSend();
  1825. ref->senderRef = reference();
  1826. ref->senderData = senderData;
  1827. ref->tableId = tabPtr.i;
  1828. ref->errorCode = errCode;
  1829. sendSignal(senderRef, GSN_DROP_TAB_REF, signal,
  1830.    DropTabRef::SignalLength, JBB);
  1831. return;
  1832.       }
  1833.     }
  1834.     removeTable(tabPtr.i);
  1835.     
  1836.   } while(false);
  1837.   
  1838.   ndbrequire(tabPtr.p->usageCount == 0);
  1839.   tabPtr.p->tableStatus = Tablerec::NOT_DEFINED;
  1840.   
  1841.   DropTabConf * const dropConf = (DropTabConf *)signal->getDataPtrSend();
  1842.   dropConf->senderRef = reference();
  1843.   dropConf->senderData = senderData;
  1844.   dropConf->tableId = tabPtr.i;
  1845.   sendSignal(senderRef, GSN_DROP_TAB_CONF,
  1846.              signal, DropTabConf::SignalLength, JBB);
  1847. }
  1848. Uint32
  1849. Dblqh::checkDropTabState(Tablerec::TableStatus status, Uint32 gsn) const{
  1850.   
  1851.   if(gsn == GSN_PREP_DROP_TAB_REQ){
  1852.     switch(status){
  1853.     case Tablerec::NOT_DEFINED:
  1854.       jam();
  1855.       // Fall through
  1856.     case Tablerec::ADD_TABLE_ONGOING:
  1857.       jam();
  1858.       return PrepDropTabRef::NoSuchTable;
  1859.       break;
  1860.     case Tablerec::PREP_DROP_TABLE_ONGOING:
  1861.       jam();
  1862.       return PrepDropTabRef::PrepDropInProgress;
  1863.       break;
  1864.     case Tablerec::PREP_DROP_TABLE_DONE:
  1865.       jam();
  1866.       return PrepDropTabRef::DropInProgress;
  1867.       break;
  1868.     case Tablerec::TABLE_DEFINED:
  1869.       jam();
  1870.       return 0;
  1871.       break;
  1872.     }
  1873.     ndbrequire(0);
  1874.   }
  1875.   if(gsn == GSN_DROP_TAB_REQ){
  1876.     switch(status){
  1877.     case Tablerec::NOT_DEFINED:
  1878.       jam();
  1879.       // Fall through
  1880.     case Tablerec::ADD_TABLE_ONGOING:
  1881.       jam();
  1882.       return DropTabRef::NoSuchTable;
  1883.       break;
  1884.     case Tablerec::PREP_DROP_TABLE_ONGOING:
  1885.       jam();
  1886.       return DropTabRef::PrepDropInProgress;
  1887.       break;
  1888.     case Tablerec::PREP_DROP_TABLE_DONE:
  1889.       jam();
  1890.       return 0;
  1891.       break;
  1892.     case Tablerec::TABLE_DEFINED:
  1893.       jam();
  1894.       return DropTabRef::DropWoPrep;
  1895.     }
  1896.     ndbrequire(0);
  1897.   }
  1898.   ndbrequire(0);
  1899.   return RNIL;
  1900. }
  1901. void Dblqh::removeTable(Uint32 tableId)
  1902. {
  1903.   tabptr.i = tableId;
  1904.   ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
  1905.   
  1906.   for (Uint32 i = (MAX_FRAG_PER_NODE - 1); (Uint32)~i; i--) {
  1907.     jam();
  1908.     if (tabptr.p->fragid[i] != ZNIL) {
  1909.       jam();
  1910.       deleteFragrec(tabptr.p->fragid[i]);
  1911.     }//if
  1912.   }//for
  1913. }//Dblqh::removeTable()
  1914. void
  1915. Dblqh::execALTER_TAB_REQ(Signal* signal)
  1916. {
  1917.   jamEntry();
  1918.   AlterTabReq* const req = (AlterTabReq*)signal->getDataPtr();
  1919.   const Uint32 senderRef = req->senderRef;
  1920.   const Uint32 senderData = req->senderData;
  1921.   const Uint32 changeMask = req->changeMask;
  1922.   const Uint32 tableId = req->tableId;
  1923.   const Uint32 tableVersion = req->tableVersion;
  1924.   const Uint32 gci = req->gci;
  1925.   AlterTabReq::RequestType requestType =
  1926.     (AlterTabReq::RequestType) req->requestType;
  1927.   TablerecPtr tablePtr;
  1928.   tablePtr.i = tableId;
  1929.   ptrCheckGuard(tablePtr, ctabrecFileSize, tablerec);
  1930.   tablePtr.p->schemaVersion = tableVersion;
  1931.   // Request handled successfully
  1932.   AlterTabConf * conf = (AlterTabConf*)signal->getDataPtrSend();
  1933.   conf->senderRef = reference();
  1934.   conf->senderData = senderData;
  1935.   conf->changeMask = changeMask;
  1936.   conf->tableId = tableId;
  1937.   conf->tableVersion = tableVersion;
  1938.   conf->gci = gci;
  1939.   conf->requestType = requestType;
  1940.   sendSignal(senderRef, GSN_ALTER_TAB_CONF, signal,
  1941.      AlterTabConf::SignalLength, JBB);
  1942. }
  1943. /* ************************************************************************>> 
  1944.  * TIME_SIGNAL: Handles time-out of local operations. This is a clean-up 
  1945.  * handler. If no other measure has succeeded in cleaning up after time-outs 
  1946.  * or else then this routine will remove the transaction after 120 seconds of 
  1947.  * inactivity. The check is performed once per 10 second. Sender is QMGR.
  1948.  * ************************************************************************>> */
  1949. void Dblqh::execTIME_SIGNAL(Signal* signal)
  1950. {
  1951.   jamEntry();
  1952.   cLqhTimeOutCount++;
  1953.   cLqhTimeOutCheckCount++;
  1954.   if ((cCounterAccCommitBlocked > 0) ||
  1955.      (cCounterTupCommitBlocked > 0)) {
  1956.     jam();
  1957.     signal->theData[0] = EventReport::UndoLogBlocked;
  1958.     signal->theData[1] = cCounterTupCommitBlocked;
  1959.     signal->theData[2] = cCounterAccCommitBlocked;
  1960.     sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  1961.     cCounterTupCommitBlocked = 0;
  1962.     cCounterAccCommitBlocked = 0;
  1963.   }//if
  1964.   if (cLqhTimeOutCheckCount < 10) {
  1965.     jam();
  1966.     return;
  1967.   }//if
  1968.   cLqhTimeOutCheckCount = 0;
  1969. #ifdef VM_TRACE
  1970.   TcConnectionrecPtr tTcConptr;
  1971.   
  1972.   for (tTcConptr.i = 0; tTcConptr.i < ctcConnectrecFileSize;
  1973.        tTcConptr.i++) {
  1974.     jam();
  1975.     ptrAss(tTcConptr, tcConnectionrec);
  1976.     if ((tTcConptr.p->tcTimer != 0) &&
  1977. ((tTcConptr.p->tcTimer + 120) < cLqhTimeOutCount)) {
  1978.       ndbout << "Dblqh::execTIME_SIGNAL"<<endl
  1979.      << "Timeout found in tcConnectRecord " <<tTcConptr.i<<endl
  1980.      << " cLqhTimeOutCount = " << cLqhTimeOutCount << endl
  1981.      << " tcTimer="<<tTcConptr.p->tcTimer<<endl
  1982.      << " tcTimer+120="<<tTcConptr.p->tcTimer + 120<<endl;
  1983.   
  1984.       ndbout << " transactionState = " << tTcConptr.p->transactionState<<endl;
  1985.       ndbout << " operation = " << tTcConptr.p->operation<<endl;
  1986.       ndbout << " tcNodeFailrec = " << tTcConptr.p->tcNodeFailrec
  1987.      << " seqNoReplica = " << tTcConptr.p->seqNoReplica
  1988.      << " simpleRead = " << tTcConptr.p->simpleRead
  1989.      << endl;
  1990.       ndbout << " replicaType = " << tTcConptr.p->replicaType
  1991.      << " reclenAiLqhkey = " << tTcConptr.p->reclenAiLqhkey
  1992.      << " opExec = " << tTcConptr.p->opExec
  1993.      << endl;
  1994.       ndbout << " opSimple = " << tTcConptr.p->opSimple
  1995.      << " nextSeqNoReplica = " << tTcConptr.p->nextSeqNoReplica
  1996.      << " lockType = " << tTcConptr.p->lockType
  1997.      << " localFragptr = " << tTcConptr.p->localFragptr
  1998.      << endl;
  1999.       ndbout << " lastReplicaNo = " << tTcConptr.p->lastReplicaNo
  2000.      << " indTakeOver = " << tTcConptr.p->indTakeOver
  2001.      << " dirtyOp = " << tTcConptr.p->dirtyOp
  2002.      << endl;
  2003.       ndbout << " activeCreat = " << tTcConptr.p->activeCreat
  2004.      << " tcBlockref = " << hex << tTcConptr.p->tcBlockref
  2005.      << " reqBlockref = " << hex << tTcConptr.p->reqBlockref
  2006.      << " primKeyLen = " << tTcConptr.p->primKeyLen
  2007.      << endl;
  2008.       ndbout << " nextReplica = " << tTcConptr.p->nextReplica
  2009.      << " tcBlockref = " << hex << tTcConptr.p->tcBlockref
  2010.      << " reqBlockref = " << hex << tTcConptr.p->reqBlockref
  2011.      << " primKeyLen = " << tTcConptr.p->primKeyLen
  2012.      << endl;
  2013.       ndbout << " logStopPageNo = " << tTcConptr.p->logStopPageNo
  2014.      << " logStartPageNo = " << tTcConptr.p->logStartPageNo
  2015.      << " logStartPageIndex = " << tTcConptr.p->logStartPageIndex
  2016.      << endl;
  2017.       ndbout << " errorCode = " << tTcConptr.p->errorCode
  2018.      << " clientBlockref = " << hex << tTcConptr.p->clientBlockref
  2019.      << " applRef = " << hex << tTcConptr.p->applRef
  2020.      << " totSendlenAi = " << tTcConptr.p->totSendlenAi
  2021.      << endl;
  2022.       ndbout << " totReclenAi = " << tTcConptr.p->totReclenAi
  2023.      << " tcScanRec = " << tTcConptr.p->tcScanRec
  2024.      << " tcScanInfo = " << tTcConptr.p->tcScanInfo
  2025.      << " tcOprec = " << hex << tTcConptr.p->tcOprec
  2026.      << endl;
  2027.       ndbout << " tableref = " << tTcConptr.p->tableref
  2028.      << " simpleTcConnect = " << tTcConptr.p->simpleTcConnect
  2029.      << " storedProcId = " << tTcConptr.p->storedProcId
  2030.      << " schemaVersion = " << tTcConptr.p->schemaVersion
  2031.      << endl;
  2032.       ndbout << " reqinfo = " << tTcConptr.p->reqinfo
  2033.      << " reqRef = " << tTcConptr.p->reqRef
  2034.      << " readlenAi = " << tTcConptr.p->readlenAi
  2035.      << " prevTc = " << tTcConptr.p->prevTc
  2036.      << endl;
  2037.       ndbout << " prevLogTcrec = " << tTcConptr.p->prevLogTcrec
  2038.      << " prevHashRec = " << tTcConptr.p->prevHashRec
  2039.      << " nodeAfterNext0 = " << tTcConptr.p->nodeAfterNext[0]
  2040.      << " nodeAfterNext1 = " << tTcConptr.p->nodeAfterNext[1]
  2041.      << endl;
  2042.       ndbout << " nextTcConnectrec = " << tTcConptr.p->nextTcConnectrec
  2043.      << " nextTc = " << tTcConptr.p->nextTc
  2044.      << " nextTcLogQueue = " << tTcConptr.p->nextTcLogQueue
  2045.      << " nextLogTcrec = " << tTcConptr.p->nextLogTcrec
  2046.      << endl;
  2047.       ndbout << " nextHashRec = " << tTcConptr.p->nextHashRec
  2048.      << " logWriteState = " << tTcConptr.p->logWriteState
  2049.      << " logStartFileNo = " << tTcConptr.p->logStartFileNo
  2050.      << " listState = " << tTcConptr.p->listState
  2051.      << endl;
  2052.       ndbout << " lastAttrinbuf = " << tTcConptr.p->lastAttrinbuf
  2053.      << " lastTupkeybuf = " << tTcConptr.p->lastTupkeybuf
  2054.      << " hashValue = " << tTcConptr.p->hashValue
  2055.      << endl;
  2056.       ndbout << " gci = " << tTcConptr.p->gci
  2057.      << " fragmentptr = " << tTcConptr.p->fragmentptr
  2058.      << " fragmentid = " << tTcConptr.p->fragmentid
  2059.      << " firstTupkeybuf = " << tTcConptr.p->firstTupkeybuf
  2060.      << endl;
  2061.       ndbout << " firstAttrinbuf = " << tTcConptr.p->firstAttrinbuf
  2062.      << " currTupAiLen = " << tTcConptr.p->currTupAiLen
  2063.      << " currReclenAi = " << tTcConptr.p->currReclenAi
  2064.      << endl;
  2065.       ndbout << " tcTimer = " << tTcConptr.p->tcTimer
  2066.      << " clientConnectrec = " << tTcConptr.p->clientConnectrec
  2067.      << " applOprec = " << hex << tTcConptr.p->applOprec
  2068.      << " abortState = " << tTcConptr.p->abortState
  2069.      << endl;
  2070.       ndbout << " transid0 = " << hex << tTcConptr.p->transid[0]
  2071.      << " transid1 = " << hex << tTcConptr.p->transid[1]
  2072.      << " tupkeyData0 = " << tTcConptr.p->tupkeyData[0]
  2073.      << " tupkeyData1 = " << tTcConptr.p->tupkeyData[1]
  2074.      << endl;
  2075.       ndbout << " tupkeyData2 = " << tTcConptr.p->tupkeyData[2]
  2076.      << " tupkeyData3 = " << tTcConptr.p->tupkeyData[3]
  2077.      << endl;
  2078.       switch (tTcConptr.p->transactionState) {
  2079.       case TcConnectionrec::SCAN_STATE_USED:
  2080. if (tTcConptr.p->tcScanRec < cscanrecFileSize){
  2081.   ScanRecordPtr TscanPtr;
  2082.   c_scanRecordPool.getPtr(TscanPtr, tTcConptr.p->tcScanRec);
  2083.   ndbout << " scanState = " << TscanPtr.p->scanState << endl;
  2084.   //TscanPtr.p->scanLocalref[2];
  2085.   ndbout << " copyPtr="<<TscanPtr.p->copyPtr
  2086.  << " scanAccPtr="<<TscanPtr.p->scanAccPtr
  2087.  << " scanAiLength="<<TscanPtr.p->scanAiLength
  2088.  << endl;
  2089.   ndbout << " m_curr_batch_size_rows="<<
  2090.     TscanPtr.p->m_curr_batch_size_rows
  2091.  << " m_max_batch_size_rows="<<
  2092.     TscanPtr.p->m_max_batch_size_rows
  2093.  << " scanErrorCounter="<<TscanPtr.p->scanErrorCounter
  2094.  << " scanLocalFragid="<<TscanPtr.p->scanLocalFragid
  2095.  << endl;
  2096.   ndbout << " scanSchemaVersion="<<TscanPtr.p->scanSchemaVersion
  2097.  << "  scanStoredProcId="<<TscanPtr.p->scanStoredProcId
  2098.  << "  scanTcrec="<<TscanPtr.p->scanTcrec
  2099.  << endl;
  2100.   ndbout << "  scanType="<<TscanPtr.p->scanType
  2101.  << "  scanApiBlockref="<<TscanPtr.p->scanApiBlockref
  2102.  << "  scanNodeId="<<TscanPtr.p->scanNodeId
  2103.  << "  scanCompletedStatus="<<TscanPtr.p->scanCompletedStatus
  2104.  << endl;
  2105.   ndbout << "  scanFlag="<<TscanPtr.p->scanFlag
  2106.  << "  scanLockHold="<<TscanPtr.p->scanLockHold
  2107.  << "  scanLockMode="<<TscanPtr.p->scanLockMode
  2108.  << "  scanNumber="<<TscanPtr.p->scanNumber
  2109.  << endl;
  2110.   ndbout << "  scanReleaseCounter="<<TscanPtr.p->scanReleaseCounter
  2111.  << "  scanTcWaiting="<<TscanPtr.p->scanTcWaiting
  2112.  << "  scanKeyinfoFlag="<<TscanPtr.p->scanKeyinfoFlag
  2113.  << endl;
  2114. }else{
  2115.   ndbout << "No connected scan record found" << endl;
  2116. }
  2117. break;
  2118.       default:
  2119.         break;
  2120.       }//switch
  2121.       // Reset the timer 
  2122.       tTcConptr.p->tcTimer = 0;
  2123.     }//if
  2124.   }//for
  2125. #endif
  2126. #ifdef VM_TRACE
  2127.   for (lfoPtr.i = 0; lfoPtr.i < clfoFileSize; lfoPtr.i++) {
  2128.     ptrAss(lfoPtr, logFileOperationRecord);
  2129.     if ((lfoPtr.p->lfoTimer != 0) &&
  2130.         ((lfoPtr.p->lfoTimer + 120) < cLqhTimeOutCount)) {
  2131.       ndbout << "We have lost LFO record" << endl;
  2132.       ndbout << "index = " << lfoPtr.i;
  2133.       ndbout << "State = " << lfoPtr.p->lfoState;
  2134.       ndbout << " Page No = " << lfoPtr.p->lfoPageNo;
  2135.       ndbout << " noPagesRw = " << lfoPtr.p->noPagesRw;
  2136.       ndbout << "lfoWordWritten = " << lfoPtr.p->lfoWordWritten << endl;
  2137.       lfoPtr.p->lfoTimer = cLqhTimeOutCount;
  2138.     }//if
  2139.   }//for
  2140. #endif
  2141. #if 0
  2142.   LcpRecordPtr TlcpPtr;
  2143.   // Print information about the current local checkpoint
  2144.   TlcpPtr.i = 0;
  2145.   ptrAss(TlcpPtr, lcpRecord);
  2146.   ndbout << "Information about LCP in this LQH" << endl
  2147.  << "  lcpState="<<TlcpPtr.p->lcpState<<endl
  2148.  << "   firstLcpLocAcc="<<TlcpPtr.p->firstLcpLocAcc<<endl
  2149.  << "   firstLcpLocTup="<<TlcpPtr.p->firstLcpLocTup<<endl
  2150.  << "   lcpAccptr="<<TlcpPtr.p->lcpAccptr<<endl
  2151.  << "   lastFragmentFlag="<<TlcpPtr.p->lastFragmentFlag<<endl
  2152.  << "   lcpQueued="<<TlcpPtr.p->lcpQueued<<endl
  2153.  << "   reportEmptyref="<< TlcpPtr.p->reportEmptyRef<<endl
  2154.  << "   reportEmpty="<<TlcpPtr.p->reportEmpty<<endl;
  2155. #endif
  2156. }//Dblqh::execTIME_SIGNAL()
  2157. /* ######################################################################### */
  2158. /* #######                  EXECUTION MODULE                         ####### */
  2159. /* THIS MODULE HANDLES THE RECEPTION OF LQHKEYREQ AND ALL PROCESSING         */
  2160. /* OF OPERATIONS ON BEHALF OF THIS REQUEST. THIS DOES ALSO INVOLVE           */
  2161. /* RECEPTION OF VARIOUS TYPES OF ATTRINFO AND KEYINFO. IT DOES ALSO          */
  2162. /* INVOLVE COMMUNICATION WITH ACC AND TUP.                                   */
  2163. /* ######################################################################### */
  2164. void Dblqh::noFreeRecordLab(Signal* signal, 
  2165.     const LqhKeyReq * lqhKeyReq,
  2166.     Uint32 errCode) 
  2167. {
  2168.   jamEntry();
  2169.   const Uint32 transid1  = lqhKeyReq->transId1;
  2170.   const Uint32 transid2  = lqhKeyReq->transId2;
  2171.   const Uint32 reqInfo   = lqhKeyReq->requestInfo;
  2172.   
  2173.   if(errCode == ZNO_FREE_MARKER_RECORDS_ERROR ||
  2174.      errCode == ZNODE_SHUTDOWN_IN_PROGESS){
  2175.     releaseTcrec(signal, tcConnectptr);
  2176.   }
  2177.   if (LqhKeyReq::getSimpleFlag(reqInfo) && 
  2178.       LqhKeyReq::getOperation(reqInfo) == ZREAD){ 
  2179.     jam();
  2180.     ndbrequire(LqhKeyReq::getApplicationAddressFlag(reqInfo));
  2181.     const Uint32 apiRef   = lqhKeyReq->variableData[0];
  2182.     const Uint32 apiOpRec = lqhKeyReq->variableData[1];
  2183.     TcKeyRef * const tcKeyRef = (TcKeyRef *) signal->getDataPtrSend();
  2184.     
  2185.     tcKeyRef->connectPtr = apiOpRec;
  2186.     tcKeyRef->transId[0] = transid1;
  2187.     tcKeyRef->transId[1] = transid2;
  2188.     tcKeyRef->errorCode = errCode;
  2189.     sendSignal(apiRef, GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
  2190.   } else {
  2191.     jam();
  2192.     const Uint32 clientPtr = lqhKeyReq->clientConnectPtr;
  2193.     Uint32 TcOprec = clientPtr;
  2194.     if(LqhKeyReq::getSameClientAndTcFlag(reqInfo) == 1){
  2195.       if(LqhKeyReq::getApplicationAddressFlag(reqInfo))
  2196. TcOprec = lqhKeyReq->variableData[2];
  2197.       else
  2198. TcOprec = lqhKeyReq->variableData[0];
  2199.     }
  2200.     LqhKeyRef * const ref = (LqhKeyRef*)signal->getDataPtrSend();
  2201.     ref->userRef = clientPtr;
  2202.     ref->connectPtr = TcOprec;
  2203.     ref->errorCode = errCode;
  2204.     ref->transId1 = transid1;
  2205.     ref->transId2 = transid2;
  2206.     sendSignal(signal->senderBlockRef(), GSN_LQHKEYREF, signal, 
  2207.        LqhKeyRef::SignalLength, JBB);
  2208.   }//if
  2209.   return;
  2210. }//Dblqh::noFreeRecordLab()
  2211. void Dblqh::LQHKEY_abort(Signal* signal, int errortype)
  2212. {
  2213.   switch (errortype) {
  2214.   case 0:
  2215.     jam();
  2216.     terrorCode = ZCOPY_NODE_ERROR;
  2217.     break;
  2218.   case 1:
  2219.     jam();
  2220.     terrorCode = ZNO_FREE_LQH_CONNECTION;
  2221.     break;
  2222.   case 2:
  2223.     jam();
  2224.     terrorCode = signal->theData[1];
  2225.     break;
  2226.   case 3:
  2227.     jam();
  2228.     ndbrequire((tcConnectptr.p->transactionState == TcConnectionrec::WAIT_ACC_ABORT) ||
  2229.                (tcConnectptr.p->transactionState == TcConnectionrec::ABORT_STOPPED)  ||
  2230.                (tcConnectptr.p->transactionState == TcConnectionrec::ABORT_QUEUED));
  2231.     return;
  2232.     break;
  2233.   case 4:
  2234.     jam();
  2235.     if(tabptr.p->tableStatus == Tablerec::NOT_DEFINED){
  2236.       jam();
  2237.       terrorCode = ZTABLE_NOT_DEFINED;
  2238.     } else if (tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_ONGOING ||
  2239.        tabptr.p->tableStatus == Tablerec::PREP_DROP_TABLE_DONE){
  2240.       jam();
  2241.       terrorCode = ZDROP_TABLE_IN_PROGRESS;
  2242.     } else {
  2243.       ndbrequire(0);
  2244.     }
  2245.     break;
  2246.   case 5:
  2247.     jam();
  2248.     terrorCode = ZINVALID_SCHEMA_VERSION;
  2249.     break;
  2250.   default:
  2251.     ndbrequire(false);
  2252.     break;
  2253.   }//switch
  2254.   abortErrorLab(signal);
  2255. }//Dblqh::LQHKEY_abort()
  2256. void Dblqh::LQHKEY_error(Signal* signal, int errortype)
  2257. {
  2258.   switch (errortype) {
  2259.   case 0:
  2260.     jam();
  2261.     break;
  2262.   case 1:
  2263.     jam();
  2264.     break;
  2265.   case 2:
  2266.     jam();
  2267.     break;
  2268.   case 3:
  2269.     jam();
  2270.     break;
  2271.   case 4:
  2272.     jam();
  2273.     break;
  2274.   case 5:
  2275.     jam();
  2276.     break;
  2277.   case 6:
  2278.     jam();
  2279.     break;
  2280.   default:
  2281.     jam();
  2282.     break;
  2283.   }//switch
  2284.   ndbrequire(false);
  2285. }//Dblqh::LQHKEY_error()
  2286. void Dblqh::execLQHKEYREF(Signal* signal) 
  2287. {
  2288.   jamEntry();
  2289.   tcConnectptr.i = signal->theData[0];
  2290.   terrorCode = signal->theData[2];
  2291.   Uint32 transid1 = signal->theData[3];
  2292.   Uint32 transid2 = signal->theData[4];
  2293.   if (tcConnectptr.i >= ctcConnectrecFileSize) {
  2294.     errorReport(signal, 3);
  2295.     return;
  2296.   }//if
  2297. /*------------------------------------------------------------------*/
  2298. /*       WE HAVE TO CHECK THAT THE SIGNAL DO NOT BELONG TO SOMETHING*/
  2299. /*       REMOVED DUE TO A TIME-OUT.                                 */
  2300. /*------------------------------------------------------------------*/
  2301.   ptrAss(tcConnectptr, tcConnectionrec);
  2302.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2303.   switch (regTcPtr->connectState) {
  2304.   case TcConnectionrec::CONNECTED:
  2305.     jam();
  2306.     if ((regTcPtr->transid[0] != transid1) ||
  2307.         (regTcPtr->transid[1] != transid2)) {
  2308.       warningReport(signal, 14);
  2309.       return;
  2310.     }//if
  2311.     if (regTcPtr->abortState != TcConnectionrec::ABORT_IDLE) {
  2312.       warningReport(signal, 15);
  2313.       return;
  2314.     }//if
  2315.     abortErrorLab(signal);
  2316.     return;
  2317.     break;
  2318.   case TcConnectionrec::LOG_CONNECTED:
  2319.     jam();
  2320.     logLqhkeyrefLab(signal);
  2321.     return;
  2322.     break;
  2323.   case TcConnectionrec::COPY_CONNECTED:
  2324.     jam();
  2325.     copyLqhKeyRefLab(signal);
  2326.     return;
  2327.     break;
  2328.   default:
  2329.     warningReport(signal, 16);
  2330.     return;
  2331.     break;
  2332.   }//switch
  2333. }//Dblqh::execLQHKEYREF()
  2334. /* -------------------------------------------------------------------------- */
  2335. /* -------                       ENTER PACKED_SIGNAL                  ------- */
  2336. /* Execution of packed signal. The packed signal can contain COMMIT, COMPLETE */
  2337. /* or LQHKEYCONF signals. These signals will be executed by their resp. exec  */
  2338. /* functions.                                                                 */
  2339. /* -------------------------------------------------------------------------- */
  2340. void Dblqh::execPACKED_SIGNAL(Signal* signal) 
  2341. {
  2342.   Uint32 Tstep = 0;
  2343.   Uint32 Tlength;
  2344.   Uint32 TpackedData[28];
  2345.   Uint32 sig0, sig1, sig2, sig3 ,sig4, sig5, sig6;
  2346.   jamEntry();
  2347.   Tlength = signal->length();
  2348.   ndbrequire(Tlength <= 25);
  2349.   MEMCOPY_NO_WORDS(&TpackedData[0], &signal->theData[0], Tlength);
  2350.   while (Tlength > Tstep) {
  2351.     switch (TpackedData[Tstep] >> 28) {
  2352.     case ZCOMMIT:
  2353.       jam();
  2354.       sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
  2355.       sig1 = TpackedData[Tstep + 1];
  2356.       sig2 = TpackedData[Tstep + 2];
  2357.       sig3 = TpackedData[Tstep + 3];
  2358.       signal->theData[0] = sig0;
  2359.       signal->theData[1] = sig1;
  2360.       signal->theData[2] = sig2;
  2361.       signal->theData[3] = sig3;
  2362.       signal->header.theLength = 4;
  2363.       execCOMMIT(signal);
  2364.       Tstep += 4;
  2365.       break;
  2366.     case ZCOMPLETE:
  2367.       jam();
  2368.       sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
  2369.       sig1 = TpackedData[Tstep + 1];
  2370.       sig2 = TpackedData[Tstep + 2];
  2371.       signal->theData[0] = sig0;
  2372.       signal->theData[1] = sig1;
  2373.       signal->theData[2] = sig2;
  2374.       signal->header.theLength = 3;
  2375.       execCOMPLETE(signal);
  2376.       Tstep += 3;
  2377.       break;
  2378.     case ZLQHKEYCONF: {
  2379.       jam();
  2380.       LqhKeyConf * const lqhKeyConf = (LqhKeyConf *)signal->getDataPtr();
  2381.       sig0 = TpackedData[Tstep + 0] & 0x0FFFFFFF;
  2382.       sig1 = TpackedData[Tstep + 1];
  2383.       sig2 = TpackedData[Tstep + 2];
  2384.       sig3 = TpackedData[Tstep + 3];
  2385.       sig4 = TpackedData[Tstep + 4];
  2386.       sig5 = TpackedData[Tstep + 5];
  2387.       sig6 = TpackedData[Tstep + 6];
  2388.       lqhKeyConf->connectPtr = sig0;
  2389.       lqhKeyConf->opPtr = sig1;
  2390.       lqhKeyConf->userRef = sig2;
  2391.       lqhKeyConf->readLen = sig3;
  2392.       lqhKeyConf->transId1 = sig4;
  2393.       lqhKeyConf->transId2 = sig5;
  2394.       lqhKeyConf->noFiredTriggers = sig6;
  2395.       execLQHKEYCONF(signal);
  2396.       Tstep += LqhKeyConf::SignalLength;
  2397.       break;
  2398.     }
  2399.     case ZREMOVE_MARKER:
  2400.       jam();
  2401.       sig0 = TpackedData[Tstep + 1];
  2402.       sig1 = TpackedData[Tstep + 2];
  2403.       signal->theData[0] = sig0;
  2404.       signal->theData[1] = sig1;
  2405.       signal->header.theLength = 2;
  2406.       execREMOVE_MARKER_ORD(signal);
  2407.       Tstep += 3;
  2408.       break;
  2409.     default:
  2410.       ndbrequire(false);
  2411.       return;
  2412.     }//switch
  2413.   }//while
  2414.   ndbrequire(Tlength == Tstep);
  2415.   return;
  2416. }//Dblqh::execPACKED_SIGNAL()
  2417. void
  2418. Dblqh::execREMOVE_MARKER_ORD(Signal* signal)
  2419. {  
  2420.   CommitAckMarker key;
  2421.   key.transid1 = signal->theData[0];
  2422.   key.transid2 = signal->theData[1];
  2423.   jamEntry();
  2424.   
  2425.   CommitAckMarkerPtr removedPtr;
  2426.   m_commitAckMarkerHash.release(removedPtr, key);
  2427.   ndbrequire(removedPtr.i != RNIL);
  2428. #ifdef MARKER_TRACE
  2429.   ndbout_c("Rem marker[%.8x %.8x]", key.transid1, key.transid2);
  2430. #endif
  2431. }
  2432. /* -------------------------------------------------------------------------- */
  2433. /* -------                 ENTER SEND_PACKED                          ------- */
  2434. /* Used to force a packed signal to be sent if local signal buffer is not     */
  2435. /* empty.                                                                     */
  2436. /* -------------------------------------------------------------------------- */
  2437. void Dblqh::execSEND_PACKED(Signal* signal) 
  2438. {
  2439.   HostRecordPtr Thostptr;
  2440.   UintR i;
  2441.   UintR TpackedListIndex = cpackedListIndex;
  2442.   jamEntry();
  2443.   for (i = 0; i < TpackedListIndex; i++) {
  2444.     Thostptr.i = cpackedList[i];
  2445.     ptrAss(Thostptr, hostRecord);
  2446.     jam();
  2447.     ndbrequire(Thostptr.i - 1 < MAX_NDB_NODES - 1);
  2448.     if (Thostptr.p->noOfPackedWordsLqh > 0) {
  2449.       jam();
  2450.       sendPackedSignalLqh(signal, Thostptr.p);
  2451.     }//if
  2452.     if (Thostptr.p->noOfPackedWordsTc > 0) {
  2453.       jam();
  2454.       sendPackedSignalTc(signal, Thostptr.p);
  2455.     }//if
  2456.     Thostptr.p->inPackedList = false;
  2457.   }//for
  2458.   cpackedListIndex = 0;
  2459.   return;
  2460. }//Dblqh::execSEND_PACKED()
  2461. void
  2462. Dblqh::updatePackedList(Signal* signal, HostRecord * ahostptr, Uint16 hostId)
  2463. {
  2464.   Uint32 TpackedListIndex = cpackedListIndex;
  2465.   if (ahostptr->inPackedList == false) {
  2466.     jam();
  2467.     ahostptr->inPackedList = true;
  2468.     cpackedList[TpackedListIndex] = hostId;
  2469.     cpackedListIndex = TpackedListIndex + 1;
  2470.   }//if
  2471. }//Dblqh::updatePackedList()
  2472. void
  2473. Dblqh::execREAD_PSUEDO_REQ(Signal* signal){
  2474.   jamEntry();
  2475.   TcConnectionrecPtr regTcPtr;
  2476.   regTcPtr.i = signal->theData[0];
  2477.   ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec);
  2478.   
  2479.   FragrecordPtr regFragptr;
  2480.   regFragptr.i = regTcPtr.p->fragmentptr;
  2481.   ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  2482.   signal->theData[0] = regFragptr.p->accFragptr[regTcPtr.p->localFragptr];
  2483.   EXECUTE_DIRECT(DBACC, GSN_READ_PSUEDO_REQ, signal, 2);
  2484. }
  2485. /* ************>> */
  2486. /*  TUPKEYCONF  > */
  2487. /* ************>> */
  2488. void Dblqh::execTUPKEYCONF(Signal* signal) 
  2489. {
  2490.   TcConnectionrec *regTcConnectionrec = tcConnectionrec;
  2491.   Uint32 ttcConnectrecFileSize = ctcConnectrecFileSize;
  2492.   const TupKeyConf * const tupKeyConf = (TupKeyConf *)signal->getDataPtr();
  2493.   Uint32 tcIndex = tupKeyConf->userPtr;
  2494.   jamEntry();
  2495.   tcConnectptr.i = tcIndex;
  2496.   ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
  2497.   if (tcConnectptr.p->seqNoReplica == 0) // Primary replica
  2498.     tcConnectptr.p->noFiredTriggers = tupKeyConf->noFiredTriggers;
  2499.   switch (tcConnectptr.p->transactionState) {
  2500.   case TcConnectionrec::WAIT_TUP:
  2501.     jam();
  2502.     tupkeyConfLab(signal);
  2503.     break;
  2504.   case TcConnectionrec::COPY_TUPKEY:
  2505.     jam();
  2506.     copyTupkeyConfLab(signal);
  2507.     break;
  2508.   case TcConnectionrec::SCAN_TUPKEY:
  2509.     jam();
  2510.     scanTupkeyConfLab(signal);
  2511.     break;
  2512.   case TcConnectionrec::WAIT_TUP_TO_ABORT:
  2513.     jam();
  2514. /* ------------------------------------------------------------------------- */
  2515. // Abort was not ready to start until this signal came back. Now we are ready
  2516. // to start the abort.
  2517. /* ------------------------------------------------------------------------- */
  2518.     releaseActiveFrag(signal);
  2519.     abortCommonLab(signal);
  2520.     break;
  2521.   case TcConnectionrec::WAIT_ACC_ABORT:
  2522.   case TcConnectionrec::ABORT_QUEUED:
  2523.     jam();
  2524. /* -------------------------------------------------------------------------- */
  2525. /*       IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY.             */
  2526. /* -------------------------------------------------------------------------- */
  2527.     break;
  2528.   default:
  2529.     ndbrequire(false);
  2530.     break;
  2531.   }//switch
  2532. }//Dblqh::execTUPKEYCONF()
  2533. /* ************> */
  2534. /*  TUPKEYREF  > */
  2535. /* ************> */
  2536. void Dblqh::execTUPKEYREF(Signal* signal) 
  2537. {
  2538.   const TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtr();
  2539.   jamEntry();
  2540.   tcConnectptr.i = tupKeyRef->userRef;
  2541.   terrorCode = tupKeyRef->errorCode;
  2542.   ptrCheckGuard(tcConnectptr, ctcConnectrecFileSize, tcConnectionrec);
  2543.   switch (tcConnectptr.p->transactionState) {
  2544.   case TcConnectionrec::WAIT_TUP:
  2545.     jam();
  2546.     releaseActiveFrag(signal);
  2547.     abortErrorLab(signal);
  2548.     break;
  2549.   case TcConnectionrec::COPY_TUPKEY:
  2550.     ndbrequire(false);
  2551.     break;
  2552.   case TcConnectionrec::SCAN_TUPKEY:
  2553.     jam();
  2554.     scanTupkeyRefLab(signal);
  2555.     break;
  2556.   case TcConnectionrec::WAIT_TUP_TO_ABORT:
  2557.     jam();
  2558. /* ------------------------------------------------------------------------- */
  2559. // Abort was not ready to start until this signal came back. Now we are ready
  2560. // to start the abort.
  2561. /* ------------------------------------------------------------------------- */
  2562.     releaseActiveFrag(signal);
  2563.     abortCommonLab(signal);
  2564.     break;
  2565.   case TcConnectionrec::WAIT_ACC_ABORT:
  2566.   case TcConnectionrec::ABORT_QUEUED:
  2567.     jam();
  2568. /* ------------------------------------------------------------------------- */
  2569. /*       IGNORE SINCE ABORT OF THIS OPERATION IS ONGOING ALREADY.            */
  2570. /* ------------------------------------------------------------------------- */
  2571.     break;
  2572.   default:
  2573.     ndbrequire(false);
  2574.     break;
  2575.   }//switch
  2576. }//Dblqh::execTUPKEYREF()
  2577. void Dblqh::sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr)
  2578. {
  2579.   Uint32 noOfWords = ahostptr->noOfPackedWordsLqh;
  2580.   BlockReference hostRef = ahostptr->hostLqhBlockRef;
  2581.   MEMCOPY_NO_WORDS(&signal->theData[0],
  2582.                    &ahostptr->packedWordsLqh[0],
  2583.                    noOfWords);
  2584.   sendSignal(hostRef, GSN_PACKED_SIGNAL, signal, noOfWords, JBB);
  2585.   ahostptr->noOfPackedWordsLqh = 0;
  2586. }//Dblqh::sendPackedSignalLqh()
  2587. void Dblqh::sendPackedSignalTc(Signal* signal, HostRecord * ahostptr)
  2588. {
  2589.   Uint32 noOfWords = ahostptr->noOfPackedWordsTc;
  2590.   BlockReference hostRef = ahostptr->hostTcBlockRef;
  2591.   MEMCOPY_NO_WORDS(&signal->theData[0],
  2592.                    &ahostptr->packedWordsTc[0],
  2593.                    noOfWords);
  2594.   sendSignal(hostRef, GSN_PACKED_SIGNAL, signal, noOfWords, JBB);
  2595.   ahostptr->noOfPackedWordsTc = 0;
  2596. }//Dblqh::sendPackedSignalTc()
  2597. void Dblqh::sendCommitLqh(Signal* signal, BlockReference alqhBlockref)
  2598. {
  2599.   HostRecordPtr Thostptr;
  2600.   Thostptr.i = refToNode(alqhBlockref);
  2601.   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
  2602.   if (Thostptr.p->noOfPackedWordsLqh > 21) {
  2603.     jam();
  2604.     sendPackedSignalLqh(signal, Thostptr.p);
  2605.   } else {
  2606.     jam();
  2607.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  2608.   }//if
  2609.   Uint32 pos = Thostptr.p->noOfPackedWordsLqh;
  2610.   Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMMIT << 28);
  2611.   Uint32 gci = tcConnectptr.p->gci;
  2612.   Uint32 transid1 = tcConnectptr.p->transid[0];
  2613.   Uint32 transid2 = tcConnectptr.p->transid[1];
  2614.   Thostptr.p->packedWordsLqh[pos] = ptrAndType;
  2615.   Thostptr.p->packedWordsLqh[pos + 1] = gci;
  2616.   Thostptr.p->packedWordsLqh[pos + 2] = transid1;
  2617.   Thostptr.p->packedWordsLqh[pos + 3] = transid2;
  2618.   Thostptr.p->noOfPackedWordsLqh = pos + 4;
  2619. }//Dblqh::sendCommitLqh()
  2620. void Dblqh::sendCompleteLqh(Signal* signal, BlockReference alqhBlockref)
  2621. {
  2622.   HostRecordPtr Thostptr;
  2623.   Thostptr.i = refToNode(alqhBlockref);
  2624.   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
  2625.   if (Thostptr.p->noOfPackedWordsLqh > 22) {
  2626.     jam();
  2627.     sendPackedSignalLqh(signal, Thostptr.p);
  2628.   } else {
  2629.     jam();
  2630.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  2631.   }//if
  2632.   Uint32 pos = Thostptr.p->noOfPackedWordsLqh;
  2633.   Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMPLETE << 28);
  2634.   Uint32 transid1 = tcConnectptr.p->transid[0];
  2635.   Uint32 transid2 = tcConnectptr.p->transid[1];
  2636.   Thostptr.p->packedWordsLqh[pos] = ptrAndType;
  2637.   Thostptr.p->packedWordsLqh[pos + 1] = transid1;
  2638.   Thostptr.p->packedWordsLqh[pos + 2] = transid2;
  2639.   Thostptr.p->noOfPackedWordsLqh = pos + 3;
  2640. }//Dblqh::sendCompleteLqh()
  2641. void Dblqh::sendCommittedTc(Signal* signal, BlockReference atcBlockref)
  2642. {
  2643.   HostRecordPtr Thostptr;
  2644.   Thostptr.i = refToNode(atcBlockref);
  2645.   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
  2646.   if (Thostptr.p->noOfPackedWordsTc > 22) {
  2647.     jam();
  2648.     sendPackedSignalTc(signal, Thostptr.p);
  2649.   } else {
  2650.     jam();
  2651.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  2652.   }//if
  2653.   Uint32 pos = Thostptr.p->noOfPackedWordsTc;
  2654.   Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMMITTED << 28);
  2655.   Uint32 transid1 = tcConnectptr.p->transid[0];
  2656.   Uint32 transid2 = tcConnectptr.p->transid[1];
  2657.   Thostptr.p->packedWordsTc[pos] = ptrAndType;
  2658.   Thostptr.p->packedWordsTc[pos + 1] = transid1;
  2659.   Thostptr.p->packedWordsTc[pos + 2] = transid2;
  2660.   Thostptr.p->noOfPackedWordsTc = pos + 3;
  2661. }//Dblqh::sendCommittedTc()
  2662. void Dblqh::sendCompletedTc(Signal* signal, BlockReference atcBlockref)
  2663. {
  2664.   HostRecordPtr Thostptr;
  2665.   Thostptr.i = refToNode(atcBlockref);
  2666.   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
  2667.   if (Thostptr.p->noOfPackedWordsTc > 22) {
  2668.     jam();
  2669.     sendPackedSignalTc(signal, Thostptr.p);
  2670.   } else {
  2671.     jam();
  2672.     updatePackedList(signal, Thostptr.p, Thostptr.i);
  2673.   }//if
  2674.   Uint32 pos = Thostptr.p->noOfPackedWordsTc;
  2675.   Uint32 ptrAndType = tcConnectptr.p->clientConnectrec | (ZCOMPLETED << 28);
  2676.   Uint32 transid1 = tcConnectptr.p->transid[0];
  2677.   Uint32 transid2 = tcConnectptr.p->transid[1];
  2678.   Thostptr.p->packedWordsTc[pos] = ptrAndType;
  2679.   Thostptr.p->packedWordsTc[pos + 1] = transid1;
  2680.   Thostptr.p->packedWordsTc[pos + 2] = transid2;
  2681.   Thostptr.p->noOfPackedWordsTc = pos + 3;
  2682. }//Dblqh::sendCompletedTc()
  2683. void Dblqh::sendLqhkeyconfTc(Signal* signal, BlockReference atcBlockref)
  2684. {
  2685.   LqhKeyConf* lqhKeyConf;
  2686.   HostRecordPtr Thostptr;
  2687.   Thostptr.i = refToNode(atcBlockref);
  2688.   ptrCheckGuard(Thostptr, chostFileSize, hostRecord);
  2689.   if (refToBlock(atcBlockref) == DBTC) {
  2690.     jam();
  2691. /*******************************************************************
  2692. // This signal was intended for DBTC as part of the normal transaction
  2693. // execution.
  2694. ********************************************************************/
  2695.     if (Thostptr.p->noOfPackedWordsTc > (25 - LqhKeyConf::SignalLength)) {
  2696.       jam();
  2697.       sendPackedSignalTc(signal, Thostptr.p);
  2698.     } else {
  2699.       jam();
  2700.       updatePackedList(signal, Thostptr.p, Thostptr.i);
  2701.     }//if
  2702.     lqhKeyConf = (LqhKeyConf *)
  2703.       &Thostptr.p->packedWordsTc[Thostptr.p->noOfPackedWordsTc];
  2704.     Thostptr.p->noOfPackedWordsTc += LqhKeyConf::SignalLength;
  2705.   } else {
  2706.     jam();
  2707. /*******************************************************************
  2708. // This signal was intended for DBLQH as part of log execution or
  2709. // node recovery.
  2710. ********************************************************************/
  2711.     if (Thostptr.p->noOfPackedWordsLqh > (25 - LqhKeyConf::SignalLength)) {
  2712.       jam();
  2713.       sendPackedSignalLqh(signal, Thostptr.p);
  2714.     } else {
  2715.       jam();
  2716.       updatePackedList(signal, Thostptr.p, Thostptr.i);
  2717.     }//if
  2718.     lqhKeyConf = (LqhKeyConf *)
  2719.       &Thostptr.p->packedWordsLqh[Thostptr.p->noOfPackedWordsLqh];
  2720.     Thostptr.p->noOfPackedWordsLqh += LqhKeyConf::SignalLength;
  2721.   }//if
  2722.   Uint32 ptrAndType = tcConnectptr.i | (ZLQHKEYCONF << 28);
  2723.   Uint32 tcOprec = tcConnectptr.p->tcOprec;
  2724.   Uint32 ownRef = cownref;
  2725.   Uint32 readlenAi = tcConnectptr.p->readlenAi;
  2726.   Uint32 transid1 = tcConnectptr.p->transid[0];
  2727.   Uint32 transid2 = tcConnectptr.p->transid[1];
  2728.   Uint32 noFiredTriggers = tcConnectptr.p->noFiredTriggers;
  2729.   lqhKeyConf->connectPtr = ptrAndType;
  2730.   lqhKeyConf->opPtr = tcOprec;
  2731.   lqhKeyConf->userRef = ownRef;
  2732.   lqhKeyConf->readLen = readlenAi;
  2733.   lqhKeyConf->transId1 = transid1;
  2734.   lqhKeyConf->transId2 = transid2;
  2735.   lqhKeyConf->noFiredTriggers = noFiredTriggers;
  2736. }//Dblqh::sendLqhkeyconfTc()
  2737. /* ************************************************************************>>
  2738.  * KEYINFO: Get tuple request from DBTC. Next step is to contact DBACC to get 
  2739.  * key to tuple if all key/attrinfo has been received, else for more attrinfo 
  2740.  * signals.      
  2741.  * ************************************************************************>> */
  2742. void Dblqh::execKEYINFO(Signal* signal) 
  2743. {
  2744.   Uint32 tcOprec = signal->theData[0];
  2745.   Uint32 transid1 = signal->theData[1];
  2746.   Uint32 transid2 = signal->theData[2];
  2747.   jamEntry();
  2748.   if (findTransaction(transid1, transid2, tcOprec) != ZOK) {
  2749.     jam();
  2750.     return;
  2751.   }//if
  2752.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2753.   TcConnectionrec::TransactionState state = regTcPtr->transactionState;
  2754.   if (state != TcConnectionrec::WAIT_TUPKEYINFO &&
  2755.       state != TcConnectionrec::WAIT_SCAN_AI)
  2756.   {
  2757.     jam();
  2758. /*****************************************************************************/
  2759. /* TRANSACTION WAS ABORTED, THIS IS MOST LIKELY A SIGNAL BELONGING TO THE    */
  2760. /* ABORTED TRANSACTION. THUS IGNORE THE SIGNAL.                              */
  2761. /*****************************************************************************/
  2762.     return;
  2763.   }//if
  2764.   Uint32 errorCode = handleLongTupKey(signal,
  2765.                                       (Uint32)regTcPtr->save1,
  2766.                                       (Uint32)regTcPtr->primKeyLen,
  2767.                                       &signal->theData[3]);
  2768.   if (errorCode != 0) {
  2769.     if (errorCode == 1) {
  2770.       jam();
  2771.       return;
  2772.     }//if
  2773.     jam();
  2774.     terrorCode = errorCode;
  2775.     if(state == TcConnectionrec::WAIT_TUPKEYINFO)
  2776.       abortErrorLab(signal);
  2777.     else
  2778.       abort_scan(signal, regTcPtr->tcScanRec, errorCode);
  2779.     return;
  2780.   }//if
  2781.   if(state == TcConnectionrec::WAIT_TUPKEYINFO)
  2782.   {
  2783.     FragrecordPtr regFragptr;
  2784.     regFragptr.i = regTcPtr->fragmentptr;
  2785.     ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord);
  2786.     fragptr = regFragptr;
  2787.     endgettupkeyLab(signal);
  2788.   }
  2789.   return;
  2790. }//Dblqh::execKEYINFO()
  2791. /* ------------------------------------------------------------------------- */
  2792. /* FILL IN KEY DATA INTO DATA BUFFERS.                                       */
  2793. /* ------------------------------------------------------------------------- */
  2794. Uint32 Dblqh::handleLongTupKey(Signal* signal,
  2795.        Uint32 keyLength,
  2796.        Uint32 primKeyLength,
  2797.        Uint32* dataPtr) 
  2798. {
  2799.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2800.   Uint32 dataPos = 0;
  2801.   while (true) {
  2802.     keyLength += 4;
  2803.     if (cfirstfreeDatabuf == RNIL) {
  2804.       jam();
  2805.       return ZGET_DATAREC_ERROR;
  2806.     }//if
  2807.     seizeTupkeybuf(signal);
  2808.     Databuf * const regDataPtr = databufptr.p;
  2809.     Uint32 data0 = dataPtr[dataPos];
  2810.     Uint32 data1 = dataPtr[dataPos + 1];
  2811.     Uint32 data2 = dataPtr[dataPos + 2];
  2812.     Uint32 data3 = dataPtr[dataPos + 3];
  2813.     regDataPtr->data[0] = data0;
  2814.     regDataPtr->data[1] = data1;
  2815.     regDataPtr->data[2] = data2;
  2816.     regDataPtr->data[3] = data3;
  2817.     dataPos += 4;
  2818.     if (keyLength < primKeyLength) {
  2819.       if (dataPos > 16) {
  2820.         jam();
  2821. /* SAVE STATE AND WAIT FOR KEYINFO */
  2822.         regTcPtr->save1 = keyLength;
  2823.         return 1;
  2824.       }//if
  2825.     } else {
  2826.       jam();
  2827.       return 0;
  2828.     }//if
  2829.   }//while
  2830. }//Dblqh::handleLongTupKey()
  2831. /* ------------------------------------------------------------------------- */
  2832. /* -------                HANDLE ATTRINFO SIGNALS                    ------- */
  2833. /*                                                                           */
  2834. /* ------------------------------------------------------------------------- */
  2835. /* ************************************************************************>> */
  2836. /*  ATTRINFO: Continuation of KEYINFO signal (except for scans that do not use*/
  2837. /*  any KEYINFO). When all key and attribute info is received we contact DBACC*/
  2838. /*  for index handling.                                                       */
  2839. /* ************************************************************************>> */
  2840. void Dblqh::execATTRINFO(Signal* signal) 
  2841. {
  2842.   Uint32 tcOprec = signal->theData[0];
  2843.   Uint32 transid1 = signal->theData[1];
  2844.   Uint32 transid2 = signal->theData[2];
  2845.   jamEntry();
  2846.   if (findTransaction(transid1,
  2847.                       transid2,
  2848.                       tcOprec) != ZOK) {
  2849.     jam();
  2850.     return;
  2851.   }//if
  2852.   TcConnectionrec * const regTcPtr = tcConnectptr.p;
  2853.   Uint32 length = signal->length() - 3;
  2854.   Uint32 totReclenAi = regTcPtr->totReclenAi;
  2855.   Uint32 currReclenAi = regTcPtr->currReclenAi + length;
  2856.   Uint32* dataPtr = &signal->theData[3];
  2857.   regTcPtr->currReclenAi = currReclenAi;
  2858.   if (totReclenAi == currReclenAi) {
  2859.     switch (regTcPtr->transactionState) {
  2860.     case TcConnectionrec::WAIT_ATTR:
  2861.     {
  2862.       Fragrecord *regFragrecord = fragrecord;
  2863.       Uint32 fragIndex = regTcPtr->fragmentptr;
  2864.       Uint32 tfragrecFileSize = cfragrecFileSize;
  2865.       jam();
  2866.       fragptr.i = fragIndex;
  2867.       ptrCheckGuard(fragptr, tfragrecFileSize, regFragrecord);
  2868.       lqhAttrinfoLab(signal, dataPtr, length);
  2869.       endgettupkeyLab(signal);
  2870.       return;
  2871.       break;
  2872.     }
  2873.     case TcConnectionrec::WAIT_SCAN_AI:
  2874.       jam();
  2875.       scanAttrinfoLab(signal, dataPtr, length);
  2876.       return;
  2877.       break;
  2878.     case TcConnectionrec::WAIT_TUP_TO_ABORT:
  2879.     case TcConnectionrec::LOG_ABORT_QUEUED:
  2880.     case TcConnectionrec::ABORT_QUEUED:
  2881.     case TcConnectionrec::ABORT_STOPPED:
  2882.     case TcConnectionrec::WAIT_ACC_ABORT:
  2883.     case TcConnectionrec::WAIT_AI_AFTER_ABORT:
  2884.       jam();
  2885.       aiStateErrorCheckLab(signal, dataPtr,length);
  2886.       return;
  2887.       break;
  2888.     default:
  2889.       jam();
  2890.       ndbrequire(regTcPtr->abortState != TcConnectionrec::ABORT_IDLE);
  2891.       break;
  2892.     }//switch
  2893.   } else if (currReclenAi < totReclenAi) {
  2894.     jam();
  2895.     switch (regTcPtr->transactionState) {
  2896.     case TcConnectionrec::WAIT_ATTR:
  2897.       jam();
  2898.       lqhAttrinfoLab(signal, dataPtr, length);
  2899.       return;
  2900.       break;
  2901.     case TcConnectionrec::WAIT_SCAN_AI:
  2902.       jam();
  2903.       scanAttrinfoLab(signal, dataPtr, length);
  2904.       return;
  2905.       break;
  2906.     case TcConnectionrec::WAIT_TUP_TO_ABORT:
  2907.     case TcConnectionrec::LOG_ABORT_QUEUED:
  2908.     case TcConnectionrec::ABORT_QUEUED:
  2909.     case TcConnectionrec::ABORT_STOPPED:
  2910.     case TcConnectionrec::WAIT_ACC_ABORT:
  2911.     case TcConnectionrec::WAIT_AI_AFTER_ABORT:
  2912.       jam();
  2913.       aiStateErrorCheckLab(signal, dataPtr, length);
  2914.       return;
  2915.       break;
  2916.     default:
  2917.       jam();
  2918.       ndbrequire(regTcPtr->abortState != TcConnectionrec::ABORT_IDLE);
  2919.       break;
  2920.     }//switch
  2921.   } else {
  2922.     switch (regTcPtr->transactionState) {
  2923.     case TcConnectionrec::WAIT_SCAN_AI:
  2924.       jam();
  2925.       scanAttrinfoLab(signal, dataPtr, length);
  2926.       return;
  2927.       break;
  2928.     default:
  2929.       ndbout_c("%d", regTcPtr->transactionState);
  2930.       ndbrequire(false);