📄 ndboperationsearch.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 *//******************************************************************************Name: NdbOperationSearch.CInclude:Link:Author: UABMNST Mona Natterkvist UAB/B/SD Date: 970829Version: 0.1Description: Interface between TIS and NDBDocumentation:Adjust: 971022 UABMNST First version. 971206 UABRONM *****************************************************************************/#include "API.hpp"#include <NdbOperation.hpp>#include "NdbApiSignal.hpp"#include <NdbTransaction.hpp>#include <Ndb.hpp>#include "NdbImpl.hpp"#include <NdbOut.hpp>#include <AttributeHeader.hpp>#include <signaldata/TcKeyReq.hpp>#include <signaldata/KeyInfo.hpp>#include "NdbDictionaryImpl.hpp"#include <md5_hash.hpp>/******************************************************************************CondIdType equal(const char* anAttrName, char* aValue, Uint32 aVarKeylen);Return Value Return 0 : Equal was successful. Return -1: In all other case. Parameters: anAttrName : Attribute name for search condition.. aValue : Referense to the search value. aVariableKeylen : The length of key in bytes Remark: Defines search condition with equality anAttrName.******************************************************************************/intNdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, const char* aValuePassed, Uint32 aVariableKeyLen){ DBUG_ENTER("NdbOperation::equal_impl"); DBUG_PRINT("enter", ("col=%s op=%d val=0x%x len=%u", tAttrInfo->m_name.c_str(), theOperationType, aValuePassed, aVariableKeyLen)); if (aValuePassed != NULL) DBUG_DUMP("value", (char*)aValuePassed, aVariableKeyLen); register Uint32 tAttrId; Uint32 tData; Uint32 tKeyInfoPosition; const char* aValue = aValuePassed; Uint64 tempData[512]; if ((theStatus == OperationDefined) && (aValue != NULL) && (tAttrInfo != NULL )) {/****************************************************************************** * Start by checking that the attribute is a tuple key. * This value is also the word order in the tuple key of this * tuple key attribute. * Then check that this tuple key has not already been defined. * Finally check if all tuple key attributes have been defined. If * this is true then set Operation state to tuple key defined. *****************************************************************************/ tAttrId = tAttrInfo->m_attrId; tKeyInfoPosition = tAttrInfo->m_keyInfoPos; bool tDistrKey = tAttrInfo->m_distributionKey; Uint32 i = 0; if (tAttrInfo->m_pk) { Uint32 tKeyDefined = theTupleKeyDefined[0][2]; Uint32 tKeyAttrId = theTupleKeyDefined[0][0]; do { if (tKeyDefined == false) { goto keyEntryFound; } else { if (tKeyAttrId != tAttrId) { /****************************************************************** * We read the key defined variable in advance. * It could potentially read outside its area when * i = MAXNROFTUPLEKEY - 1, * it is not a problem as long as the variable * theTupleKeyDefined is defined * in the middle of the object. * Reading wrong data and not using it causes no problems. *****************************************************************/ i++; tKeyAttrId = theTupleKeyDefined[i][0]; tKeyDefined = theTupleKeyDefined[i][2]; continue; } else { goto equal_error2; }//if }//if } while (i < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY); goto equal_error2; } else { goto equal_error1; } /************************************************************************* * Now it is time to retrieve the tuple key data from the pointer supplied * by the application. * We have to retrieve the size of the attribute in words and bits. *************************************************************************/ keyEntryFound: theTupleKeyDefined[i][0] = tAttrId; theTupleKeyDefined[i][1] = tKeyInfoPosition; theTupleKeyDefined[i][2] = true; OperationType tOpType = theOperationType; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; { /************************************************************************ * Check if the pointer of the value passed is aligned on a 4 byte * boundary. If so only assign the pointer to the internal variable * aValue. If it is not aligned then we start by copying the value to * tempData and use this as aValue instead. ***********************************************************************/ const int attributeSize = sizeInBytes; const int slack = sizeInBytes & 3; const int align = UintPtr(aValue) & 7; if (((align & 3) != 0) || (slack != 0) || (tDistrKey && (align != 0))) { ((Uint32*)tempData)[attributeSize >> 2] = 0; memcpy(&tempData[0], aValue, attributeSize); aValue = (char*)&tempData[0]; }//if } Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word if (true){ //tArraySize != 0) { Uint32 tTupKeyLen = theTupKeyLen; theTupKeyLen = tTupKeyLen + totalSizeInWords; if ((aVariableKeyLen == sizeInBytes) || (aVariableKeyLen == 0)) { ; } else { goto equal_error3; } }#if 0 else { /************************************************************************ * The attribute is a variable array. We need to use the length parameter * to know the size of this attribute in the key information and * variable area. A key is however not allowed to be larger than 4 * kBytes and this is checked for variable array attributes * used as keys. ************************************************************************/ Uint32 tMaxVariableKeyLenInWord = (MAXTUPLEKEYLENOFATTERIBUTEINWORD - tKeyInfoPosition); tAttrSizeInBits = aVariableKeyLen << 3; tAttrSizeInWords = tAttrSizeInBits >> 5; tAttrBitsInLastWord = tAttrSizeInBits - (tAttrSizeInWords << 5); tAttrLenInWords = ((tAttrSizeInBits + 31) >> 5); if (tAttrLenInWords > tMaxVariableKeyLenInWord) { setErrorCodeAbort(4207); return -1; }//if theTupKeyLen = theTupKeyLen + tAttrLenInWords; }//if#endif /************************************************************************** * If the operation is an insert request and the attribute is stored then * we also set the value in the stored part through putting the * information in the ATTRINFO signals. *************************************************************************/ if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { Uint32 ahValue; const Uint32 sz = totalSizeInWords; // XXX if(m_accessTable == m_currentTable) { AttributeHeader::init(&ahValue, tAttrId, sz); } else { assert(m_accessTable->m_index); int attr_id_current_table = m_accessTable->m_index->m_columns[tAttrId]->m_keyInfoPos; AttributeHeader::init(&ahValue, attr_id_current_table, sz); } insertATTRINFO( ahValue ); insertATTRINFOloop((Uint32*)aValue, sz); }//if /************************************************************************** * Store the Key information in the TCKEYREQ and KEYINFO signals. *************************************************************************/ if (insertKEYINFO(aValue, tKeyInfoPosition, totalSizeInWords) != -1) { /************************************************************************ * Add one to number of tuple key attributes defined. * If all have been defined then set the operation state to indicate * that tuple key is defined. * Thereby no more search conditions are allowed in this version. ***********************************************************************/ Uint32 tNoKeysDef = theNoOfTupKeyLeft - 1; Uint32 tErrorLine = theErrorLine; unsigned char tInterpretInd = theInterpretIndicator; theNoOfTupKeyLeft = tNoKeysDef; tErrorLine++; theErrorLine = tErrorLine; if (tNoKeysDef == 0) { if (tOpType == UpdateRequest) { if (tInterpretInd == 1) { theStatus = GetValue; } else { theStatus = SetValue; }//if DBUG_RETURN(0); } else if ((tOpType == ReadRequest) || (tOpType == DeleteRequest) || (tOpType == ReadExclusive)) { theStatus = GetValue; // create blob handles automatically if (tOpType == DeleteRequest && m_currentTable->m_noOfBlobs != 0) { for (unsigned i = 0; i < m_currentTable->m_columns.size(); i++) { NdbColumnImpl* c = m_currentTable->m_columns[i]; assert(c != 0); if (c->getBlobType()) { if (getBlobHandle(theNdbCon, c) == NULL) DBUG_RETURN(-1); } } } DBUG_RETURN(0); } else if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { theStatus = SetValue; DBUG_RETURN(0); } else { setErrorCodeAbort(4005); DBUG_RETURN(-1); }//if DBUG_RETURN(0); }//if } else { DBUG_RETURN(-1); }//if DBUG_RETURN(0); } if (aValue == NULL) { // NULL value in primary key setErrorCodeAbort(4505); DBUG_RETURN(-1); }//if if ( tAttrInfo == NULL ) { // Attribute name not found in table setErrorCodeAbort(4004); DBUG_RETURN(-1); }//if if (theStatus == GetValue || theStatus == SetValue){ // All pk's defined setErrorCodeAbort(4225); DBUG_RETURN(-1); }//if ndbout_c("theStatus: %d", theStatus); // If we come here, set a general errorcode // and exit setErrorCodeAbort(4200); DBUG_RETURN(-1); equal_error1: setErrorCodeAbort(4205);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -