📄 ndboperationexec.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <ndb_global.h>#include <NdbOperation.hpp>#include <NdbTransaction.hpp>#include "NdbApiSignal.hpp"#include <Ndb.hpp>#include <NdbRecAttr.hpp>#include "NdbUtil.hpp"#include "Interpreter.hpp"#include <AttributeHeader.hpp>#include <signaldata/TcKeyReq.hpp>#include <signaldata/KeyInfo.hpp>#include <signaldata/AttrInfo.hpp>#include <signaldata/ScanTab.hpp>#include <ndb_version.h>#include "API.hpp"#include <NdbOut.hpp>voidNdbOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag){ TcKeyReq * const req = CAST_PTR(TcKeyReq, signal->getDataPtrSend()); TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);}/******************************************************************************int doSend()Return Value: Return >0 : send was succesful, returns number of signals sent Return -1: In all other case. Parameters: aProcessorId: Receiving processor nodeRemark: Sends the TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.******************************************************************************/intNdbOperation::doSend(int aNodeId, Uint32 lastFlag){ int tReturnCode; int tSignalCount = 0; assert(theTCREQ != NULL); setLastFlag(theTCREQ, lastFlag); TransporterFacade *tp = TransporterFacade::instance(); tReturnCode = tp->sendSignal(theTCREQ, aNodeId); tSignalCount++; if (tReturnCode == -1) { return -1; } NdbApiSignal *tSignal = theTCREQ->next(); while (tSignal != NULL) { NdbApiSignal* tnextSignal = tSignal->next(); tReturnCode = tp->sendSignal(tSignal, aNodeId); tSignal = tnextSignal; if (tReturnCode == -1) { return -1; } tSignalCount++; }//while tSignal = theFirstATTRINFO; while (tSignal != NULL) { NdbApiSignal* tnextSignal = tSignal->next(); tReturnCode = tp->sendSignal(tSignal, aNodeId); tSignal = tnextSignal; if (tReturnCode == -1) { return -1; } tSignalCount++; }//while theNdbCon->OpSent(); return tSignalCount;}//NdbOperation::doSend()/***************************************************************************int prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)Return Value: Return 0 : preparation of send was succesful. Return -1: In all other case. Parameters: aTC_ConnectPtr: the Connect pointer to TC. aTransactionId: the Transaction identity of the transaction.Remark: Puts the the data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.***************************************************************************/intNdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId){ Uint32 tTransId1, tTransId2; Uint32 tReqInfo; Uint8 tInterpretInd = theInterpretIndicator; Uint8 tDirtyIndicator = theDirtyIndicator; Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len; theErrorLine = 0; if (tInterpretInd != 1) { OperationType tOpType = theOperationType; OperationStatus tStatus = theStatus; if ((tOpType == UpdateRequest) || (tOpType == InsertRequest) || (tOpType == WriteRequest)) { if (tStatus != SetValue) { setErrorCodeAbort(4116); return -1; }//if } else if ((tOpType == ReadRequest) || (tOpType == ReadExclusive) || (tOpType == DeleteRequest)) { if (tStatus != GetValue) { setErrorCodeAbort(4116); return -1; } else if(unlikely(tDirtyIndicator && tTotalCurrAI_Len == 0)) { getValue(NdbDictionary::Column::FRAGMENT); tTotalCurrAI_Len = theTotalCurrAI_Len; assert(theTotalCurrAI_Len); } } else { setErrorCodeAbort(4005); return -1; }//if } else { if (prepareSendInterpreted() == -1) { return -1; }//if tTotalCurrAI_Len = theTotalCurrAI_Len; }//if //-------------------------------------------------------------// We start by filling in the first 9 unconditional words of the// TCKEYREQ signal.//------------------------------------------------------------- TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend()); Uint32 tTableId = m_currentTable->m_tableId; Uint32 tSchemaVersion = m_currentTable->m_version; tcKeyReq->apiConnectPtr = aTC_ConnectPtr; tcKeyReq->apiOperationPtr = ptr2int(); // Check if too much attrinfo have been defined if (tTotalCurrAI_Len > TcKeyReq::MaxTotalAttrInfo){ setErrorCodeAbort(4257); return -1; } Uint32 TattrLen = 0; tcKeyReq->setAttrinfoLen(TattrLen, tTotalCurrAI_Len); tcKeyReq->setAPIVersion(TattrLen, NDB_VERSION); tcKeyReq->attrLen = TattrLen; tcKeyReq->tableId = tTableId; tcKeyReq->tableSchemaVersion = tSchemaVersion; tTransId1 = (Uint32) aTransId; tTransId2 = (Uint32) (aTransId >> 32); Uint8 tSimpleIndicator = theSimpleIndicator; Uint8 tCommitIndicator = theCommitIndicator; Uint8 tStartIndicator = theStartIndicator; Uint8 tInterpretIndicator = theInterpretIndicator;//-------------------------------------------------------------// Simple state is set if start and commit is set and it is// a read request. Otherwise it is set to zero.//------------------------------------------------------------- Uint8 tReadInd = (theOperationType == ReadRequest); Uint8 tSimpleState = tReadInd & tSimpleIndicator; tcKeyReq->transId1 = tTransId1; tcKeyReq->transId2 = tTransId2; tReqInfo = 0; if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) { tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len); } else { tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo); }//if tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator); tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator); tcKeyReq->setStartFlag(tReqInfo, tStartIndicator); tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator); OperationType tOperationType = theOperationType; Uint32 tTupKeyLen = theTupKeyLen; Uint8 abortOption = m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption; tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator); tcKeyReq->setOperationType(tReqInfo, tOperationType); tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen); // A simple read is always ignore error abortOption = tSimpleIndicator ? AO_IgnoreError : abortOption; tcKeyReq->setAbortOption(tReqInfo, abortOption); Uint8 tDistrKeyIndicator = theDistrKeyIndicator_; Uint8 tScanIndicator = theScanInfo & 1; tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator); tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator); tcKeyReq->requestInfo = tReqInfo;//-------------------------------------------------------------// The next step is to fill in the upto three conditional words.//------------------------------------------------------------- Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo; Uint32 tDistrGHIndex = tScanIndicator; Uint32 tDistrKeyIndex = tDistrGHIndex; Uint32 tScanInfo = theScanInfo; Uint32 tDistrKey = theDistributionKey; tOptionalDataPtr[0] = tScanInfo; tOptionalDataPtr[tDistrKeyIndex] = tDistrKey;//-------------------------------------------------------------// The next is step is to compress the key data part of the// TCKEYREQ signal.//------------------------------------------------------------- Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator; Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex]; Uint32 Tdata1 = tcKeyReq->keyInfo[0]; Uint32 Tdata2 = tcKeyReq->keyInfo[1]; Uint32 Tdata3 = tcKeyReq->keyInfo[2]; Uint32 Tdata4 = tcKeyReq->keyInfo[3]; Uint32 Tdata5; tKeyDataPtr[0] = Tdata1; tKeyDataPtr[1] = Tdata2; tKeyDataPtr[2] = Tdata3; tKeyDataPtr[3] = Tdata4; if (tTupKeyLen > 4) { Tdata1 = tcKeyReq->keyInfo[4]; Tdata2 = tcKeyReq->keyInfo[5]; Tdata3 = tcKeyReq->keyInfo[6]; Tdata4 = tcKeyReq->keyInfo[7]; tKeyDataPtr[4] = Tdata1; tKeyDataPtr[5] = Tdata2; tKeyDataPtr[6] = Tdata3; tKeyDataPtr[7] = Tdata4; }//if//-------------------------------------------------------------// Finally we also compress the ATTRINFO part of the signal.// We optimise by using the if-statement for sending KEYINFO// signals to calculating the new Attrinfo Index.//------------------------------------------------------------- Uint32 tAttrInfoIndex; if (tTupKeyLen > TcKeyReq::MaxKeyInfo) { /** * Set transid, TC connect ptr and length in the KEYINFO signals */ NdbApiSignal* tSignal = theTCREQ->next(); Uint32 remainingKey = tTupKeyLen - TcKeyReq::MaxKeyInfo; do { Uint32* tSigDataPtr = tSignal->getDataPtrSend(); NdbApiSignal* tnextSignal = tSignal->next(); tSigDataPtr[0] = aTC_ConnectPtr; tSigDataPtr[1] = tTransId1; tSigDataPtr[2] = tTransId2; if (remainingKey > KeyInfo::DataLength) { // The signal is full tSignal->setLength(KeyInfo::MaxSignalLength); remainingKey -= KeyInfo::DataLength; } else { // Last signal tSignal->setLength(KeyInfo::HeaderLength + remainingKey); remainingKey = 0; } tSignal = tnextSignal; } while (tSignal != NULL); tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo; } else { tAttrInfoIndex = tKeyIndex + tTupKeyLen; }//if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -