dbtupexecquery.cpp
来自「这个文件是windows mysql源码」· C++ 代码 · 共 1,852 行 · 第 1/5 页
CPP
1,852 行
/* 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; version 2 of the License. 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 */#define DBTUP_C#include "Dbtup.hpp"#include <RefConvert.hpp>#include <ndb_limits.h>#include <pc.hpp>#include <AttributeDescriptor.hpp>#include "AttributeOffset.hpp"#include <AttributeHeader.hpp>#include <Interpreter.hpp>#include <signaldata/TupCommit.hpp>#include <signaldata/TupKey.hpp>#include <NdbSqlUtil.hpp>/* ----------------------------------------------------------------- *//* ----------- INIT_STORED_OPERATIONREC -------------- *//* ----------------------------------------------------------------- */int Dbtup::initStoredOperationrec(Operationrec* const regOperPtr, Uint32 storedId) { jam(); StoredProcPtr storedPtr; c_storedProcPool.getPtr(storedPtr, storedId); if (storedPtr.i != RNIL) { if (storedPtr.p->storedCode == ZSCAN_PROCEDURE) { storedPtr.p->storedCounter++; regOperPtr->firstAttrinbufrec = storedPtr.p->storedLinkFirst; regOperPtr->lastAttrinbufrec = storedPtr.p->storedLinkLast; regOperPtr->attrinbufLen = storedPtr.p->storedProcLength; regOperPtr->currentAttrinbufLen = storedPtr.p->storedProcLength; return ZOK; }//if }//if terrorCode = ZSTORED_PROC_ID_ERROR; return terrorCode;}//Dbtup::initStoredOperationrec()void Dbtup::copyAttrinfo(Signal* signal, Operationrec * const regOperPtr, Uint32* inBuffer){ AttrbufrecPtr copyAttrBufPtr; Uint32 RnoOfAttrBufrec = cnoOfAttrbufrec; int RbufLen; Uint32 RinBufIndex = 0; Uint32 Rnext; Uint32 Rfirst; Uint32 TstoredProcedure = (regOperPtr->storedProcedureId != ZNIL); Uint32 RnoFree = cnoFreeAttrbufrec;//-------------------------------------------------------------------------// As a prelude to the execution of the TUPKEYREQ we will copy the program// into the inBuffer to enable easy execution without any complex jumping// between the buffers. In particular this will make the interpreter less// complex. Hopefully it does also improve performance.//------------------------------------------------------------------------- copyAttrBufPtr.i = regOperPtr->firstAttrinbufrec; while (copyAttrBufPtr.i != RNIL) { jam(); ndbrequire(copyAttrBufPtr.i < RnoOfAttrBufrec); ptrAss(copyAttrBufPtr, attrbufrec); RbufLen = copyAttrBufPtr.p->attrbuf[ZBUF_DATA_LEN]; Rnext = copyAttrBufPtr.p->attrbuf[ZBUF_NEXT]; Rfirst = cfirstfreeAttrbufrec; /* * ATTRINFO comes from 2 mutually exclusive places: * 1) TUPKEYREQ (also interpreted part) * 2) STORED_PROCREQ before scan start * Assert here that both have a check for overflow. * The "<" instead of "<=" is intentional. */ ndbrequire(RinBufIndex + RbufLen < ZATTR_BUFFER_SIZE); MEMCOPY_NO_WORDS(&inBuffer[RinBufIndex], ©AttrBufPtr.p->attrbuf[0], RbufLen); RinBufIndex += RbufLen; if (!TstoredProcedure) { copyAttrBufPtr.p->attrbuf[ZBUF_NEXT] = Rfirst; cfirstfreeAttrbufrec = copyAttrBufPtr.i; RnoFree++; }//if copyAttrBufPtr.i = Rnext; }//while cnoFreeAttrbufrec = RnoFree; if (TstoredProcedure) { jam(); StoredProcPtr storedPtr; c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId); ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE); storedPtr.p->storedCounter--; regOperPtr->storedProcedureId = ZNIL; }//if // Release the ATTRINFO buffers regOperPtr->firstAttrinbufrec = RNIL; regOperPtr->lastAttrinbufrec = RNIL;}//Dbtup::copyAttrinfo()void Dbtup::handleATTRINFOforTUPKEYREQ(Signal* signal, Uint32 length, Operationrec * const regOperPtr) { AttrbufrecPtr TAttrinbufptr; TAttrinbufptr.i = cfirstfreeAttrbufrec; if ((cfirstfreeAttrbufrec < cnoOfAttrbufrec) && (cnoFreeAttrbufrec > MIN_ATTRBUF)) { ptrAss(TAttrinbufptr, attrbufrec); MEMCOPY_NO_WORDS(&TAttrinbufptr.p->attrbuf[0], &signal->theData[3], length); Uint32 RnoFree = cnoFreeAttrbufrec; Uint32 Rnext = TAttrinbufptr.p->attrbuf[ZBUF_NEXT]; TAttrinbufptr.p->attrbuf[ZBUF_DATA_LEN] = length; TAttrinbufptr.p->attrbuf[ZBUF_NEXT] = RNIL; AttrbufrecPtr locAttrinbufptr; Uint32 RnewLen = regOperPtr->currentAttrinbufLen; locAttrinbufptr.i = regOperPtr->lastAttrinbufrec; cfirstfreeAttrbufrec = Rnext; cnoFreeAttrbufrec = RnoFree - 1; RnewLen += length; regOperPtr->lastAttrinbufrec = TAttrinbufptr.i; regOperPtr->currentAttrinbufLen = RnewLen; if (locAttrinbufptr.i == RNIL) { regOperPtr->firstAttrinbufrec = TAttrinbufptr.i; return; } else { jam(); ptrCheckGuard(locAttrinbufptr, cnoOfAttrbufrec, attrbufrec); locAttrinbufptr.p->attrbuf[ZBUF_NEXT] = TAttrinbufptr.i; }//if if (RnewLen < ZATTR_BUFFER_SIZE) { return; } else { jam(); regOperPtr->transstate = TOO_MUCH_AI; return; }//if } else if (cnoFreeAttrbufrec <= MIN_ATTRBUF) { jam(); regOperPtr->transstate = ERROR_WAIT_TUPKEYREQ; } else { ndbrequire(false); }//if}//Dbtup::handleATTRINFOforTUPKEYREQ()void Dbtup::execATTRINFO(Signal* signal) { OperationrecPtr regOpPtr; Uint32 Rsig0 = signal->theData[0]; Uint32 Rlen = signal->length(); regOpPtr.i = Rsig0; jamEntry(); ptrCheckGuard(regOpPtr, cnoOfOprec, operationrec); if (regOpPtr.p->transstate == IDLE) { handleATTRINFOforTUPKEYREQ(signal, Rlen - 3, regOpPtr.p); return; } else if (regOpPtr.p->transstate == WAIT_STORED_PROCEDURE_ATTR_INFO) { storedProcedureAttrInfo(signal, regOpPtr.p, Rlen - 3, 3, false); return; }//if switch (regOpPtr.p->transstate) { case ERROR_WAIT_STORED_PROCREQ: jam(); case TOO_MUCH_AI: jam(); case ERROR_WAIT_TUPKEYREQ: jam(); return; /* IGNORE ATTRINFO IN THOSE STATES, WAITING FOR ABORT SIGNAL */ break; case DISCONNECTED: jam(); case STARTED: jam(); default: ndbrequire(false); }//switch}//Dbtup::execATTRINFO()void Dbtup::execTUP_ALLOCREQ(Signal* signal){ OperationrecPtr regOperPtr; TablerecPtr regTabPtr; FragrecordPtr regFragPtr; jamEntry(); regOperPtr.i = signal->theData[0]; regFragPtr.i = signal->theData[1]; regTabPtr.i = signal->theData[2]; if (!((regOperPtr.i < cnoOfOprec) && (regFragPtr.i < cnoOfFragrec) && (regTabPtr.i < cnoOfTablerec))) { ndbrequire(false); }//if ptrAss(regOperPtr, operationrec); ptrAss(regFragPtr, fragrecord); ptrAss(regTabPtr, tablerec);//---------------------------------------------------/* --- Allocate a tuple as requested by ACC --- *///--------------------------------------------------- PagePtr pagePtr; Uint32 pageOffset; if (ERROR_INSERTED(4025)) { signal->theData[0] = 827; return; } if (ERROR_INSERTED(4026)) { CLEAR_ERROR_INSERT_VALUE; signal->theData[0] = 827; return; } if (ERROR_INSERTED(4027) && (rand() % 100) > 25) { signal->theData[0] = 827; return; } if (ERROR_INSERTED(4028) && (rand() % 100) > 25) { CLEAR_ERROR_INSERT_VALUE; signal->theData[0] = 827; return; } if (!allocTh(regFragPtr.p, regTabPtr.p, NORMAL_PAGE, signal, pageOffset, pagePtr)) { signal->theData[0] = terrorCode; // Indicate failure return; }//if Uint32 fragPageId = pagePtr.p->pageWord[ZPAGE_FRAG_PAGE_ID_POS]; Uint32 pageIndex = ((pageOffset - ZPAGE_HEADER_SIZE) / regTabPtr.p->tupheadsize) << 1; regOperPtr.p->tableRef = regTabPtr.i; regOperPtr.p->fragId = regFragPtr.p->fragmentId; regOperPtr.p->realPageId = pagePtr.i; regOperPtr.p->fragPageId = fragPageId; regOperPtr.p->pageOffset = pageOffset; regOperPtr.p->pageIndex = pageIndex; /* -------------------------------------------------------------- */ /* AN INSERT IS UNDONE BY FREEING THE DATA OCCUPIED BY THE INSERT */ /* THE ONLY DATA WE HAVE TO LOG EXCEPT THE TYPE, PAGE AND INDEX */ /* IS THE AMOUNT OF DATA TO FREE */ /* -------------------------------------------------------------- */ if (isUndoLoggingNeeded(regFragPtr.p, fragPageId)) { jam(); cprAddUndoLogRecord(signal, ZLCPR_TYPE_DELETE_TH, fragPageId, pageIndex, regTabPtr.i, regFragPtr.p->fragmentId, regFragPtr.p->checkpointVersion); }//if //--------------------------------------------------------------- // Initialise Active operation list by setting the list to empty //--------------------------------------------------------------- ndbrequire(pageOffset < ZWORDS_ON_PAGE); pagePtr.p->pageWord[pageOffset] = RNIL; signal->theData[0] = 0; signal->theData[1] = fragPageId; signal->theData[2] = pageIndex;}//Dbtup::execTUP_ALLOCREQ()voidDbtup::setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize){ // 2 == regTabPtr.p->tupChecksumIndex pagePtr->pageWord[tupHeadOffset + 2] = 0; Uint32 checksum = calculateChecksum(pagePtr, tupHeadOffset, tupHeadSize); pagePtr->pageWord[tupHeadOffset + 2] = checksum;}//Dbtup::setChecksum()Uint32Dbtup::calculateChecksum(Page* pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize){ Uint32 checksum = 0; Uint32 loopStop = tupHeadOffset + tupHeadSize; ndbrequire(loopStop <= ZWORDS_ON_PAGE); // includes tupVersion for (Uint32 i = tupHeadOffset + 1; i < loopStop; i++) { checksum ^= pagePtr->pageWord[i]; }//if return checksum;}//Dbtup::calculateChecksum()/* ----------------------------------------------------------------- *//* ----------- INSERT_ACTIVE_OP_LIST -------------- *//* ----------------------------------------------------------------- */void Dbtup::insertActiveOpList(Signal* signal, OperationrecPtr regOperPtr, Page* const pagePtr, Uint32 pageOffset) { OperationrecPtr iaoPrevOpPtr; ndbrequire(regOperPtr.p->inActiveOpList == ZFALSE); regOperPtr.p->inActiveOpList = ZTRUE; ndbrequire(pageOffset < ZWORDS_ON_PAGE); iaoPrevOpPtr.i = pagePtr->pageWord[pageOffset]; pagePtr->pageWord[pageOffset] = regOperPtr.i; regOperPtr.p->prevActiveOp = RNIL; regOperPtr.p->nextActiveOp = iaoPrevOpPtr.i; if (iaoPrevOpPtr.i == RNIL) { return; } else { jam(); ptrCheckGuard(iaoPrevOpPtr, cnoOfOprec, operationrec); iaoPrevOpPtr.p->prevActiveOp = regOperPtr.i; if (iaoPrevOpPtr.p->optype == ZDELETE && regOperPtr.p->optype == ZINSERT) { jam(); // mark both iaoPrevOpPtr.p->deleteInsertFlag = 1; regOperPtr.p->deleteInsertFlag = 1; } return; }//if}//Dbtup::insertActiveOpList()void Dbtup::linkOpIntoFragList(OperationrecPtr regOperPtr, Fragrecord* const regFragPtr) { OperationrecPtr sopTmpOperPtr; Uint32 tail = regFragPtr->lastusedOprec; ndbrequire(regOperPtr.p->inFragList == ZFALSE); regOperPtr.p->inFragList = ZTRUE; regOperPtr.p->prevOprecInList = tail; regOperPtr.p->nextOprecInList = RNIL; sopTmpOperPtr.i = tail; if (tail == RNIL) { regFragPtr->firstusedOprec = regOperPtr.i; } else { jam(); ptrCheckGuard(sopTmpOperPtr, cnoOfOprec, operationrec); sopTmpOperPtr.p->nextOprecInList = regOperPtr.i; }//if regFragPtr->lastusedOprec = regOperPtr.i;}//Dbtup::linkOpIntoFragList()/*This routine is optimised for use from TUPKEYREQ.This means that a lot of input data is stored in the operation record.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?