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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <NdbOperation.hpp>
  15. #include <NdbConnection.hpp>
  16. #include "NdbApiSignal.hpp"
  17. #include <Ndb.hpp>
  18. #include <NdbRecAttr.hpp>
  19. #include "NdbUtil.hpp"
  20. #include "Interpreter.hpp"
  21. #include <AttributeHeader.hpp>
  22. #include <signaldata/TcKeyReq.hpp>
  23. #include <signaldata/KeyInfo.hpp>
  24. #include <signaldata/AttrInfo.hpp>
  25. #include <signaldata/ScanTab.hpp>
  26. #include <ndb_version.h>
  27. #include "API.hpp"
  28. #include <NdbOut.hpp>
  29. void
  30. NdbOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag)
  31. {
  32.   TcKeyReq * const req = CAST_PTR(TcKeyReq, signal->getDataPtrSend());
  33.   TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);
  34. }
  35. /******************************************************************************
  36. int doSend()
  37. Return Value:   Return >0 : send was succesful, returns number of signals sent
  38.                 Return -1: In all other case.   
  39. Parameters:     aProcessorId: Receiving processor node
  40. Remark:         Sends the TCKEYREQ signal and optional KEYINFO and ATTRINFO 
  41.                 signals.
  42. ******************************************************************************/
  43. int
  44. NdbOperation::doSend(int aNodeId, Uint32 lastFlag)
  45. {
  46.   int tReturnCode;
  47.   int tSignalCount = 0;
  48.   assert(theTCREQ != NULL);
  49.   setLastFlag(theTCREQ, lastFlag);
  50.   TransporterFacade *tp = TransporterFacade::instance();
  51.   tReturnCode = tp->sendSignal(theTCREQ, aNodeId);
  52.   tSignalCount++;
  53.   if (tReturnCode == -1) {
  54.     return -1;
  55.   }
  56.   NdbApiSignal *tSignal = theFirstKEYINFO;
  57.   while (tSignal != NULL) {
  58.     NdbApiSignal* tnextSignal = tSignal->next();
  59.     tReturnCode = tp->sendSignal(tSignal, aNodeId);
  60.     tSignal = tnextSignal;
  61.     if (tReturnCode == -1) {
  62.       return -1;
  63.     }
  64.     tSignalCount++;
  65.   }//while
  66.   tSignal = theFirstATTRINFO;
  67.   while (tSignal != NULL) {
  68.     NdbApiSignal* tnextSignal = tSignal->next();
  69.     tReturnCode = tp->sendSignal(tSignal, aNodeId);
  70.     tSignal = tnextSignal;
  71.     if (tReturnCode == -1) {
  72.       return -1;
  73.     }
  74.     tSignalCount++;
  75.   }//while
  76.   theNdbCon->OpSent();
  77.   return tSignalCount;
  78. }//NdbOperation::doSend()
  79. /***************************************************************************
  80. int prepareSend(Uint32 aTC_ConnectPtr,
  81.                 Uint64 aTransactionId)
  82. Return Value:   Return 0 : preparation of send was succesful.
  83.                 Return -1: In all other case.   
  84. Parameters:     aTC_ConnectPtr: the Connect pointer to TC.
  85. aTransactionId: the Transaction identity of the transaction.
  86. Remark:         Puts the the data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.
  87. ***************************************************************************/
  88. int
  89. NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
  90. {
  91.   Uint32 tTransId1, tTransId2;
  92.   Uint32 tReqInfo;
  93.   Uint8 tInterpretInd = theInterpretIndicator;
  94.   Uint8 tDirtyIndicator = theDirtyIndicator;
  95.   Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
  96.   theErrorLine = 0;
  97.   if (tInterpretInd != 1) {
  98.     OperationType tOpType = theOperationType;
  99.     OperationStatus tStatus = theStatus;
  100.     if ((tOpType == UpdateRequest) ||
  101. (tOpType == InsertRequest) ||
  102. (tOpType == WriteRequest)) {
  103.       if (tStatus != SetValue) {
  104.         setErrorCodeAbort(4116);
  105.         return -1;
  106.       }//if
  107.     } else if ((tOpType == ReadRequest) || (tOpType == ReadExclusive) ||
  108.        (tOpType == DeleteRequest)) {
  109.       if (tStatus != GetValue) {
  110.         setErrorCodeAbort(4116);
  111.         return -1;
  112.       } 
  113.       else if(unlikely(tDirtyIndicator && tTotalCurrAI_Len == 0))
  114.       {
  115. getValue(NdbDictionary::Column::FRAGMENT);
  116. tTotalCurrAI_Len = theTotalCurrAI_Len;
  117. assert(theTotalCurrAI_Len);
  118.       }
  119.     } else {
  120.       setErrorCodeAbort(4005);      
  121.       return -1;
  122.     }//if
  123.   } else {
  124.     if (prepareSendInterpreted() == -1) {
  125.       return -1;
  126.     }//if
  127.     tTotalCurrAI_Len = theTotalCurrAI_Len;
  128.   }//if
  129.   
  130. //-------------------------------------------------------------
  131. // We start by filling in the first 9 unconditional words of the
  132. // TCKEYREQ signal.
  133. //-------------------------------------------------------------
  134.   TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
  135.   Uint32 tTableId = m_currentTable->m_tableId;
  136.   Uint32 tSchemaVersion = m_currentTable->m_version;
  137.   
  138.   tcKeyReq->apiConnectPtr      = aTC_ConnectPtr;
  139.   tcKeyReq->apiOperationPtr    = ptr2int();
  140.   // Check if too much attrinfo have been defined
  141.   if (tTotalCurrAI_Len > TcKeyReq::MaxTotalAttrInfo){
  142.     setErrorCodeAbort(4257);
  143.     return -1;
  144.   }
  145.   Uint32 TattrLen = 0;
  146.   tcKeyReq->setAttrinfoLen(TattrLen, tTotalCurrAI_Len);
  147.   tcKeyReq->setAPIVersion(TattrLen, NDB_VERSION);
  148.   tcKeyReq->attrLen            = TattrLen;
  149.   tcKeyReq->tableId            = tTableId;
  150.   tcKeyReq->tableSchemaVersion = tSchemaVersion;
  151.   tTransId1 = (Uint32) aTransId;
  152.   tTransId2 = (Uint32) (aTransId >> 32);
  153.   
  154.   Uint8 tSimpleIndicator = theSimpleIndicator;
  155.   Uint8 tCommitIndicator = theCommitIndicator;
  156.   Uint8 tStartIndicator = theStartIndicator;
  157.   Uint8 tInterpretIndicator = theInterpretIndicator;
  158. //-------------------------------------------------------------
  159. // Simple state is set if start and commit is set and it is
  160. // a read request. Otherwise it is set to zero.
  161. //-------------------------------------------------------------
  162.   Uint8 tReadInd = (theOperationType == ReadRequest);
  163.   Uint8 tSimpleState = tReadInd & tSimpleIndicator;
  164.   tcKeyReq->transId1           = tTransId1;
  165.   tcKeyReq->transId2           = tTransId2;
  166.   
  167.   tReqInfo = 0;
  168.   if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) {
  169.     tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len);
  170.   } else {
  171.     tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo);
  172.   }//if
  173.   tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator);
  174.   tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator);
  175.   tcKeyReq->setStartFlag(tReqInfo, tStartIndicator);
  176.   tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator);
  177.   OperationType tOperationType = theOperationType;
  178.   Uint32 tTupKeyLen = theTupKeyLen;
  179.   Uint8 abortOption =
  180.     m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
  181.   tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
  182.   tcKeyReq->setOperationType(tReqInfo, tOperationType);
  183.   tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen);
  184.   
  185.   // A simple read is always ignore error
  186.   abortOption = tSimpleIndicator ? AO_IgnoreError : abortOption;
  187.   tcKeyReq->setAbortOption(tReqInfo, abortOption);
  188.   
  189.   Uint8 tDistrKeyIndicator = theDistrKeyIndicator;
  190.   Uint8 tDistrGroupIndicator = theDistrGroupIndicator;
  191.   Uint8 tDistrGroupType = theDistrGroupType;
  192.   Uint8 tScanIndicator = theScanInfo & 1;
  193.   tcKeyReq->setDistributionGroupFlag(tReqInfo, tDistrGroupIndicator);
  194.   tcKeyReq->setDistributionGroupTypeFlag(tReqInfo, tDistrGroupType);
  195.   tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
  196.   tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator);
  197.   tcKeyReq->requestInfo  = tReqInfo;
  198. //-------------------------------------------------------------
  199. // The next step is to fill in the upto three conditional words.
  200. //-------------------------------------------------------------
  201.   Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo;
  202.   Uint32 tDistrGHIndex = tScanIndicator;
  203.   Uint32 tDistrKeyIndex = tDistrGHIndex + tDistrGroupIndicator;
  204.   Uint32 tScanInfo = theScanInfo;
  205.   Uint32 tDistributionGroup = theDistributionGroup;
  206.   Uint32 tDistrKeySize = theDistrKeySize;
  207.   tOptionalDataPtr[0] = tScanInfo;
  208.   tOptionalDataPtr[tDistrGHIndex] = tDistributionGroup;
  209.   tOptionalDataPtr[tDistrKeyIndex] = tDistrKeySize;
  210. //-------------------------------------------------------------
  211. // The next is step is to compress the key data part of the
  212. // TCKEYREQ signal.
  213. //-------------------------------------------------------------
  214.   Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator;
  215.   Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex];
  216.   Uint32 Tdata1 = tcKeyReq->keyInfo[0];
  217.   Uint32 Tdata2 = tcKeyReq->keyInfo[1];
  218.   Uint32 Tdata3 = tcKeyReq->keyInfo[2];
  219.   Uint32 Tdata4 = tcKeyReq->keyInfo[3];
  220.   Uint32 Tdata5;
  221.   tKeyDataPtr[0] = Tdata1;
  222.   tKeyDataPtr[1] = Tdata2;
  223.   tKeyDataPtr[2] = Tdata3;
  224.   tKeyDataPtr[3] = Tdata4;
  225.   if (tTupKeyLen > 4) {
  226.     Tdata1 = tcKeyReq->keyInfo[4];
  227.     Tdata2 = tcKeyReq->keyInfo[5];
  228.     Tdata3 = tcKeyReq->keyInfo[6];
  229.     Tdata4 = tcKeyReq->keyInfo[7];
  230.     tKeyDataPtr[4] = Tdata1;
  231.     tKeyDataPtr[5] = Tdata2;
  232.     tKeyDataPtr[6] = Tdata3;
  233.     tKeyDataPtr[7] = Tdata4;
  234.   }//if
  235. //-------------------------------------------------------------
  236. // Finally we also compress the ATTRINFO part of the signal.
  237. // We optimise by using the if-statement for sending KEYINFO
  238. // signals to calculating the new Attrinfo Index.
  239. //-------------------------------------------------------------
  240.   Uint32 tAttrInfoIndex;  
  241.   if (tTupKeyLen > TcKeyReq::MaxKeyInfo) {
  242.     /**
  243.      * Set transid, TC connect ptr and length in the KEYINFO signals
  244.      */
  245.     NdbApiSignal* tSignal = theFirstKEYINFO;
  246.     Uint32 remainingKey = tTupKeyLen - TcKeyReq::MaxKeyInfo;
  247.     do {
  248.       Uint32* tSigDataPtr = tSignal->getDataPtrSend();
  249.       NdbApiSignal* tnextSignal = tSignal->next();
  250.       tSigDataPtr[0] = aTC_ConnectPtr;
  251.       tSigDataPtr[1] = tTransId1;
  252.       tSigDataPtr[2] = tTransId2;
  253.       if (remainingKey > KeyInfo::DataLength) {
  254. // The signal is full
  255. tSignal->setLength(KeyInfo::MaxSignalLength);
  256. remainingKey -= KeyInfo::DataLength;
  257.       }
  258.       else {
  259. // Last signal
  260. tSignal->setLength(KeyInfo::HeaderLength + remainingKey);
  261. remainingKey = 0;
  262.       }
  263.       tSignal = tnextSignal;
  264.     } while (tSignal != NULL);
  265.     tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo;
  266.   } else {
  267.     tAttrInfoIndex = tKeyIndex + tTupKeyLen;
  268.   }//if
  269. //-------------------------------------------------------------
  270. // Perform the Attrinfo packing in the TCKEYREQ signal started
  271. // above.
  272. //-------------------------------------------------------------
  273.   Uint32* tAIDataPtr = &tOptionalDataPtr[tAttrInfoIndex];
  274.   Tdata1 = tcKeyReq->attrInfo[0];
  275.   Tdata2 = tcKeyReq->attrInfo[1];
  276.   Tdata3 = tcKeyReq->attrInfo[2];
  277.   Tdata4 = tcKeyReq->attrInfo[3];
  278.   Tdata5 = tcKeyReq->attrInfo[4];
  279.   theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) +
  280.                       tAttrInfoIndex + TcKeyReq::StaticLength);
  281.   tAIDataPtr[0] = Tdata1;
  282.   tAIDataPtr[1] = Tdata2;
  283.   tAIDataPtr[2] = Tdata3;
  284.   tAIDataPtr[3] = Tdata4;
  285.   tAIDataPtr[4] = Tdata5;
  286. /***************************************************
  287. *  Send the ATTRINFO signals.
  288. ***************************************************/
  289.   if (tTotalCurrAI_Len > 5) {
  290.     // Set the last signal's length.
  291.     NdbApiSignal* tSignal = theFirstATTRINFO;
  292.     theCurrentATTRINFO->setLength(theAI_LenInCurrAI);
  293.     do {
  294.       Uint32* tSigDataPtr = tSignal->getDataPtrSend();
  295.       NdbApiSignal* tnextSignal = tSignal->next();
  296.       tSigDataPtr[0] = aTC_ConnectPtr;
  297.       tSigDataPtr[1] = tTransId1;
  298.       tSigDataPtr[2] = tTransId2;
  299.       tSignal = tnextSignal;
  300.     } while (tSignal != NULL);
  301.   }//if
  302.   theStatus = WaitResponse;
  303.   theReceiver.prepareSend();
  304.   return 0;
  305. }//NdbOperation::prepareSend()
  306. /***************************************************************************
  307. int prepareSendInterpreted()
  308. Make preparations to send an interpreted operation.
  309. Return Value:   Return 0 : succesful.
  310.                 Return -1: In all other case.   
  311. ***************************************************************************/
  312. int
  313. NdbOperation::prepareSendInterpreted()
  314. {
  315.   Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
  316.   Uint32 tInitReadSize = theInitialReadSize;
  317.   if (theStatus == ExecInterpretedValue) {
  318.     if (insertATTRINFO(Interpreter::EXIT_OK) != -1) {
  319. //-------------------------------------------------------------------------
  320. // Since we read the total length before inserting the last entry in the
  321. // signals we need to add one to the total length.
  322. //-------------------------------------------------------------------------
  323.       theInterpretedSize = (tTotalCurrAI_Len + 1) -
  324.        (tInitReadSize + 5);
  325.     } else {
  326.       return -1;
  327.     }//if
  328.   } else if (theStatus == FinalGetValue) {
  329.     theFinalReadSize = tTotalCurrAI_Len -
  330.       (tInitReadSize + theInterpretedSize + theFinalUpdateSize + 5);
  331.   } else if (theStatus == SetValueInterpreted) {
  332.     theFinalUpdateSize = tTotalCurrAI_Len -
  333.        (tInitReadSize + theInterpretedSize + 5);
  334.   } else if (theStatus == SubroutineEnd) {
  335.     theSubroutineSize = tTotalCurrAI_Len -
  336.       (tInitReadSize + theInterpretedSize + 
  337.          theFinalUpdateSize + theFinalReadSize + 5);
  338.   } else if (theStatus == GetValue) {
  339.     theInitialReadSize = tTotalCurrAI_Len - 5;
  340.   } else {
  341.     setErrorCodeAbort(4116);
  342.     return -1;
  343.   }
  344.   while (theFirstBranch != NULL) {
  345.     Uint32 tRelAddress;
  346.     Uint32 tLabelAddress = 0;
  347.     int     tAddress = -1;
  348.     NdbBranch* tNdbBranch = theFirstBranch;
  349.     Uint32 tBranchLabel = tNdbBranch->theBranchLabel;
  350.     NdbLabel* tNdbLabel = theFirstLabel;
  351.     if (tBranchLabel >= theNoOfLabels) {
  352.       setErrorCodeAbort(4221);
  353.       return -1;
  354.     }//if
  355.     // Find the label address
  356.     while (tNdbLabel != NULL) {
  357.       for(tLabelAddress = 0; tLabelAddress<16; tLabelAddress++){
  358. const Uint32 labelNo = tNdbLabel->theLabelNo[tLabelAddress];
  359. if(tBranchLabel == labelNo){
  360.   tAddress = tNdbLabel->theLabelAddress[tLabelAddress];
  361.   break;
  362. }
  363.       }
  364.       
  365.       if(tAddress != -1)
  366. break;
  367.       tNdbLabel = tNdbLabel->theNext;
  368.     }//while
  369.     if (tAddress == -1) {
  370. //-------------------------------------------------------------------------
  371. // We were unable to find any label which the branch refers to. This means
  372. // that the application have not programmed the interpreter program correctly.
  373. //-------------------------------------------------------------------------
  374.       setErrorCodeAbort(4222);
  375.       return -1;
  376.     }//if
  377.     if (tNdbLabel->theSubroutine[tLabelAddress] != tNdbBranch->theSubroutine) {
  378.       setErrorCodeAbort(4224);
  379.       return -1;
  380.     }//if
  381.     // Now it is time to update the signal data with the relative branch jump.
  382.     if (tAddress < int(tNdbBranch->theBranchAddress)) {
  383.       tRelAddress = (tNdbBranch->theBranchAddress - tAddress) << 16;
  384.       
  385.       // Indicate backward jump direction
  386.       tRelAddress = tRelAddress + (1 << 31);
  387.     } else if (tAddress > int(tNdbBranch->theBranchAddress)) {
  388.       tRelAddress = (tAddress - tNdbBranch->theBranchAddress) << 16;
  389.     } else {
  390.        setErrorCodeAbort(4223);
  391.        return -1;
  392.     }//if
  393.     NdbApiSignal* tSignal = tNdbBranch->theSignal;
  394.     Uint32 tReadData = tSignal->readData(tNdbBranch->theSignalAddress);
  395.     tSignal->setData((tRelAddress + tReadData), tNdbBranch->theSignalAddress);
  396.       
  397.     theFirstBranch = theFirstBranch->theNext;
  398.     theNdb->releaseNdbBranch(tNdbBranch);
  399.   }//while
  400.   while (theFirstCall != NULL) {
  401.     Uint32 tSubroutineCount = 0;
  402.     int     tAddress = -1;
  403.     NdbSubroutine* tNdbSubroutine;
  404.     NdbCall* tNdbCall = theFirstCall;
  405.     if (tNdbCall->theSubroutine >= theNoOfSubroutines) {
  406.       setErrorCodeAbort(4221);
  407.       return -1;
  408.     }//if
  409. // Find the subroutine address
  410.     tNdbSubroutine = theFirstSubroutine;
  411.     while (tNdbSubroutine != NULL) {
  412.       tSubroutineCount += 16;
  413.       if (tNdbCall->theSubroutine < tSubroutineCount) {
  414. // Subroutine Found
  415.         Uint32 tSubroutineAddress = tNdbCall->theSubroutine - (tSubroutineCount - 16);
  416.         tAddress = tNdbSubroutine->theSubroutineAddress[tSubroutineAddress];
  417.         break;
  418.       }//if
  419.       tNdbSubroutine = tNdbSubroutine->theNext;
  420.     }//while
  421.     if (tAddress == -1) {
  422.       setErrorCodeAbort(4222);
  423.       return -1;
  424.     }//if
  425. // Now it is time to update the signal data with the relative branch jump.
  426.     NdbApiSignal* tSignal = tNdbCall->theSignal;
  427.     Uint32 tReadData = tSignal->readData(tNdbCall->theSignalAddress);
  428.     tSignal->setData(((tAddress << 16) + tReadData), tNdbCall->theSignalAddress);
  429.       
  430.     theFirstCall = theFirstCall->theNext;
  431.     theNdb->releaseNdbCall(tNdbCall);
  432.   }//while
  433.   
  434.   Uint32 tInitialReadSize = theInitialReadSize;
  435.   Uint32 tInterpretedSize = theInterpretedSize;
  436.   Uint32 tFinalUpdateSize = theFinalUpdateSize;
  437.   Uint32 tFinalReadSize   = theFinalReadSize;
  438.   Uint32 tSubroutineSize  = theSubroutineSize;
  439.   if (theOperationType != OpenScanRequest &&
  440.       theOperationType != OpenRangeScanRequest) {
  441.     TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
  442.     tcKeyReq->attrInfo[0] = tInitialReadSize;
  443.     tcKeyReq->attrInfo[1] = tInterpretedSize;
  444.     tcKeyReq->attrInfo[2] = tFinalUpdateSize;
  445.     tcKeyReq->attrInfo[3] = tFinalReadSize;
  446.     tcKeyReq->attrInfo[4] = tSubroutineSize;
  447.   } else {
  448.     // If a scan is defined we use the first ATTRINFO instead of TCKEYREQ.
  449.     theFirstATTRINFO->setData(tInitialReadSize, 4);
  450.     theFirstATTRINFO->setData(tInterpretedSize, 5);
  451.     theFirstATTRINFO->setData(tFinalUpdateSize, 6);
  452.     theFirstATTRINFO->setData(tFinalReadSize, 7);
  453.     theFirstATTRINFO->setData(tSubroutineSize, 8);  
  454.   }//if
  455.   theReceiver.prepareSend();
  456.   return 0;
  457. }//NdbOperation::prepareSendInterpreted()
  458. int
  459. NdbOperation::checkState_TransId(NdbApiSignal* aSignal)
  460. {
  461.   Uint64 tRecTransId, tCurrTransId;
  462.   Uint32 tTmp1, tTmp2;
  463.   if (theStatus != WaitResponse) {
  464. #ifdef NDB_NO_DROPPED_SIGNAL
  465.     abort();
  466. #endif
  467.     return -1;
  468.   }//if
  469.   tTmp1 = aSignal->readData(2);
  470.   tTmp2 = aSignal->readData(3);
  471.   tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
  472.   tCurrTransId = theNdbCon->getTransactionId();
  473.   if (tCurrTransId != tRecTransId) {
  474. #ifdef NDB_NO_DROPPED_SIGNAL
  475.     abort();
  476. #endif
  477.     return -1;
  478.   }//if
  479.   return 0;
  480. }//NdbOperation::checkState_TransId()
  481. /***************************************************************************
  482. int receiveTCKEYREF( NdbApiSignal* aSignal)
  483. Return Value:   Return 0 : send was succesful.
  484.                 Return -1: In all other case.   
  485. Parameters:     aSignal: the signal object that contains the TCKEYREF signal from TC.
  486. Remark:         Handles the reception of the TCKEYREF signal.
  487. ***************************************************************************/
  488. int
  489. NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
  490. {
  491.   if (checkState_TransId(aSignal) == -1) {
  492.     return -1;
  493.   }//if
  494.   AbortOption ao = (AbortOption)
  495.     (m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption);
  496.   theReceiver.m_received_result_length = ~0;
  497.   theStatus = Finished;
  498.   // blobs want this
  499.   if (m_abortOption != AO_IgnoreError)
  500.     theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
  501.   theError.code = aSignal->readData(4);
  502.   theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), m_abortOption);
  503.   if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
  504.     return theNdbCon->OpCompleteFailure(ao, m_abortOption != AO_IgnoreError);
  505.   
  506.   /**
  507.    * If TCKEYCONF has arrived
  508.    *   op has completed (maybe trans has completed)
  509.    */
  510.   if(theReceiver.m_expected_result_length)
  511.   {
  512.     return theNdbCon->OpCompleteFailure(AbortOnError);
  513.   }
  514.   
  515.   return -1;
  516. }
  517. void
  518. NdbOperation::handleFailedAI_ElemLen()
  519. {
  520.   NdbRecAttr* tRecAttr = theReceiver.theFirstRecAttr;
  521.   while (tRecAttr != NULL) {
  522.     tRecAttr->setNULL();
  523.     tRecAttr = tRecAttr->next();
  524.   }//while
  525. }//NdbOperation::handleFailedAI_ElemLen()