diff options
Diffstat (limited to 'ndb/src/ndbapi')
39 files changed, 2201 insertions, 2543 deletions
diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index 1fe0cedbd6c..71938e27037 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -260,6 +260,7 @@ ClusterMgr::Node::Node() : m_state(NodeState::SL_NOTHING) { compatible = nfCompleteRep = true; connected = defined = m_alive = false; + m_state.m_connected_nodes.clear(); } /****************************************************************************** @@ -410,7 +411,13 @@ ClusterMgr::reportConnected(NodeId nodeId){ theNode.connected = true; theNode.hbSent = 0; theNode.hbCounter = 0; - + + /** + * make sure the node itself is marked connected even + * if first API_REGCONF has not arrived + */ + theNode.m_state.m_connected_nodes.set(nodeId); + if (theNode.m_info.m_type != NodeInfo::REP) { theNode.hbFrequency = 0; } @@ -428,7 +435,9 @@ ClusterMgr::reportDisconnected(NodeId nodeId){ noOfConnectedNodes--; theNodes[nodeId].connected = false; - theNodes[nodeId].m_info.m_connectCount ++; + + theNodes[nodeId].m_state.m_connected_nodes.clear(); + reportNodeFailed(nodeId); } @@ -438,18 +447,22 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ Node & theNode = theNodes[nodeId]; theNode.m_alive = false; + theNode.m_info.m_connectCount ++; + if(theNode.connected) + { theFacade.doDisconnect(nodeId); - + } const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING); theNode.m_state.startLevel = NodeState::SL_NOTHING; - if(report){ + if(report) + { theFacade.ReportNodeDead(nodeId); - } - + } + theNode.nfCompleteRep = false; - + if(noOfConnectedNodes == 0){ NFCompleteRep rep; for(Uint32 i = 1; i<MAX_NODES; i++){ diff --git a/ndb/src/ndbapi/Makefile.am b/ndb/src/ndbapi/Makefile.am index 9f8a851b995..b734e058b87 100644 --- a/ndb/src/ndbapi/Makefile.am +++ b/ndb/src/ndbapi/Makefile.am @@ -14,15 +14,14 @@ libndbapi_la_SOURCES = \ Ndberr.cpp \ ndberror.c \ NdbErrorOut.cpp \ - NdbConnection.cpp \ - NdbConnectionScan.cpp \ + NdbTransaction.cpp \ + NdbTransactionScan.cpp \ NdbOperation.cpp \ NdbOperationSearch.cpp \ NdbOperationScan.cpp \ NdbOperationInt.cpp \ NdbOperationDefine.cpp \ NdbOperationExec.cpp \ - NdbResultSet.cpp \ NdbScanOperation.cpp NdbScanFilter.cpp \ NdbIndexOperation.cpp \ NdbEventOperation.cpp \ diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index b5493622b70..b047ae1bd1a 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -27,7 +27,7 @@ Name: Ndb.cpp #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbEventOperation.hpp> #include <NdbRecAttr.hpp> #include <md5_hash.hpp> @@ -43,11 +43,13 @@ void connect(); Connect to any node which has no connection at the moment. ****************************************************************************/ -NdbConnection* Ndb::doConnect(Uint32 tConNode) +NdbTransaction* Ndb::doConnect(Uint32 tConNode) { Uint32 tNode; Uint32 tAnyAlive = 0; - int TretCode; + int TretCode= 0; + + DBUG_ENTER("Ndb::doConnect"); if (tConNode != 0) { TretCode = NDB_connect(tConNode); @@ -55,7 +57,7 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tConNode); + DBUG_RETURN(getConnectedNdbTransaction(tConNode)); } else if (TretCode != 0) { tAnyAlive = 1; }//if @@ -78,10 +80,13 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tNode); + DBUG_RETURN(getConnectedNdbTransaction(tNode)); } else if (TretCode != 0) { tAnyAlive= 1; }//if + DBUG_PRINT("info",("tried node %d, TretCode %d, error code %d, %s", + tNode, TretCode, getNdbError().code, + getNdbError().message)); } } else // just do a regular round robin @@ -103,10 +108,11 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tNode); + DBUG_RETURN(getConnectedNdbTransaction(tNode)); } else if (TretCode != 0) { tAnyAlive= 1; }//if + DBUG_PRINT("info",("tried node %d TretCode %d", tNode, TretCode)); } while (Tcount < tNoOfDbNodes); } //**************************************************************************** @@ -121,7 +127,7 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) } else { theError.code = 4009; }//if - return NULL; + DBUG_RETURN(NULL); } int @@ -134,36 +140,38 @@ Ndb::NDB_connect(Uint32 tNode) int tReturnCode; TransporterFacade *tp = TransporterFacade::instance(); + DBUG_ENTER("Ndb::NDB_connect"); + bool nodeAvail = tp->get_node_alive(tNode); if(nodeAvail == false){ - return 0; + DBUG_RETURN(0); } - NdbConnection * tConArray = theConnectionArray[tNode]; + NdbTransaction * tConArray = theConnectionArray[tNode]; if (tConArray != NULL) { - return 2; + DBUG_RETURN(2); } - NdbConnection * tNdbCon = getNdbCon(); // Get free connection object. + NdbTransaction * tNdbCon = getNdbCon(); // Get free connection object. if (tNdbCon == NULL) { - return 4; + DBUG_RETURN(4); }//if NdbApiSignal* tSignal = getSignal(); // Get signal object if (tSignal == NULL) { releaseNdbCon(tNdbCon); - return 4; + DBUG_RETURN(4); }//if if (tSignal->setSignal(GSN_TCSEIZEREQ) == -1) { releaseNdbCon(tNdbCon); releaseSignal(tSignal); - return 4; + DBUG_RETURN(4); }//if tSignal->setData(tNdbCon->ptr2int(), 1); //************************************************ -// Set connection pointer as NdbConnection object +// Set connection pointer as NdbTransaction object //************************************************ tSignal->setData(theMyRef, 2); // Set my block reference - tNdbCon->Status(NdbConnection::Connecting); // Set status to connecting + tNdbCon->Status(NdbTransaction::Connecting); // Set status to connecting Uint32 nodeSequence; { // send and receive signal Guard guard(tp->theMutexPtr); @@ -182,34 +190,37 @@ Ndb::NDB_connect(Uint32 tNode) tReturnCode = -1; }//if } - if ((tReturnCode == 0) && (tNdbCon->Status() == NdbConnection::Connected)) { + if ((tReturnCode == 0) && (tNdbCon->Status() == NdbTransaction::Connected)) { //************************************************ // Send and receive was successful //************************************************ - NdbConnection* tPrevFirst = theConnectionArray[tNode]; + NdbTransaction* tPrevFirst = theConnectionArray[tNode]; tNdbCon->setConnectedNodeId(tNode, nodeSequence); tNdbCon->setMyBlockReference(theMyRef); theConnectionArray[tNode] = tNdbCon; tNdbCon->theNext = tPrevFirst; - return 1; + DBUG_RETURN(1); } else { releaseNdbCon(tNdbCon); //**************************************************************************** // Unsuccessful connect is indicated by 3. //**************************************************************************** - return 3; + DBUG_PRINT("info", + ("unsuccessful connect tReturnCode %d, tNdbCon->Status() %d", + tReturnCode, tNdbCon->Status())); + DBUG_RETURN(3); }//if }//Ndb::NDB_connect() -NdbConnection * -Ndb::getConnectedNdbConnection(Uint32 nodeId){ - NdbConnection* next = theConnectionArray[nodeId]; +NdbTransaction * +Ndb::getConnectedNdbTransaction(Uint32 nodeId){ + NdbTransaction* next = theConnectionArray[nodeId]; theConnectionArray[nodeId] = next->theNext; next->theNext = NULL; return next; -}//Ndb::getConnectedNdbConnection() +}//Ndb::getConnectedNdbTransaction() /***************************************************************************** disconnect(); @@ -220,7 +231,7 @@ void Ndb::doDisconnect() { DBUG_ENTER("Ndb::doDisconnect"); - NdbConnection* tNdbCon; + NdbTransaction* tNdbCon; CHECK_STATUS_MACRO_VOID; Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes; @@ -231,14 +242,14 @@ Ndb::doDisconnect() Uint32 tNode = theDBnodes[i]; tNdbCon = theConnectionArray[tNode]; while (tNdbCon != NULL) { - NdbConnection* tmpNdbCon = tNdbCon; + NdbTransaction* tmpNdbCon = tNdbCon; tNdbCon = tNdbCon->theNext; releaseConnectToNdb(tmpNdbCon); }//while }//for tNdbCon = theTransactionList; while (tNdbCon != NULL) { - NdbConnection* tmpNdbCon = tNdbCon; + NdbTransaction* tmpNdbCon = tNdbCon; tNdbCon = tNdbCon->theNext; releaseConnectToNdb(tmpNdbCon); }//while @@ -292,34 +303,58 @@ Ndb::waitUntilReady(int timeout) } /***************************************************************************** -NdbConnection* startTransaction(); +NdbTransaction* startTransaction(); Return Value: Returns a pointer to a connection object. Return NULL otherwise. Remark: Start transaction. Synchronous. *****************************************************************************/ -NdbConnection* -Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) +NdbTransaction* +Ndb::startTransaction(const NdbDictionary::Table *table, + const char * keyData, Uint32 keyLen) { DBUG_ENTER("Ndb::startTransaction"); if (theInitState == Initialised) { theError.code = 0; checkFailedNode(); - /** - * If the user supplied key data - * We will make a qualified quess to which node is the primary for the - * the fragment and contact that node - */ + /** + * If the user supplied key data + * We will make a qualified quess to which node is the primary for the + * the fragment and contact that node + */ Uint32 nodeId; - if(keyData != 0) { - nodeId = 0; // guess not supported - // nodeId = m_ndb_cluster_connection->guess_primary_node(keyData, keyLen); + NdbTableImpl* impl; + if(table != 0 && keyData != 0 && (impl= &NdbTableImpl::getImpl(*table))) + { + Uint32 hashValue; + { + Uint32 buf[4]; + if((UintPtr(keyData) & 7) == 0 && (keyLen & 3) == 0) + { + md5_hash(buf, (const Uint64*)keyData, keyLen >> 2); + } + else + { + Uint64 tmp[1000]; + tmp[keyLen/8] = 0; + memcpy(tmp, keyData, keyLen); + md5_hash(buf, tmp, (keyLen+3) >> 2); + } + hashValue= buf[1]; + } + const Uint16 *nodes; + Uint32 cnt= impl->get_nodes(hashValue, &nodes); + if(cnt) + nodeId= nodes[0]; + else + nodeId= 0; } else { nodeId = 0; }//if + { - NdbConnection *trans= startTransactionLocal(aPriority, nodeId); + NdbTransaction *trans= startTransactionLocal(0, nodeId); DBUG_PRINT("exit",("start trans: 0x%x transid: 0x%llx", trans, trans ? trans->getTransactionId() : 0)); DBUG_RETURN(trans); @@ -330,15 +365,15 @@ Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) }//Ndb::startTransaction() /***************************************************************************** -NdbConnection* hupp(NdbConnection* pBuddyTrans); +NdbTransaction* hupp(NdbTransaction* pBuddyTrans); Return Value: Returns a pointer to a connection object. Connected to the same node as pBuddyTrans and also using the same transction id Remark: Start transaction. Synchronous. *****************************************************************************/ -NdbConnection* -Ndb::hupp(NdbConnection* pBuddyTrans) +NdbTransaction* +Ndb::hupp(NdbTransaction* pBuddyTrans) { DBUG_ENTER("Ndb::hupp"); @@ -354,7 +389,7 @@ Ndb::hupp(NdbConnection* pBuddyTrans) checkFailedNode(); Uint32 nodeId = pBuddyTrans->getConnectedNodeId(); - NdbConnection* pCon = startTransactionLocal(aPriority, nodeId); + NdbTransaction* pCon = startTransactionLocal(aPriority, nodeId); if(pCon == NULL) DBUG_RETURN(NULL); @@ -375,8 +410,7 @@ Ndb::hupp(NdbConnection* pBuddyTrans) }//if }//Ndb::hupp() - -NdbConnection* +NdbTransaction* Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) { #ifdef VM_TRACE @@ -390,13 +424,13 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) DBUG_ENTER("Ndb::startTransactionLocal"); DBUG_PRINT("enter", ("nodeid: %d", nodeId)); - NdbConnection* tConnection; + NdbTransaction* tConnection; Uint64 tFirstTransId = theFirstTransId; tConnection = doConnect(nodeId); if (tConnection == NULL) { DBUG_RETURN(NULL); }//if - NdbConnection* tConNext = theTransactionList; + NdbTransaction* tConNext = theTransactionList; tConnection->init(); theTransactionList = tConnection; // into a transaction list. tConnection->next(tConNext); // Add the active connection object @@ -412,7 +446,7 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) theFirstTransId = tFirstTransId + 1; }//if #ifdef VM_TRACE - if (tConnection->theListState != NdbConnection::NotInList) { + if (tConnection->theListState != NdbTransaction::NotInList) { printState("startTransactionLocal %x", tConnection); abort(); } @@ -421,17 +455,17 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) }//Ndb::startTransactionLocal() /***************************************************************************** -void closeTransaction(NdbConnection* aConnection); +void closeTransaction(NdbTransaction* aConnection); Parameters: aConnection: the connection used in the transaction. Remark: Close transaction by releasing the connection and all operations. *****************************************************************************/ void -Ndb::closeTransaction(NdbConnection* aConnection) +Ndb::closeTransaction(NdbTransaction* aConnection) { DBUG_ENTER("Ndb::closeTransaction"); - NdbConnection* tCon; - NdbConnection* tPreviousCon; + NdbTransaction* tCon; + NdbTransaction* tPreviousCon; if (aConnection == NULL) { //----------------------------------------------------- @@ -464,12 +498,12 @@ Ndb::closeTransaction(NdbConnection* aConnection) if(aConnection->theError.code == 4008){ /** - * When a SCAN timed-out, returning the NdbConnection leads + * When a SCAN timed-out, returning the NdbTransaction leads * to reuse. And TC crashes when the API tries to reuse it to * something else... */ #ifdef VM_TRACE - printf("Scan timeout:ed NdbConnection-> " + printf("Scan timeout:ed NdbTransaction-> " "not returning it-> memory leak\n"); #endif DBUG_VOID_RETURN; @@ -491,12 +525,12 @@ Ndb::closeTransaction(NdbConnection* aConnection) if(aConnection->theError.code == 4008){ /** - * Something timed-out, returning the NdbConnection leads + * Something timed-out, returning the NdbTransaction leads * to reuse. And TC crashes when the API tries to reuse it to * something else... */ #ifdef VM_TRACE - printf("Con timeout:ed NdbConnection-> not returning it-> memory leak\n"); + printf("Con timeout:ed NdbTransaction-> not returning it-> memory leak\n"); #endif DBUG_VOID_RETURN; } @@ -535,7 +569,7 @@ Remark: Sends a signal to DIH. int Ndb::NdbTamper(TamperType aAction, int aNode) { - NdbConnection* tNdbConn; + NdbTransaction* tNdbConn; NdbApiSignal tSignal(theMyRef); int tNode; int tAction; @@ -577,7 +611,7 @@ Ndb::NdbTamper(TamperType aAction, int aNode) tSignal.setData (tAction, 1); tSignal.setData(tNdbConn->ptr2int(),2); tSignal.setData(theMyRef,3); // Set return block reference - tNdbConn->Status(NdbConnection::Connecting); // Set status to connecting + tNdbConn->Status(NdbTransaction::Connecting); // Set status to connecting TransporterFacade *tp = TransporterFacade::instance(); if (tAction == 3) { tp->lock_mutex(); @@ -610,7 +644,7 @@ Ndb::NdbTamper(TamperType aAction, int aNode) }//if ret_code = sendRecSignal(tNode, WAIT_NDB_TAMPER, &tSignal, 0); if (ret_code == 0) { - if (tNdbConn->Status() != NdbConnection::Connected) { + if (tNdbConn->Status() != NdbTransaction::Connected) { theRestartGCI = 0; }//if releaseNdbCon(tNdbConn); @@ -865,10 +899,11 @@ Ndb::setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase ) Uint64 Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) { - DEBUG_TRACE("opTupleIdOnNdb"); + DBUG_ENTER("Ndb::opTupleIdOnNdb"); + DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op)); - NdbConnection* tConnection; - NdbOperation* tOperation; + NdbTransaction* tConnection; + NdbOperation* tOperation= 0; // Compiler warning if not initialized Uint64 tValue; NdbRecAttr* tRecAttrResult; int result; @@ -961,7 +996,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) setDatabaseName(currentDb.c_str()); setDatabaseSchemaName(currentSchema.c_str()); - return ret; + DBUG_RETURN(ret); error_handler: theError.code = tConnection->theError.code; @@ -971,7 +1006,11 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) setDatabaseName(currentDb.c_str()); setDatabaseSchemaName(currentSchema.c_str()); - return ~0; + DBUG_PRINT("error", ("ndb=%d con=%d op=%d", + theError.code, + tConnection ? tConnection->theError.code : -1, + tOperation ? tOperation->theError.code : -1)); + DBUG_RETURN(~0); } Uint32 @@ -1173,7 +1212,14 @@ NdbEventOperation* Ndb::createEventOperation(const char* eventName, tOp = new NdbEventOperation(this, eventName, bufferLength); - if (tOp->getState() != NdbEventOperation::CREATED) { + if (tOp == 0) + { + theError.code= 4000; + return NULL; + } + + if (tOp->getState() != NdbEventOperation::EO_CREATED) { + theError.code= tOp->getNdbError().code; delete tOp; tOp = NULL; } @@ -1209,7 +1255,7 @@ Ndb::pollEvents(int aMillisecondNumber) extern NdbMutex *ndb_print_state_mutex; static bool -checkdups(NdbConnection** list, unsigned no) +checkdups(NdbTransaction** list, unsigned no) { for (unsigned i = 0; i < no; i++) for (unsigned j = i + 1; j < no; j++) @@ -1234,7 +1280,7 @@ Ndb::printState(const char* fmt, ...) #endif ndbout << endl; for (unsigned n = 0; n < MAX_NDB_NODES; n++) { - NdbConnection* con = theConnectionArray[n]; + NdbTransaction* con = theConnectionArray[n]; if (con != 0) { ndbout << "conn " << n << ":" << endl; while (con != 0) { diff --git a/ndb/src/ndbapi/NdbApiSignal.cpp b/ndb/src/ndbapi/NdbApiSignal.cpp index a1d34896968..b1671e593e1 100644 --- a/ndb/src/ndbapi/NdbApiSignal.cpp +++ b/ndb/src/ndbapi/NdbApiSignal.cpp @@ -213,7 +213,7 @@ NdbApiSignal::setSignal(int aNdbSignalType) theTrace = TestOrd::TraceAPI; theReceiversBlockNumber = DBTC; theVerId_signalNumber = GSN_TCINDXREQ; - theLength = TcIndxReq::SignalLength; + theLength = TcKeyReq::SignalLength; } break; diff --git a/ndb/src/ndbapi/NdbApiSignal.hpp b/ndb/src/ndbapi/NdbApiSignal.hpp index 52c3be2256c..353c575d420 100644 --- a/ndb/src/ndbapi/NdbApiSignal.hpp +++ b/ndb/src/ndbapi/NdbApiSignal.hpp @@ -93,7 +93,7 @@ private: void setDataPtr(Uint32 *); - friend class NdbConnection; + friend class NdbTransaction; friend class NdbScanReceiver; friend class Table; void copyFrom(const NdbApiSignal * src); diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index f72361b86ac..0638f6e4c51 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -16,7 +16,7 @@ #include <Ndb.hpp> #include <NdbDictionaryImpl.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbIndexOperation.hpp> #include <NdbRecAttr.hpp> @@ -100,8 +100,8 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm bt.setFragmentType(t->getFragmentType()); { NdbDictionary::Column bc("PK"); bc.setType(NdbDictionary::Column::Unsigned); - assert(t->m_sizeOfKeysInWords != 0); - bc.setLength(t->m_sizeOfKeysInWords); + assert(t->m_keyLenInWords != 0); + bc.setLength(t->m_keyLenInWords); bc.setPrimaryKey(true); bc.setDistributionKey(true); bt.addColumn(bc); @@ -347,7 +347,7 @@ int NdbBlob::setTableKeyValue(NdbOperation* anOp) { const Uint32* data = (const Uint32*)theKeyBuf.data; - DBG("setTableKeyValue key=" << ndb_blob_debug(data, theTable->m_sizeOfKeysInWords)); + DBG("setTableKeyValue key=" << ndb_blob_debug(data, theTable->m_keyLenInWords)); const unsigned columns = theTable->m_columns.size(); unsigned pos = 0; for (unsigned i = 0; i < columns; i++) { @@ -370,7 +370,7 @@ int NdbBlob::setAccessKeyValue(NdbOperation* anOp) { const Uint32* data = (const Uint32*)theAccessKeyBuf.data; - DBG("setAccessKeyValue key=" << ndb_blob_debug(data, theAccessTable->m_sizeOfKeysInWords)); + DBG("setAccessKeyValue key=" << ndb_blob_debug(data, theAccessTable->m_keyLenInWords)); const unsigned columns = theAccessTable->m_columns.size(); unsigned pos = 0; for (unsigned i = 0; i < columns; i++) { @@ -393,7 +393,7 @@ int NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part) { Uint32* data = (Uint32*)theKeyBuf.data; - unsigned size = theTable->m_sizeOfKeysInWords; + unsigned size = theTable->m_keyLenInWords; DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size)); // TODO use attr ids after compatibility with 4.1.7 not needed if (anOp->equal("PK", theKeyBuf.data) == -1 || @@ -875,7 +875,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::ReadRequest); @@ -898,7 +898,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::InsertRequest); @@ -921,7 +921,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::UpdateRequest); @@ -943,7 +943,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; n++; thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); @@ -976,11 +976,11 @@ NdbBlob::deletePartsUnknown(Uint32 part) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption= NdbTransaction::AO_IgnoreError; n++; } DBG("deletePartsUnknown: executeNoBlobs [in] bat=" << bat); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("deletePartsUnknown: executeNoBlobs [out]"); n = 0; @@ -1012,7 +1012,7 @@ NdbBlob::executePendingBlobReads() Uint8 flags = (1 << NdbOperation::ReadRequest); if (thePendingBlobOps & flags) { DBG("executePendingBlobReads: executeNoBlobs [in]"); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("executePendingBlobReads: executeNoBlobs [out]"); thePendingBlobOps = 0; @@ -1027,7 +1027,7 @@ NdbBlob::executePendingBlobWrites() Uint8 flags = 0xFF & ~(1 << NdbOperation::ReadRequest); if (thePendingBlobOps & flags) { DBG("executePendingBlobWrites: executeNoBlobs [in]"); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("executePendingBlobWrites: executeNoBlobs [out]"); thePendingBlobOps = 0; @@ -1060,7 +1060,7 @@ NdbBlob::invokeActiveHook() * data. For read operation adds read of head+inline. */ int -NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn) +NdbBlob::atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn) { assert(theState == Idle); // ndb api stuff @@ -1106,8 +1106,8 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* theBlobTable = &NdbTableImpl::getImpl(*bt); } // buffers - theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2); - theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2); + theKeyBuf.alloc(theTable->m_keyLenInWords << 2); + theAccessKeyBuf.alloc(theAccessTable->m_keyLenInWords << 2); theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize); theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize); thePartBuf.alloc(thePartSize); @@ -1119,7 +1119,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* if (isTableOp()) { // get table key Uint32* data = (Uint32*)theKeyBuf.data; - unsigned size = theTable->m_sizeOfKeysInWords; + unsigned size = theTable->m_keyLenInWords; if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { setErrorCode(NdbBlobImpl::ErrUsage); return -1; @@ -1128,7 +1128,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* if (isIndexOp()) { // get index key Uint32* data = (Uint32*)theAccessKeyBuf.data; - unsigned size = theAccessTable->m_sizeOfKeysInWords; + unsigned size = theAccessTable->m_keyLenInWords; if (theNdbOp->getKeyFromTCREQ(data, size) == -1) { setErrorCode(NdbBlobImpl::ErrUsage); return -1; @@ -1175,7 +1175,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* * back after postExecute. */ int -NdbBlob::preExecute(ExecType anExecType, bool& batch) +NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) { DBG("preExecute [in]"); if (theState == Invalid) @@ -1224,7 +1224,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) return -1; } if (isWriteOp()) { - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption = NdbTransaction::AO_IgnoreError; } theHeadInlineReadOp = tOp; // execute immediately @@ -1270,7 +1270,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) return -1; } if (isWriteOp()) { - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption = NdbTransaction::AO_IgnoreError; } theHeadInlineReadOp = tOp; // execute immediately @@ -1316,18 +1316,18 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) * any remaining prepared operations. */ int -NdbBlob::postExecute(ExecType anExecType) +NdbBlob::postExecute(NdbTransaction::ExecType anExecType) { DBG("postExecute [in] type=" << anExecType); if (theState == Invalid) return -1; if (theState == Active) { - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); DBG("postExecute [skip]"); return 0; } assert(theState == Prepared); - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); assert(isKeyOp()); if (isIndexOp()) { NdbBlob* tFirstBlob = theNdbOp->theBlobList; @@ -1343,14 +1343,15 @@ NdbBlob::postExecute(ExecType anExecType) return -1; if (theGetFlag) { assert(theGetSetBytes == 0 || theGetBuf != 0); - assert(theGetSetBytes <= theInlineSize || anExecType == NoCommit); + assert(theGetSetBytes <= theInlineSize || + anExecType == NdbTransaction::NoCommit); Uint32 bytes = theGetSetBytes; if (readDataPrivate(theGetBuf, bytes) == -1) return -1; } } if (isUpdateOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); getHeadFromRecAttr(); if (theSetFlag) { // setValue overwrites everything @@ -1367,7 +1368,7 @@ NdbBlob::postExecute(ExecType anExecType) } } if (isWriteOp() && isTableOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); if (theHeadInlineReadOp->theError.code == 0) { int tNullFlag = theNullFlag; Uint64 tLength = theLength; @@ -1418,18 +1419,18 @@ NdbBlob::postExecute(ExecType anExecType) } } if (isDeleteOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); getHeadFromRecAttr(); if (deleteParts(0, getPartCount()) == -1) return -1; } - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); // activation callback if (theActiveHook != NULL) { if (invokeActiveHook() == -1) return -1; } - if (anExecType == NoCommit && theHeadInlineUpdateFlag) { + if (anExecType == NdbTransaction::NoCommit && theHeadInlineUpdateFlag) { NdbOperation* tOp = theNdbCon->getNdbOperation(theTable); if (tOp == NULL || tOp->updateTuple() == -1 || @@ -1438,7 +1439,7 @@ NdbBlob::postExecute(ExecType anExecType) setErrorCode(NdbBlobImpl::ErrAbort); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; DBG("added op to update head+inline"); } DBG("postExecute [out]"); @@ -1468,7 +1469,7 @@ NdbBlob::preCommit() setErrorCode(NdbBlobImpl::ErrAbort); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; DBG("added op to update head+inline"); } } @@ -1488,7 +1489,7 @@ NdbBlob::atNextResult() assert(isScanOp()); // get primary key { Uint32* data = (Uint32*)theKeyBuf.data; - unsigned size = theTable->m_sizeOfKeysInWords; + unsigned size = theTable->m_keyLenInWords; if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) { setErrorCode(NdbBlobImpl::ErrUsage); return -1; @@ -1551,7 +1552,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag) } void -NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag) +NdbBlob::setErrorCode(NdbTransaction* aCon, bool invalidFlag) { int code = 0; if (theNdbCon != NULL && (code = theNdbCon->theError.code) != 0) diff --git a/ndb/src/ndbapi/NdbCursorOperation.cpp b/ndb/src/ndbapi/NdbCursorOperation.cpp deleted file mode 100644 index a9f84c4c110..00000000000 --- a/ndb/src/ndbapi/NdbCursorOperation.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* 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: NdbCursorOperation.cpp - * Include: - * Link: - * Author: UABMASD Martin Sköld INN/V Alzato - * Date: 2002-04-01 - * Version: 0.1 - * Description: Cursor support - * Documentation: - * Adjust: 2002-04-01 UABMASD First version. - ****************************************************************************/ - -#include <NdbCursorOperation.hpp> -#include <NdbResultSet.hpp> - -NdbCursorOperation::NdbCursorOperation(Ndb* aNdb) : -{ -} - -NdbCursorOperation::~NdbCursorOperation() -{ - if (m_resultSet) - delete m_resultSet; -} - -void NdbCursorOperation::cursInit() -{ - // Initialize result set -} - -NdbResultSet* NdbCursorOperation::getResultSet() -{ -} - - diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 00db5704949..4cc47543cec 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -176,52 +176,16 @@ NdbDictionary::Column::getPrimaryKey() const { return m_impl.m_pk; } -void -NdbDictionary::Column::setTupleKey(bool val){ - m_impl.m_tupleKey = val; -} - -bool -NdbDictionary::Column::getTupleKey() const { - return m_impl.m_tupleKey; -} - void -NdbDictionary::Column::setDistributionKey(bool val){ +NdbDictionary::Column::setPartitionKey(bool val){ m_impl.m_distributionKey = val; } bool -NdbDictionary::Column::getDistributionKey() const{ +NdbDictionary::Column::getPartitionKey() const{ return m_impl.m_distributionKey; } -void -NdbDictionary::Column::setDistributionGroup(bool val, int bits){ - m_impl.m_distributionGroup = val; - m_impl.m_distributionGroupBits = bits; -} - -bool -NdbDictionary::Column::getDistributionGroup() const { - return m_impl.m_distributionGroup; -} - -int -NdbDictionary::Column::getDistributionGroupBits() const{ - return m_impl.m_distributionGroupBits; -} - -void -NdbDictionary::Column::setIndexOnlyStorage(bool val){ - m_impl.m_indexOnly = val; -} - -bool -NdbDictionary::Column::getIndexOnlyStorage() const { - return m_impl.m_indexOnly; -} - const NdbDictionary::Table * NdbDictionary::Column::getBlobTable() const { NdbTableImpl * t = m_impl.m_blobTable; @@ -267,6 +231,12 @@ NdbDictionary::Column::equal(const NdbDictionary::Column & col) const { return m_impl.equal(col.m_impl); } +int +NdbDictionary::Column::getSizeInBytes() const +{ + return m_impl.m_attrSize * m_impl.m_arraySize; +} + /***************************************************************** * Table facade */ @@ -462,13 +432,17 @@ NdbDictionary::Table::getRowSizeInBytes() const { int sz = 0; for(int i = 0; i<getNoOfColumns(); i++){ const NdbDictionary::Column * c = getColumn(i); - const NdbColumnImpl & col = NdbColumnImpl::getImpl(* c); - sz += (((col.m_attrSize * col.m_arraySize) + 3) / 4); + sz += (c->getSizeInBytes()+ 3) / 4; } return sz * 4; } int +NdbDictionary::Table::getReplicaCount() const { + return m_impl.m_replicaCount; +} + +int NdbDictionary::Table::createTableInDb(Ndb* pNdb, bool equalOk) const { const NdbDictionary::Table * pTab = pNdb->getDictionary()->getTable(getName()); @@ -621,6 +595,13 @@ NdbDictionary::Event::Event(const char * name) setName(name); } +NdbDictionary::Event::Event(const char * name, const Table& table) + : m_impl(* new NdbEventImpl(* this)) +{ + setName(name); + setTable(table); +} + NdbDictionary::Event::Event(NdbEventImpl & impl) : m_impl(impl) { @@ -640,12 +621,30 @@ NdbDictionary::Event::setName(const char * name) m_impl.setName(name); } +const char * +NdbDictionary::Event::getName() const +{ + return m_impl.getName(); +} + +void +NdbDictionary::Event::setTable(const Table& table) +{ + m_impl.setTable(table); +} + void NdbDictionary::Event::setTable(const char * table) { m_impl.setTable(table); } +const char* +NdbDictionary::Event::getTableName() const +{ + return m_impl.getTableName(); +} + void NdbDictionary::Event::addTableEvent(const TableEvent t) { @@ -653,11 +652,17 @@ NdbDictionary::Event::addTableEvent(const TableEvent t) } void -NdbDictionary::Event::setDurability(const EventDurability d) +NdbDictionary::Event::setDurability(EventDurability d) { m_impl.setDurability(d); } +NdbDictionary::Event::EventDurability +NdbDictionary::Event::getDurability() const +{ + return m_impl.getDurability(); +} + void NdbDictionary::Event::addColumn(const Column & c){ NdbColumnImpl* col = new NdbColumnImpl; @@ -685,6 +690,11 @@ NdbDictionary::Event::addEventColumns(int n, const char ** names) addEventColumn(names[i]); } +int NdbDictionary::Event::getNoOfEventColumns() const +{ + return m_impl.getNoOfEventColumns(); +} + NdbDictionary::Object::Status NdbDictionary::Event::getObjectStatus() const { @@ -742,7 +752,8 @@ NdbDictionary::Dictionary::alterTable(const Table & t){ } const NdbDictionary::Table * -NdbDictionary::Dictionary::getTable(const char * name, void **data){ +NdbDictionary::Dictionary::getTable(const char * name, void **data) const +{ NdbTableImpl * t = m_impl.getTable(name, data); if(t) return t->m_facade; @@ -755,7 +766,8 @@ void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz) } const NdbDictionary::Table * -NdbDictionary::Dictionary::getTable(const char * name){ +NdbDictionary::Dictionary::getTable(const char * name) const +{ return getTable(name, 0); } @@ -788,7 +800,7 @@ NdbDictionary::Dictionary::dropIndex(const char * indexName, const NdbDictionary::Index * NdbDictionary::Dictionary::getIndex(const char * indexName, - const char * tableName) + const char * tableName) const { NdbIndexImpl * i = m_impl.getIndex(indexName, tableName); if(i) @@ -818,7 +830,7 @@ NdbDictionary::Dictionary::removeCachedIndex(const char * indexName, const NdbDictionary::Table * NdbDictionary::Dictionary::getIndexTable(const char * indexName, - const char * tableName) + const char * tableName) const { NdbIndexImpl * i = m_impl.getIndex(indexName, tableName); NdbTableImpl * t = m_impl.getTable(tableName); @@ -858,6 +870,12 @@ NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) } int +NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) const +{ + return m_impl.listObjects(list, type); +} + +int NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName) { const NdbDictionary::Table* tab= getTable(tableName); @@ -868,6 +886,18 @@ NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName) return m_impl.listIndexes(list, tab->getTableId()); } +int +NdbDictionary::Dictionary::listIndexes(List& list, + const char * tableName) const +{ + const NdbDictionary::Table* tab= getTable(tableName); + if(tab == 0) + { + return -1; + } + return m_impl.listIndexes(list, tab->getTableId()); +} + const struct NdbError & NdbDictionary::Dictionary::getNdbError() const { return m_impl.getNdbError(); @@ -924,6 +954,12 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) case NdbDictionary::Column::Olddecimalunsigned: out << "Olddecimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")"; break; + case NdbDictionary::Column::Decimal: + out << "Decimal(" << col.getPrecision() << "," << col.getScale() << ")"; + break; + case NdbDictionary::Column::Decimalunsigned: + out << "Decimalunsigned(" << col.getPrecision() << "," << col.getScale() << ")"; + break; case NdbDictionary::Column::Char: out << "Char(" << col.getLength() << ";" << csname << ")"; break; @@ -962,10 +998,37 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) case NdbDictionary::Column::Undefined: out << "Undefined"; break; + case NdbDictionary::Column::Bit: + out << "Bit(" << col.getLength() << ")"; + break; + case NdbDictionary::Column::Longvarchar: + out << "Longvarchar(" << col.getLength() << ";" << csname << ")"; + break; + case NdbDictionary::Column::Longvarbinary: + out << "Longvarbinary(" << col.getLength() << ")"; + break; default: out << "Type" << (Uint32)col.getType(); break; } + // show unusual (non-MySQL) array size + if (col.getLength() != 1) { + switch (col.getType()) { + case NdbDictionary::Column::Char: + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Binary: + case NdbDictionary::Column::Varbinary: + case NdbDictionary::Column::Blob: + case NdbDictionary::Column::Text: + case NdbDictionary::Column::Bit: + case NdbDictionary::Column::Longvarchar: + case NdbDictionary::Column::Longvarbinary: + break; + default: + out << " [" << col.getLength() << "]"; + break; + } + } if (col.getPrimaryKey()) out << " PRIMARY KEY"; else if (! col.getNullable()) @@ -973,13 +1036,15 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) else out << " NULL"; - if (col.getDistributionKey()) + if(col.getDistributionKey()) out << " DISTRIBUTION KEY"; - + return out; } const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT = 0; +const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_MEMORY = 0; const NdbDictionary::Column * NdbDictionary::Column::ROW_COUNT = 0; const NdbDictionary::Column * NdbDictionary::Column::COMMIT_COUNT = 0; - +const NdbDictionary::Column * NdbDictionary::Column::ROW_SIZE = 0; +const NdbDictionary::Column * NdbDictionary::Column::RANGE_NO = 0; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index e88f76ef513..ff87a72f636 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -70,16 +70,11 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) m_scale = col.m_scale; m_length = col.m_length; m_pk = col.m_pk; - m_tupleKey = col.m_tupleKey; m_distributionKey = col.m_distributionKey; - m_distributionGroup = col.m_distributionGroup; - m_distributionGroupBits = col.m_distributionGroupBits; m_nullable = col.m_nullable; - m_indexOnly = col.m_indexOnly; m_autoIncrement = col.m_autoIncrement; m_autoIncrementInitialValue = col.m_autoIncrementInitialValue; m_defaultValue = col.m_defaultValue; - m_attrType = col.m_attrType; m_attrSize = col.m_attrSize; m_arraySize = col.m_arraySize; m_keyInfoPos = col.m_keyInfoPos; @@ -116,6 +111,8 @@ NdbColumnImpl::init(Type t) break; case Olddecimal: case Olddecimalunsigned: + case Decimal: + case Decimalunsigned: m_precision = 10; m_scale = 0; m_length = 1; @@ -157,17 +154,31 @@ NdbColumnImpl::init(Type t) m_length = 1; m_cs = NULL; break; + case Bit: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Longvarchar: + m_precision = 0; + m_scale = 0; + m_length = 1; // legal + m_cs = default_cs; + break; + case Longvarbinary: + m_precision = 0; + m_scale = 0; + m_length = 1; // legal + m_cs = NULL; + break; case Undefined: assert(false); break; } m_pk = false; m_nullable = false; - m_tupleKey = false; - m_indexOnly = false; m_distributionKey = false; - m_distributionGroup = false; - m_distributionGroupBits = 8; m_keyInfoPos = 0; // next 2 are set at run time m_attrSize = 0; @@ -184,50 +195,38 @@ NdbColumnImpl::~NdbColumnImpl() bool NdbColumnImpl::equal(const NdbColumnImpl& col) const { + DBUG_ENTER("NdbColumnImpl::equal"); if(strcmp(m_name.c_str(), col.m_name.c_str()) != 0){ - return false; + DBUG_RETURN(false); } if(m_type != col.m_type){ - return false; + DBUG_RETURN(false); } if(m_pk != col.m_pk){ - return false; + DBUG_RETURN(false); } if(m_nullable != col.m_nullable){ - return false; + DBUG_RETURN(false); } if(m_pk){ - if(m_tupleKey != col.m_tupleKey){ - return false; - } - if(m_indexOnly != col.m_indexOnly){ - return false; - } if(m_distributionKey != col.m_distributionKey){ - return false; - } - if(m_distributionGroup != col.m_distributionGroup){ - return false; - } - if(m_distributionGroup && - (m_distributionGroupBits != col.m_distributionGroupBits)){ - return false; + DBUG_RETURN(false); } } if (m_precision != col.m_precision || m_scale != col.m_scale || m_length != col.m_length || m_cs != col.m_cs) { - return false; + DBUG_RETURN(false); } if (m_autoIncrement != col.m_autoIncrement){ - return false; + DBUG_RETURN(false); } if(strcmp(m_defaultValue.c_str(), col.m_defaultValue.c_str()) != 0){ - return false; + DBUG_RETURN(false); } - return true; + DBUG_RETURN(true); } NdbDictionary::Column * @@ -239,6 +238,11 @@ NdbColumnImpl::create_psuedo(const char * name){ col->m_impl.m_attrId = AttributeHeader::FRAGMENT; col->m_impl.m_attrSize = 4; col->m_impl.m_arraySize = 1; + } else if(!strcmp(name, "NDB$FRAGMENT_MEMORY")){ + col->setType(NdbDictionary::Column::Bigunsigned); + col->m_impl.m_attrId = AttributeHeader::FRAGMENT_MEMORY; + col->m_impl.m_attrSize = 8; + col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$ROW_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::ROW_COUNT; @@ -249,6 +253,16 @@ NdbColumnImpl::create_psuedo(const char * name){ col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT; col->m_impl.m_attrSize = 8; col->m_impl.m_arraySize = 1; + } else if(!strcmp(name, "NDB$ROW_SIZE")){ + col->setType(NdbDictionary::Column::Unsigned); + col->m_impl.m_attrId = AttributeHeader::ROW_SIZE; + col->m_impl.m_attrSize = 4; + col->m_impl.m_arraySize = 1; + } else if(!strcmp(name, "NDB$RANGE_NO")){ + col->setType(NdbDictionary::Column::Unsigned); + col->m_impl.m_attrId = AttributeHeader::RANGE_NO; + col->m_impl.m_attrSize = 4; + col->m_impl.m_arraySize = 1; } else { abort(); } @@ -295,57 +309,71 @@ NdbTableImpl::init(){ m_indexType = NdbDictionary::Index::Undefined; m_noOfKeys = 0; + m_noOfDistributionKeys = 0; m_fragmentCount = 0; - m_sizeOfKeysInWords = 0; + m_keyLenInWords = 0; m_noOfBlobs = 0; } bool NdbTableImpl::equal(const NdbTableImpl& obj) const { + DBUG_ENTER("NdbTableImpl::equal"); if ((m_internalName.c_str() == NULL) || (strcmp(m_internalName.c_str(), "") == 0) || (obj.m_internalName.c_str() == NULL) || (strcmp(obj.m_internalName.c_str(), "") == 0)) { // Shallow equal if(strcmp(getName(), obj.getName()) != 0){ - return false; + DBUG_PRINT("info",("name %s != %s",getName(),obj.getName())); + DBUG_RETURN(false); } } else // Deep equal if(strcmp(m_internalName.c_str(), obj.m_internalName.c_str()) != 0){ - return false; + { + DBUG_PRINT("info",("m_internalName %s != %s", + m_internalName.c_str(),obj.m_internalName.c_str())); + DBUG_RETURN(false); + } } if(m_fragmentType != obj.m_fragmentType){ - return false; + DBUG_PRINT("info",("m_fragmentType %d != %d",m_fragmentType,obj.m_fragmentType)); + DBUG_RETURN(false); } if(m_columns.size() != obj.m_columns.size()){ - return false; + DBUG_PRINT("info",("m_columns.size %d != %d",m_columns.size(),obj.m_columns.size())); + DBUG_RETURN(false); } for(unsigned i = 0; i<obj.m_columns.size(); i++){ if(!m_columns[i]->equal(* obj.m_columns[i])){ - return false; + DBUG_PRINT("info",("m_columns [%d] != [%d]",i,i)); + DBUG_RETURN(false); } } if(m_logging != obj.m_logging){ - return false; + DBUG_PRINT("info",("m_logging %d != %d",m_logging,obj.m_logging)); + DBUG_RETURN(false); } if(m_kvalue != obj.m_kvalue){ - return false; + DBUG_PRINT("info",("m_kvalue %d != %d",m_kvalue,obj.m_kvalue)); + DBUG_RETURN(false); } if(m_minLoadFactor != obj.m_minLoadFactor){ - return false; + DBUG_PRINT("info",("m_minLoadFactor %d != %d",m_minLoadFactor,obj.m_minLoadFactor)); + DBUG_RETURN(false); } if(m_maxLoadFactor != obj.m_maxLoadFactor){ - return false; + DBUG_PRINT("info",("m_maxLoadFactor %d != %d",m_maxLoadFactor,obj.m_maxLoadFactor)); + DBUG_RETURN(false); } - return true; + DBUG_RETURN(true); } void @@ -375,8 +403,9 @@ NdbTableImpl::assign(const NdbTableImpl& org) delete m_index; m_index = org.m_index; + m_noOfDistributionKeys = org.m_noOfDistributionKeys; m_noOfKeys = org.m_noOfKeys; - m_sizeOfKeysInWords = org.m_sizeOfKeysInWords; + m_keyLenInWords = org.m_keyLenInWords; m_noOfBlobs = org.m_noOfBlobs; m_version = org.m_version; @@ -477,6 +506,26 @@ NdbTableImpl::buildColumnHash(){ } #endif } + +Uint32 +NdbTableImpl::get_nodes(Uint32 hashValue, const Uint16 ** nodes) const +{ + if(m_replicaCount > 0) + { + Uint32 fragmentId = hashValue & m_hashValueMask; + if(fragmentId < m_hashpointerValue) + { + fragmentId = hashValue & ((m_hashValueMask << 1) + 1); + } + Uint32 pos = fragmentId * m_replicaCount; + if(pos + m_replicaCount <= m_fragments.size()) + { + * nodes = m_fragments.getBase()+pos; + return m_replicaCount; + } + } + return 0; +} /** * NdbIndexImpl @@ -565,24 +614,30 @@ void NdbEventImpl::setName(const char * name) m_externalName.assign(name); } +const char *NdbEventImpl::getName() const +{ + return m_externalName.c_str(); +} + +void +NdbEventImpl::setTable(const NdbDictionary::Table& table) +{ + m_tableImpl= &NdbTableImpl::getImpl(table); + m_tableName.assign(m_tableImpl->getName()); +} + void NdbEventImpl::setTable(const char * table) { m_tableName.assign(table); } -const char * -NdbEventImpl::getTable() const +const char * +NdbEventImpl::getTableName() const { return m_tableName.c_str(); } -const char * -NdbEventImpl::getName() const -{ - return m_externalName.c_str(); -} - void NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDictionary::Event::TE_ALL) { @@ -595,11 +650,22 @@ NdbEventImpl::addTableEvent(const NdbDictionary::Event::TableEvent t = NdbDicti } void -NdbEventImpl::setDurability(const NdbDictionary::Event::EventDurability d) +NdbEventImpl::setDurability(NdbDictionary::Event::EventDurability d) { m_dur = d; } +NdbDictionary::Event::EventDurability +NdbEventImpl::getDurability() const +{ + return m_dur; +} + +int NdbEventImpl::getNoOfEventColumns() const +{ + return m_attrIds.size() + m_columns.size(); +} + /** * NdbDictionaryImpl */ @@ -643,11 +709,15 @@ NdbDictionaryImpl::~NdbDictionaryImpl() m_globalHash->lock(); if(--f_dictionary_count == 0){ delete NdbDictionary::Column::FRAGMENT; + delete NdbDictionary::Column::FRAGMENT_MEMORY; delete NdbDictionary::Column::ROW_COUNT; delete NdbDictionary::Column::COMMIT_COUNT; + delete NdbDictionary::Column::ROW_SIZE; NdbDictionary::Column::FRAGMENT= 0; + NdbDictionary::Column::FRAGMENT_MEMORY= 0; NdbDictionary::Column::ROW_COUNT= 0; NdbDictionary::Column::COMMIT_COUNT= 0; + NdbDictionary::Column::ROW_SIZE= 0; } m_globalHash->unlock(); } else { @@ -710,10 +780,16 @@ NdbDictionaryImpl::setTransporter(class Ndb* ndb, if(f_dictionary_count++ == 0){ NdbDictionary::Column::FRAGMENT= NdbColumnImpl::create_psuedo("NDB$FRAGMENT"); + NdbDictionary::Column::FRAGMENT_MEMORY= + NdbColumnImpl::create_psuedo("NDB$FRAGMENT_MEMORY"); NdbDictionary::Column::ROW_COUNT= NdbColumnImpl::create_psuedo("NDB$ROW_COUNT"); NdbDictionary::Column::COMMIT_COUNT= NdbColumnImpl::create_psuedo("NDB$COMMIT_COUNT"); + NdbDictionary::Column::ROW_SIZE= + NdbColumnImpl::create_psuedo("NDB$ROW_SIZE"); + NdbDictionary::Column::RANGE_NO= + NdbColumnImpl::create_psuedo("NDB$RANGE_NO"); } m_globalHash->unlock(); return true; @@ -745,7 +821,7 @@ NdbDictInterface::setTransporter(class TransporterFacade * tf) execNodeStatus); if ( m_blockNumber == -1 ) { - m_error.code = 4105; + m_error.code= 4105; return false; // no more free blocknumbers }//if Uint32 theNode = tf->ownId(); @@ -899,7 +975,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, aNodeId = m_transporter->get_an_alive_node(); } if(aNodeId == 0){ - m_error.code = 4009; + m_error.code= 4009; m_transporter->unlock_mutex(); DBUG_RETURN(-1); } @@ -926,7 +1002,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, } } - m_error.code = 0; + m_error.code= 0; m_waiter.m_node = aNodeId; m_waiter.m_state = wst; @@ -960,7 +1036,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, for (int j=0; j < noerrcodes; j++) if(m_error.code == errcodes[j]) { doContinue = 1; - continue; + break; } if (doContinue) continue; @@ -1000,7 +1076,7 @@ NdbDictInterface::getTable(const char * name, bool fullyQualifiedNames) const Uint32 strLen = strlen(name) + 1; // NULL Terminated if(strLen > MAX_TAB_NAME_SIZE) {//sizeof(req->tableName)){ - m_error.code = 4307; + m_error.code= 4307; return 0; } @@ -1026,18 +1102,20 @@ NdbDictInterface::getTable(class NdbApiSignal * signal, Uint32 noOfSections, bool fullyQualifiedNames) { //GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, signal->getDataPtrSend()); + int errCodes[] = {GetTabInfoRef::Busy }; + int r = dictSignal(signal,ptr,noOfSections, 0/*do not use masternode id*/, 100, WAIT_GET_TAB_INFO_REQ, WAITFOR_RESPONSE_TIMEOUT, - NULL,0); + errCodes, 1); if (r) return 0; NdbTableImpl * rt = 0; - m_error.code = parseTableInfo(&rt, - (Uint32*)m_buffer.get_data(), - m_buffer.length() / 4, fullyQualifiedNames); + m_error.code= parseTableInfo(&rt, + (Uint32*)m_buffer.get_data(), + m_buffer.length() / 4, fullyQualifiedNames); rt->buildColumnHash(); return rt; } @@ -1072,7 +1150,7 @@ NdbDictInterface::execGET_TABINFO_REF(NdbApiSignal * signal, { const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef, signal->getDataPtr()); - m_error.code = ref->errorCode; + m_error.code= ref->errorCode; m_waiter.signal(NO_WAIT); } @@ -1128,8 +1206,6 @@ objectTypeMapping[] = { { DictTabInfo::SystemTable, NdbDictionary::Object::SystemTable }, { DictTabInfo::UserTable, NdbDictionary::Object::UserTable }, { DictTabInfo::UniqueHashIndex, NdbDictionary::Object::UniqueHashIndex }, - { DictTabInfo::HashIndex, NdbDictionary::Object::HashIndex }, - { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Object::UniqueOrderedIndex }, { DictTabInfo::OrderedIndex, NdbDictionary::Object::OrderedIndex }, { DictTabInfo::HashIndexTrigger, NdbDictionary::Object::HashIndexTrigger }, { DictTabInfo::IndexTrigger, NdbDictionary::Object::IndexTrigger }, @@ -1161,49 +1237,17 @@ static const ApiKernelMapping indexTypeMapping[] = { { DictTabInfo::UniqueHashIndex, NdbDictionary::Index::UniqueHashIndex }, - { DictTabInfo::HashIndex, NdbDictionary::Index::HashIndex }, - { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Index::UniqueOrderedIndex}, { DictTabInfo::OrderedIndex, NdbDictionary::Index::OrderedIndex }, { -1, -1 } }; -// TODO: remove, api-kernel type codes must match now -static const -ApiKernelMapping -columnTypeMapping[] = { - { DictTabInfo::ExtTinyint, NdbDictionary::Column::Tinyint }, - { DictTabInfo::ExtTinyunsigned, NdbDictionary::Column::Tinyunsigned }, - { DictTabInfo::ExtSmallint, NdbDictionary::Column::Smallint }, - { DictTabInfo::ExtSmallunsigned, NdbDictionary::Column::Smallunsigned }, - { DictTabInfo::ExtMediumint, NdbDictionary::Column::Mediumint }, - { DictTabInfo::ExtMediumunsigned, NdbDictionary::Column::Mediumunsigned }, - { DictTabInfo::ExtInt, NdbDictionary::Column::Int }, - { DictTabInfo::ExtUnsigned, NdbDictionary::Column::Unsigned }, - { DictTabInfo::ExtBigint, NdbDictionary::Column::Bigint }, - { DictTabInfo::ExtBigunsigned, NdbDictionary::Column::Bigunsigned }, - { DictTabInfo::ExtFloat, NdbDictionary::Column::Float }, - { DictTabInfo::ExtDouble, NdbDictionary::Column::Double }, - { DictTabInfo::ExtOlddecimal, NdbDictionary::Column::Olddecimal }, - { DictTabInfo::ExtOlddecimalunsigned, NdbDictionary::Column::Olddecimalunsigned }, - { DictTabInfo::ExtChar, NdbDictionary::Column::Char }, - { DictTabInfo::ExtVarchar, NdbDictionary::Column::Varchar }, - { DictTabInfo::ExtBinary, NdbDictionary::Column::Binary }, - { DictTabInfo::ExtVarbinary, NdbDictionary::Column::Varbinary }, - { DictTabInfo::ExtDatetime, NdbDictionary::Column::Datetime }, - { DictTabInfo::ExtDate, NdbDictionary::Column::Date }, - { DictTabInfo::ExtBlob, NdbDictionary::Column::Blob }, - { DictTabInfo::ExtText, NdbDictionary::Column::Text }, - { DictTabInfo::ExtTime, NdbDictionary::Column::Time }, - { DictTabInfo::ExtYear, NdbDictionary::Column::Year }, - { DictTabInfo::ExtTimestamp, NdbDictionary::Column::Timestamp }, - { -1, -1 } -}; - int NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, const Uint32 * data, Uint32 len, bool fullyQualifiedNames) { + DBUG_ENTER("NdbDictInterface::parseTableInfo"); + SimplePropertiesLinearReader it(data, len); DictTabInfo::Table tableDesc; tableDesc.init(); SimpleProperties::UnpackStatus s; @@ -1213,7 +1257,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, true, true); if(s != SimpleProperties::Break){ - return 703; + DBUG_RETURN(703); } const char * internalName = tableDesc.TableName; const char * externalName = Ndb::externalizeTableName(internalName, fullyQualifiedNames); @@ -1236,7 +1280,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_kvalue = tableDesc.TableKValue; impl->m_minLoadFactor = tableDesc.MinLoadFactor; impl->m_maxLoadFactor = tableDesc.MaxLoadFactor; - impl->m_fragmentCount = tableDesc.FragmentCount; impl->m_indexType = (NdbDictionary::Index::Type) getApiConstant(tableDesc.TableType, @@ -1253,8 +1296,10 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, Uint32 keyInfoPos = 0; Uint32 keyCount = 0; Uint32 blobCount = 0; + Uint32 distKeys = 0; - for(Uint32 i = 0; i < tableDesc.NoOfAttributes; i++) { + Uint32 i; + for(i = 0; i < tableDesc.NoOfAttributes; i++) { DictTabInfo::Attribute attrDesc; attrDesc.init(); s = SimpleProperties::unpack(it, &attrDesc, @@ -1263,21 +1308,19 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, true, true); if(s != SimpleProperties::Break){ delete impl; - return 703; + DBUG_RETURN(703); } NdbColumnImpl * col = new NdbColumnImpl(); col->m_attrId = attrDesc.AttributeId; col->setName(attrDesc.AttributeName); - col->m_type = (NdbDictionary::Column::Type) - getApiConstant(attrDesc.AttributeExtType, - columnTypeMapping, - NdbDictionary::Column::Undefined); - if (col->m_type == NdbDictionary::Column::Undefined) { + + // check type and compute attribute size and array size + if (! attrDesc.translateExtType()) { delete impl; - return 703; + DBUG_RETURN(703); } - col->m_extType = attrDesc.AttributeExtType; + col->m_type = (NdbDictionary::Column::Type)attrDesc.AttributeExtType; col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF); col->m_scale = attrDesc.AttributeExtScale; col->m_length = attrDesc.AttributeExtLength; @@ -1286,32 +1329,26 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, // charset is defined exactly for char types if (col->getCharType() != (cs_number != 0)) { delete impl; - return 703; + DBUG_RETURN(703); } if (col->getCharType()) { col->m_cs = get_charset(cs_number, MYF(0)); if (col->m_cs == NULL) { delete impl; - return 743; + DBUG_RETURN(743); } } - - // translate to old kernel types and sizes - if (! attrDesc.translateExtType()) { - delete impl; - return 703; - } - col->m_attrType =attrDesc.AttributeType; col->m_attrSize = (1 << attrDesc.AttributeSize) / 8; col->m_arraySize = attrDesc.AttributeArraySize; + if(attrDesc.AttributeSize == 0) + { + col->m_attrSize = 4; + col->m_arraySize = (attrDesc.AttributeArraySize + 31) >> 5; + } col->m_pk = attrDesc.AttributeKeyFlag; - col->m_tupleKey = 0; col->m_distributionKey = attrDesc.AttributeDKey; - col->m_distributionGroup = attrDesc.AttributeDGroup; - col->m_distributionGroupBits = 16; col->m_nullable = attrDesc.AttributeNullableFlag; - col->m_indexOnly = (attrDesc.AttributeStoredInd ? false : true); col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false); col->m_autoIncrementInitialValue = ~0; col->m_defaultValue.assign(attrDesc.AttributeDefaultValue); @@ -1320,6 +1357,9 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, col->m_keyInfoPos = keyInfoPos + 1; keyInfoPos += ((col->m_attrSize * col->m_arraySize + 3) / 4); keyCount++; + + if(attrDesc.AttributeDKey) + distKeys++; } else { col->m_keyInfoPos = 0; } @@ -1330,7 +1370,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, if(impl->m_columns[attrDesc.AttributeId] != 0){ delete col; delete impl; - return 703; + DBUG_RETURN(703); } impl->m_columns[attrDesc.AttributeId] = col; it.next(); @@ -1338,10 +1378,49 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_noOfKeys = keyCount; impl->m_keyLenInWords = keyInfoPos; - impl->m_sizeOfKeysInWords = keyInfoPos; impl->m_noOfBlobs = blobCount; + impl->m_noOfDistributionKeys = distKeys; + + if(tableDesc.FragmentDataLen > 0) + { + Uint32 replicaCount = tableDesc.FragmentData[0]; + Uint32 fragCount = tableDesc.FragmentData[1]; + + impl->m_replicaCount = replicaCount; + impl->m_fragmentCount = fragCount; + + for(i = 0; i<(fragCount*replicaCount); i++) + { + impl->m_fragments.push_back(tableDesc.FragmentData[i+2]); + } + + Uint32 topBit = (1 << 31); + for(; topBit && !(fragCount & topBit); ){ + topBit >>= 1; + } + impl->m_hashValueMask = topBit - 1; + impl->m_hashpointerValue = fragCount - (impl->m_hashValueMask + 1); + } + else + { + impl->m_fragmentCount = tableDesc.FragmentCount; + impl->m_replicaCount = 0; + impl->m_hashValueMask = 0; + impl->m_hashpointerValue = 0; + } + + if(distKeys == 0) + { + for(i = 0; i < tableDesc.NoOfAttributes; i++) + { + if(impl->m_columns[i]->getPrimaryKey()) + impl->m_columns[i]->m_distributionKey = true; + } + } + * ret = impl; - return 0; + + DBUG_RETURN(0); } /***************************************************************** @@ -1358,13 +1437,13 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t) Ndb_local_table_info *info= get_local_table_info(t.m_internalName.c_str(),false); if (info == NULL) { - m_error.code = 709; + m_error.code= 709; return -1; } if (createBlobTables(*(info->m_table_impl)) != 0) { int save_code = m_error.code; (void)dropTable(t); - m_error.code = save_code; + m_error.code= save_code; return -1; } return 0; @@ -1430,11 +1509,10 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) BaseString internalName = impl.m_internalName; const char * originalInternalName = internalName.c_str(); BaseString externalName = impl.m_externalName; - const char * originalExternalName = externalName.c_str(); DBUG_ENTER("NdbDictionaryImpl::alterTable"); if(!get_local_table_info(originalInternalName, false)){ - m_error.code = 709; + m_error.code= 709; DBUG_RETURN(-1); } // Alter the table @@ -1470,12 +1548,12 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, DBUG_ENTER("NdbDictInterface::createOrAlterTable"); unsigned i; if((unsigned)impl.getNoOfPrimaryKeys() > NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY){ - m_error.code = 4317; + m_error.code= 4317; DBUG_RETURN(-1); } unsigned sz = impl.m_columns.size(); if (sz > NDB_MAX_ATTRIBUTES_IN_TABLE){ - m_error.code = 4318; + m_error.code= 4318; DBUG_RETURN(-1); } @@ -1500,8 +1578,8 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, continue; if (col->m_autoIncrement) { if (haveAutoIncrement) { - m_error.code = 4335; - return -1; + m_error.code= 4335; + DBUG_RETURN(-1); } haveAutoIncrement = true; autoIncrementValue = col->m_autoIncrementInitialValue; @@ -1510,7 +1588,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, // Check max length of frm data if (impl.m_frm.length() > MAX_FRM_DATA_SIZE){ - m_error.code = 1229; + m_error.code= 1229; DBUG_RETURN(-1); } tmpTab.FrmLen = impl.m_frm.length(); @@ -1538,6 +1616,7 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, abort(); } + int distKeys= impl.m_noOfDistributionKeys; for(i = 0; i<sz; i++){ const NdbColumnImpl * col = impl.m_columns[i]; if(col == 0) @@ -1547,27 +1626,33 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName), col->m_name.c_str()); tmpAttr.AttributeId = i; - tmpAttr.AttributeKeyFlag = col->m_pk || col->m_tupleKey; + tmpAttr.AttributeKeyFlag = col->m_pk; tmpAttr.AttributeNullableFlag = col->m_nullable; - tmpAttr.AttributeStoredInd = (col->m_indexOnly ? 0 : 1); tmpAttr.AttributeDKey = col->m_distributionKey; - tmpAttr.AttributeDGroup = col->m_distributionGroup; - tmpAttr.AttributeExtType = - getKernelConstant(col->m_type, - columnTypeMapping, - DictTabInfo::ExtUndefined); + tmpAttr.AttributeExtType = (Uint32)col->m_type; tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF); tmpAttr.AttributeExtScale = col->m_scale; tmpAttr.AttributeExtLength = col->m_length; + + // check type and compute attribute size and array size + if (! tmpAttr.translateExtType()) { + m_error.code= 703; + DBUG_RETURN(-1); + } // charset is defined exactly for char types if (col->getCharType() != (col->m_cs != NULL)) { - m_error.code = 703; + m_error.code= 703; DBUG_RETURN(-1); } // primary key type check if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) { - m_error.code = 743; + m_error.code= (col->m_cs != 0 ? 743 : 739); + DBUG_RETURN(-1); + } + // distribution key not supported for Char attribute + if (distKeys && col->m_distributionKey && col->m_cs != NULL) { + m_error.code= 745; DBUG_RETURN(-1); } // charset in upper half of precision @@ -1575,9 +1660,6 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16); } - // DICT will ignore and recompute this - (void)tmpAttr.translateExtType(); - tmpAttr.AttributeAutoIncrement = col->m_autoIncrement; BaseString::snprintf(tmpAttr.AttributeDefaultValue, sizeof(tmpAttr.AttributeDefaultValue), @@ -1622,13 +1704,13 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, ret= createTable(&tSignal, ptr); if (ret) - return ret; + DBUG_RETURN(ret); if (haveAutoIncrement) { if (!ndb.setAutoIncrementValue(impl.m_externalName.c_str(), autoIncrementValue)) { if (ndb.theError.code == 0) { - m_error.code = 4336; + m_error.code= 4336; ndb.theError = m_error; } else m_error= ndb.theError; @@ -1664,11 +1746,12 @@ void NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { +#if 0 const CreateTableConf* const conf= CAST_CONSTPTR(CreateTableConf, signal->getDataPtr()); Uint32 tableId= conf->tableId; Uint32 tableVersion= conf->tableVersion; - +#endif m_waiter.signal(NO_WAIT); } @@ -1678,7 +1761,7 @@ NdbDictInterface::execCREATE_TABLE_REF(NdbApiSignal * signal, { const CreateTableRef* const ref= CAST_CONSTPTR(CreateTableRef, signal->getDataPtr()); - m_error.code = ref->errorCode; + m_error.code= ref->errorCode; m_masterNodeId = ref->masterNodeId; m_waiter.signal(NO_WAIT); } @@ -1722,7 +1805,7 @@ NdbDictInterface::execALTER_TABLE_REF(NdbApiSignal * signal, { const AlterTableRef * const ref = CAST_CONSTPTR(AlterTableRef, signal->getDataPtr()); - m_error.code = ref->errorCode; + m_error.code= ref->errorCode; m_masterNodeId = ref->masterNodeId; m_waiter.signal(NO_WAIT); } @@ -1737,7 +1820,7 @@ NdbDictionaryImpl::dropTable(const char * name) DBUG_PRINT("enter",("name: %s", name)); NdbTableImpl * tab = getTable(name); if(tab == 0){ - return -1; + DBUG_RETURN(-1); } int ret = dropTable(* tab); // If table stored in cache is incompatible with the one in the kernel @@ -1767,7 +1850,7 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl) } if (impl.m_indexType != NdbDictionary::Index::Undefined) { - m_receiver.m_error.code = 1228; + m_receiver.m_error.code= 1228; return -1; } @@ -1867,19 +1950,23 @@ void NdbDictInterface::execDROP_TABLE_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { + DBUG_ENTER("NdbDictInterface::execDROP_TABLE_CONF"); //DropTableConf* const conf = CAST_CONSTPTR(DropTableConf, signal->getDataPtr()); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execDROP_TABLE_REF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { + DBUG_ENTER("NdbDictInterface::execDROP_TABLE_REF"); const DropTableRef* const ref = CAST_CONSTPTR(DropTableRef, signal->getDataPtr()); - m_error.code = ref->errorCode; + m_error.code= ref->errorCode; m_masterNodeId = ref->masterNodeId; m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } int @@ -1951,7 +2038,7 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, int NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, - const NdbTableImpl* tab, + NdbTableImpl* tab, const NdbTableImpl* prim){ NdbIndexImpl *idx = new NdbIndexImpl(); idx->m_version = tab->m_version; @@ -1959,22 +2046,49 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, idx->m_indexId = tab->m_tableId; idx->m_externalName.assign(tab->getName()); idx->m_tableName.assign(prim->m_externalName); - idx->m_type = tab->m_indexType; + NdbDictionary::Index::Type type = idx->m_type = tab->m_indexType; idx->m_logging = tab->m_logging; // skip last attribute (NDB$PK or NDB$TNODE) - for(unsigned i = 0; i+1<tab->m_columns.size(); i++){ + + const Uint32 distKeys = prim->m_noOfDistributionKeys; + Uint32 keyCount = (distKeys ? distKeys : prim->m_noOfKeys); + + unsigned i; + for(i = 0; i+1<tab->m_columns.size(); i++){ + NdbColumnImpl* org = tab->m_columns[i]; + NdbColumnImpl* col = new NdbColumnImpl; // Copy column definition - *col = *tab->m_columns[i]; + *col = * org; idx->m_columns.push_back(col); + /** * reverse map */ - int key_id = prim->getColumn(col->getName())->getColumnNo(); + const NdbColumnImpl* primCol = prim->getColumn(col->getName()); + int key_id = primCol->getColumnNo(); int fill = -1; idx->m_key_ids.fill(key_id, fill); idx->m_key_ids[key_id] = i; col->m_keyInfoPos = key_id; + + if(type == NdbDictionary::Index::OrderedIndex && + (primCol->m_distributionKey || + (distKeys == 0 && primCol->getPrimaryKey()))) + { + keyCount--; + org->m_distributionKey = 1; + } + } + + if(keyCount == 0) + { + tab->m_noOfDistributionKeys = (distKeys ? distKeys : prim->m_noOfKeys); + } + else + { + for(i = 0; i+1<tab->m_columns.size(); i++) + tab->m_columns[i]->m_distributionKey = 0; } * dst = idx; @@ -2053,10 +2167,6 @@ NdbDictInterface::createIndex(Ndb & ndb, // Copy column definition *impl.m_columns[i] = *col; - if(col->m_pk && col->m_indexOnly){ - m_error.code = 4245; - return -1; - } // index key type check if (it == DictTabInfo::UniqueHashIndex && ! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) || @@ -2067,26 +2177,6 @@ NdbDictInterface::createIndex(Ndb & ndb, } attributeList.id[i] = col->m_attrId; } - if (it == DictTabInfo::UniqueHashIndex) { - // Sort index attributes according to primary table (using insertion sort) - for(i = 1; i < attributeList.sz; i++) { - unsigned int temp = attributeList.id[i]; - unsigned int j = i; - while((j > 0) && (attributeList.id[j - 1] > temp)) { - attributeList.id[j] = attributeList.id[j - 1]; - j--; - } - attributeList.id[j] = temp; - } - // Check for illegal duplicate attributes - for(i = 0; i<attributeList.sz; i++) { - if ((i != (attributeList.sz - 1)) && - (attributeList.id[i] == attributeList.id[i+1])) { - m_error.code = 4258; - return -1; - } - } - } LinearSectionPtr ptr[3]; ptr[0].p = (Uint32*)&attributeList; ptr[0].sz = 1 + attributeList.sz; @@ -2263,13 +2353,12 @@ int NdbDictionaryImpl::createEvent(NdbEventImpl & evnt) { int i; - NdbTableImpl* tab = getTable(evnt.getTable()); + NdbTableImpl* tab = getTable(evnt.getTableName()); if(tab == 0){ - // m_error.code = 3249; - ndbout_c(":createEvent: table %s not found", evnt.getTable()); #ifdef EVENT_DEBUG - ndbout_c("NdbDictionaryImpl::createEvent: table not found: %s", evnt.getTable()); + ndbout_c("NdbDictionaryImpl::createEvent: table not found: %s", + evnt.getTableName()); #endif return -1; } @@ -2291,7 +2380,8 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt) evnt.m_facade->addColumn(*(col_impl->m_facade)); } else { ndbout_c("Attr id %u in table %s not found", evnt.m_attrIds[i], - evnt.getTable()); + evnt.getTableName()); + m_error.code= 4713; return -1; } } @@ -2310,7 +2400,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt) const NdbColumnImpl* col = table.getColumn(evnt.m_columns[i]->m_name.c_str()); if(col == 0){ - m_error.code = 4247; + m_error.code= 4247; return -1; } // Copy column definition @@ -2336,7 +2426,7 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt) // Check for illegal duplicate attributes for(i = 1; i<attributeList_sz; i++) { if (evnt.m_columns[i-1]->m_attrId == evnt.m_columns[i]->m_attrId) { - m_error.code = 4258; + m_error.code= 4258; return -1; } } @@ -2384,7 +2474,7 @@ NdbDictInterface::createEvent(class Ndb & ndb, const size_t len = strlen(evnt.m_externalName.c_str()) + 1; if(len > MAX_TAB_NAME_SIZE) { - m_error.code = 4241; + m_error.code= 4241; return -1; } @@ -2457,6 +2547,7 @@ int NdbDictInterface::executeSubscribeEvent(class Ndb & ndb, NdbEventImpl & evnt) { + DBUG_ENTER("NdbDictInterface::executeSubscribeEvent"); NdbApiSignal tSignal(m_reference); // tSignal.theReceiversBlockNumber = SUMA; tSignal.theReceiversBlockNumber = DBDICT; @@ -2471,7 +2562,7 @@ NdbDictInterface::executeSubscribeEvent(class Ndb & ndb, sumaStart->subscriberData = evnt.m_bufferId & 0xFF; sumaStart->subscriberRef = m_reference; - return executeSubscribeEvent(&tSignal, NULL); + DBUG_RETURN(executeSubscribeEvent(&tSignal, NULL)); } int @@ -2497,9 +2588,7 @@ int NdbDictInterface::stopSubscribeEvent(class Ndb & ndb, NdbEventImpl & evnt) { -#ifdef EVENT_DEBUG - ndbout_c("SUB_STOP_REQ"); -#endif + DBUG_ENTER("NdbDictInterface::stopSubscribeEvent"); NdbApiSignal tSignal(m_reference); // tSignal.theReceiversBlockNumber = SUMA; @@ -2515,7 +2604,7 @@ NdbDictInterface::stopSubscribeEvent(class Ndb & ndb, sumaStop->part = (Uint32) SubscriptionData::TableData; sumaStop->subscriberRef = m_reference; - return stopSubscribeEvent(&tSignal, NULL); + DBUG_RETURN(stopSubscribeEvent(&tSignal, NULL)); } int @@ -2549,8 +2638,8 @@ NdbDictionaryImpl::getEvent(const char * eventName) } // We only have the table name with internal name - ev->setTable(m_ndb.externalizeTableName(ev->getTable())); - ev->m_tableImpl = getTable(ev->getTable()); + ev->setTable(m_ndb.externalizeTableName(ev->getTableName())); + ev->m_tableImpl = getTable(ev->getTableName()); // get the columns from the attrListBitmask @@ -2575,7 +2664,7 @@ NdbDictionaryImpl::getEvent(const char * eventName) #ifdef EVENT_DEBUG ndbout_c("NdbDictionaryImpl::getEvent could not find column id %d", id); #endif - m_error.code = 4247; + m_error.code= 4247; delete ev; return NULL; } @@ -2593,9 +2682,8 @@ void NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "NdbDictionaryImpl.cpp: execCREATE_EVNT_CONF" << endl; -#endif + DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_CONF"); + m_buffer.clear(); unsigned int len = signal->getLength() << 2; m_buffer.append((char *)&len, sizeof(len)); @@ -2605,118 +2693,123 @@ NdbDictInterface::execCREATE_EVNT_CONF(NdbApiSignal * signal, m_buffer.append((char *)ptr[0].p, strlen((char *)ptr[0].p)+1); } + const CreateEvntConf * const createEvntConf= + CAST_CONSTPTR(CreateEvntConf, signal->getDataPtr()); + + Uint32 subscriptionId = createEvntConf->getEventId(); + Uint32 subscriptionKey = createEvntConf->getEventKey(); + + DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d", + subscriptionId,subscriptionKey)); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execCREATE_EVNT_REF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "NdbDictionaryImpl.cpp: execCREATE_EVNT_REF" << endl; - ndbout << "Exiting" << endl; - exit(-1); -#endif + DBUG_ENTER("NdbDictInterface::execCREATE_EVNT_REF"); - const CreateEvntRef* const ref = CAST_CONSTPTR(CreateEvntRef, signal->getDataPtr()); - m_error.code = ref->getErrorCode(); -#ifdef EVENT_DEBUG - ndbout_c("execCREATE_EVNT_REF"); - ndbout_c("ErrorCode %u", ref->getErrorCode()); - ndbout_c("Errorline %u", ref->getErrorLine()); - ndbout_c("ErrorNode %u", ref->getErrorNode()); -#endif - m_waiter.signal(NO_WAIT); + const CreateEvntRef* const ref= + CAST_CONSTPTR(CreateEvntRef, signal->getDataPtr()); + m_error.code= ref->getErrorCode(); + DBUG_PRINT("error",("error=%d,line=%d,node=%d",ref->getErrorCode(), + ref->getErrorLine(),ref->getErrorNode())); + m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execSUB_STOP_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "Got GSN_SUB_STOP_CONF" << endl; -#endif - // SubRemoveConf * const sumaRemoveConf = CAST_CONSTPTR(SubRemoveConf, signal->getDataPtr()); + DBUG_ENTER("NdbDictInterface::execSUB_STOP_CONF"); + const SubStopConf * const subStopConf= + CAST_CONSTPTR(SubStopConf, signal->getDataPtr()); - // Uint32 subscriptionId = sumaRemoveConf->subscriptionId; - // Uint32 subscriptionKey = sumaRemoveConf->subscriptionKey; - // Uint32 senderData = sumaRemoveConf->senderData; + Uint32 subscriptionId = subStopConf->subscriptionId; + Uint32 subscriptionKey = subStopConf->subscriptionKey; + Uint32 subscriberData = subStopConf->subscriberData; + DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d", + subscriptionId,subscriptionKey,subscriberData)); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execSUB_STOP_REF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "Got GSN_SUB_STOP_REF" << endl; -#endif - // SubRemoveConf * const sumaRemoveRef = CAST_CONSTPTR(SubRemoveRef, signal->getDataPtr()); + DBUG_ENTER("NdbDictInterface::execSUB_STOP_REF"); + const SubStopRef * const subStopRef= + CAST_CONSTPTR(SubStopRef, signal->getDataPtr()); - // Uint32 subscriptionId = sumaRemoveRef->subscriptionId; - // Uint32 subscriptionKey = sumaRemoveRef->subscriptionKey; - // Uint32 senderData = sumaRemoveRef->senderData; + Uint32 subscriptionId = subStopRef->subscriptionId; + Uint32 subscriptionKey = subStopRef->subscriptionKey; + Uint32 subscriberData = subStopRef->subscriberData; + m_error.code= subStopRef->errorCode; - m_error.code = 1; + DBUG_PRINT("error",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d,error=%d", + subscriptionId,subscriptionKey,subscriberData,m_error.code)); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execSUB_START_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "Got GSN_SUB_START_CONF" << endl; -#endif - const SubStartConf * const sumaStartConf = CAST_CONSTPTR(SubStartConf, signal->getDataPtr()); + DBUG_ENTER("NdbDictInterface::execSUB_START_CONF"); + const SubStartConf * const subStartConf= + CAST_CONSTPTR(SubStartConf, signal->getDataPtr()); - // Uint32 subscriptionId = sumaStartConf->subscriptionId; - // Uint32 subscriptionKey = sumaStartConf->subscriptionKey; + Uint32 subscriptionId = subStartConf->subscriptionId; + Uint32 subscriptionKey = subStartConf->subscriptionKey; SubscriptionData::Part part = - (SubscriptionData::Part)sumaStartConf->part; - // Uint32 subscriberData = sumaStartConf->subscriberData; + (SubscriptionData::Part)subStartConf->part; + Uint32 subscriberData = subStartConf->subscriberData; switch(part) { case SubscriptionData::MetaData: { -#ifdef EVENT_DEBUG - ndbout << "SubscriptionData::MetaData" << endl; -#endif - m_error.code = 1; + DBUG_PRINT("error",("SubscriptionData::MetaData")); + m_error.code= 1; break; } case SubscriptionData::TableData: { -#ifdef EVENT_DEBUG - ndbout << "SubscriptionData::TableData" << endl; -#endif + DBUG_PRINT("info",("SubscriptionData::TableData")); break; } default: { -#ifdef EVENT_DEBUG - ndbout_c("NdbDictInterface::execSUB_START_CONF wrong data"); -#endif - m_error.code = 1; + DBUG_PRINT("error",("wrong data")); + m_error.code= 2; break; } } + DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d", + subscriptionId,subscriptionKey,subscriberData)); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execSUB_START_REF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "Got GSN_SUB_START_REF" << endl; -#endif - m_error.code = 1; - m_waiter.signal(NO_WAIT); + DBUG_ENTER("NdbDictInterface::execSUB_START_REF"); + const SubStartRef * const subStartRef= + CAST_CONSTPTR(SubStartRef, signal->getDataPtr()); + m_error.code= subStartRef->errorCode; + m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execSUB_GCP_COMPLETE_REP(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { - const SubGcpCompleteRep * const rep = CAST_CONSTPTR(SubGcpCompleteRep, signal->getDataPtr()); + const SubGcpCompleteRep * const rep= + CAST_CONSTPTR(SubGcpCompleteRep, signal->getDataPtr()); const Uint32 gci = rep->gci; // const Uint32 senderRef = rep->senderRef; @@ -2727,7 +2820,8 @@ NdbDictInterface::execSUB_GCP_COMPLETE_REP(NdbApiSignal * signal, const Uint32 ref = signal->theSendersBlockRef; NdbApiSignal tSignal(m_reference); - SubGcpCompleteAcc * acc = CAST_PTR(SubGcpCompleteAcc, tSignal.getDataPtrSend()); + SubGcpCompleteAcc * acc= + CAST_PTR(SubGcpCompleteAcc, tSignal.getDataPtrSend()); acc->rep = *rep; @@ -2785,9 +2879,9 @@ NdbDictInterface::execSUB_TABLE_DATA(NdbApiSignal * signal, int NdbDictionaryImpl::dropEvent(const char * eventName) { - NdbEventImpl *ev = new NdbEventImpl(); + NdbEventImpl *ev= new NdbEventImpl(); ev->setName(eventName); - int ret = m_receiver.dropEvent(*ev); + int ret= m_receiver.dropEvent(*ev); delete ev; // printf("__________________RET %u\n", ret); @@ -2836,31 +2930,25 @@ void NdbDictInterface::execDROP_EVNT_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "NdbDictionaryImpl.cpp: execDROP_EVNT_CONF" << endl; -#endif - + DBUG_ENTER("NdbDictInterface::execDROP_EVNT_CONF"); m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } void NdbDictInterface::execDROP_EVNT_REF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { -#ifdef EVENT_DEBUG - ndbout << "NdbDictionaryImpl.cpp: execDROP_EVNT_REF" << endl; -#endif - const DropEvntRef* const ref = CAST_CONSTPTR(DropEvntRef, signal->getDataPtr()); - m_error.code = ref->getErrorCode(); + DBUG_ENTER("NdbDictInterface::execDROP_EVNT_REF"); + const DropEvntRef* const ref= + CAST_CONSTPTR(DropEvntRef, signal->getDataPtr()); + m_error.code= ref->getErrorCode(); -#if 0 - ndbout_c("execDROP_EVNT_REF"); - ndbout_c("ErrorCode %u", ref->getErrorCode()); - ndbout_c("Errorline %u", ref->getErrorLine()); - ndbout_c("ErrorNode %u", ref->getErrorNode()); -#endif + DBUG_PRINT("info",("ErrorCode=%u Errorline=%u ErrorNode=%u", + ref->getErrorCode(), ref->getErrorLine(), ref->getErrorNode())); - m_waiter.signal(NO_WAIT); + m_waiter.signal(NO_WAIT); + DBUG_VOID_RETURN; } /***************************************************************** @@ -2925,7 +3013,7 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list, } if (! ok) { // bad signal data - m_error.code = 4213; + m_error.code= 4213; return -1; } list.count = count; @@ -2947,8 +3035,6 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list, BaseString schemaName; BaseString objectName; if ((element.type == NdbDictionary::Object::UniqueHashIndex) || - (element.type == NdbDictionary::Object::HashIndex) || - (element.type == NdbDictionary::Object::UniqueOrderedIndex) || (element.type == NdbDictionary::Object::OrderedIndex)) { char * indexName = new char[n << 2]; memcpy(indexName, &data[pos], n << 2); @@ -2993,7 +3079,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal) m_transporter->lock_mutex(); Uint16 aNodeId = m_transporter->get_an_alive_node(); if (aNodeId == 0) { - m_error.code = 4009; + m_error.code= 4009; m_transporter->unlock_mutex(); return -1; } @@ -3001,7 +3087,7 @@ NdbDictInterface::listObjects(NdbApiSignal* signal) m_transporter->unlock_mutex(); continue; } - m_error.code = 0; + m_error.code= 0; m_waiter.m_node = aNodeId; m_waiter.m_state = WAIT_LIST_TABLES_CONF; m_waiter.wait(WAITFOR_RESPONSE_TIMEOUT); @@ -3030,6 +3116,7 @@ NdbDictInterface::execLIST_TABLES_CONF(NdbApiSignal* signal, } template class Vector<int>; +template class Vector<Uint16>; template class Vector<Uint32>; template class Vector<Vector<Uint32> >; template class Vector<NdbTableImpl*>; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 602a2d6b6ca..59a5956715a 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -63,12 +63,8 @@ public: CHARSET_INFO * m_cs; // not const in MySQL bool m_pk; - bool m_tupleKey; bool m_distributionKey; - bool m_distributionGroup; - int m_distributionGroupBits; bool m_nullable; - bool m_indexOnly; bool m_autoIncrement; Uint64 m_autoIncrementInitialValue; BaseString m_defaultValue; @@ -77,13 +73,13 @@ public: /** * Internal types and sizes, and aggregates */ - Uint32 m_attrType; // type outsize API and DICT Uint32 m_attrSize; // element size (size when arraySize==1) Uint32 m_arraySize; // length or length+2 for Var* types Uint32 m_keyInfoPos; - Uint32 m_extType; // used by restore (kernel type in versin v2x) + // TODO: use bits in attr desc 2 bool getInterpretableType() const ; bool getCharType() const; + bool getStringType() const; bool getBlobType() const; /** @@ -123,13 +119,20 @@ public: Vector<Uint32> m_columnHash; Vector<NdbColumnImpl *> m_columns; void buildColumnHash(); - + + /** + * Fragment info + */ + Uint32 m_hashValueMask; + Uint32 m_hashpointerValue; + Vector<Uint16> m_fragments; + bool m_logging; int m_kvalue; int m_minLoadFactor; int m_maxLoadFactor; - int m_keyLenInWords; - int m_fragmentCount; + Uint16 m_keyLenInWords; + Uint16 m_fragmentCount; NdbDictionaryImpl * m_dictionary; NdbIndexImpl * m_index; @@ -147,9 +150,11 @@ public: /** * Aggregates */ - Uint32 m_noOfKeys; - unsigned short m_sizeOfKeysInWords; - unsigned short m_noOfBlobs; + Uint8 m_noOfKeys; + Uint8 m_noOfDistributionKeys; + Uint8 m_noOfBlobs; + + Uint8 m_replicaCount; /** * Equality/assign @@ -162,6 +167,11 @@ public: static NdbTableImpl & getImpl(NdbDictionary::Table & t); static NdbTableImpl & getImpl(const NdbDictionary::Table & t); NdbDictionary::Table * m_facade; + + /** + * Return count + */ + Uint32 get_nodes(Uint32 hashValue, const Uint16** nodes) const ; }; class NdbIndexImpl : public NdbDictionary::Index, public NdbDictObjectImpl { @@ -201,11 +211,14 @@ public: void setName(const char * name); const char * getName() const; + void setTable(const NdbDictionary::Table& table); void setTable(const char * table); - const char * getTable() const; + const char * getTableName() const; void addTableEvent(const NdbDictionary::Event::TableEvent t); - void setDurability(const NdbDictionary::Event::EventDurability d); + void setDurability(NdbDictionary::Event::EventDurability d); + NdbDictionary::Event::EventDurability getDurability() const; void addEventColumn(const NdbColumnImpl &c); + int getNoOfEventColumns() const; void print() { ndbout_c("NdbEventImpl: id=%d, key=%d", @@ -307,8 +320,8 @@ public: bool fullyQualifiedNames); static int create_index_obj_from_table(NdbIndexImpl ** dst, - const NdbTableImpl*, - const NdbTableImpl*); + NdbTableImpl* index_table, + const NdbTableImpl* primary_table); NdbError & m_error; private: @@ -454,7 +467,19 @@ bool NdbColumnImpl::getCharType() const { return (m_type == NdbDictionary::Column::Char || m_type == NdbDictionary::Column::Varchar || - m_type == NdbDictionary::Column::Text); + m_type == NdbDictionary::Column::Text || + m_type == NdbDictionary::Column::Longvarchar); +} + +inline +bool +NdbColumnImpl::getStringType() const { + return (m_type == NdbDictionary::Column::Char || + m_type == NdbDictionary::Column::Varchar || + m_type == NdbDictionary::Column::Longvarchar || + m_type == NdbDictionary::Column::Binary || + m_type == NdbDictionary::Column::Varbinary || + m_type == NdbDictionary::Column::Longvarbinary); } inline @@ -535,7 +560,7 @@ NdbTableImpl::getColumn(const char * name){ do { if(hashValue == (tmp & 0xFFFE)){ NdbColumnImpl* col = cols[tmp >> 16]; - if(strcmp(name, col->m_name.c_str()) == 0){ + if(strncmp(name, col->m_name.c_str(), NDB_MAX_ATTR_NAME_SIZE-1) == 0){ return col; } } @@ -553,7 +578,7 @@ NdbTableImpl::getColumn(const char * name){ } else { for(Uint32 i = 0; i<sz; i++){ NdbColumnImpl* col = * cols++; - if(col != 0 && strcmp(name, col->m_name.c_str()) == 0) + if(col != 0 && strncmp(name, col->m_name.c_str(), NDB_MAX_ATTR_NAME_SIZE-1) == 0) return col; } } diff --git a/ndb/src/ndbapi/NdbEventOperation.cpp b/ndb/src/ndbapi/NdbEventOperation.cpp index d209293f8b0..e99cad918c5 100644 --- a/ndb/src/ndbapi/NdbEventOperation.cpp +++ b/ndb/src/ndbapi/NdbEventOperation.cpp @@ -15,23 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/***************************************************************************** - * Name: NdbEventOperation.cpp - * Include: - * Link: - * Author: Tomas Ulin MySQL AB - * Date: 2003-11-21 - * Version: 0.1 - * Description: Event support - * Documentation: - * Adjust: 2003-11-21 Tomas Ulin First version. - ****************************************************************************/ - #include <Ndb.hpp> -#include <signaldata/SumaImpl.hpp> +#include <NdbError.hpp> #include <portlib/NdbMem.h> -#include <transporter/TransporterDefinitions.hpp> -#include <NdbEventOperation.hpp> #include "NdbEventOperationImpl.hpp" #include "NdbDictionaryImpl.hpp" @@ -123,3 +109,7 @@ NdbEventOperation::wait(void *p, int aMillisecondNumber) NdbEventOperation::NdbEventOperation(NdbEventOperationImpl& impl) : m_impl(impl) {} +const struct NdbError & +NdbEventOperation::getNdbError() const { + return m_impl.getNdbError(); +} diff --git a/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/ndb/src/ndbapi/NdbEventOperationImpl.cpp index 87bbca5fc71..208525bfc15 100644 --- a/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -55,14 +55,17 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N, const char* eventName, const int bufferLength) : NdbEventOperation(*this), m_ndb(theNdb), - m_state(ERROR), m_bufferL(bufferLength) + m_state(EO_ERROR), m_bufferL(bufferLength) { - m_eventId = 0; - theFirstRecAttrs[0] = NULL; - theCurrentRecAttrs[0] = NULL; - theFirstRecAttrs[1] = NULL; - theCurrentRecAttrs[1] = NULL; + theFirstPkAttrs[0] = NULL; + theCurrentPkAttrs[0] = NULL; + theFirstPkAttrs[1] = NULL; + theCurrentPkAttrs[1] = NULL; + theFirstDataAttrs[0] = NULL; + theCurrentDataAttrs[0] = NULL; + theFirstDataAttrs[1] = NULL; + theCurrentDataAttrs[1] = NULL; sdata = NULL; ptr[0].p = NULL; ptr[1].p = NULL; @@ -71,16 +74,17 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N, // we should lookup id in Dictionary, TODO // also make sure we only have one listener on each event - if (!m_ndb) { ndbout_c("m_ndb=NULL"); return; } + if (!m_ndb) abort(); NdbDictionary::Dictionary *myDict = m_ndb->getDictionary(); - if (!myDict) { ndbout_c("getDictionary=NULL"); return; } + if (!myDict) { m_error.code= m_ndb->getNdbError().code; return; } const NdbDictionary::Event *myEvnt = myDict->getEvent(eventName); - if (!myEvnt) { ndbout_c("getEvent()=NULL"); return; } + if (!myEvnt) { m_error.code= myDict->getNdbError().code; return; } m_eventImpl = &myEvnt->m_impl; - if (!m_eventImpl) { ndbout_c("m_impl=NULL"); return; } + + m_eventId = m_eventImpl->m_eventId; m_bufferHandle = m_ndb->getGlobalEventBufferHandle(); if (m_bufferHandle->m_bufferL > 0) @@ -88,25 +92,30 @@ NdbEventOperationImpl::NdbEventOperationImpl(NdbEventOperation &N, else m_bufferHandle->m_bufferL = m_bufferL; - m_state = CREATED; + m_state = EO_CREATED; } NdbEventOperationImpl::~NdbEventOperationImpl() { int i; - if (sdata) NdbMem_Free(sdata); - for (i=0 ; i<3; i++) { - if (ptr[i].p) NdbMem_Free(ptr[i].p); + if (sdata) NdbMem_Free((char*)sdata); + for (i=0 ; i<2; i++) { + NdbRecAttr *p = theFirstPkAttrs[i]; + while (p) { + NdbRecAttr *p_next = p->next(); + m_ndb->releaseRecAttr(p); + p = p_next; + } } for (i=0 ; i<2; i++) { - NdbRecAttr *p = theFirstRecAttrs[i]; + NdbRecAttr *p = theFirstDataAttrs[i]; while (p) { NdbRecAttr *p_next = p->next(); m_ndb->releaseRecAttr(p); p = p_next; } } - if (m_state == NdbEventOperation::EXECUTING) { + if (m_state == EO_EXECUTING) { stop(); // m_bufferHandle->dropSubscribeEvent(m_bufferId); ; // We should send stop signal here @@ -122,36 +131,50 @@ NdbEventOperationImpl::getState() NdbRecAttr* NdbEventOperationImpl::getValue(const char *colName, char *aValue, int n) { - if (m_state != NdbEventOperation::CREATED) { + DBUG_ENTER("NdbEventOperationImpl::getValue"); + if (m_state != EO_CREATED) { ndbout_c("NdbEventOperationImpl::getValue may only be called between instantiation and execute()"); - return NULL; + DBUG_RETURN(NULL); } NdbColumnImpl *tAttrInfo = m_eventImpl->m_tableImpl->getColumn(colName); if (tAttrInfo == NULL) { ndbout_c("NdbEventOperationImpl::getValue attribute %s not found",colName); - return NULL; + DBUG_RETURN(NULL); } - return NdbEventOperationImpl::getValue(tAttrInfo, aValue, n); + DBUG_RETURN(NdbEventOperationImpl::getValue(tAttrInfo, aValue, n)); } NdbRecAttr* NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, int n) { + DBUG_ENTER("NdbEventOperationImpl::getValue"); // Insert Attribute Id into ATTRINFO part. - NdbRecAttr *&theFirstRecAttr = theFirstRecAttrs[n]; - NdbRecAttr *&theCurrentRecAttr = theCurrentRecAttrs[n]; - + + NdbRecAttr **theFirstAttr; + NdbRecAttr **theCurrentAttr; + + if (tAttrInfo->getPrimaryKey()) + { + theFirstAttr = &theFirstPkAttrs[n]; + theCurrentAttr = &theCurrentPkAttrs[n]; + } + else + { + theFirstAttr = &theFirstDataAttrs[n]; + theCurrentAttr = &theCurrentDataAttrs[n]; + } + /************************************************************************ * Get a Receive Attribute object and link it into the operation object. ************************************************************************/ - NdbRecAttr *tRecAttr = m_ndb->getRecAttr(); - if (tRecAttr == NULL) { + NdbRecAttr *tAttr = m_ndb->getRecAttr(); + if (tAttr == NULL) { exit(-1); //setErrorCodeAbort(4000); - return NULL; + DBUG_RETURN(NULL); } /********************************************************************** @@ -159,63 +182,65 @@ NdbEventOperationImpl::getValue(const NdbColumnImpl *tAttrInfo, char *aValue, in * the RecAttr object * Also set attribute size, array size and attribute type ********************************************************************/ - if (tRecAttr->setup(tAttrInfo, aValue)) { + if (tAttr->setup(tAttrInfo, aValue)) { //setErrorCodeAbort(4000); - m_ndb->releaseRecAttr(tRecAttr); + m_ndb->releaseRecAttr(tAttr); exit(-1); - return NULL; + DBUG_RETURN(NULL); } //theErrorLine++; - tRecAttr->setNULL(); + tAttr->setUNDEFINED(); // We want to keep the list sorted to make data insertion easier later - if (theFirstRecAttr == NULL) { - theFirstRecAttr = tRecAttr; - theCurrentRecAttr = tRecAttr; - tRecAttr->next(NULL); + + if (*theFirstAttr == NULL) { + *theFirstAttr = tAttr; + *theCurrentAttr = tAttr; + tAttr->next(NULL); } else { Uint32 tAttrId = tAttrInfo->m_attrId; - if (tAttrId > theCurrentRecAttr->attrId()) { // right order - theCurrentRecAttr->next(tRecAttr); - tRecAttr->next(NULL); - theCurrentRecAttr = tRecAttr; - } else if (theFirstRecAttr->next() == NULL || // only one in list - theFirstRecAttr->attrId() > tAttrId) {// or first - tRecAttr->next(theFirstRecAttr); - theFirstRecAttr = tRecAttr; + if (tAttrId > (*theCurrentAttr)->attrId()) { // right order + (*theCurrentAttr)->next(tAttr); + tAttr->next(NULL); + *theCurrentAttr = tAttr; + } else if ((*theFirstAttr)->next() == NULL || // only one in list + (*theFirstAttr)->attrId() > tAttrId) {// or first + tAttr->next(*theFirstAttr); + *theFirstAttr = tAttr; } else { // at least 2 in list and not first and not last - NdbRecAttr *p = theFirstRecAttr; + NdbRecAttr *p = *theFirstAttr; NdbRecAttr *p_next = p->next(); while (tAttrId > p_next->attrId()) { p = p_next; p_next = p->next(); } if (tAttrId == p_next->attrId()) { // Using same attribute twice - tRecAttr->release(); // do I need to do this? - m_ndb->releaseRecAttr(tRecAttr); + tAttr->release(); // do I need to do this? + m_ndb->releaseRecAttr(tAttr); exit(-1); - return NULL; + DBUG_RETURN(NULL); } // this is it, between p and p_next - p->next(tRecAttr); - tRecAttr->next(p_next); + p->next(tAttr); + tAttr->next(p_next); } } - - return tRecAttr; + DBUG_RETURN(tAttr); } int NdbEventOperationImpl::execute() { + DBUG_ENTER("NdbEventOperationImpl::execute"); NdbDictionary::Dictionary *myDict = m_ndb->getDictionary(); if (!myDict) { - ndbout_c("NdbEventOperation::execute(): getDictionary=NULL"); - return 0; + m_error.code= m_ndb->getNdbError().code; + DBUG_RETURN(-1); } - if (theFirstRecAttrs[0] == NULL) { // defaults to get all + if (theFirstPkAttrs[0] == NULL && + theFirstDataAttrs[0] == NULL) { // defaults to get all } @@ -223,13 +248,18 @@ NdbEventOperationImpl::execute() int hasSubscriber; - m_bufferId = - m_bufferHandle->prepareAddSubscribeEvent(m_eventImpl->m_eventId, - hasSubscriber /* return value */); + int r= m_bufferHandle->prepareAddSubscribeEvent(this, + hasSubscriber /*return value*/); + m_error.code= 4709; + + if (r < 0) + { + DBUG_RETURN(-1); + } - m_eventImpl->m_bufferId = m_bufferId; + m_eventImpl->m_bufferId = m_bufferId = (Uint32)r; - int r = -1; + r = -1; if (m_bufferId >= 0) { // now we check if there's already a subscriber @@ -241,30 +271,33 @@ NdbEventOperationImpl::execute() if (r) { //Error m_bufferHandle->unprepareAddSubscribeEvent(m_bufferId); - m_state = NdbEventOperation::ERROR; + m_state = EO_ERROR; } else { m_bufferHandle->addSubscribeEvent(m_bufferId, this); - m_state = NdbEventOperation::EXECUTING; + m_state = EO_EXECUTING; } } else { //Error - m_state = NdbEventOperation::ERROR; + m_state = EO_ERROR; } - return r; + DBUG_RETURN(r); } int NdbEventOperationImpl::stop() { - if (m_state != NdbEventOperation::EXECUTING) - return -1; + DBUG_ENTER("NdbEventOperationImpl::stop"); + if (m_state != EO_EXECUTING) + { + DBUG_RETURN(-1); + } // ndbout_c("NdbEventOperation::stopping()"); NdbDictionary::Dictionary *myDict = m_ndb->getDictionary(); if (!myDict) { - ndbout_c("NdbEventOperation::stop(): getDictionary=NULL"); - return 0; + m_error.code= m_ndb->getNdbError().code; + DBUG_RETURN(-1); } NdbDictionaryImpl & myDictImpl = NdbDictionaryImpl::getImpl(*myDict); @@ -275,8 +308,8 @@ NdbEventOperationImpl::stop() hasSubscriber /* return value */); if (ret < 0) { - ndbout_c("prepareDropSubscribeEvent failed"); - return -1; + m_error.code= 4712; + DBUG_RETURN(-1); } // m_eventImpl->m_bufferId = m_bufferId; @@ -293,17 +326,17 @@ NdbEventOperationImpl::stop() if (r) { //Error m_bufferHandle->unprepareDropSubscribeEvent(m_bufferId); - m_state = NdbEventOperation::ERROR; + m_error.code= myDictImpl.m_error.code; + m_state = EO_ERROR; } else { #ifdef EVENT_DEBUG ndbout_c("NdbEventOperation::dropping()"); #endif m_bufferHandle->dropSubscribeEvent(m_bufferId); - m_state = NdbEventOperation::CREATED; + m_state = EO_CREATED; } - - return r; + DBUG_RETURN(r); } bool @@ -327,6 +360,7 @@ NdbEventOperationImpl::getLatestGCI() int NdbEventOperationImpl::next(int *pOverrun) { + DBUG_ENTER("NdbEventOperationImpl::next"); int nr = 10000; // a high value int tmpOverrun = 0; int *ptmpOverrun; @@ -343,7 +377,10 @@ NdbEventOperationImpl::next(int *pOverrun) *pOverrun = tmpOverrun; } - if (r <= 0) return r; // no data + if (r <= 0) + { + DBUG_RETURN(r); // no data + } if (r < nr) r = nr; else nr--; // we don't want to be stuck here forever @@ -352,8 +389,13 @@ NdbEventOperationImpl::next(int *pOverrun) #endif // now move the data into the RecAttrs - if ((theFirstRecAttrs[0] == NULL) && - (theFirstRecAttrs[1] == NULL)) return r; + if ((theFirstPkAttrs[0] == NULL) && + (theFirstPkAttrs[1] == NULL) && + (theFirstDataAttrs[0] == NULL) && + (theFirstDataAttrs[1] == NULL)) + { + DBUG_RETURN(r); + } // no copying since no RecAttr's @@ -364,20 +406,37 @@ NdbEventOperationImpl::next(int *pOverrun) #ifdef EVENT_DEBUG int i; printf("after values sz=%u\n", ptr[1].sz); - for (i=0; i < ptr[1].sz; i++) + for(i=0; i < (int)ptr[1].sz; i++) printf ("H'%.8X ",ptr[1].p[i]); printf("\n"); printf("before values sz=%u\n", ptr[2].sz); - for (i=0; i < ptr[2].sz; i++) + for(i=0; i < (int)ptr[2].sz; i++) printf ("H'%.8X ",ptr[2].p[i]); printf("\n"); #endif - NdbRecAttr *tWorkingRecAttr = theFirstRecAttrs[0]; - // copy data into the RecAttr's // we assume that the respective attribute lists are sorted + // first the pk's + { + NdbRecAttr *tAttr= theFirstPkAttrs[0]; + while(tAttr) + { + assert(aAttrPtr < aAttrEndPtr); + unsigned tDataSz= AttributeHeader(*aAttrPtr).getDataSize(); + assert(tAttr->attrId() == + AttributeHeader(*aAttrPtr).getAttributeId()); + assert(tAttr->receive_data(aDataPtr, tDataSz)); + // next + aAttrPtr++; + aDataPtr+= tDataSz; + tAttr= tAttr->next(); + } + } + + NdbRecAttr *tWorkingRecAttr = theFirstDataAttrs[0]; + Uint32 tRecAttrId; Uint32 tAttrId; Uint32 tDataSz; @@ -389,7 +448,7 @@ NdbEventOperationImpl::next(int *pOverrun) while (tAttrId > tRecAttrId) { //printf("[%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); - tWorkingRecAttr->setNULL(); + tWorkingRecAttr->setUNDEFINED(); tWorkingRecAttr = tWorkingRecAttr->next(); if (tWorkingRecAttr == NULL) break; @@ -401,32 +460,25 @@ NdbEventOperationImpl::next(int *pOverrun) //printf("[%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); if (tAttrId == tRecAttrId) { - if (!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey()) - hasSomeData++; + hasSomeData++; //printf("set!\n"); - tWorkingRecAttr->receive_data(aDataPtr, tDataSz); - - // move forward, data has already moved forward - aAttrPtr++; - aDataPtr += tDataSz; + assert(tWorkingRecAttr->receive_data(aDataPtr, tDataSz)); tWorkingRecAttr = tWorkingRecAttr->next(); - } else { - // move only attr forward - aAttrPtr++; - aDataPtr += tDataSz; } + aAttrPtr++; + aDataPtr += tDataSz; } while (tWorkingRecAttr != NULL) { tRecAttrId = tWorkingRecAttr->attrId(); //printf("set undefined [%u] %u %u [%u]\n", tAttrId, tDataSz, *aDataPtr, tRecAttrId); - tWorkingRecAttr->setNULL(); + tWorkingRecAttr->setUNDEFINED(); tWorkingRecAttr = tWorkingRecAttr->next(); } - tWorkingRecAttr = theFirstRecAttrs[1]; + tWorkingRecAttr = theFirstDataAttrs[1]; aDataPtr = ptr[2].p; Uint32 *aDataEndPtr = aDataPtr + ptr[2].sz; while ((aDataPtr < aDataEndPtr) && (tWorkingRecAttr != NULL)) { @@ -435,7 +487,7 @@ NdbEventOperationImpl::next(int *pOverrun) tDataSz = AttributeHeader(*aDataPtr).getDataSize(); aDataPtr++; while (tAttrId > tRecAttrId) { - tWorkingRecAttr->setNULL(); + tWorkingRecAttr->setUNDEFINED(); tWorkingRecAttr = tWorkingRecAttr->next(); if (tWorkingRecAttr == NULL) break; @@ -444,27 +496,25 @@ NdbEventOperationImpl::next(int *pOverrun) if (tWorkingRecAttr == NULL) break; if (tAttrId == tRecAttrId) { - if (!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey()) - hasSomeData++; + assert(!m_eventImpl->m_tableImpl->getColumn(tRecAttrId)->getPrimaryKey()); + hasSomeData++; - tWorkingRecAttr->receive_data(aDataPtr, tDataSz); - aDataPtr += tDataSz; - // move forward, data+attr has already moved forward + assert(tWorkingRecAttr->receive_data(aDataPtr, tDataSz)); tWorkingRecAttr = tWorkingRecAttr->next(); - } else { - // move only data+attr forward - aDataPtr += tDataSz; } + aDataPtr += tDataSz; } while (tWorkingRecAttr != NULL) { - tWorkingRecAttr->setNULL(); + tWorkingRecAttr->setUNDEFINED(); tWorkingRecAttr = tWorkingRecAttr->next(); } if (hasSomeData) - return r; + { + DBUG_RETURN(r); + } } - return 0; + DBUG_RETURN(0); } NdbDictionary::Event::TableEvent @@ -487,10 +537,20 @@ NdbEventOperationImpl::getEventType() void NdbEventOperationImpl::print() { + int i; ndbout << "EventId " << m_eventId << "\n"; - for (int i = 0; i < 2; i++) { - NdbRecAttr *p = theFirstRecAttrs[i]; + for (i = 0; i < 2; i++) { + NdbRecAttr *p = theFirstPkAttrs[i]; + ndbout << " %u " << i; + while (p) { + ndbout << " : " << p->attrId() << " = " << *p; + p = p->next(); + } + ndbout << "\n"; + } + for (i = 0; i < 2; i++) { + NdbRecAttr *p = theFirstDataAttrs[i]; ndbout << " %u " << i; while (p) { ndbout << " : " << p->attrId() << " = " << *p; @@ -639,23 +699,28 @@ NdbGlobalEventBufferHandle::~NdbGlobalEventBufferHandle() void NdbGlobalEventBufferHandle::addBufferId(int bufferId) { + DBUG_ENTER("NdbGlobalEventBufferHandle::addBufferId"); + DBUG_PRINT("enter",("bufferId=%d",bufferId)); if (m_nids >= NDB_MAX_ACTIVE_EVENTS) { ndbout_c("NdbGlobalEventBufferHandle::addBufferId error in paramerer setting"); exit(-1); } m_bufferIds[m_nids] = bufferId; m_nids++; + DBUG_VOID_RETURN; } void NdbGlobalEventBufferHandle::dropBufferId(int bufferId) { + DBUG_ENTER("NdbGlobalEventBufferHandle::dropBufferId"); + DBUG_PRINT("enter",("bufferId=%d",bufferId)); for (int i = 0; i < m_nids; i++) if (m_bufferIds[i] == bufferId) { m_nids--; for (; i < m_nids; i++) m_bufferIds[i] = m_bufferIds[i+1]; - return; + DBUG_VOID_RETURN; } ndbout_c("NdbGlobalEventBufferHandle::dropBufferId %d does not exist", bufferId); @@ -674,10 +739,11 @@ NdbGlobalEventBufferHandle::drop(NdbGlobalEventBufferHandle *handle) } */ int -NdbGlobalEventBufferHandle::prepareAddSubscribeEvent(Uint32 eventId, - int& hasSubscriber) +NdbGlobalEventBufferHandle::prepareAddSubscribeEvent +(NdbEventOperationImpl *eventOp, int& hasSubscriber) { - ADD_DROP_LOCK_GUARDR(int,real_prepareAddSubscribeEvent(this, eventId, hasSubscriber)); + ADD_DROP_LOCK_GUARDR(int,real_prepareAddSubscribeEvent(this, eventOp, + hasSubscriber)); } void NdbGlobalEventBufferHandle::addSubscribeEvent @@ -830,57 +896,68 @@ NdbGlobalEventBuffer::~NdbGlobalEventBuffer() // NdbMem_Deallocate(m_eventBufferIdToEventId); } void -NdbGlobalEventBuffer::real_init (NdbGlobalEventBufferHandle *h, +NdbGlobalEventBuffer::real_init (NdbGlobalEventBufferHandle *h, int MAX_NUMBER_ACTIVE_EVENTS) { - if (m_handlers.size() == 0) { // First init + DBUG_ENTER("NdbGlobalEventBuffer::real_init"); + DBUG_PRINT("enter",("m_handles.size()=%u %u", m_handlers.size(), h)); + if (m_handlers.size() == 0) + { // First init + DBUG_PRINT("info",("first to come")); m_max = MAX_NUMBER_ACTIVE_EVENTS; m_buf = new BufItem[m_max]; - // (BufItem *)NdbMem_Allocate(m_max*sizeof(BufItem)); - for (int i=0; i<m_max; i++) { - m_buf[i].gId = 0; + m_buf[i].gId= 0; } } + assert(m_max == MAX_NUMBER_ACTIVE_EVENTS); // TODO make sure we don't hit roof - // m_handlers[m_nhandlers] = h; m_handlers.push_back(h); - // ndbout_c("NdbGlobalEventBuffer::real_init(), m_handles=%u %u", m_nhandlers, h); + DBUG_VOID_RETURN; } void NdbGlobalEventBuffer::real_remove(NdbGlobalEventBufferHandle *h) { - // ndbout_c("NdbGlobalEventBuffer::real_init_remove(), m_handles=%u %u", m_nhandlers, h); - for (Uint32 i=0 ; i < m_handlers.size(); i++) { - // ndbout_c("%u %u %u", i, m_handlers[i], h); - if (m_handlers[i] == h) { + DBUG_ENTER("NdbGlobalEventBuffer::real_remove"); + DBUG_PRINT("enter",("m_handles.size()=%u %u", m_handlers.size(), h)); + for (Uint32 i=0 ; i < m_handlers.size(); i++) + { + DBUG_PRINT("info",("m_handlers[%u] %u", i, m_handlers[i])); + if (m_handlers[i] == h) + { m_handlers.erase(i); - if (m_handlers.size() == 0) { - // ndbout_c("last to go"); + if (m_handlers.size() == 0) + { + DBUG_PRINT("info",("last to go")); delete[] m_buf; m_buf = NULL; - // NdbMem_Free((char*)m_buf); } - return; + DBUG_VOID_RETURN; } } - ndbout_c("NdbGlobalEventBuffer::real_init_remove() non-existing handle"); - exit(-1); + ndbout_c("NdbGlobalEventBuffer::real_remove() non-existing handle"); + DBUG_PRINT("error",("non-existing handle")); + abort(); + DBUG_VOID_RETURN; } -int +int NdbGlobalEventBuffer::real_prepareAddSubscribeEvent -(NdbGlobalEventBufferHandle *aHandle, Uint32 eventId, int& hasSubscriber) +(NdbGlobalEventBufferHandle *aHandle, NdbEventOperationImpl *eventOp, + int& hasSubscriber) { + DBUG_ENTER("NdbGlobalEventBuffer::real_prepareAddSubscribeEvent"); int i; - int bufferId = -1; + int bufferId= -1; + Uint32 eventId= eventOp->m_eventId; + DBUG_PRINT("enter",("eventId: %u", eventId)); // add_drop_lock(); // only one thread can do add or drop at a time // Find place where eventId already set for (i=0; i<m_no; i++) { if (m_buf[i].gId == eventId) { - bufferId = i; + bufferId= i; break; } } @@ -888,53 +965,55 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent // find space for new bufferId for (i=0; i<m_no; i++) { if (m_buf[i].gId == 0) { - bufferId = i; // we found an empty spot - break; + bufferId= i; // we found an empty spot + goto found_bufferId; } } if (bufferId < 0 && m_no < m_max) { // room for more so get that - bufferId=m_no; - m_buf[m_no].gId = 0; + bufferId= m_no; + m_buf[m_no].gId= 0; m_no++; } else { - ndbout_c("prepareAddSubscribeEvent: Can't accept more subscribers"); - // add_drop_unlock(); - return -1; + // add_drop_unlock(); + DBUG_PRINT("error",("Can't accept more subscribers:" + " bufferId=%d, m_no=%d, m_max=%d", + bufferId, m_no, m_max)); + DBUG_RETURN(-1); } } +found_bufferId: - BufItem &b = m_buf[ID(bufferId)]; + BufItem &b= m_buf[ID(bufferId)]; if (b.gId == 0) { // first subscriber needs some initialization - bufferId = NO_ID(0, bufferId); + bufferId= NO_ID(0, bufferId); - b.gId = eventId; + b.gId= eventId; + b.eventType= (Uint32)eventOp->m_eventImpl->mi_type; - if ((b.p_buf_mutex = NdbMutex_Create()) == NULL) { + if ((b.p_buf_mutex= NdbMutex_Create()) == NULL) { ndbout_c("NdbGlobalEventBuffer: NdbMutex_Create() failed"); - exit(-1); + abort(); } - b.subs = 0; - b.f = 0; - b.sz = 0; - b.max_sz = aHandle->m_bufferL; - b.data = + b.subs= 0; + b.f= 0; + b.sz= 0; + b.max_sz= aHandle->m_bufferL; + b.data= (BufItem::Data *)NdbMem_Allocate(b.max_sz*sizeof(BufItem::Data)); for (int i = 0; i < b.max_sz; i++) { - b.data[i].sdata = NULL; - b.data[i].ptr[0].p = NULL; - b.data[i].ptr[1].p = NULL; - b.data[i].ptr[2].p = NULL; + b.data[i].sdata= NULL; + b.data[i].ptr[0].p= NULL; + b.data[i].ptr[1].p= NULL; + b.data[i].ptr[2].p= NULL; } } else { -#ifdef EVENT_DEBUG - ndbout_c("NdbGlobalEventBuffer::prepareAddSubscribeEvent: TRYING handle one subscriber per event b.subs = %u", b.subs); -#endif - + DBUG_PRINT("info", + ("TRYING handle one subscriber per event b.subs=%u",b.subs)); int ni = -1; for(int i=0; i < b.subs;i++) { if (b.ps[i].theHandle == NULL) { @@ -946,9 +1025,10 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent if (b.subs < MAX_SUBSCRIBERS_PER_EVENT) { ni = b.subs; } else { - ndbout_c("prepareAddSubscribeEvent: Can't accept more subscribers"); + DBUG_PRINT("error", + ("Can't accept more subscribers: b.subs=%d",b.subs)); // add_drop_unlock(); - return -1; + DBUG_RETURN(-1); } } bufferId = NO_ID(ni, bufferId); @@ -969,23 +1049,25 @@ NdbGlobalEventBuffer::real_prepareAddSubscribeEvent else hasSubscriber = 0; -#ifdef EVENT_DEBUG - ndbout_c("prepareAddSubscribeEvent: handed out bufferId %d for eventId %d", - bufferId, eventId); -#endif + DBUG_PRINT("info",("handed out bufferId=%d for eventId=%d hasSubscriber=%d", + bufferId, eventId, hasSubscriber)); /* we now have a lock on the prepare so that no one can mess with this * unlock comes in unprepareAddSubscribeEvent or addSubscribeEvent */ - return bufferId; + DBUG_RETURN(bufferId); } void NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId) { + DBUG_ENTER("NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent"); BufItem &b = m_buf[ID(bufferId)]; int n = NO(bufferId); + DBUG_PRINT("enter", ("bufferId=%d,ID(bufferId)=%d,NO(bufferId)=%d", + bufferId, ID(bufferId), NO(bufferId))); + b.ps[n].theHandle = NULL; // remove subscribers from the end, @@ -998,10 +1080,8 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId) break; if (b.subs == 0) { -#ifdef EVENT_DEBUG - ndbout_c("unprepareAddSubscribeEvent: no more subscribers left on eventId %d", b.gId); -#endif - b.gId = 0; // We don't have any subscribers, reuse BufItem + DBUG_PRINT("info",("no more subscribers left on eventId %d", b.gId)); + b.gId= 0; // We don't have any subscribers, reuse BufItem if (b.data) { NdbMem_Free((void *)b.data); b.data = NULL; @@ -1012,12 +1092,14 @@ NdbGlobalEventBuffer::real_unprepareAddSubscribeEvent(int bufferId) } } // add_drop_unlock(); + DBUG_VOID_RETURN; } void NdbGlobalEventBuffer::real_addSubscribeEvent(int bufferId, void *ndbEventOperation) { + DBUG_ENTER("NdbGlobalEventBuffer::real_addSubscribeEvent"); BufItem &b = m_buf[ID(bufferId)]; int n = NO(bufferId); @@ -1025,9 +1107,8 @@ NdbGlobalEventBuffer::real_addSubscribeEvent(int bufferId, b.ps[n].theHandle->addBufferId(bufferId); // add_drop_unlock(); -#ifdef EVENT_DEBUG - ndbout_c("addSubscribeEvent:: added bufferId %d", bufferId); -#endif + DBUG_PRINT("info",("added bufferId %d", bufferId)); + DBUG_VOID_RETURN; } void @@ -1040,6 +1121,7 @@ int NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId, int& hasSubscriber) { + DBUG_ENTER("NdbGlobalEventBuffer::real_prepareDropSubscribeEvent"); // add_drop_lock(); // only one thread can do add or drop at a time BufItem &b = m_buf[ID(bufferId)]; @@ -1055,14 +1137,17 @@ NdbGlobalEventBuffer::real_prepareDropSubscribeEvent(int bufferId, else if (n == 1) hasSubscriber = 0; else - return -1; + { + DBUG_RETURN(-1); + } - return 0; + DBUG_RETURN(0); } void NdbGlobalEventBuffer::real_dropSubscribeEvent(int bufferId) { + DBUG_ENTER("NdbGlobalEventBuffer::real_dropSubscribeEvent"); // add_drop_lock(); // only one thread can do add-drop at a time BufItem &b = m_buf[ID(bufferId)]; @@ -1078,6 +1163,7 @@ NdbGlobalEventBuffer::real_dropSubscribeEvent(int bufferId) #ifdef EVENT_DEBUG ndbout_c("dropSubscribeEvent:: dropped bufferId %d", bufferId); #endif + DBUG_VOID_RETURN; } void @@ -1100,10 +1186,13 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId, const SubTableData * const sdata, LinearSectionPtr ptr[3]) { + DBUG_ENTER("NdbGlobalEventBuffer::real_insertDataL"); BufItem &b = m_buf[ID(bufferId)]; #ifdef EVENT_DEBUG int n = NO(bufferId); #endif + + if ( b.eventType & (1 << (Uint32)sdata->operation) ) { if (b.subs) { #ifdef EVENT_DEBUG @@ -1112,7 +1201,9 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId, // move front forward if (copy_data_alloc(sdata, ptr, b.data[b.f].sdata, b.data[b.f].ptr)) - return -1; + { + DBUG_RETURN(-1); + } for (int i=0; i < b.subs; i++) { NdbGlobalEventBuffer::BufItem::Ps &e = b.ps[i]; if (e.theHandle) { // active subscriber @@ -1120,7 +1211,7 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId, if (e.bufferempty == 0) { e.overrun++; // another item has been overwritten e.b++; // move next-to-read next since old item was overwritten - if (e.b == b.max_sz) e.b = 0; // start from beginning + if (e.b == b.max_sz) e.b= 0; // start from beginning } } e.bufferempty = 0; @@ -1140,21 +1231,35 @@ NdbGlobalEventBuffer::real_insertDataL(int bufferId, #endif } } - return 0; + else + { +#ifdef EVENT_DEBUG + ndbout_c("skipped"); +#endif + } + + DBUG_RETURN(0); } int NdbGlobalEventBuffer::hasData(int bufferId) { + DBUG_ENTER("NdbGlobalEventBuffer::hasData"); BufItem &b = m_buf[ID(bufferId)]; int n = NO(bufferId); NdbGlobalEventBuffer::BufItem::Ps &e = b.ps[n]; if(e.bufferempty) - return 0; + { + DBUG_RETURN(0); + } if (b.f <= e.b) - return b.max_sz-e.b + b.f; + { + DBUG_RETURN(b.max_sz-e.b + b.f); + } else - return b.f-e.b; + { + DBUG_RETURN(b.f-e.b); + } } int NdbGlobalEventBuffer::real_getDataL(const int bufferId, @@ -1162,6 +1267,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId, LinearSectionPtr ptr[3], int *pOverrun) { + DBUG_ENTER("NdbGlobalEventBuffer::real_getDataL"); BufItem &b = m_buf[ID(bufferId)]; int n = NO(bufferId); NdbGlobalEventBuffer::BufItem::Ps &e = b.ps[n]; @@ -1172,13 +1278,20 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId, } if (e.bufferempty) - return 0; // nothing to get + { + DBUG_RETURN(0); // nothing to get + } + + DBUG_PRINT("info",("ID(bufferId) %d NO(bufferId) %d e.b %d", + ID(bufferId), NO(bufferId), e.b)); if (copy_data_alloc(b.data[e.b].sdata, b.data[e.b].ptr, sdata, ptr)) - return -1; + { + DBUG_RETURN(-1); + } - e.b++; if (e.b == b.max_sz) e.b = 0; // move next-to-read forward + e.b++; if (e.b == b.max_sz) e.b= 0; // move next-to-read forward if (b.f == e.b) // back has cought up with front e.bufferempty = 1; @@ -1187,7 +1300,7 @@ int NdbGlobalEventBuffer::real_getDataL(const int bufferId, ndbout_c("getting data from buffer %d with eventId %d", bufferId, b.gId); #endif - return hasData(bufferId)+1; + DBUG_RETURN(hasData(bufferId)+1); } int NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata, @@ -1195,49 +1308,59 @@ NdbGlobalEventBuffer::copy_data_alloc(const SubTableData * const f_sdata, SubTableData * &t_sdata, LinearSectionPtr t_ptr[3]) { - if (t_sdata == NULL) { - t_sdata = (SubTableData *)NdbMem_Allocate(sizeof(SubTableData)); - } + DBUG_ENTER("NdbGlobalEventBuffer::copy_data_alloc"); + unsigned sz4= (sizeof(SubTableData)+3)>>2; + Uint32 *ptr= (Uint32*)NdbMem_Allocate((sz4 + + f_ptr[0].sz + + f_ptr[1].sz + + f_ptr[2].sz) * sizeof(Uint32)); + if (t_sdata) + NdbMem_Free((char*)t_sdata); + t_sdata= (SubTableData *)ptr; memcpy(t_sdata,f_sdata,sizeof(SubTableData)); + ptr+= sz4; + for (int i = 0; i < 3; i++) { LinearSectionPtr & f_p = f_ptr[i]; LinearSectionPtr & t_p = t_ptr[i]; if (f_p.sz > 0) { - if (t_p.p == NULL) { - t_p.p = (Uint32 *)NdbMem_Allocate(sizeof(Uint32)*f_p.sz); - } else if (t_p.sz != f_p.sz) { - NdbMem_Free(t_p.p); - t_p.p = (Uint32 *)NdbMem_Allocate(sizeof(Uint32)*f_p.sz); - } + t_p.p= (Uint32 *)ptr; memcpy(t_p.p, f_p.p, sizeof(Uint32)*f_p.sz); - } else if (t_p.p != NULL) { - NdbMem_Free(t_p.p); - t_p.p = NULL; + ptr+= f_p.sz; + t_p.sz= f_p.sz; + } else { + t_p.p= NULL; + t_p.sz= 0; } - t_p.sz = f_p.sz; } - return 0; + DBUG_RETURN(0); } int NdbGlobalEventBuffer::real_wait(NdbGlobalEventBufferHandle *h, int aMillisecondNumber) { + DBUG_ENTER("NdbGlobalEventBuffer::real_wait"); // check if there are anything in any of the buffers int i; int n = 0; for (i = 0; i < h->m_nids; i++) n += hasData(h->m_bufferIds[i]); - if (n) return n; + if (n) + { + DBUG_RETURN(n); + } int r = NdbCondition_WaitTimeout(h->p_cond, ndb_global_event_buffer_mutex, aMillisecondNumber); if (r > 0) - return -1; + { + DBUG_RETURN(-1); + } n = 0; for (i = 0; i < h->m_nids; i++) n += hasData(h->m_bufferIds[i]); - return n; + DBUG_RETURN(n); } template class Vector<NdbGlobalEventBufferHandle*>; diff --git a/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/ndb/src/ndbapi/NdbEventOperationImpl.hpp index f67c998e639..96958979c76 100644 --- a/ndb/src/ndbapi/NdbEventOperationImpl.hpp +++ b/ndb/src/ndbapi/NdbEventOperationImpl.hpp @@ -14,21 +14,13 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/***************************************************************************** - * Name: NdbEventOperationImpl.hpp - * Include: - * Link: - * Author: Tomas Ulin MySQL AB - * Date: 2003-11-21 - * Version: 0.1 - * Description: Event support - * Documentation: - * Adjust: 2003-11-21 Tomas Ulin First version. - ****************************************************************************/ - #ifndef NdbEventOperationImpl_H #define NdbEventOperationImpl_H +#include <NdbEventOperation.hpp> +#include <signaldata/SumaImpl.hpp> +#include <transporter/TransporterDefinitions.hpp> + class NdbGlobalEventBufferHandle; class NdbEventOperationImpl : public NdbEventOperation { public: @@ -61,12 +53,17 @@ public: void print(); void printAll(); + const NdbError & getNdbError() const; + NdbError m_error; + Ndb *m_ndb; NdbEventImpl *m_eventImpl; NdbGlobalEventBufferHandle *m_bufferHandle; - NdbRecAttr *theFirstRecAttrs[2]; - NdbRecAttr *theCurrentRecAttrs[2]; + NdbRecAttr *theFirstPkAttrs[2]; + NdbRecAttr *theCurrentPkAttrs[2]; + NdbRecAttr *theFirstDataAttrs[2]; + NdbRecAttr *theCurrentDataAttrs[2]; NdbEventOperation::State m_state; Uint32 m_eventId; @@ -84,7 +81,7 @@ public: //static NdbGlobalEventBufferHandle *init(int MAX_NUMBER_ACTIVE_EVENTS); // returns bufferId 0-N if ok otherwise -1 - int prepareAddSubscribeEvent(Uint32 eventId, int& hasSubscriber); + int prepareAddSubscribeEvent(NdbEventOperationImpl *, int& hasSubscriber); void unprepareAddSubscribeEvent(int bufferId); void addSubscribeEvent(int bufferId, NdbEventOperationImpl *ndbEventOperationImpl); @@ -138,7 +135,8 @@ private: int MAX_NUMBER_ACTIVE_EVENTS); int real_prepareAddSubscribeEvent(NdbGlobalEventBufferHandle *h, - Uint32 eventId, int& hasSubscriber); + NdbEventOperationImpl *, + int& hasSubscriber); void real_unprepareAddSubscribeEvent(int bufferId); void real_addSubscribeEvent(int bufferId, void *ndbEventOperation); @@ -182,6 +180,7 @@ private: // local mutex for each event/buffer NdbMutex *p_buf_mutex; Uint32 gId; + Uint32 eventType; struct Data { SubTableData *sdata; LinearSectionPtr ptr[3]; diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index 00a8ef19f3a..d649b39c5eb 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -89,9 +89,9 @@ Ndb::void2rec(void* val){ } inline -NdbConnection * +NdbTransaction * Ndb::void2con(void* val){ - return (NdbConnection*)val; + return (NdbTransaction*)val; } inline @@ -107,7 +107,7 @@ Ndb::void2rec_iop(void* val){ } inline -NdbConnection * +NdbTransaction * NdbReceiver::getTransaction(){ return ((NdbOperation*)m_owner)->theNdbCon; } diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 23af646c4c7..4cedffed4a2 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -16,9 +16,8 @@ #include <ndb_global.h> #include <NdbIndexOperation.hpp> -#include <NdbResultSet.hpp> #include <Ndb.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <AttributeHeader.hpp> #include <signaldata/TcIndx.hpp> @@ -28,9 +27,7 @@ NdbIndexOperation::NdbIndexOperation(Ndb* aNdb) : NdbOperation(aNdb), - m_theIndex(NULL), - m_theIndexLen(0), - m_theNoOfIndexDefined(0) + m_theIndex(NULL) { m_tcReqGSN = GSN_TCINDXREQ; m_attrInfoGSN = GSN_INDXATTRINFO; @@ -56,7 +53,7 @@ NdbIndexOperation::~NdbIndexOperation() int NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, const NdbTableImpl * aTable, - NdbConnection* myConnection) + NdbTransaction* myConnection) { NdbOperation::init(aTable, myConnection); @@ -64,25 +61,13 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, case(NdbDictionary::Index::UniqueHashIndex): break; case(NdbDictionary::Index::Undefined): - case(NdbDictionary::Index::HashIndex): - case(NdbDictionary::Index::UniqueOrderedIndex): case(NdbDictionary::Index::OrderedIndex): setErrorCodeAbort(4003); return -1; } m_theIndex = anIndex; - m_thePrimaryTable = aTable; m_accessTable = anIndex->m_table; - m_theIndexLen = 0; - m_theNoOfIndexDefined = 0; - for (Uint32 i=0; i<NDB_MAX_ATTRIBUTES_IN_INDEX; i++) - for (int j=0; j<3; j++) - m_theIndexDefined[i][j] = false; - - TcIndxReq * const tcIndxReq = CAST_PTR(TcIndxReq, theTCREQ->getDataPtrSend()); - tcIndxReq->scanInfo = 0; - theKEYINFOptr = &tcIndxReq->keyInfo[0]; - theATTRINFOptr = &tcIndxReq->attrInfo[0]; + theNoOfTupKeyLeft = m_accessTable->getNoOfPrimaryKeys(); return 0; } @@ -179,310 +164,6 @@ int NdbIndexOperation::interpretedDeleteTuple() return NdbOperation::interpretedDeleteTuple(); } -int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, - const char* aValuePassed, - Uint32 aVariableKeyLen) -{ - register Uint32 tAttrId; - - Uint32 tData; - Uint32 tKeyInfoPosition; - const char* aValue = aValuePassed; - Uint32 xfrmData[1024]; - Uint32 tempData[1024]; - - if ((theStatus == OperationDefined) && - (aValue != NULL) && - (tAttrInfo != NULL )) { - /************************************************************************ - * Start by checking that the attribute is an index 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; - Uint32 i = 0; - - // Check that the attribute is part if the index attributes - // by checking if it is a primary key attribute of index table - 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_ATTRIBUTES_IN_INDEX); - 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: - m_theIndexDefined[i][0] = tAttrId; - m_theIndexDefined[i][1] = tKeyInfoPosition; - m_theIndexDefined[i][2] = true; - - 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; - if ((((UintPtr)aValue & 3) != 0) || (slack != 0)){ - memcpy(&tempData[0], aValue, attributeSize); - aValue = (char*)&tempData[0]; - if(slack != 0) { - char * tmp = (char*)&tempData[0]; - memset(&tmp[attributeSize], 0, (4 - slack)); - }//if - }//if - } - const char* aValueToWrite = aValue; - - CHARSET_INFO* cs = tAttrInfo->m_cs; - if (cs != 0) { - // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply <= 1); - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)xfrmData, sizeof(xfrmData), - (const uchar*)aValue, sizeInBytes); - while (n < sizeInBytes) - ((uchar*)xfrmData)[n++] = 0x20; - aValue = (char*)xfrmData; - } - - Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ; - Uint32 totalSizeInWords = (sizeInBytes + 3)/4;// Inc. bits in last word - Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word - - if (true){ //tArraySize != 0) { - Uint32 tIndexLen = m_theIndexLen; - - m_theIndexLen = tIndexLen + 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 - m_theIndexLen = m_theIndexLen + tAttrLenInWords; - }//if -#endif - int tDistrKey = tAttrInfo->m_distributionKey; - int tDistrGroup = tAttrInfo->m_distributionGroup; - OperationType tOpType = theOperationType; - if ((tDistrKey != 1) && (tDistrGroup != 1)) { - ; - } else if (tDistrKey == 1) { - theDistrKeySize += totalSizeInWords; - theDistrKeyIndicator = 1; - } else { - Uint32 TsizeInBytes = sizeInBytes; - Uint32 TbyteOrderFix = 0; - char* TcharByteOrderFix = (char*)&TbyteOrderFix; - if (tAttrInfo->m_distributionGroupBits == 8) { - char tFirstChar = aValue[TsizeInBytes - 2]; - char tSecondChar = aValue[TsizeInBytes - 2]; - TcharByteOrderFix[0] = tFirstChar; - TcharByteOrderFix[1] = tSecondChar; - TcharByteOrderFix[2] = 0x30; - TcharByteOrderFix[3] = 0x30; - theDistrGroupType = 0; - } else { - TbyteOrderFix = ((aValue[TsizeInBytes - 2] - 0x30) * 10) - + (aValue[TsizeInBytes - 1] - 0x30); - theDistrGroupType = 1; - }//if - theDistributionGroup = TbyteOrderFix; - theDistrGroupIndicator = 1; - }//if - /************************************************************************** - * If the operation is a write request and the attribute is stored then - * we also set the value in the stored part through putting the - * information in the INDXATTRINFO signals. - *************************************************************************/ - if ((tOpType == WriteRequest)) { - if (!tAttrInfo->m_indexOnly){ - // invalid data can crash kernel - if (cs != NULL && - (*cs->cset->well_formed_len)(cs, - aValueToWrite, - aValueToWrite + sizeInBytes, - sizeInBytes) != sizeInBytes) - goto equal_error4; - Uint32 ahValue; - Uint32 sz = totalSizeInWords; - /* - * XXX should be linked in metadata but cannot now because - * things can be defined in arbitrary order - */ - const NdbColumnImpl* primaryCol = m_thePrimaryTable->getColumn(tAttrInfo->m_name.c_str()); - assert(primaryCol != NULL); - AttributeHeader::init(&ahValue, primaryCol->m_attrId, sz); - insertATTRINFO( ahValue ); - insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords); - if (bitsInLastWord != 0) { - tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2)); - tData = convertEndian(tData); - tData = tData & ((1 << bitsInLastWord) - 1); - tData = convertEndian(tData); - insertATTRINFO( tData ); - }//if - }//if - }//if - /************************************************************************** - * Store the Key information in the TCINDXREQ and INDXKEYINFO signals. - *************************************************************************/ - if (insertKEYINFO(aValue, tKeyInfoPosition, - totalSizeInWords, bitsInLastWord) != -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 tNoIndexDef = m_theNoOfIndexDefined; - Uint32 tErrorLine = theErrorLine; - int tNoIndexAttrs = m_theIndex->m_columns.size(); - unsigned char tInterpretInd = theInterpretIndicator; - tNoIndexDef++; - m_theNoOfIndexDefined = tNoIndexDef; - tErrorLine++; - theErrorLine = tErrorLine; - if (int(tNoIndexDef) == tNoIndexAttrs) { - if (tOpType == UpdateRequest) { - if (tInterpretInd == 1) { - theStatus = GetValue; - } else { - theStatus = SetValue; - }//if - 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) - return -1; - } - } - } - return 0; - } else if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { - theStatus = SetValue; - return 0; - } else { - setErrorCodeAbort(4005); - return -1; - }//if - }//if - return 0; - } else { - - return -1; - }//if - } else { - if (theStatus != OperationDefined) { - return -1; - }//if - - if (aValue == NULL) { - setErrorCodeAbort(4505); - return -1; - }//if - - if ( tAttrInfo == NULL ) { - setErrorCodeAbort(4004); - return -1; - }//if - }//if - return -1; - - equal_error1: - setErrorCodeAbort(4205); - return -1; - - equal_error2: - setErrorCodeAbort(4206); - return -1; - - equal_error3: - setErrorCodeAbort(4209); - return -1; - - equal_error4: - setErrorCodeAbort(744); - return -1; -} - -int NdbIndexOperation::executeCursor(int aProcessorId) -{ - printf("NdbIndexOperation::executeCursor NYI\n"); - // NYI - return -1; -} -void -NdbIndexOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag) -{ - TcIndxReq * const req = CAST_PTR(TcIndxReq, signal->getDataPtrSend()); - TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag); -} - int NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) { @@ -523,18 +204,18 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) // We start by filling in the first 8 unconditional words of the // TCINDXREQ signal. //------------------------------------------------------------- - TcIndxReq * const tcIndxReq = - CAST_PTR(TcIndxReq, theTCREQ->getDataPtrSend()); + TcKeyReq * tcKeyReq = + CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend()); Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len; Uint32 tIndexId = m_theIndex->m_indexId; Uint32 tSchemaVersion = m_theIndex->m_version; - tcIndxReq->apiConnectPtr = aTC_ConnectPtr; - tcIndxReq->senderData = ptr2int(); - tcIndxReq->attrLen = tTotalCurrAI_Len; - tcIndxReq->indexId = tIndexId; - tcIndxReq->indexSchemaVersion = tSchemaVersion; + tcKeyReq->apiConnectPtr = aTC_ConnectPtr; + tcKeyReq->senderData = ptr2int(); + tcKeyReq->attrLen = tTotalCurrAI_Len; + tcKeyReq->tableId = tIndexId; + tcKeyReq->tableSchemaVersion = tSchemaVersion; tTransId1 = (Uint32) aTransactionId; tTransId2 = (Uint32) (aTransactionId >> 32); @@ -562,59 +243,53 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) Uint8 tSimpleState = tReadInd & tSimpleAlt; //theNdbCon->theSimpleState = tSimpleState; - tcIndxReq->transId1 = tTransId1; - tcIndxReq->transId2 = tTransId2; + tcKeyReq->transId1 = tTransId1; + tcKeyReq->transId2 = tTransId2; tReqInfo = 0; - if (tTotalCurrAI_Len <= TcIndxReq::MaxAttrInfo) { - tcIndxReq->setAIInTcIndxReq(tReqInfo, tTotalCurrAI_Len); + if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) { + tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len); } else { - tcIndxReq->setAIInTcIndxReq(tReqInfo, TcIndxReq::MaxAttrInfo); + tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo); }//if - tcIndxReq->setSimpleFlag(tReqInfo, tSimpleIndicator); - tcIndxReq->setCommitFlag(tReqInfo, tCommitIndicator); - tcIndxReq->setStartFlag(tReqInfo, tStartIndicator); + tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator); + tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator); + tcKeyReq->setStartFlag(tReqInfo, tStartIndicator); const Uint8 tInterpretIndicator = theInterpretIndicator; - tcIndxReq->setInterpretedFlag(tReqInfo, tInterpretIndicator); + tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator); Uint8 tDirtyIndicator = theDirtyIndicator; OperationType tOperationType = theOperationType; - Uint32 tIndexLen = m_theIndexLen; + Uint32 tIndexLen = theTupKeyLen; Uint8 abortOption = theNdbCon->m_abortOption; - tcIndxReq->setDirtyFlag(tReqInfo, tDirtyIndicator); - tcIndxReq->setOperationType(tReqInfo, tOperationType); - tcIndxReq->setIndexLength(tReqInfo, tIndexLen); - tcIndxReq->setCommitType(tReqInfo, abortOption); + tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator); + tcKeyReq->setOperationType(tReqInfo, tOperationType); + tcKeyReq->setKeyLength(tReqInfo, tIndexLen); + tcKeyReq->setAbortOption(tReqInfo, abortOption); - Uint8 tDistrKeyIndicator = theDistrKeyIndicator; - Uint8 tDistrGroupIndicator = theDistrGroupIndicator; - Uint8 tDistrGroupType = theDistrGroupType; + Uint8 tDistrKeyIndicator = theDistrKeyIndicator_; Uint8 tScanIndicator = theScanInfo & 1; - tcIndxReq->setDistributionGroupFlag(tReqInfo, tDistrGroupIndicator); - tcIndxReq->setDistributionGroupTypeFlag(tReqInfo, tDistrGroupType); - tcIndxReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator); - tcIndxReq->setScanIndFlag(tReqInfo, tScanIndicator); + tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator); + tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator); - tcIndxReq->requestInfo = tReqInfo; + tcKeyReq->requestInfo = tReqInfo; //------------------------------------------------------------- // The next step is to fill in the upto three conditional words. //------------------------------------------------------------- - Uint32* tOptionalDataPtr = &tcIndxReq->scanInfo; + Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo; Uint32 tDistrGHIndex = tScanIndicator; - Uint32 tDistrKeyIndex = tDistrGHIndex + tDistrGroupIndicator; + Uint32 tDistrKeyIndex = tDistrGHIndex; Uint32 tScanInfo = theScanInfo; - Uint32 tDistributionGroup = theDistributionGroup; - Uint32 tDistrKeySize = theDistrKeySize; + Uint32 tDistrKey = theDistributionKey; tOptionalDataPtr[0] = tScanInfo; - tOptionalDataPtr[tDistrGHIndex] = tDistributionGroup; - tOptionalDataPtr[tDistrKeyIndex] = tDistrKeySize; + tOptionalDataPtr[tDistrKeyIndex] = tDistrKey; //------------------------------------------------------------- // The next is step is to compress the key data part of the @@ -622,10 +297,10 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) //------------------------------------------------------------- Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator; Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex]; - Uint32 Tdata1 = tcIndxReq->keyInfo[0]; - Uint32 Tdata2 = tcIndxReq->keyInfo[1]; - Uint32 Tdata3 = tcIndxReq->keyInfo[2]; - Uint32 Tdata4 = tcIndxReq->keyInfo[3]; + 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; @@ -633,10 +308,10 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) tKeyDataPtr[2] = Tdata3; tKeyDataPtr[3] = Tdata4; if (tIndexLen > 4) { - Tdata1 = tcIndxReq->keyInfo[4]; - Tdata2 = tcIndxReq->keyInfo[5]; - Tdata3 = tcIndxReq->keyInfo[6]; - Tdata4 = tcIndxReq->keyInfo[7]; + Tdata1 = tcKeyReq->keyInfo[4]; + Tdata2 = tcKeyReq->keyInfo[5]; + Tdata3 = tcKeyReq->keyInfo[6]; + Tdata4 = tcKeyReq->keyInfo[7]; tKeyDataPtr[4] = Tdata1; tKeyDataPtr[5] = Tdata2; @@ -650,12 +325,12 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) //------------------------------------------------------------- Uint32 tAttrInfoIndex; - if (tIndexLen > TcIndxReq::MaxKeyInfo) { + if (tIndexLen > TcKeyReq::MaxKeyInfo) { /** * Set transid and TC connect ptr in the INDXKEYINFO signals */ - NdbApiSignal* tSignal = theFirstKEYINFO; - Uint32 remainingKey = tIndexLen - TcIndxReq::MaxKeyInfo; + NdbApiSignal* tSignal = theTCREQ->next(); + Uint32 remainingKey = tIndexLen - TcKeyReq::MaxKeyInfo; do { Uint32* tSigDataPtr = tSignal->getDataPtrSend(); @@ -676,7 +351,7 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) } tSignal = tnextSignal; } while (tSignal != NULL); - tAttrInfoIndex = tKeyIndex + TcIndxReq::MaxKeyInfo; + tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo; } else { tAttrInfoIndex = tKeyIndex + tIndexLen; }//if @@ -686,14 +361,14 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) // above. //------------------------------------------------------------- Uint32* tAIDataPtr = &tOptionalDataPtr[tAttrInfoIndex]; - Tdata1 = tcIndxReq->attrInfo[0]; - Tdata2 = tcIndxReq->attrInfo[1]; - Tdata3 = tcIndxReq->attrInfo[2]; - Tdata4 = tcIndxReq->attrInfo[3]; - Tdata5 = tcIndxReq->attrInfo[4]; - - theTCREQ->setLength(tcIndxReq->getAIInTcIndxReq(tReqInfo) + - tAttrInfoIndex + TcIndxReq::StaticLength); + Tdata1 = tcKeyReq->attrInfo[0]; + Tdata2 = tcKeyReq->attrInfo[1]; + Tdata3 = tcKeyReq->attrInfo[2]; + Tdata4 = tcKeyReq->attrInfo[3]; + Tdata5 = tcKeyReq->attrInfo[4]; + + theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) + + tAttrInfoIndex + TcKeyReq::StaticLength); tAIDataPtr[0] = Tdata1; tAIDataPtr[1] = Tdata2; tAIDataPtr[2] = Tdata3; @@ -722,11 +397,6 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId) return 0; } -void NdbIndexOperation::closeScan() -{ - printf("NdbIndexOperation::closeScan NYI\n"); -} - /*************************************************************************** int receiveTCINDXREF( NdbApiSignal* aSignal) @@ -738,17 +408,5 @@ Remark: Handles the reception of the TCKEYREF signal. int NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal) { - const TcIndxRef * const tcIndxRef = CAST_CONSTPTR(TcIndxRef, aSignal->getDataPtr()); - - if (checkState_TransId(aSignal) == -1) { - return -1; - }//if - - theStatus = Finished; - - theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - Uint32 errorCode = tcIndxRef->errorCode; - theError.code = errorCode; - theNdbCon->setOperationErrorCodeAbort(errorCode); - return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption); + return receiveTCKEYREF(aSignal); }//NdbIndexOperation::receiveTCINDXREF() diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 88d8a000d50..c9143444908 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include "NdbApiSignal.hpp" #include "NdbRecAttr.hpp" @@ -49,7 +49,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : theCurrentATTRINFO(NULL), theTotalCurrAI_Len(0), theAI_LenInCurrAI(0), - theFirstKEYINFO(NULL), theLastKEYINFO(NULL), theFirstLabel(NULL), @@ -68,13 +67,11 @@ NdbOperation::NdbOperation(Ndb* aNdb) : //theSchemaVersion(0), theTotalNrOfKeyWordInSignal(8), theTupKeyLen(0), - theNoOfTupKeyDefined(0), + theNoOfTupKeyLeft(0), theOperationType(NotDefined), theStatus(Init), theMagicNumber(0xFE11D0), theScanInfo(0), - theDistrKeySize(0), - theDistributionGroup(0), m_tcReqGSN(GSN_TCKEYREQ), m_keyInfoGSN(GSN_KEYINFO), m_attrInfoGSN(GSN_ATTRINFO), @@ -131,7 +128,7 @@ NdbOperation::setErrorCodeAbort(int anErrorCode) *****************************************************************************/ int -NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ +NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){ NdbApiSignal* tSignal; theStatus = Init; theError.code = 0; @@ -145,14 +142,11 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ theFirstATTRINFO = NULL; theCurrentATTRINFO = NULL; - theFirstKEYINFO = NULL; theLastKEYINFO = NULL; - theTupKeyLen = 0; - theNoOfTupKeyDefined = 0; - theDistrKeySize = 0; - theDistributionGroup = 0; + theTupKeyLen = 0; + theNoOfTupKeyLeft = tab->getNoOfPrimaryKeys(); theTotalCurrAI_Len = 0; theAI_LenInCurrAI = 0; @@ -161,9 +155,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ theSimpleIndicator = 0; theDirtyIndicator = 0; theInterpretIndicator = 0; - theDistrGroupIndicator= 0; - theDistrGroupType = 0; - theDistrKeyIndicator = 0; + theDistrKeyIndicator_ = 0; theScanInfo = 0; theTotalNrOfKeyWordInSignal = 8; theMagicNumber = 0xABCDEF01; @@ -210,11 +202,16 @@ NdbOperation::release() NdbBlob* tBlob; NdbBlob* tSaveBlob; - if (theTCREQ != NULL) + tSignal = theTCREQ; + while (tSignal != NULL) { - theNdb->releaseSignal(theTCREQ); - } + tSaveSignal = tSignal; + tSignal = tSignal->next(); + theNdb->releaseSignal(tSaveSignal); + } theTCREQ = NULL; + theLastKEYINFO = NULL; + tSignal = theFirstATTRINFO; while (tSignal != NULL) { @@ -224,15 +221,7 @@ NdbOperation::release() } theFirstATTRINFO = NULL; theCurrentATTRINFO = NULL; - tSignal = theFirstKEYINFO; - while (tSignal != NULL) - { - tSaveSignal = tSignal; - tSignal = tSignal->next(); - theNdb->releaseSignal(tSaveSignal); - } - theFirstKEYINFO = NULL; - theLastKEYINFO = NULL; + if (theInterpretIndicator == 1) { tBranch = theFirstBranch; @@ -403,3 +392,9 @@ NdbOperation::getTableName() const { return m_currentTable->m_externalName.c_str(); } + +const NdbDictionary::Table* +NdbOperation::getTable() const +{ + return m_currentTable; +} diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index c4aaffb3119..835e33dfb40 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -14,28 +14,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/***************************************************************************** - * Name: NdbOperationDefine.C - * Include: - * Link: - * Author: UABMNST Mona Natterkvist UAB/B/SD - * Date: 970829 - * Version: 0.1 - * Description: Interface between TIS and NDB - * Documentation: - * Adjust: 971022 UABMNST First version. - *****************************************************************************/ -#include "NdbOperation.hpp" +#include <ndb_global.h> +#include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include "NdbConnection.hpp" -#include "Ndb.hpp" -#include "NdbRecAttr.hpp" +#include <NdbTransaction.hpp> +#include <Ndb.hpp> +#include <NdbRecAttr.hpp> #include "NdbUtil.hpp" #include "NdbOut.hpp" #include "NdbImpl.hpp" #include <NdbIndexScanOperation.hpp> -#include "NdbBlob.hpp" +#include <NdbBlob.hpp> #include <Interpreter.hpp> @@ -48,7 +37,7 @@ int NdbOperation::insertTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -68,7 +57,7 @@ NdbOperation::insertTuple() int NdbOperation::updateTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -88,7 +77,7 @@ NdbOperation::updateTuple() int NdbOperation::writeTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -128,7 +117,7 @@ NdbOperation::readTuple(NdbOperation::LockMode lm) int NdbOperation::readTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -149,7 +138,7 @@ NdbOperation::readTuple() int NdbOperation::deleteTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -170,7 +159,7 @@ NdbOperation::deleteTuple() int NdbOperation::readTupleExclusive() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -247,7 +236,7 @@ NdbOperation::committedRead() int NdbOperation::dirtyUpdate() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -270,7 +259,7 @@ NdbOperation::dirtyUpdate() int NdbOperation::dirtyWrite() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -293,7 +282,7 @@ NdbOperation::dirtyWrite() int NdbOperation::interpretedUpdateTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -316,7 +305,7 @@ NdbOperation::interpretedUpdateTuple() int NdbOperation::interpretedDeleteTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -350,7 +339,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue) { NdbRecAttr* tRecAttr; if ((tAttrInfo != NULL) && - (!tAttrInfo->m_indexOnly) && (theStatus != Init)){ if (theStatus != GetValue) { if (theInterpretIndicator == 1) { @@ -398,10 +386,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue) setErrorCodeAbort(4004); return NULL; }//if - if (tAttrInfo->m_indexOnly){ - setErrorCodeAbort(4208); - return NULL; - }//if }//if setErrorCodeAbort(4200); return NULL; @@ -422,6 +406,14 @@ int NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, const char* aValuePassed, Uint32 len) { + DBUG_ENTER("NdbOperation::setValue"); + DBUG_PRINT("enter", ("col=%s op=%d val=0x%x len=%u", + tAttrInfo->m_name.c_str(), + theOperationType, + aValuePassed, len)); + if (aValuePassed != NULL) + DBUG_DUMP("value", (char*)aValuePassed, len); + int tReturnCode; Uint32 tAttrId; Uint32 tData; @@ -437,7 +429,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, ; } else { setErrorCodeAbort(4234); - return -1; + DBUG_RETURN(-1); }//if } else { if (tStatus == GetValue) { @@ -448,7 +440,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, // to set values in the tuple by setValue. //-------------------------------------------------------------------- if (insertATTRINFO(Interpreter::EXIT_OK) == -1){ - return -1; + DBUG_RETURN(-1); } theInterpretedSize = theTotalCurrAI_Len - (theInitialReadSize + 5); @@ -459,47 +451,47 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, // setValue used in the wrong context. Application coding error. //------------------------------------------------------------------- setErrorCodeAbort(4234); //Wrong error code - return -1; + DBUG_RETURN(-1); }//if theStatus = SetValueInterpreted; }//if } else if (tOpType == InsertRequest) { if ((theStatus != SetValue) && (theStatus != OperationDefined)) { setErrorCodeAbort(4234); - return -1; + DBUG_RETURN(-1); }//if } else if (tOpType == ReadRequest || tOpType == ReadExclusive) { setErrorCodeAbort(4504); - return -1; + DBUG_RETURN(-1); } else if (tOpType == DeleteRequest) { setErrorCodeAbort(4504); - return -1; + DBUG_RETURN(-1); } else if (tOpType == OpenScanRequest || tOpType == OpenRangeScanRequest) { setErrorCodeAbort(4228); - return -1; + DBUG_RETURN(-1); } else { //--------------------------------------------------------------------- // setValue with undefined operation type. // Probably application coding error. //--------------------------------------------------------------------- setErrorCodeAbort(4108); - return -1; + DBUG_RETURN(-1); }//if if (tAttrInfo == NULL) { setErrorCodeAbort(4004); - return -1; + DBUG_RETURN(-1); }//if if (tAttrInfo->m_pk) { if (theOperationType == InsertRequest) { - return equal_impl(tAttrInfo, aValuePassed, len); + DBUG_RETURN(equal_impl(tAttrInfo, aValuePassed, len)); } else { setErrorCodeAbort(4202); - return -1; + DBUG_RETURN(-1); }//if }//if if (len > 8000) { setErrorCodeAbort(4216); - return -1; + DBUG_RETURN(-1); }//if tAttrId = tAttrInfo->m_attrId; @@ -512,31 +504,19 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, insertATTRINFO(ahValue); // Insert Attribute Id with the value // NULL into ATTRINFO part. - return 0; + DBUG_RETURN(0); } else { /*********************************************************************** * Setting a NULL value on a NOT NULL attribute is not allowed. **********************************************************************/ setErrorCodeAbort(4203); - return -1; + DBUG_RETURN(-1); }//if }//if // Insert Attribute Id into ATTRINFO part. const Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; - CHARSET_INFO* cs = tAttrInfo->m_cs; - // invalid data can crash kernel - if (cs != NULL && - // fast fix bug#7340 - tAttrInfo->m_type != NdbDictionary::Column::Text && - (*cs->cset->well_formed_len)(cs, - aValue, - aValue + sizeInBytes, - sizeInBytes) != sizeInBytes) { - setErrorCodeAbort(744); - return -1; - } #if 0 tAttrSize = tAttrInfo->theAttrSize; tArraySize = tAttrInfo->theArraySize; @@ -550,7 +530,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, const Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ; if (len != sizeInBytes && (len != 0)) { setErrorCodeAbort(4209); - return -1; + DBUG_RETURN(-1); }//if const Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Including bits in last word const Uint32 sizeInWords = sizeInBytes / 4; // Excluding bits in last word @@ -578,7 +558,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, tReturnCode = insertATTRINFOloop((Uint32*)aValue, sizeInWords); if (tReturnCode == -1) { - return tReturnCode; + DBUG_RETURN(tReturnCode); }//if if (bitsInLastWord != 0) { tData = *(Uint32*)(aValue + sizeInWords*4); @@ -587,15 +567,15 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, tData = convertEndian(tData); tReturnCode = insertATTRINFO(tData); if (tReturnCode == -1) { - return tReturnCode; + DBUG_RETURN(tReturnCode); }//if }//if theErrorLine++; - return 0; + DBUG_RETURN(0); }//NdbOperation::setValue() NdbBlob* -NdbOperation::getBlobHandle(NdbConnection* aCon, const NdbColumnImpl* tAttrInfo) +NdbOperation::getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* tAttrInfo) { NdbBlob* tBlob = theBlobList; NdbBlob* tLastBlob = NULL; diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index afa3609e11c..4200300615d 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -16,7 +16,7 @@ #include <ndb_global.h> #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <Ndb.hpp> #include <NdbRecAttr.hpp> @@ -65,7 +65,7 @@ NdbOperation::doSend(int aNodeId, Uint32 lastFlag) if (tReturnCode == -1) { return -1; } - NdbApiSignal *tSignal = theFirstKEYINFO; + NdbApiSignal *tSignal = theTCREQ->next(); while (tSignal != NULL) { NdbApiSignal* tnextSignal = tSignal->next(); tReturnCode = tp->sendSignal(tSignal, aNodeId); @@ -202,13 +202,9 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) abortOption = tSimpleIndicator ? AO_IgnoreError : abortOption; tcKeyReq->setAbortOption(tReqInfo, abortOption); - Uint8 tDistrKeyIndicator = theDistrKeyIndicator; - Uint8 tDistrGroupIndicator = theDistrGroupIndicator; - Uint8 tDistrGroupType = theDistrGroupType; + Uint8 tDistrKeyIndicator = theDistrKeyIndicator_; Uint8 tScanIndicator = theScanInfo & 1; - tcKeyReq->setDistributionGroupFlag(tReqInfo, tDistrGroupIndicator); - tcKeyReq->setDistributionGroupTypeFlag(tReqInfo, tDistrGroupType); tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator); tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator); @@ -219,15 +215,13 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) //------------------------------------------------------------- Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo; Uint32 tDistrGHIndex = tScanIndicator; - Uint32 tDistrKeyIndex = tDistrGHIndex + tDistrGroupIndicator; + Uint32 tDistrKeyIndex = tDistrGHIndex; Uint32 tScanInfo = theScanInfo; - Uint32 tDistributionGroup = theDistributionGroup; - Uint32 tDistrKeySize = theDistrKeySize; + Uint32 tDistrKey = theDistributionKey; tOptionalDataPtr[0] = tScanInfo; - tOptionalDataPtr[tDistrGHIndex] = tDistributionGroup; - tOptionalDataPtr[tDistrKeyIndex] = tDistrKeySize; + tOptionalDataPtr[tDistrKeyIndex] = tDistrKey; //------------------------------------------------------------- // The next is step is to compress the key data part of the @@ -267,7 +261,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) /** * Set transid, TC connect ptr and length in the KEYINFO signals */ - NdbApiSignal* tSignal = theFirstKEYINFO; + NdbApiSignal* tSignal = theTCREQ->next(); Uint32 remainingKey = tTupKeyLen - TcKeyReq::MaxKeyInfo; do { Uint32* tSigDataPtr = tSignal->getDataPtrSend(); @@ -549,10 +543,11 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) theStatus = Finished; // blobs want this if (m_abortOption != AO_IgnoreError) - theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - + { + theNdbCon->theReturnStatus = NdbTransaction::ReturnFailure; + } theError.code = aSignal->readData(4); - theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), m_abortOption); + theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao); if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read return theNdbCon->OpCompleteFailure(ao, m_abortOption != AO_IgnoreError); diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index ace90e35ca4..41e0cb1d140 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -14,13 +14,12 @@ 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 "NdbApiSignal.hpp" -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <Ndb.hpp> -#include "NdbRecAttr.hpp" +#include <NdbRecAttr.hpp> #include "NdbUtil.hpp" #include "Interpreter.hpp" #include <NdbIndexScanOperation.hpp> @@ -84,7 +83,7 @@ NdbOperation::incCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -136,7 +135,7 @@ NdbOperation::write_attrCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -184,7 +183,7 @@ NdbOperation::read_attrCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -220,7 +219,7 @@ NdbOperation::initial_interpreterCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -246,7 +245,7 @@ NdbOperation::labelCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -266,7 +265,7 @@ NdbOperation::intermediate_interpreterCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -1012,33 +1011,56 @@ NdbOperation::insertCall(Uint32 aCall) int NdbOperation::branch_col(Uint32 type, - Uint32 ColId, const char * val, Uint32 len, + Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ + DBUG_ENTER("NdbOperation::branch_col"); + DBUG_PRINT("enter", ("type=%u col=%u val=0x%x len=%u label=%u", + type, ColId, val, len, Label)); + if (val != NULL) + DBUG_DUMP("value", (char*)val, len); + if (initial_interpreterCheck() == -1) - return -1; + DBUG_RETURN(-1); Interpreter::BinaryCondition c = (Interpreter::BinaryCondition)type; - - const NdbDictionary::Column * col = + + const NdbColumnImpl * col = m_currentTable->getColumn(ColId); if(col == 0){ abort(); } - Uint32 vc = col->getType() == NdbDictionary::Column::Varchar; - Uint32 colLen = col->getLength() + 2 * vc; - Uint32 al = (4 - (colLen & 3)) & 0x3; - - if (insertATTRINFO(Interpreter::BranchCol(c, al, vc, nopad)) == -1) - return -1; + if (val == NULL) + len = 0; + else { + if (! col->getStringType()) { + // prevent assert in NdbSqlUtil on length error + Uint32 sizeInBytes = col->m_attrSize * col->m_arraySize; + if (len != 0 && len != sizeInBytes) + { + setErrorCodeAbort(4209); + DBUG_RETURN(-1); + } + len = sizeInBytes; + } + } + + Uint32 tempData[2000]; + if (((UintPtr)val & 3) != 0) { + memcpy(tempData, val, len); + val = tempData; + } + + if (insertATTRINFO(Interpreter::BranchCol(c, 0, 0, false)) == -1) + DBUG_RETURN(-1); if (insertBranch(Label) == -1) - return -1; + DBUG_RETURN(-1); if (insertATTRINFO(Interpreter::BranchCol_2(ColId, len))) - return -1; + DBUG_RETURN(-1); Uint32 len2 = Interpreter::mod4(len); if(len2 == len){ @@ -1049,64 +1071,64 @@ NdbOperation::branch_col(Uint32 type, Uint32 tmp = 0; for (Uint32 i = 0; i < len-len2; i++) { char* p = (char*)&tmp; - p[i] = val[len2+i]; + p[i] = ((char*)val)[len2+i]; } insertATTRINFO(tmp); } theErrorLine++; - return 0; + DBUG_RETURN(0); } int -NdbOperation::branch_col_eq(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_eq(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_eq %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::EQ, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_ne(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_ne(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ne %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::NE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_lt(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_lt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_lt %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LT, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_le(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_le(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_le %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_gt(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_gt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_gt %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::GT, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_ge(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_ge(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ge %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::GE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_like(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_like(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_like %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LIKE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_notlike(Uint32 ColId, const char * val, Uint32 len, - bool nopad, Uint32 Label){ +NdbOperation::branch_col_notlike(Uint32 ColId, const void * val, Uint32 len, + bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_notlike %u %.*s(%u,%d) -> %u", ColId,len,val,len,nopad,Label)); return branch_col(Interpreter::NOT_LIKE, ColId, val, len, nopad, Label); } diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 28a70abcb9b..06d8ddd412b 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -31,14 +31,16 @@ Adjust: 971022 UABMNST First version. #include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include <NdbConnection.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); @@ -55,13 +57,20 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, const char* aValuePassed, Uint32 aVariableKeyLen) { - register Uint32 tAttrId; + 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; - Uint32 xfrmData[1024]; - Uint32 tempData[1024]; + Uint64 tempData[512]; if ((theStatus == OperationDefined) && (aValue != NULL) && @@ -76,6 +85,8 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, *****************************************************************************/ 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]; @@ -117,44 +128,29 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, 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. - *****************************************************************************/ + /************************************************************************ + * 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; - - if ((((UintPtr)aValue & 3) != 0) || (slack != 0)){ + 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(slack != 0) { - char * tmp = (char*)&tempData[0]; - memset(&tmp[attributeSize], 0, (4 - slack)); - }//if }//if } - const char* aValueToWrite = aValue; - - CHARSET_INFO* cs = tAttrInfo->m_cs; - if (cs != 0) { - // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply <= 1); - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)xfrmData, sizeof(xfrmData), - (const uchar*)aValue, sizeInBytes); - while (n < sizeInBytes) - ((uchar*)xfrmData)[n++] = 0x20; - aValue = (char*)xfrmData; - } - Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ; Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word - Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word if (true){ //tArraySize != 0) { Uint32 tTupKeyLen = theTupKeyLen; @@ -190,91 +186,58 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, }//if #endif - int tDistrKey = tAttrInfo->m_distributionKey; - int tDistrGroup = tAttrInfo->m_distributionGroup; - OperationType tOpType = theOperationType; - if ((tDistrKey != 1) && (tDistrGroup != 1)) { - ; - } else if (tDistrKey == 1) { - theDistrKeySize += totalSizeInWords; - theDistrKeyIndicator = 1; - } else { - Uint32 TsizeInBytes = sizeInBytes; - Uint32 TbyteOrderFix = 0; - char* TcharByteOrderFix = (char*)&TbyteOrderFix; - if (tAttrInfo->m_distributionGroupBits == 8) { - char tFirstChar = aValue[TsizeInBytes - 2]; - char tSecondChar = aValue[TsizeInBytes - 2]; - TcharByteOrderFix[0] = tFirstChar; - TcharByteOrderFix[1] = tSecondChar; - TcharByteOrderFix[2] = 0x30; - TcharByteOrderFix[3] = 0x30; - theDistrGroupType = 0; - } else { - TbyteOrderFix = ((aValue[TsizeInBytes - 2] - 0x30) * 10) - + (aValue[TsizeInBytes - 1] - 0x30); - theDistrGroupType = 1; - }//if - theDistributionGroup = TbyteOrderFix; - theDistrGroupIndicator = 1; - }//if - /****************************************************************************** + /************************************************************************** * 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)) { - if (!tAttrInfo->m_indexOnly){ - // invalid data can crash kernel - if (cs != NULL && - (*cs->cset->well_formed_len)(cs, - aValueToWrite, - aValueToWrite + sizeInBytes, - sizeInBytes) != sizeInBytes) - goto equal_error4; - Uint32 ahValue; - const Uint32 sz = totalSizeInWords; + Uint32 ahValue; + const Uint32 sz = totalSizeInWords; + + // XXX + if(m_accessTable == m_currentTable) + { AttributeHeader::init(&ahValue, tAttrId, sz); - insertATTRINFO( ahValue ); - insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords); - if (bitsInLastWord != 0) { - tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2)); - tData = convertEndian(tData); - tData = tData & ((1 << bitsInLastWord) - 1); - tData = convertEndian(tData); - insertATTRINFO( tData ); - }//if - }//if + } + 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, bitsInLastWord) != -1) { - /************************************************************************* + *************************************************************************/ + 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 = theNoOfTupKeyDefined; + ***********************************************************************/ + Uint32 tNoKeysDef = theNoOfTupKeyLeft - 1; Uint32 tErrorLine = theErrorLine; - int tNoTableKeys = m_currentTable->m_noOfKeys; unsigned char tInterpretInd = theInterpretIndicator; - tNoKeysDef++; - theNoOfTupKeyDefined = tNoKeysDef; + theNoOfTupKeyLeft = tNoKeysDef; tErrorLine++; theErrorLine = tErrorLine; - if (int(tNoKeysDef) == tNoTableKeys) { + + if (tNoKeysDef == 0) { if (tOpType == UpdateRequest) { if (tInterpretInd == 1) { theStatus = GetValue; } else { theStatus = SetValue; }//if - return 0; + DBUG_RETURN(0); } else if ((tOpType == ReadRequest) || (tOpType == DeleteRequest) || (tOpType == ReadExclusive)) { theStatus = GetValue; @@ -285,89 +248,62 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, assert(c != 0); if (c->getBlobType()) { if (getBlobHandle(theNdbCon, c) == NULL) - return -1; + DBUG_RETURN(-1); } } } - return 0; + DBUG_RETURN(0); } else if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { theStatus = SetValue; - return 0; + DBUG_RETURN(0); } else { setErrorCodeAbort(4005); - return -1; + DBUG_RETURN(-1); }//if + DBUG_RETURN(0); }//if - return 0; } else { - return -1; + DBUG_RETURN(-1); }//if + DBUG_RETURN(0); } - + if (aValue == NULL) { // NULL value in primary key setErrorCodeAbort(4505); - return -1; + DBUG_RETURN(-1); }//if if ( tAttrInfo == NULL ) { // Attribute name not found in table setErrorCodeAbort(4004); - return -1; + DBUG_RETURN(-1); }//if if (theStatus == GetValue || theStatus == SetValue){ // All pk's defined setErrorCodeAbort(4225); - return -1; + DBUG_RETURN(-1); }//if + + ndbout_c("theStatus: %d", theStatus); // If we come here, set a general errorcode // and exit setErrorCodeAbort(4200); - return -1; + DBUG_RETURN(-1); equal_error1: setErrorCodeAbort(4205); - return -1; + DBUG_RETURN(-1); equal_error2: setErrorCodeAbort(4206); - return -1; + DBUG_RETURN(-1); equal_error3: setErrorCodeAbort(4209); - return -1; - - equal_error4: - setErrorCodeAbort(744); - return -1; -} - -/****************************************************************************** - * Uint64 setTupleId( void ) - * - * Return Value: Return > 0: OK - * Return 0 : setTupleId failed - * Parameters: - * Remark: - *****************************************************************************/ -Uint64 -NdbOperation::setTupleId() -{ - if (theStatus != OperationDefined) - { - return 0; - } - Uint64 tTupleId = theNdb->getTupleIdFromNdb(m_currentTable->m_tableId); - if (tTupleId == ~(Uint64)0){ - setErrorCodeAbort(theNdb->theError.code); - return 0; - } - if (equal((Uint32)0, tTupleId) == -1) - return 0; - - return tTupleId; + DBUG_RETURN(-1); } /****************************************************************************** @@ -387,8 +323,7 @@ NdbOperation::setTupleId() int NdbOperation::insertKEYINFO(const char* aValue, register Uint32 aStartPosition, - register Uint32 anAttrSizeInWords, - register Uint32 anAttrBitsInLastWord) + register Uint32 anAttrSizeInWords) { NdbApiSignal* tSignal; NdbApiSignal* tCurrentKEYINFO; @@ -408,7 +343,7 @@ NdbOperation::insertKEYINFO(const char* aValue, *****************************************************************************/ tEndPos = aStartPosition + anAttrSizeInWords - 1; - if ((tEndPos < 9) && (anAttrBitsInLastWord == 0)) { + if ((tEndPos < 9)) { register Uint32 tkeyData = *(Uint32*)aValue; //TcKeyReq* tcKeyReq = CAST_PTR(TcKeyReq, tTCREQ->getDataPtrSend()); register Uint32* tDataPtr = (Uint32*)aValue; @@ -449,10 +384,11 @@ NdbOperation::insertKEYINFO(const char* aValue, setErrorCodeAbort(4001); return -1; } - if (theFirstKEYINFO != NULL) + if (theTCREQ->next() != NULL) theLastKEYINFO->next(tSignal); else - theFirstKEYINFO = tSignal; + theTCREQ->next(tSignal); + theLastKEYINFO = tSignal; theLastKEYINFO->next(NULL); theTotalNrOfKeyWordInSignal += 20; @@ -465,7 +401,7 @@ NdbOperation::insertKEYINFO(const char* aValue, * this is the first word in a KEYINFO signal. * *****************************************************************************/ tPosition = aStartPosition; - tCurrentKEYINFO = theFirstKEYINFO; + tCurrentKEYINFO = theTCREQ->next(); /***************************************************************************** * Start by filling up Key information in the 8 words allocated in the * @@ -518,39 +454,20 @@ NdbOperation::insertKEYINFO(const char* aValue, } while (1); LastWordLabel: - -/***************************************************************************** - * There could be a last word that only contains partial data. This word* - * will contain zeroes in the rest of the bits since the index expects * - * a certain number of words and do not care for parts of words. * - *****************************************************************************/ - if (anAttrBitsInLastWord != 0) { - tData = *(Uint32*)(aValue + (anAttrSizeInWords - 1) * 4); - tData = convertEndian(tData); - tData = tData & ((1 << anAttrBitsInLastWord) - 1); - tData = convertEndian(tData); - if (tPosition > 8) { - tCurrentKEYINFO->setData(tData, signalCounter); - signalCounter++; - } else { - theTCREQ->setData(tData, (12 + tPosition)); - }//if - }//if - return 0; } int NdbOperation::getKeyFromTCREQ(Uint32* data, unsigned size) { - assert(m_accessTable != 0 && m_accessTable->m_sizeOfKeysInWords != 0); - assert(m_accessTable->m_sizeOfKeysInWords == size); + assert(m_accessTable != 0 && m_accessTable->m_keyLenInWords != 0); + assert(m_accessTable->m_keyLenInWords == size); unsigned pos = 0; while (pos < 8 && pos < size) { data[pos] = theKEYINFOptr[pos]; pos++; } - NdbApiSignal* tSignal = theFirstKEYINFO; + NdbApiSignal* tSignal = theTCREQ->next(); unsigned n = 0; while (pos < size) { if (n == 20) { @@ -561,3 +478,115 @@ NdbOperation::getKeyFromTCREQ(Uint32* data, unsigned size) } return 0; } + +int +NdbOperation::handle_distribution_key(const Uint64* value, Uint32 len) +{ + if(theDistrKeyIndicator_ == 1 || + (theNoOfTupKeyLeft > 0 && m_accessTable->m_noOfDistributionKeys > 1)) + { + return 0; + } + + if(m_accessTable->m_noOfDistributionKeys == 1) + { + setPartitionHash(value, len); + } + else if(theTCREQ->readSignalNumber() == GSN_TCKEYREQ) + { + // No support for combined distribution key and scan + + /** + * Copy distribution key to linear memory + */ + NdbColumnImpl* const * cols = m_accessTable->m_columns.getBase(); + Uint32 len = 0; + Uint64 tmp[1000]; + + Uint32 chunk = 8; + Uint32* dst = (Uint32*)tmp; + NdbApiSignal* tSignal = theTCREQ; + Uint32* src = ((TcKeyReq*)tSignal->getDataPtrSend())->keyInfo; + if(tSignal->readSignalNumber() == GSN_SCAN_TABREQ) + { + tSignal = tSignal->next(); + src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + chunk = KeyInfo::DataLength; + } + + for(unsigned i = m_accessTable->m_columns.size(); i>0; cols++, i--) + { + if (!(* cols)->getPrimaryKey()) + continue; + + NdbColumnImpl* tAttrInfo = * cols; + Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + Uint32 currLen = (sizeInBytes + 3) >> 2; + if (tAttrInfo->getDistributionKey()) + { + while (currLen >= chunk) + { + memcpy(dst, src, 4*chunk); + dst += chunk; + tSignal = tSignal->next(); + src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + currLen -= chunk; + chunk = KeyInfo::DataLength; + } + + memcpy(dst, src, 4*currLen); + dst += currLen; + src += currLen; + chunk -= currLen; + } + else + { + while (currLen >= chunk) + { + tSignal = tSignal->next(); + src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + currLen -= chunk; + chunk = KeyInfo::DataLength; + } + + src += currLen; + chunk -= currLen; + } + } + setPartitionHash(tmp, dst - (Uint32*)tmp); + } + return 0; +} + +void +NdbOperation::setPartitionHash(Uint32 value) +{ + union { + Uint32 tmp32; + Uint64 tmp64; + }; + + tmp32 = value; + setPartitionHash(&tmp64, 1); +} + +void +NdbOperation::setPartitionHash(const Uint64* value, Uint32 len) +{ + Uint32 buf[4]; + md5_hash(buf, value, len); + setPartitionId(buf[1]); +} + +void +NdbOperation::setPartitionId(Uint32 value) +{ + theDistributionKey = value; + theDistrKeyIndicator_ = 1; +} + +Uint32 +NdbOperation::getPartitionId() const +{ + return theDistributionKey; +} diff --git a/ndb/src/ndbapi/NdbPool.cpp b/ndb/src/ndbapi/NdbPool.cpp index ba58520c1dc..a8263f564f1 100644 --- a/ndb/src/ndbapi/NdbPool.cpp +++ b/ndb/src/ndbapi/NdbPool.cpp @@ -21,14 +21,16 @@ static NdbPool* m_pool = 0; bool -create_instance(Uint32 max_ndb_objects, +create_instance(Ndb_cluster_connection* cc, + Uint32 max_ndb_objects, Uint32 no_conn_obj, Uint32 init_no_ndb_objects) { if (m_pool != NULL) { return false; } - m_pool = NdbPool::create_instance(max_ndb_objects, + m_pool = NdbPool::create_instance(cc, + max_ndb_objects, no_conn_obj, init_no_ndb_objects); if (m_pool == NULL) { diff --git a/ndb/src/ndbapi/NdbPoolImpl.cpp b/ndb/src/ndbapi/NdbPoolImpl.cpp index 131edc74246..32e0a6f1410 100644 --- a/ndb/src/ndbapi/NdbPoolImpl.cpp +++ b/ndb/src/ndbapi/NdbPoolImpl.cpp @@ -20,7 +20,8 @@ NdbMutex *NdbPool::pool_mutex = NULL; NdbPool *the_pool = NULL; NdbPool* -NdbPool::create_instance(Uint32 max_ndb_obj, +NdbPool::create_instance(Ndb_cluster_connection* cc, + Uint32 max_ndb_obj, Uint32 no_conn_obj, Uint32 init_no_ndb_objects) { @@ -32,7 +33,7 @@ NdbPool::create_instance(Uint32 max_ndb_obj, if (the_pool != NULL) { a_pool = NULL; } else { - the_pool = new NdbPool(max_ndb_obj, no_conn_obj); + the_pool = new NdbPool(cc, max_ndb_obj, no_conn_obj); if (!the_pool->init(init_no_ndb_objects)) { delete the_pool; the_pool = NULL; @@ -76,7 +77,8 @@ NdbPool::initPoolMutex() return ret_result; } -NdbPool::NdbPool(Uint32 max_no_objects, +NdbPool::NdbPool(Ndb_cluster_connection* cc, + Uint32 max_no_objects, Uint32 no_conn_objects) { if (no_conn_objects > 1024) { @@ -101,6 +103,7 @@ NdbPool::NdbPool(Uint32 max_no_objects, m_output_queue = 0; m_input_queue = 0; m_signal_count = 0; + m_cluster_connection = cc; } NdbPool::~NdbPool() @@ -294,9 +297,9 @@ NdbPool::allocate_ndb(Uint32 &id, return false; } if (a_schema_name) { - a_ndb = new Ndb(a_schema_name, a_catalog_name); + a_ndb = new Ndb(m_cluster_connection, a_schema_name, a_catalog_name); } else { - a_ndb = new Ndb(""); + a_ndb = new Ndb(m_cluster_connection, ""); } if (a_ndb == NULL) { return false; diff --git a/ndb/src/ndbapi/NdbPoolImpl.hpp b/ndb/src/ndbapi/NdbPoolImpl.hpp index af6cf4708cf..cd36f30e90b 100644 --- a/ndb/src/ndbapi/NdbPoolImpl.hpp +++ b/ndb/src/ndbapi/NdbPoolImpl.hpp @@ -92,7 +92,8 @@ class NdbPool { Uint16 prev_db_object; }; public: - static NdbPool* create_instance(Uint32 max_ndb_objects = 240, + static NdbPool* create_instance(Ndb_cluster_connection*, + Uint32 max_ndb_objects = 240, Uint32 no_conn_obj = 4, Uint32 init_no_ndb_objects = 8); static void drop_instance(); @@ -104,7 +105,8 @@ class NdbPool { bool init(Uint32 initial_no_of_ndb_objects = 8); void release_all(); static bool initPoolMutex(); - NdbPool(Uint32 max_no_of_ndb_objects, Uint32 no_conn_objects); + NdbPool(Ndb_cluster_connection*, + Uint32 max_no_of_ndb_objects, Uint32 no_conn_objects); ~NdbPool(); /* We have three lists: @@ -158,5 +160,7 @@ class NdbPool { Uint16 m_input_queue; Uint16 m_output_queue; Uint16 m_signal_count; + + Ndb_cluster_connection * m_cluster_connection; }; #endif diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index db83e9c5fcf..5e5306fc33a 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -15,17 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/************************************************************************************************ -Name: NdbRecAttr.C -Include: -Link: -Author: UABRONM Mikael Ronström UAB/B/SD -Date: 971206 -Version: 0.1 -Description: Interface between TIS and NDB -Documentation: -Adjust: 971206 UABRONM First version -************************************************************************************************/ #include <ndb_global.h> #include <NdbOut.hpp> #include <NdbRecAttr.hpp> @@ -148,6 +137,40 @@ NdbRecAttr::receive_data(const Uint32 * data, Uint32 sz){ return false; } +static void +ndbrecattr_print_string(NdbOut& out, const char *type, + const char *aref, unsigned sz) +{ + const unsigned char* ref = (const unsigned char*)aref; + int i, len, printable= 1; + // trailing zeroes are not printed + for (i=sz-1; i >= 0; i--) + if (ref[i] == 0) sz--; + else break; + if (sz == 0) return; // empty + + for (len=0; len < (int)sz && ref[i] != 0; len++) + if (printable && !isprint((int)ref[i])) + printable= 0; + + if (printable) + out.print("%.*s", len, ref); + else + { + out.print("0x"); + for (i=0; i < len; i++) + out.print("%02X", (int)ref[i]); + } + if (len != (int)sz) + { + out.print("["); + for (i= len+1; ref[i] != 0; i++) + out.print("%u]",len-i); + assert((int)sz > i); + ndbrecattr_print_string(out,type,aref+i,sz-i); + } +} + NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) { if (r.isNULL()) @@ -171,6 +194,9 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) case NdbDictionary::Column::Bigunsigned: out << r.u_64_value(); break; + case NdbDictionary::Column::Bit: + out << hex << "H'" << r.u_32_value() << dec; + break; case NdbDictionary::Column::Unsigned: out << r.u_32_value(); break; @@ -192,17 +218,21 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) case NdbDictionary::Column::Tinyint: out << (int) r.char_value(); break; + case NdbDictionary::Column::Binary: + ndbrecattr_print_string(out,"Binary",r.aRef(),r.arraySize()); + j = r.arraySize(); + break; case NdbDictionary::Column::Char: - out.print("%.*s", r.arraySize(), r.aRef()); + ndbrecattr_print_string(out,"Char",r.aRef(),r.arraySize()); j = length; break; case NdbDictionary::Column::Varchar: - { - short len = ntohs(r.u_short_value()); - out.print("%.*s", len, r.aRef()+2); - } - j = length; - break; + { + unsigned len = *(const unsigned char*)r.aRef(); + ndbrecattr_print_string(out,"Varchar", r.aRef()+1,len); + j = length; + } + break; case NdbDictionary::Column::Float: out << r.float_value(); break; @@ -221,6 +251,10 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) out.print("%.*s", len, r.aRef()); } break; + case NdbDictionary::Column::Decimal: + case NdbDictionary::Column::Decimalunsigned: + goto unknown; // TODO + break; // for dates cut-and-paste from field.cc case NdbDictionary::Column::Datetime: { @@ -323,6 +357,14 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) j = length; } break; + case NdbDictionary::Column::Longvarchar: + { + unsigned len = uint2korr(r.aRef()); + ndbrecattr_print_string(out,"Longvarchar", r.aRef()+2,len); + j = length; + } + break; + unknown: default: /* no print functions for the rest, just print type */ out << (int) r.getType(); j = length; diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index cad247512b2..df16ae66915 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -20,7 +20,7 @@ #include "NdbDictionaryImpl.hpp" #include <NdbRecAttr.hpp> #include <AttributeHeader.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <TransporterFacade.hpp> #include <signaldata/TcKeyConf.hpp> @@ -140,7 +140,10 @@ NdbReceiver::calculate_batch_size(Uint32 key_size, } void -NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ +NdbReceiver::do_get_value(NdbReceiver * org, + Uint32 rows, + Uint32 key_size, + Uint32 range_no){ if(rows > m_defined_rows){ delete[] m_rows; m_defined_rows = rows; @@ -155,7 +158,7 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ key.m_attrSize = 4; key.m_nullable = true; // So that receive works w.r.t KEYINFO20 } - m_key_info = key_size; + m_hidden_count = (key_size ? 1 : 0) + range_no ; for(Uint32 i = 0; i<rows; i++){ NdbRecAttr * prev = theCurrentRecAttr; @@ -167,6 +170,12 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ return ; // -1 } + if(range_no && + !getValue(&NdbColumnImpl::getImpl(* NdbDictionary::Column::RANGE_NO),0)) + { + abort(); + } + NdbRecAttr* tRecAttr = org->theFirstRecAttr; while(tRecAttr != 0){ if(getValue(&NdbColumnImpl::getImpl(*tRecAttr->m_column), (char*)0) != 0) @@ -192,14 +201,14 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ return; } -void +NdbRecAttr* NdbReceiver::copyout(NdbReceiver & dstRec){ - NdbRecAttr* src = m_rows[m_current_row++]; - NdbRecAttr* dst = dstRec.theFirstRecAttr; - Uint32 tmp = m_key_info; - if(tmp > 0){ + NdbRecAttr *src = m_rows[m_current_row++]; + NdbRecAttr *dst = dstRec.theFirstRecAttr; + NdbRecAttr *start = src; + Uint32 tmp = m_hidden_count; + while(tmp--) src = src->next(); - } while(dst){ Uint32 len = ((src->theAttrSize * src->theArraySize)+3)/4; @@ -207,6 +216,8 @@ NdbReceiver::copyout(NdbReceiver & dstRec){ src = src->next(); dst = dst->next(); } + + return start; } int diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp deleted file mode 100644 index d9d71464026..00000000000 --- a/ndb/src/ndbapi/NdbResultSet.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* 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: NdbResultSet.cpp - * Include: - * Link: - * Author: UABMASD Martin Sköld INN/V Alzato - * Date: 2002-04-01 - * Version: 0.1 - * Description: Cursor class - * Documentation: - * Adjust: 2002-04-01 UABMASD First version. - ****************************************************************************/ - -#include <Ndb.hpp> -#include <NdbConnection.hpp> -#include <NdbResultSet.hpp> -#include <NdbBlob.hpp> - -NdbResultSet::NdbResultSet(NdbScanOperation *owner) -: m_operation(owner) -{ -} - -NdbResultSet::~NdbResultSet() -{ -} - -void NdbResultSet::init() -{ -} - -int NdbResultSet::nextResult(bool fetchAllowed, bool forceSend) -{ - int res; - if ((res = m_operation->nextResult(fetchAllowed, forceSend)) == 0) { - // handle blobs - NdbBlob* tBlob = m_operation->theBlobList; - while (tBlob != 0) { - if (tBlob->atNextResult() == -1) - return -1; - tBlob = tBlob->theNext; - } - /* - * Flush blob part ops on behalf of user because - * - nextResult is analogous to execute(NoCommit) - * - user is likely to want blob value before next execute - */ - if (m_operation->m_transConnection->executePendingBlobOps() == -1) - return -1; - return 0; - } - return res; -} - -void NdbResultSet::close(bool forceSend) -{ - m_operation->closeScan(forceSend); -} - -NdbOperation* -NdbResultSet::updateTuple(){ - return updateTuple(m_operation->m_transConnection); -} - -NdbOperation* -NdbResultSet::updateTuple(NdbConnection* takeOverTrans){ - return m_operation->takeOverScanOp(NdbOperation::UpdateRequest, - takeOverTrans); -} - -int -NdbResultSet::deleteTuple(){ - return deleteTuple(m_operation->m_transConnection); -} - -int -NdbResultSet::deleteTuple(NdbConnection * takeOverTrans){ - void * res = m_operation->takeOverScanOp(NdbOperation::DeleteRequest, - takeOverTrans); - if(res == 0) - return -1; - return 0; -} - -int -NdbResultSet::restart(bool forceSend){ - return m_operation->restart(forceSend); -} diff --git a/ndb/src/ndbapi/NdbScanFilter.cpp b/ndb/src/ndbapi/NdbScanFilter.cpp index 0c851427ba5..b39fd10fe95 100644 --- a/ndb/src/ndbapi/NdbScanFilter.cpp +++ b/ndb/src/ndbapi/NdbScanFilter.cpp @@ -48,11 +48,8 @@ public: int cond_col(Interpreter::UnaryCondition, Uint32 attrId); - template<typename T> - int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, T value); - int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, - const char * value, Uint32 len, bool nopad); + const void * value, Uint32 len); }; const Uint32 LabelExit = ~0; @@ -247,68 +244,7 @@ NdbScanFilter::isfalse(){ typedef int (NdbOperation:: * Branch1)(Uint32, Uint32 label); -typedef int (NdbOperation:: * Branch2)(Uint32, Uint32, Uint32 label); -typedef int (NdbOperation:: * StrBranch2)(Uint32, const char*,Uint32,bool,Uint32); - -struct tab { - Branch2 m_branches[5]; -}; - -static const tab table[] = { - /** - * EQ (AND, OR, NAND, NOR) - */ - { { 0, - &NdbOperation::branch_ne, - &NdbOperation::branch_eq, - &NdbOperation::branch_eq, - &NdbOperation::branch_ne } } - - /** - * NEQ - */ - ,{ { 0, - &NdbOperation::branch_eq, - &NdbOperation::branch_ne, - &NdbOperation::branch_ne, - &NdbOperation::branch_eq } } - - /** - * LT - */ - ,{ { 0, - &NdbOperation::branch_le, - &NdbOperation::branch_gt, - &NdbOperation::branch_gt, - &NdbOperation::branch_le } } - - /** - * LE - */ - ,{ { 0, - &NdbOperation::branch_lt, - &NdbOperation::branch_ge, - &NdbOperation::branch_ge, - &NdbOperation::branch_lt } } - - /** - * GT - */ - ,{ { 0, - &NdbOperation::branch_ge, - &NdbOperation::branch_lt, - &NdbOperation::branch_lt, - &NdbOperation::branch_ge } } - - /** - * GE - */ - ,{ { 0, - &NdbOperation::branch_gt, - &NdbOperation::branch_le, - &NdbOperation::branch_le, - &NdbOperation::branch_gt } } -}; +typedef int (NdbOperation:: * StrBranch2)(Uint32, const void*, Uint32, bool, Uint32); struct tab2 { Branch1 m_branches[5]; @@ -334,134 +270,9 @@ static const tab2 table2[] = { &NdbOperation::branch_col_eq_null } } }; -const int tab_sz = sizeof(table)/sizeof(table[0]); const int tab2_sz = sizeof(table2)/sizeof(table2[0]); int -matchType(const NdbDictionary::Column * col){ - return 1; -} - -template<typename T> int load_const(NdbOperation* op, T value, Uint32 reg); - -template<> -int -load_const(NdbOperation* op, Uint32 value, Uint32 reg){ - return op->load_const_u32(reg, value); -} - -template<> -int -load_const(NdbOperation* op, Uint64 value, Uint32 reg){ - return op->load_const_u64(reg, value); -} - -template<typename T> -int -NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, - Uint32 AttrId, T value){ - - if(op < 0 || op >= tab_sz){ - m_operation->setErrorCodeAbort(4262); - return -1; - } - - if(m_current.m_group < NdbScanFilter::AND || - m_current.m_group > NdbScanFilter::NOR){ - m_operation->setErrorCodeAbort(4260); - return -1; - } - - Branch2 branch = table[op].m_branches[m_current.m_group]; - const NdbDictionary::Column * col = - m_operation->m_currentTable->getColumn(AttrId); - - if(col == 0){ - m_operation->setErrorCodeAbort(4261); - return -1; - } - - if(!matchType(col)){ - /** - * Code not reached - */ - return -1; - } - - if(m_latestAttrib != AttrId){ - m_operation->read_attr(&NdbColumnImpl::getImpl(* col), 4); - m_latestAttrib = AttrId; - } - - load_const<T>(m_operation, value, 5); - (m_operation->* branch)(4, 5, m_current.m_ownLabel); - - return 0; -} - -int -NdbScanFilter::eq(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::EQ, AttrId, value); -} - -int -NdbScanFilter::ne(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::NE, AttrId, value); -} - -int -NdbScanFilter::lt(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::LT, AttrId, value); -} - -int -NdbScanFilter::le(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::LE, AttrId, value); -} - -int -NdbScanFilter::gt(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::GT, AttrId, value); -} - -int -NdbScanFilter::ge(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::GE, AttrId, value); -} - - -int -NdbScanFilter::eq(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::EQ, AttrId, value); -} - -int -NdbScanFilter::ne(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::NE, AttrId, value); -} - -int -NdbScanFilter::lt(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::LT, AttrId, value); -} - -int -NdbScanFilter::le(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::LE, AttrId, value); -} - -int -NdbScanFilter::gt(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::GT, AttrId, value); -} - -int -NdbScanFilter::ge(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::GE, AttrId, value); -} - - -int NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){ if(op < 0 || op >= tab2_sz){ @@ -570,11 +381,10 @@ static const tab3 table3[] = { const int tab3_sz = sizeof(table3)/sizeof(table3[0]); - int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, Uint32 AttrId, - const char * value, Uint32 len, bool nopad){ + const void * value, Uint32 len){ if(op < 0 || op >= tab3_sz){ m_operation->setErrorCodeAbort(4260); return -1; @@ -595,49 +405,35 @@ NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, return -1; } - (m_operation->* branch)(AttrId, value, len, nopad, m_current.m_ownLabel); - return 0; -} - -int -NdbScanFilter::eq(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len, nopad); -} - -int -NdbScanFilter::ne(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::NE, ColId, val, len, nopad); -} - -int -NdbScanFilter::lt(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LT, ColId, val, len, nopad); + int ret = (m_operation->* branch)(AttrId, value, len, false, m_current.m_ownLabel); + return ret; } int -NdbScanFilter::le(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LE, ColId, val, len, nopad); -} - -int -NdbScanFilter::gt(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::GT, ColId, val, len, nopad); -} - -int -NdbScanFilter::ge(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::GE, ColId, val, len, nopad); -} - -int -NdbScanFilter::like(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LIKE, ColId, val, len, nopad); -} +NdbScanFilter::cmp(BinaryCondition cond, int ColId, + const void *val, Uint32 len) +{ + switch(cond){ + case COND_LE: + return m_impl.cond_col_const(Interpreter::LE, ColId, val, len); + case COND_LT: + return m_impl.cond_col_const(Interpreter::LT, ColId, val, len); + case COND_GE: + return m_impl.cond_col_const(Interpreter::GE, ColId, val, len); + case COND_GT: + return m_impl.cond_col_const(Interpreter::GT, ColId, val, len); + case COND_EQ: + return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len); + case COND_NE: + return m_impl.cond_col_const(Interpreter::NE, ColId, val, len); + case COND_LIKE: + return m_impl.cond_col_const(Interpreter::LIKE, ColId, val, len); + case COND_NOT_LIKE: + return m_impl.cond_col_const(Interpreter::NOT_LIKE, ColId, val, len); + } + return -1; +} -int -NdbScanFilter::notlike(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::NOT_LIKE, ColId, val, len, nopad); -} #if 0 int @@ -778,10 +574,4 @@ main(void){ #endif template class Vector<NdbScanFilterImpl::State>; -#if __SUNPRO_CC != 0x560 -#ifndef _FORTEC_ -template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint32); -template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint64); -#endif -#endif diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 670a18f72a0..9cd78ec721b 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -18,11 +18,11 @@ #include <Ndb.hpp> #include <NdbScanOperation.hpp> #include <NdbIndexScanOperation.hpp> -#include <NdbConnection.hpp> -#include <NdbResultSet.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <NdbOut.hpp> #include "NdbDictionaryImpl.hpp" +#include <NdbBlob.hpp> #include <NdbRecAttr.hpp> #include <NdbReceiver.hpp> @@ -39,7 +39,6 @@ NdbScanOperation::NdbScanOperation(Ndb* aNdb) : NdbOperation(aNdb), - m_resultSet(0), m_transConnection(NULL) { theParallelism = 0; @@ -60,24 +59,11 @@ NdbScanOperation::~NdbScanOperation() theNdb->releaseNdbScanRec(m_receivers[i]); } delete[] m_array; - if (m_resultSet) - delete m_resultSet; } -NdbResultSet* -NdbScanOperation::getResultSet() -{ - if (!m_resultSet) - m_resultSet = new NdbResultSet(this); - - return m_resultSet; -} - - - void NdbScanOperation::setErrorCode(int aErrorCode){ - NdbConnection* tmp = theNdbCon; + NdbTransaction* tmp = theNdbCon; theNdbCon = m_transConnection; NdbOperation::setErrorCode(aErrorCode); theNdbCon = tmp; @@ -85,7 +71,7 @@ NdbScanOperation::setErrorCode(int aErrorCode){ void NdbScanOperation::setErrorCodeAbort(int aErrorCode){ - NdbConnection* tmp = theNdbCon; + NdbTransaction* tmp = theNdbCon; theNdbCon = m_transConnection; NdbOperation::setErrorCodeAbort(aErrorCode); theNdbCon = tmp; @@ -100,11 +86,11 @@ NdbScanOperation::setErrorCodeAbort(int aErrorCode){ * Remark: Initiates operation record after allocation. *****************************************************************************/ int -NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) +NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection) { m_transConnection = myConnection; - //NdbConnection* aScanConnection = theNdb->startTransaction(myConnection); - NdbConnection* aScanConnection = theNdb->hupp(myConnection); + //NdbTransaction* aScanConnection = theNdb->startTransaction(myConnection); + NdbTransaction* aScanConnection = theNdb->hupp(myConnection); if (!aScanConnection){ setErrorCodeAbort(theNdb->getNdbError().code); return -1; @@ -120,16 +106,17 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) theStatus = GetValue; theOperationType = OpenScanRequest; theNdbCon->theMagicNumber = 0xFE11DF; - + theNoOfTupKeyLeft = tab->m_noOfDistributionKeys; + m_read_range_no = 0; return 0; } -NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, - Uint32 batch, - Uint32 parallel) +int +NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, + Uint32 batch, + Uint32 parallel) { - m_ordered = 0; - + m_ordered = m_descending = false; Uint32 fragCount = m_currentTable->m_fragmentCount; if (parallel > fragCount || parallel == 0) { @@ -142,7 +129,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, // 3. theScanOp contains a NdbScanOperation if (theNdbCon->theScanningOp != NULL){ setErrorCode(4605); - return 0; + return -1; } theNdbCon->theScanningOp = this; @@ -167,14 +154,14 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, break; default: setErrorCode(4003); - return 0; + return -1; } m_keyInfo = lockExcl ? 1 : 0; bool range = false; - if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex || - m_accessTable->m_indexType == NdbDictionary::Index::UniqueOrderedIndex){ + if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex) + { if (m_currentTable == m_accessTable){ // Old way of scanning indexes, should not be allowed m_currentTable = theNdb->theDictionary-> @@ -192,15 +179,16 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, if(fix_receivers(parallel) == -1){ setErrorCodeAbort(4000); - return 0; + return -1; } theSCAN_TABREQ = (!theSCAN_TABREQ ? theNdb->getSignal() : theSCAN_TABREQ); if (theSCAN_TABREQ == NULL) { setErrorCodeAbort(4000); - return 0; + return -1; }//if + theSCAN_TABREQ->setSignal(GSN_SCAN_TABREQ); ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); req->apiConnectPtr = theNdbCon->theTCConPtr; req->tableId = m_accessTable->m_tableId; @@ -221,10 +209,11 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, req->transId1 = (Uint32) transId; req->transId2 = (Uint32) (transId >> 32); - NdbApiSignal* tSignal = - theFirstKEYINFO; - - theFirstKEYINFO = (tSignal ? tSignal : tSignal = theNdb->getSignal()); + NdbApiSignal* tSignal = theSCAN_TABREQ->next(); + if(!tSignal) + { + theSCAN_TABREQ->next(tSignal = theNdb->getSignal()); + } theLastKEYINFO = tSignal; tSignal->setSignal(GSN_KEYINFO); @@ -232,7 +221,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, theTotalNrOfKeyWordInSignal= 0; getFirstATTRINFOScan(); - return getResultSet(); + return 0; } int @@ -356,65 +345,11 @@ NdbScanOperation::getFirstATTRINFOScan() #define FAKE_PTR 2 #define API_PTR 3 - -/* - * After setBound() are done, move the accumulated ATTRINFO signals to - * a separate list. Then continue with normal scan. - */ -#if 0 -int -NdbIndexScanOperation::saveBoundATTRINFO() -{ - theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - theBoundATTRINFO = theFirstATTRINFO; - theTotalBoundAI_Len = theTotalCurrAI_Len; - theTotalCurrAI_Len = 5; - theBoundATTRINFO->setData(theTotalBoundAI_Len, 4); - theBoundATTRINFO->setData(0, 5); - theBoundATTRINFO->setData(0, 6); - theBoundATTRINFO->setData(0, 7); - theBoundATTRINFO->setData(0, 8); - theStatus = GetValue; - - int res = getFirstATTRINFOScan(); - - /** - * Define each key with getValue (if ordered) - * unless the one's with EqBound - */ - if(!res && m_ordered){ - - /** - * If setBound EQ - */ - Uint32 i = 0; - while(theTupleKeyDefined[i][0] == SETBOUND_EQ) - i++; - - - Uint32 cnt = m_accessTable->getNoOfColumns() - 1; - m_sort_columns = cnt - i; - for(; i<cnt; i++){ - const NdbColumnImpl* key = m_accessTable->m_index->m_columns[i]; - const NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos); - NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1); - UintPtr newVal = UintPtr(tmp); - theTupleKeyDefined[i][0] = FAKE_PTR; - theTupleKeyDefined[i][1] = (newVal & 0xFFFFFFFF); -#if (SIZEOF_CHARP == 8) - theTupleKeyDefined[i][2] = (newVal >> 32); -#endif - } - } - return res; -} -#endif - #define WAITFOR_SCAN_TIMEOUT 120000 int NdbScanOperation::executeCursor(int nodeId){ - NdbConnection * tCon = theNdbCon; + NdbTransaction * tCon = theNdbCon; TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); @@ -448,7 +383,7 @@ NdbScanOperation::executeCursor(int nodeId){ TRACE_DEBUG("The node is stopping when attempting to start a scan"); setErrorCode(4030); }//if - tCon->theCommitStatus = NdbConnection::Aborted; + tCon->theCommitStatus = NdbTransaction::Aborted; }//if return -1; } @@ -456,6 +391,29 @@ NdbScanOperation::executeCursor(int nodeId){ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) { + int res; + if ((res = nextResultImpl(fetchAllowed, forceSend)) == 0) { + // handle blobs + NdbBlob* tBlob = theBlobList; + while (tBlob != 0) { + if (tBlob->atNextResult() == -1) + return -1; + tBlob = tBlob->theNext; + } + /* + * Flush blob part ops on behalf of user because + * - nextResult is analogous to execute(NoCommit) + * - user is likely to want blob value before next execute + */ + if (m_transConnection->executePendingBlobOps() == -1) + return -1; + return 0; + } + return res; +} + +int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend) +{ if(m_ordered) return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed, forceSend); @@ -466,6 +424,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) int retVal = 2; Uint32 idx = m_current_api_receiver; Uint32 last = m_api_receivers_count; + m_curr_row = 0; if(DEBUG_NEXT_RESULT) ndbout_c("nextResult(%d) idx=%d last=%d", fetchAllowed, idx, last); @@ -476,7 +435,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) for(; idx < last; idx++){ NdbReceiver* tRec = m_api_receivers[idx]; if(tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); retVal = 0; break; } @@ -552,7 +511,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) for(; idx < last; idx++){ NdbReceiver* tRec = m_api_receivers[idx]; if(tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); retVal = 0; break; } @@ -674,11 +633,11 @@ NdbScanOperation::doSend(int ProcessorId) return 0; } -void NdbScanOperation::closeScan(bool forceSend) +void NdbScanOperation::close(bool forceSend) { if(m_transConnection){ if(DEBUG_NEXT_RESULT) - ndbout_c("closeScan() theError.code = %d " + ndbout_c("close() theError.code = %d " "m_api_receivers_count = %d " "m_conf_receivers_count = %d " "m_sent_receivers_count = %d", @@ -709,17 +668,19 @@ NdbScanOperation::execCLOSE_SCAN_REP(){ void NdbScanOperation::release() { if(theNdbCon != 0 || m_transConnection != 0){ - closeScan(); + close(); } for(Uint32 i = 0; i<m_allocated_receivers; i++){ m_receivers[i]->release(); } + + NdbOperation::release(); + if(theSCAN_TABREQ) { theNdb->releaseSignal(theSCAN_TABREQ); theSCAN_TABREQ = 0; } - NdbOperation::release(); } /*************************************************************************** @@ -786,7 +747,9 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, req->requestInfo = reqInfo; for(Uint32 i = 0; i<theParallelism; i++){ - m_receivers[i]->do_get_value(&theReceiver, batch_size, key_size); + m_receivers[i]->do_get_value(&theReceiver, batch_size, + key_size, + m_read_range_no); } return 0; } @@ -814,10 +777,6 @@ NdbScanOperation::doSendScan(int aProcessorId) assert(theSCAN_TABREQ != NULL); tSignal = theSCAN_TABREQ; - if (tSignal->setSignal(GSN_SCAN_TABREQ) == -1) { - setErrorCode(4001); - return -1; - } Uint32 tupKeyLen = theTupKeyLen; Uint32 len = theTotalNrOfKeyWordInSignal; @@ -829,7 +788,12 @@ NdbScanOperation::doSendScan(int aProcessorId) // we created the ATTRINFO signals after the SCAN_TABREQ signal. ScanTabReq * const req = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend()); req->attrLenKeyLen = (tupKeyLen << 16) | theTotalCurrAI_Len; - + Uint32 tmp = req->requestInfo; + ScanTabReq::setDistributionKeyFlag(tmp, theDistrKeyIndicator_); + req->distributionKey = theDistributionKey; + req->requestInfo = tmp; + tSignal->setLength(ScanTabReq::StaticLength + theDistrKeyIndicator_); + TransporterFacade *tp = TransporterFacade::instance(); LinearSectionPtr ptr[3]; ptr[0].p = m_prepared_receivers; @@ -845,8 +809,8 @@ NdbScanOperation::doSendScan(int aProcessorId) tSignal = theLastKEYINFO; tSignal->setLength(KeyInfo::HeaderLength + theTotalNrOfKeyWordInSignal); - assert(theFirstKEYINFO != NULL); - tSignal = theFirstKEYINFO; + assert(theSCAN_TABREQ->next() != NULL); + tSignal = theSCAN_TABREQ->next(); NdbApiSignal* last; do { @@ -882,6 +846,7 @@ NdbScanOperation::doSendScan(int aProcessorId) } theStatus = WaitResponse; + m_curr_row = 0; m_sent_receivers_count = theParallelism; if(m_ordered) { @@ -893,9 +858,9 @@ NdbScanOperation::doSendScan(int aProcessorId) }//NdbOperation::doSendScan() /***************************************************************************** - * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); + * NdbOperation* takeOverScanOp(NdbTransaction* updateTrans); * - * Parameters: The update transactions NdbConnection pointer. + * Parameters: The update transactions NdbTransaction pointer. * Return Value: A reference to the transferred operation object * or NULL if no success. * Remark: Take over the scanning transactions NdbOperation @@ -905,8 +870,8 @@ NdbScanOperation::doSendScan(int aProcessorId) * * FUTURE IMPLEMENTATION: (This note was moved from header file.) * In the future, it will even be possible to transfer - * to a NdbConnection on another Ndb-object. - * In this case the receiving NdbConnection-object must call + * to a NdbTransaction on another Ndb-object. + * In this case the receiving NdbTransaction-object must call * a method receiveOpFromScan to actually receive the information. * This means that the updating transactions can be placed * in separate threads and thus increasing the parallelism during @@ -915,16 +880,9 @@ NdbScanOperation::doSendScan(int aProcessorId) int NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size) { - Uint32 idx = m_current_api_receiver; - Uint32 last = m_api_receivers_count; - - Uint32 row; - NdbReceiver * tRec; - NdbRecAttr * tRecAttr; - if(idx < last && (tRec = m_api_receivers[idx]) - && ((row = tRec->m_current_row) <= tRec->m_defined_rows) - && (tRecAttr = tRec->m_rows[row-1])){ - + NdbRecAttr * tRecAttr = m_curr_row; + if(tRecAttr) + { const Uint32 * src = (Uint32*)tRecAttr->aRef(); memcpy(data, src, 4*size); return 0; @@ -933,18 +891,12 @@ NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size) } NdbOperation* -NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ +NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans) +{ - Uint32 idx = m_current_api_receiver; - Uint32 last = m_api_receivers_count; - - Uint32 row; - NdbReceiver * tRec; - NdbRecAttr * tRecAttr; - if(idx < last && (tRec = m_api_receivers[idx]) - && ((row = tRec->m_current_row) <= tRec->m_defined_rows) - && (tRecAttr = tRec->m_rows[row-1])){ - + NdbRecAttr * tRecAttr = m_curr_row; + if(tRecAttr) + { NdbOperation * newOp = pTrans->getNdbOperation(m_currentTable); if (newOp == NULL){ return NULL; @@ -963,13 +915,15 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ const Uint32 * src = (Uint32*)tRecAttr->aRef(); const Uint32 tScanInfo = src[len] & 0x3FFFF; - const Uint32 tTakeOverNode = src[len] >> 20; + const Uint32 tTakeOverFragment = src[len] >> 20; { UintR scanInfo = 0; TcKeyReq::setTakeOverScanFlag(scanInfo, 1); - TcKeyReq::setTakeOverScanNode(scanInfo, tTakeOverNode); + TcKeyReq::setTakeOverScanFragment(scanInfo, tTakeOverFragment); TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo); newOp->theScanInfo = scanInfo; + newOp->theDistrKeyIndicator_ = 1; + newOp->theDistributionKey = tTakeOverFragment; } // Copy the first 8 words of key info from KEYINF20 into TCKEYREQ @@ -981,7 +935,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ if(i < len){ NdbApiSignal* tSignal = theNdb->getSignal(); - newOp->theFirstKEYINFO = tSignal; + newOp->theTCREQ->next(tSignal); Uint32 left = len - i; while(tSignal && left > KeyInfo::DataLength){ @@ -1116,37 +1070,28 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, Uint32 currLen = theTotalNrOfKeyWordInSignal; Uint32 remaining = KeyInfo::DataLength - currLen; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + bool tDistrKey = tAttrInfo->m_distributionKey; - // normalize char bound - CHARSET_INFO* cs = tAttrInfo->m_cs; - Uint32 xfrmData[2000]; - if (cs != NULL && aValue != NULL) { - // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply <= 1); - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)xfrmData, sizeof(xfrmData), - (const uchar*)aValue, sizeInBytes); - while (n < sizeInBytes) - ((uchar*)xfrmData)[n++] = 0x20; - aValue = (char*)xfrmData; - } + len = aValue != NULL ? sizeInBytes : 0; if (len != sizeInBytes && (len != 0)) { setErrorCodeAbort(4209); return -1; } + // insert attribute header - len = aValue != NULL ? sizeInBytes : 0; Uint32 tIndexAttrId = tAttrInfo->m_attrId; Uint32 sizeInWords = (len + 3) / 4; AttributeHeader ah(tIndexAttrId, sizeInWords); const Uint32 ahValue = ah.m_value; - const bool aligned = (UintPtr(aValue) & 3) == 0; + const Uint32 align = (UintPtr(aValue) & 7); + const bool aligned = (tDistrKey && type == BoundEQ) ? + (align == 0) : (align & 3) == 0; + const bool nobytes = (len & 0x3) == 0; const Uint32 totalLen = 2 + sizeInWords; Uint32 tupKeyLen = theTupKeyLen; - if(remaining > totalLen && aligned && nobytes){ + if(remaining > totalLen && aligned && nobytes){ Uint32 * dst = theKEYINFOptr + currLen; * dst ++ = type; * dst ++ = ahValue; @@ -1154,12 +1099,12 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, theTotalNrOfKeyWordInSignal = currLen + totalLen; } else { if(!aligned || !nobytes){ - Uint32 tempData[2002]; + Uint32 tempData[2000]; tempData[0] = type; tempData[1] = ahValue; + tempData[2 + (len >> 2)] = 0; memcpy(tempData+2, aValue, len); - while ((len & 0x3) != 0) - ((char*)&tempData[2])[len++] = 0; + insertBOUNDS(tempData, 2+sizeInWords); } else { Uint32 buf[2] = { type, ahValue }; @@ -1178,11 +1123,11 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, * so it's safe to use [tIndexAttrId] * (instead of looping as is NdbOperation::equal_impl) */ - if(type == BoundEQ && !theTupleKeyDefined[tIndexAttrId][0]){ - theNoOfTupKeyDefined++; - theTupleKeyDefined[tIndexAttrId][0] = SETBOUND_EQ; + if(type == BoundEQ && tDistrKey) + { + theNoOfTupKeyLeft--; + return handle_distribution_key((Uint64*)aValue, sizeInWords); } - return 0; } else { setErrorCodeAbort(4228); // XXX wrong code @@ -1230,14 +1175,29 @@ error: return -1; } -NdbResultSet* +int NdbIndexScanOperation::readTuples(LockMode lm, Uint32 batch, Uint32 parallel, - bool order_by){ - NdbResultSet * rs = NdbScanOperation::readTuples(lm, batch, 0); - if(rs && order_by){ - m_ordered = 1; + bool order_by, + bool order_desc, + bool read_range_no){ + int res = NdbScanOperation::readTuples(lm, batch, 0); + if(!res && read_range_no) + { + m_read_range_no = 1; + Uint32 word = 0; + AttributeHeader::init(&word, AttributeHeader::RANGE_NO, 0); + if(insertATTRINFO(word) == -1) + res = -1; + } + if(!res && order_by){ + m_ordered = true; + if (order_desc) { + m_descending = true; + ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); + ScanTabReq::setDescendingFlag(req->requestInfo, true); + } Uint32 cnt = m_accessTable->getNoOfColumns() - 1; m_sort_columns = cnt; // -1 for NDB$NODE m_current_api_receiver = m_sent_receivers_count; @@ -1256,7 +1216,10 @@ NdbIndexScanOperation::readTuples(LockMode lm, #endif } } - return rs; + m_this_bound_start = 0; + m_first_bound_word = theKEYINFOptr; + + return res; } void @@ -1298,22 +1261,23 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols, r1 = (skip ? r1->next() : r1); r2 = (skip ? r2->next() : r2); - + const int jdir = 1 - 2 * (int)m_descending; + assert(jdir == 1 || jdir == -1); while(cols > 0){ Uint32 * d1 = (Uint32*)r1->aRef(); Uint32 * d2 = (Uint32*)r2->aRef(); unsigned r1_null = r1->isNULL(); if((r1_null ^ (unsigned)r2->isNULL())){ - return (r1_null ? -1 : 1); + return (r1_null ? -1 : 1) * jdir; } const NdbColumnImpl & col = NdbColumnImpl::getImpl(* r1->m_column); - Uint32 size = (r1->theAttrSize * r1->theArraySize + 3) / 4; + Uint32 len = r1->theAttrSize * r1->theArraySize; if(!r1_null){ - const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_extType); - int r = (*sqlType.m_cmp)(col.m_cs, d1, d2, size, size); + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_type); + int r = (*sqlType.m_cmp)(col.m_cs, d1, len, d2, len, true); if(r){ assert(r != NdbSqlUtil::CmpUnknown); - return r; + return r * jdir; } } cols--; @@ -1327,6 +1291,7 @@ int NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, bool forceSend){ + m_curr_row = 0; Uint32 u_idx = 0, u_last = 0; Uint32 s_idx = m_current_api_receiver; // first sorted Uint32 s_last = theParallelism; // last sorted @@ -1400,7 +1365,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, s_idx, s_last); - Uint32 cols = m_sort_columns; + Uint32 cols = m_sort_columns + m_read_range_no; Uint32 skip = m_keyInfo; while(u_idx < u_last){ u_last--; @@ -1437,7 +1402,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, tRec = m_api_receivers[s_idx]; if(s_idx < s_last && tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); if(DEBUG_NEXT_RESULT) ndbout_c("return 0"); return 0; } @@ -1656,10 +1621,14 @@ NdbIndexScanOperation::reset_bounds(bool forceSend){ theError.code = 0; reset_receivers(theParallelism, m_ordered); - theLastKEYINFO = theFirstKEYINFO; - theKEYINFOptr = ((KeyInfo*)theFirstKEYINFO->getDataPtrSend())->keyData; + theLastKEYINFO = theSCAN_TABREQ->next(); + theKEYINFOptr = ((KeyInfo*)theLastKEYINFO->getDataPtrSend())->keyData; theTupKeyLen = 0; theTotalNrOfKeyWordInSignal = 0; + theNoOfTupKeyLeft = m_accessTable->m_noOfDistributionKeys; + theDistrKeyIndicator_ = 0; + m_this_bound_start = 0; + m_first_bound_word = theKEYINFOptr; m_transConnection ->remove_list((NdbOperation*&)m_transConnection->m_firstExecutedScanOp, this); @@ -1668,3 +1637,33 @@ NdbIndexScanOperation::reset_bounds(bool forceSend){ } return res; } + +int +NdbIndexScanOperation::end_of_bound(Uint32 no) +{ + if(no < (1 << 13)) // Only 12-bits no of ranges + { + Uint32 bound_head = * m_first_bound_word; + bound_head |= (theTupKeyLen - m_this_bound_start) << 16 | (no << 4); + * m_first_bound_word = bound_head; + + m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;; + m_this_bound_start = theTupKeyLen; + return 0; + } + return -1; +} + +int +NdbIndexScanOperation::get_range_no() +{ + NdbRecAttr* tRecAttr = m_curr_row; + if(m_read_range_no && tRecAttr) + { + if(m_keyInfo) + tRecAttr = tRecAttr->next(); + Uint32 ret = *(Uint32*)tRecAttr->aRef(); + return ret; + } + return -1; +} diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index 0a1c7303771..67581e4a0f8 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -16,7 +16,7 @@ #include <ndb_global.h> #include <NdbOut.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbScanOperation.hpp> #include <NdbIndexScanOperation.hpp> @@ -34,13 +34,13 @@ #include <signaldata/TcHbRep.hpp> /***************************************************************************** -NdbConnection( Ndb* aNdb ); +NdbTransaction( Ndb* aNdb ); Return Value: None Parameters: aNdb: Pointers to the Ndb object Remark: Creates a connection object. *****************************************************************************/ -NdbConnection::NdbConnection( Ndb* aNdb ) : +NdbTransaction::NdbTransaction( Ndb* aNdb ) : theSendStatus(NotInit), theCallbackFunction(NULL), theCallbackObject(NULL), @@ -89,19 +89,19 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size); CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size); -}//NdbConnection::NdbConnection() +}//NdbTransaction::NdbTransaction() /***************************************************************************** -~NdbConnection(); +~NdbTransaction(); Remark: Deletes the connection object. *****************************************************************************/ -NdbConnection::~NdbConnection() +NdbTransaction::~NdbTransaction() { - DBUG_ENTER("NdbConnection::~NdbConnection"); + DBUG_ENTER("NdbTransaction::~NdbTransaction"); theNdb->theImpl->theNdbObjectIdMap.unmap(theId, this); DBUG_VOID_RETURN; -}//NdbConnection::~NdbConnection() +}//NdbTransaction::~NdbTransaction() /***************************************************************************** void init(); @@ -109,7 +109,7 @@ void init(); Remark: Initialise connection object for new transaction. *****************************************************************************/ void -NdbConnection::init() +NdbTransaction::init() { theListState = NotInList; theInUseState = true; @@ -149,7 +149,7 @@ NdbConnection::init() // theBlobFlag = false; thePendingBlobOps = 0; -}//NdbConnection::init() +}//NdbTransaction::init() /***************************************************************************** setOperationErrorCode(int error); @@ -158,9 +158,9 @@ Remark: Sets an error code on the connection object from an operation object. *****************************************************************************/ void -NdbConnection::setOperationErrorCode(int error) +NdbTransaction::setOperationErrorCode(int error) { - DBUG_ENTER("NdbConnection::setOperationErrorCode"); + DBUG_ENTER("NdbTransaction::setOperationErrorCode"); setErrorCode(error); DBUG_VOID_RETURN; } @@ -172,9 +172,9 @@ Remark: Sets an error code on the connection object from an operation object. *****************************************************************************/ void -NdbConnection::setOperationErrorCodeAbort(int error, int abortOption) +NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption) { - DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort"); + DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort"); if (abortOption == -1) abortOption = m_abortOption; if (theTransactionIsStarted == false) { @@ -194,20 +194,20 @@ setErrorCode(int anErrorCode); Remark: Sets an error indication on the connection object. *****************************************************************************/ void -NdbConnection::setErrorCode(int error) +NdbTransaction::setErrorCode(int error) { - DBUG_ENTER("NdbConnection::setErrorCode"); + DBUG_ENTER("NdbTransaction::setErrorCode"); DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code)); if (theError.code == 0) theError.code = error; DBUG_VOID_RETURN; -}//NdbConnection::setErrorCode() +}//NdbTransaction::setErrorCode() int -NdbConnection::restart(){ - DBUG_ENTER("NdbConnection::restart"); +NdbTransaction::restart(){ + DBUG_ENTER("NdbTransaction::restart"); if(theCompletionStatus == CompletedSuccess){ releaseCompletedOperations(); Uint64 tTransid = theNdb->theFirstTransId; @@ -232,23 +232,8 @@ void handleExecuteCompletion(void); Remark: Handle time-out on a transaction object. *****************************************************************************/ void -NdbConnection::handleExecuteCompletion() +NdbTransaction::handleExecuteCompletion() { - - if (theCompletionStatus == CompletedFailure) { - NdbOperation* tOpTemp = theFirstExecOpInList; - while (tOpTemp != NULL) { -/***************************************************************************** - * Ensure that all executing operations report failed for each - * read attribute when failure occurs. - * We do not want any operations to report both failure and - * success on different read attributes. - ****************************************************************************/ - tOpTemp->handleFailedAI_ElemLen(); - tOpTemp = tOpTemp->next(); - }//while - theReturnStatus = ReturnFailure; - }//if /*************************************************************************** * Move the NdbOperation objects from the list of executing * operations to list of completed @@ -265,7 +250,7 @@ NdbConnection::handleExecuteCompletion() }//if theSendStatus = InitState; return; -}//NdbConnection::handleExecuteCompletion() +}//NdbTransaction::handleExecuteCompletion() /***************************************************************************** int execute(ExecType aTypeOfExec, CommitType aTypeOfCommit, int forceSend); @@ -276,11 +261,11 @@ Parameters : aTypeOfExec: Type of execute. Remark: Initialise connection object for new transaction. *****************************************************************************/ int -NdbConnection::execute(ExecType aTypeOfExec, +NdbTransaction::execute(ExecType aTypeOfExec, AbortOption abortOption, int forceSend) { - DBUG_ENTER("NdbConnection::execute"); + DBUG_ENTER("NdbTransaction::execute"); DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", aTypeOfExec, abortOption)); @@ -410,11 +395,11 @@ NdbConnection::execute(ExecType aTypeOfExec, } int -NdbConnection::executeNoBlobs(ExecType aTypeOfExec, +NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, AbortOption abortOption, int forceSend) { - DBUG_ENTER("NdbConnection::executeNoBlobs"); + DBUG_ENTER("NdbTransaction::executeNoBlobs"); DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", aTypeOfExec, abortOption)); @@ -423,7 +408,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, // since last execute or since beginning. If this works ok we will continue // by calling the poll with wait method. This method will return when // the NDB kernel has completed its task or when 10 seconds have passed. -// The NdbConnectionCallBack-method will receive the return code of the +// The NdbTransactionCallBack-method will receive the return code of the // transaction. The normal methods of reading error codes still apply. //------------------------------------------------------------------------ Ndb* tNdb = theNdb; @@ -471,7 +456,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, } thePendingBlobOps = 0; DBUG_RETURN(0); -}//NdbConnection::execute() +}//NdbTransaction::execute() /***************************************************************************** void executeAsynchPrepare(ExecType aTypeOfExec, @@ -489,12 +474,12 @@ Parameters : aTypeOfExec: Type of execute. Remark: Prepare a part of a transaction in an asynchronous manner. *****************************************************************************/ void -NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, +NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec, NdbAsynchCallback aCallback, void* anyObject, AbortOption abortOption) { - DBUG_ENTER("NdbConnection::executeAsynchPrepare"); + DBUG_ENTER("NdbTransaction::executeAsynchPrepare"); DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x", aTypeOfExec, aCallback, anyObject)); @@ -657,14 +642,14 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, NdbNodeBitmask::clear(m_db_nodes); NdbNodeBitmask::clear(m_failed_db_nodes); DBUG_VOID_RETURN; -}//NdbConnection::executeAsynchPrepare() +}//NdbTransaction::executeAsynchPrepare() -void NdbConnection::close() +void NdbTransaction::close() { theNdb->closeTransaction(this); } -int NdbConnection::refresh(){ +int NdbTransaction::refresh(){ return sendTC_HBREP(); } @@ -676,7 +661,7 @@ Parameters : None. Remark: Order NDB to refresh the timeout counter of the transaction. ******************************************************************************/ int -NdbConnection::sendTC_HBREP() // Send a TC_HBREP signal; +NdbTransaction::sendTC_HBREP() // Send a TC_HBREP signal; { NdbApiSignal* tSignal; Ndb* tNdb = theNdb; @@ -711,7 +696,7 @@ NdbConnection::sendTC_HBREP() // Send a TC_HBREP signal; } return 0; -}//NdbConnection::sendTC_HBREP() +}//NdbTransaction::sendTC_HBREP() /***************************************************************************** int doSend(); @@ -723,9 +708,9 @@ Remark: Send all operations belonging to this connection. object from the prepared transactions array on the Ndb-object. *****************************************************************************/ int -NdbConnection::doSend() +NdbTransaction::doSend() { - DBUG_ENTER("NdbConnection::doSend"); + DBUG_ENTER("NdbTransaction::doSend"); /* This method assumes that at least one operation have been defined. This @@ -784,7 +769,7 @@ NdbConnection::doSend() theTransactionIsStarted = false; theCommitStatus = Aborted; DBUG_RETURN(-1); -}//NdbConnection::doSend() +}//NdbTransaction::doSend() /************************************************************************** int sendROLLBACK(); @@ -794,7 +779,7 @@ Parameters : None. Remark: Order NDB to rollback the transaction. **************************************************************************/ int -NdbConnection::sendROLLBACK() // Send a TCROLLBACKREQ signal; +NdbTransaction::sendROLLBACK() // Send a TCROLLBACKREQ signal; { Ndb* tNdb = theNdb; if ((theTransactionIsStarted == true) && @@ -838,7 +823,7 @@ NdbConnection::sendROLLBACK() // Send a TCROLLBACKREQ signal; return 0; ; }//if -}//NdbConnection::sendROLLBACK() +}//NdbTransaction::sendROLLBACK() /*************************************************************************** int sendCOMMIT(); @@ -849,7 +834,7 @@ Parameters : None. Remark: Order NDB to commit the transaction. ***************************************************************************/ int -NdbConnection::sendCOMMIT() // Send a TC_COMMITREQ signal; +NdbTransaction::sendCOMMIT() // Send a TC_COMMITREQ signal; { NdbApiSignal tSignal(theNdb->theMyRef); Uint32 tTransId1, tTransId2; @@ -871,7 +856,7 @@ NdbConnection::sendCOMMIT() // Send a TC_COMMITREQ signal; } else { return -1; }//if -}//NdbConnection::sendCOMMIT() +}//NdbTransaction::sendCOMMIT() /****************************************************************************** void release(); @@ -879,7 +864,7 @@ void release(); Remark: Release all operations. ******************************************************************************/ void -NdbConnection::release(){ +NdbTransaction::release(){ releaseOperations(); if ( (theTransactionIsStarted == true) && ((theCommitStatus != Committed) && @@ -898,10 +883,10 @@ NdbConnection::release(){ abort(); } #endif -}//NdbConnection::release() +}//NdbTransaction::release() void -NdbConnection::releaseOps(NdbOperation* tOp){ +NdbTransaction::releaseOps(NdbOperation* tOp){ while (tOp != NULL) { NdbOperation* tmp = tOp; tOp->release(); @@ -916,7 +901,7 @@ void releaseOperations(); Remark: Release all operations. ******************************************************************************/ void -NdbConnection::releaseOperations() +NdbTransaction::releaseOperations() { // Release any open scans releaseScanOperations(m_theFirstScanOperation); @@ -936,15 +921,15 @@ NdbConnection::releaseOperations() m_theFirstScanOperation = NULL; m_theLastScanOperation = NULL; m_firstExecutedScanOp = NULL; -}//NdbConnection::releaseOperations() +}//NdbTransaction::releaseOperations() void -NdbConnection::releaseCompletedOperations() +NdbTransaction::releaseCompletedOperations() { releaseOps(theCompletedFirstOp); theCompletedFirstOp = NULL; theCompletedLastOp = NULL; -}//NdbConnection::releaseOperations() +}//NdbTransaction::releaseOperations() /****************************************************************************** void releaseScanOperations(); @@ -953,7 +938,7 @@ Remark: Release all cursor operations. (NdbScanOperation and NdbIndexOperation) ******************************************************************************/ void -NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) +NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp) { while(cursorOp != 0){ NdbIndexScanOperation* next = (NdbIndexScanOperation*)cursorOp->next(); @@ -961,7 +946,7 @@ NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) theNdb->releaseScanOperation(cursorOp); cursorOp = next; } -}//NdbConnection::releaseScanOperations() +}//NdbTransaction::releaseScanOperations() /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName); @@ -971,13 +956,13 @@ Return Value Return a pointer to a NdbOperation object if getNdbOperation Return NULL : In all other case. Parameters: aTableName : Name of the database table. Remark: Get an operation from NdbOperation idlelist and get the - NdbConnection object + NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object. synchronous ******************************************************************************/ NdbOperation* -NdbConnection::getNdbOperation(const char* aTableName) +NdbTransaction::getNdbOperation(const char* aTableName) { if (theCommitStatus == Started){ NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName); @@ -992,7 +977,7 @@ NdbConnection::getNdbOperation(const char* aTableName) setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() /***************************************************************************** NdbOperation* getNdbOperation(int aTableId); @@ -1002,13 +987,13 @@ Return Value Return a pointer to a NdbOperation object if getNdbOperation Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. Remark: Get an operation from NdbOperation object idlelist and - get the NdbConnection object who was fetch by + get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object, synchronous. *****************************************************************************/ NdbOperation* -NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) +NdbTransaction::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) { NdbOperation* tOp; @@ -1052,15 +1037,15 @@ NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() -NdbOperation* NdbConnection::getNdbOperation(const NdbDictionary::Table * table) +NdbOperation* NdbTransaction::getNdbOperation(const NdbDictionary::Table * table) { if (table) return getNdbOperation(& NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() // NdbScanOperation /***************************************************************************** @@ -1069,12 +1054,12 @@ NdbScanOperation* getNdbScanOperation(const char* aTableName); Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. Return NULL : In all other case. Parameters: aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object +Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object.synchronous ******************************************************************************/ NdbScanOperation* -NdbConnection::getNdbScanOperation(const char* aTableName) +NdbTransaction::getNdbScanOperation(const char* aTableName) { if (theCommitStatus == Started){ NdbTableImpl* tab = theNdb->theDictionary->getTable(aTableName); @@ -1088,78 +1073,104 @@ NdbConnection::getNdbScanOperation(const char* aTableName) setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() /***************************************************************************** -NdbScanOperation* getNdbScanOperation(const char* anIndexName, const char* aTableName); +NdbScanOperation* getNdbIndexScanOperation(const char* anIndexName, const char* aTableName); -Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. +Return Value Return a pointer to a NdbIndexScanOperation object if getNdbIndexScanOperation was succesful. Return NULL : In all other case. Parameters: anIndexName : Name of the index to use. aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object +Remark: Get an operation from NdbIndexScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbOperation object.synchronous + getOperation will set the theTableId in the NdbIndexScanOperation object.synchronous ******************************************************************************/ NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const char* anIndexName, +NdbTransaction::getNdbIndexScanOperation(const char* anIndexName, const char* aTableName) { NdbIndexImpl* index = theNdb->theDictionary->getIndex(anIndexName, aTableName); + if (index == 0) + { + setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code); + return 0; + } NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName); + if (table == 0) + { + setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code); + return 0; + } return getNdbIndexScanOperation(index, table); } NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, +NdbTransaction::getNdbIndexScanOperation(const NdbIndexImpl* index, const NdbTableImpl* table) { if (theCommitStatus == Started){ const NdbTableImpl * indexTable = index->getIndexTable(); if (indexTable != 0){ - NdbIndexScanOperation* tOp = - getNdbScanOperation((NdbTableImpl *) indexTable); + NdbIndexScanOperation* tOp = getNdbScanOperation(indexTable); if(tOp) { tOp->m_currentTable = table; - tOp->m_cursor_type = NdbScanOperation::IndexCursor; } return tOp; } else { - setOperationErrorCodeAbort(theNdb->theError.code); + setOperationErrorCodeAbort(4271); return NULL; }//if } setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbIndexScanOperation() +}//NdbTransaction::getNdbIndexScanOperation() + +NdbIndexScanOperation* +NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index) +{ + if (index) + { + const NdbDictionary::Table *table= + theNdb->theDictionary->getTable(index->getTable()); + + if (table) + return getNdbIndexScanOperation(index, table); + + setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code); + return NULL; + } + setOperationErrorCodeAbort(4271); + return NULL; +} NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index, +NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index, const NdbDictionary::Table * table) { if (index && table) return getNdbIndexScanOperation(& NdbIndexImpl::getImpl(*index), & NdbTableImpl::getImpl(*table)); - else - return NULL; -}//NdbConnection::getNdbIndexScanOperation() + setOperationErrorCodeAbort(4271); + return NULL; +}//NdbTransaction::getNdbIndexScanOperation() /***************************************************************************** NdbScanOperation* getNdbScanOperation(int aTableId); -Return Value Return a pointer to a NdbOperation object if getNdbOperation was succesful. +Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. -Remark: Get an operation from NdbScanOperation object idlelist and get the NdbConnection +Remark: Get an operation from NdbScanOperation object idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbOperation object, synchronous. + getOperation will set the theTableId in the NdbScanOperation object, synchronous. *****************************************************************************/ NdbIndexScanOperation* -NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) +NdbTransaction::getNdbScanOperation(const NdbTableImpl * tab) { NdbIndexScanOperation* tOp; @@ -1178,10 +1189,10 @@ NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() void -NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){ +NdbTransaction::remove_list(NdbOperation*& list, NdbOperation* op){ NdbOperation* tmp= list; if(tmp == op) list = op->next(); @@ -1194,7 +1205,7 @@ NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){ } void -NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ +NdbTransaction::define_scan_op(NdbIndexScanOperation * tOp){ // Link scan operation into list of cursor operations if (m_theLastScanOperation == NULL) m_theFirstScanOperation = m_theLastScanOperation = tOp; @@ -1206,13 +1217,13 @@ NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ } NdbScanOperation* -NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) +NdbTransaction::getNdbScanOperation(const NdbDictionary::Table * table) { if (table) return getNdbScanOperation(& NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() // IndexOperation @@ -1220,21 +1231,40 @@ NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) NdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName); -Return Value Return a pointer to a NdbOperation object if getNdbScanOperation was succesful. +Return Value Return a pointer to a NdbOperation object if getNdbIndexOperation was succesful. Return NULL : In all other case. Parameters: aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object - who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbScanOperation object.synchronous +Remark: Get an operation from NdbIndexOperation idlelist and get the NdbTransaction object + who was fetch by startTransaction pointing to this operation + getOperation will set the theTableId in the NdbIndexOperation object.synchronous ******************************************************************************/ NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const char* anIndexName, +NdbTransaction::getNdbIndexOperation(const char* anIndexName, const char* aTableName) { if (theCommitStatus == Started) { NdbTableImpl * table = theNdb->theDictionary->getTable(aTableName); - NdbIndexImpl * index = theNdb->theDictionary->getIndex(anIndexName, - aTableName); + NdbIndexImpl * index; + + if (table == 0) + { + setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code); + return NULL; + } + + if (table->m_frm.get_data()) + { + // This unique index is defined from SQL level + static const char* uniqueSuffix= "$unique"; + char uniqueIndexName[MAX_TAB_NAME_SIZE]; + + strxnmov(uniqueIndexName, MAX_TAB_NAME_SIZE, anIndexName, uniqueSuffix, NullS); + index = theNdb->theDictionary->getIndex(uniqueIndexName, + aTableName); + } + else + index = theNdb->theDictionary->getIndex(anIndexName, + aTableName); if(table != 0 && index != 0){ return getNdbIndexOperation(index, table); } @@ -1244,14 +1274,13 @@ NdbConnection::getNdbIndexOperation(const char* anIndexName, return NULL; } - // table == 0 - setOperationErrorCodeAbort(theNdb->theError.code); + setOperationErrorCodeAbort(4243); return NULL; } setOperationErrorCodeAbort(4114); return 0; -}//NdbConnection::getNdbIndexOperation() +}//NdbTransaction::getNdbIndexOperation() /***************************************************************************** NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId); @@ -1259,12 +1288,12 @@ NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId); Return Value Return a pointer to a NdbIndexOperation object if getNdbIndexOperation was succesful. Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. -Remark: Get an operation from NdbIndexOperation object idlelist and get the NdbConnection +Remark: Get an operation from NdbIndexOperation object idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbIndexOperation object, synchronous. *****************************************************************************/ NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, +NdbTransaction::getNdbIndexOperation(const NdbIndexImpl * anIndex, const NdbTableImpl * aTable, NdbOperation* aNextOp) { @@ -1305,18 +1334,37 @@ NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbIndexOperation() +}//NdbTransaction::getNdbIndexOperation() NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index, +NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index) +{ + if (index) + { + const NdbDictionary::Table *table= + theNdb->theDictionary->getTable(index->getTable()); + + if (table) + return getNdbIndexOperation(index, table); + + setOperationErrorCodeAbort(theNdb->theDictionary->getNdbError().code); + return NULL; + } + setOperationErrorCodeAbort(4271); + return NULL; +} + +NdbIndexOperation* +NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index, const NdbDictionary::Table * table) { if (index && table) return getNdbIndexOperation(& NdbIndexImpl::getImpl(*index), & NdbTableImpl::getImpl(*table)); - else - return NULL; -}//NdbConnection::getNdbIndexOperation() + + setOperationErrorCodeAbort(4271); + return NULL; +}//NdbTransaction::getNdbIndexOperation() /******************************************************************************* @@ -1328,7 +1376,7 @@ Parameters: aSignal: The signal object pointer. Remark: Sets theRestartGCI in the NDB object. *******************************************************************************/ int -NdbConnection::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) +NdbTransaction::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) { if (theStatus != Connecting) { return -1; @@ -1337,7 +1385,7 @@ NdbConnection::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) theStatus = Connected; }//if return 0; -}//NdbConnection::receiveDIHNDBTAMPER() +}//NdbTransaction::receiveDIHNDBTAMPER() /******************************************************************************* int receiveTCSEIZECONF(NdbApiSignal* aSignal); @@ -1348,7 +1396,7 @@ Parameters: aSignal: The signal object pointer. Remark: Sets TC Connect pointer at reception of TCSEIZECONF. *******************************************************************************/ int -NdbConnection::receiveTCSEIZECONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCSEIZECONF(NdbApiSignal* aSignal) { if (theStatus != Connecting) { @@ -1359,7 +1407,7 @@ NdbConnection::receiveTCSEIZECONF(NdbApiSignal* aSignal) theStatus = Connected; } return 0; -}//NdbConnection::receiveTCSEIZECONF() +}//NdbTransaction::receiveTCSEIZECONF() /******************************************************************************* int receiveTCSEIZEREF(NdbApiSignal* aSignal); @@ -1370,18 +1418,22 @@ Parameters: aSignal: The signal object pointer. Remark: Sets TC Connect pointer. *******************************************************************************/ int -NdbConnection::receiveTCSEIZEREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCSEIZEREF(NdbApiSignal* aSignal) { + DBUG_ENTER("NdbTransaction::receiveTCSEIZEREF"); if (theStatus != Connecting) { - return -1; + DBUG_RETURN(-1); } else { theStatus = ConnectFailure; theNdb->theError.code = aSignal->readData(2); - return 0; + DBUG_PRINT("info",("error code %d, %s", + theNdb->getNdbError().code, + theNdb->getNdbError().message)); + DBUG_RETURN(0); } -}//NdbConnection::receiveTCSEIZEREF() +}//NdbTransaction::receiveTCSEIZEREF() /******************************************************************************* int receiveTCRELEASECONF(NdbApiSignal* aSignal); @@ -1392,7 +1444,7 @@ Parameters: aSignal: The signal object pointer. Remark: DisConnect TC Connect pointer to NDBAPI. *******************************************************************************/ int -NdbConnection::receiveTCRELEASECONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCRELEASECONF(NdbApiSignal* aSignal) { if (theStatus != DisConnecting) { @@ -1402,7 +1454,7 @@ NdbConnection::receiveTCRELEASECONF(NdbApiSignal* aSignal) theStatus = NotConnected; } return 0; -}//NdbConnection::receiveTCRELEASECONF() +}//NdbTransaction::receiveTCRELEASECONF() /******************************************************************************* int receiveTCRELEASEREF(NdbApiSignal* aSignal); @@ -1413,7 +1465,7 @@ Parameters: aSignal: The signal object pointer. Remark: DisConnect TC Connect pointer to NDBAPI Failure. *******************************************************************************/ int -NdbConnection::receiveTCRELEASEREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCRELEASEREF(NdbApiSignal* aSignal) { if (theStatus != DisConnecting) { return -1; @@ -1422,7 +1474,7 @@ NdbConnection::receiveTCRELEASEREF(NdbApiSignal* aSignal) theNdb->theError.code = aSignal->readData(2); return 0; }//if -}//NdbConnection::receiveTCRELEASEREF() +}//NdbTransaction::receiveTCRELEASEREF() /****************************************************************************** int receiveTC_COMMITCONF(NdbApiSignal* aSignal); @@ -1433,7 +1485,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) +NdbTransaction::receiveTC_COMMITCONF(const TcCommitConf * commitConf) { if(checkState_TransId(&commitConf->transId1)){ theCommitStatus = Committed; @@ -1445,7 +1497,7 @@ NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) #endif } return -1; -}//NdbConnection::receiveTC_COMMITCONF() +}//NdbTransaction::receiveTC_COMMITCONF() /****************************************************************************** int receiveTC_COMMITREF(NdbApiSignal* aSignal); @@ -1456,13 +1508,14 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTC_COMMITREF(NdbApiSignal* aSignal) { const TcCommitRef * ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr()); if(checkState_TransId(&ref->transId1)){ setOperationErrorCodeAbort(ref->errorCode); theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1471,7 +1524,7 @@ NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTC_COMMITREF() +}//NdbTransaction::receiveTC_COMMITREF() /****************************************************************************** int receiveTCROLLBACKCONF(NdbApiSignal* aSignal); @@ -1482,7 +1535,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr() + 1)){ theCommitStatus = Aborted; @@ -1495,7 +1548,7 @@ NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCROLLBACKCONF() +}//NdbTransaction::receiveTCROLLBACKCONF() /******************************************************************************* int receiveTCROLLBACKREF(NdbApiSignal* aSignal); @@ -1506,12 +1559,13 @@ Parameters: aSignal: The signal object pointer. Remark: *******************************************************************************/ int -NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKREF(NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr() + 1)){ setOperationErrorCodeAbort(aSignal->readData(4)); theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1520,7 +1574,7 @@ NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCROLLBACKREF() +}//NdbTransaction::receiveTCROLLBACKREF() /***************************************************************************** int receiveTCROLLBACKREP( NdbApiSignal* aSignal) @@ -1532,7 +1586,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the ROLLBACKREP signal. *****************************************************************************/ int -NdbConnection::receiveTCROLLBACKREP( NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal) { /**************************************************************************** Check that we are expecting signals from this transaction and that it doesn't @@ -1551,6 +1605,7 @@ transactions. /**********************************************************************/ theCompletionStatus = CompletedFailure; theCommitStatus = Aborted; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1559,7 +1614,7 @@ transactions. } return -1; -}//NdbConnection::receiveTCROLLBACKREP() +}//NdbTransaction::receiveTCROLLBACKREP() /******************************************************************************* int receiveTCKEYCONF(NdbApiSignal* aSignal, Uint32 long_short_ind); @@ -1570,7 +1625,7 @@ Parameters: aSignal: The signal object pointer. Remark: *******************************************************************************/ int -NdbConnection::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength) +NdbTransaction::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength) { NdbReceiver* tOp; const Uint32 tTemp = keyConf->confInfo; @@ -1599,6 +1654,7 @@ from other transactions. done = 1; tOp->setErrorCode(4119); theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; } } tNoComp += done; @@ -1628,6 +1684,7 @@ from other transactions. /**********************************************************************/ theError.code = 4011; theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; theCommitStatus = Aborted; return 0; }//if @@ -1642,7 +1699,7 @@ from other transactions. } return -1; -}//NdbConnection::receiveTCKEYCONF() +}//NdbTransaction::receiveTCKEYCONF() /***************************************************************************** int receiveTCKEY_FAILCONF( NdbApiSignal* aSignal) @@ -1654,7 +1711,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCKEY_FAILCONF signal. *****************************************************************************/ int -NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) +NdbTransaction::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) { NdbOperation* tOp; /* @@ -1687,6 +1744,7 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) case NdbOperation::OpenScanRequest: case NdbOperation::OpenRangeScanRequest: theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; setOperationErrorCodeAbort(4115); tOp = NULL; break; @@ -1704,7 +1762,7 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) #endif } return -1; -}//NdbConnection::receiveTCKEY_FAILCONF() +}//NdbTransaction::receiveTCKEY_FAILCONF() /************************************************************************* int receiveTCKEY_FAILREF( NdbApiSignal* aSignal) @@ -1716,7 +1774,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCKEY_FAILREF signal. **************************************************************************/ int -NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) { /* Check that we are expecting signals from this transaction and @@ -1728,18 +1786,19 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) We received an indication of that this transaction was aborted due to a node failure. */ - if (theSendStatus == NdbConnection::sendTC_ROLLBACK) { + if (theSendStatus == NdbTransaction::sendTC_ROLLBACK) { /* We were in the process of sending a rollback anyways. We will report it as a success. */ - theCompletionStatus = NdbConnection::CompletedSuccess; + theCompletionStatus = NdbTransaction::CompletedSuccess; } else { - theCompletionStatus = NdbConnection::CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; theError.code = 4031; }//if theReleaseOnClose = true; - theCommitStatus = NdbConnection::Aborted; + theCommitStatus = NdbTransaction::Aborted; return 0; } else { #ifdef VM_TRACE @@ -1747,7 +1806,7 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) #endif } return -1; -}//NdbConnection::receiveTCKEY_FAILREF() +}//NdbTransaction::receiveTCKEY_FAILREF() /****************************************************************************** int receiveTCINDXCONF(NdbApiSignal* aSignal, Uint32 long_short_ind); @@ -1758,7 +1817,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, +NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, Uint32 aDataLength) { if(checkState_TransId(&indxConf->transId1)){ @@ -1792,8 +1851,9 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, // no Commit flag set. This is clearly an anomaly. /**********************************************************************/ theError.code = 4011; - theCompletionStatus = NdbConnection::CompletedFailure; - theCommitStatus = NdbConnection::Aborted; + theCompletionStatus = NdbTransaction::CompletedFailure; + theCommitStatus = NdbTransaction::Aborted; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; }//if if (tNoComp >= tNoSent) { @@ -1807,7 +1867,7 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, } return -1; -}//NdbConnection::receiveTCINDXCONF() +}//NdbTransaction::receiveTCINDXCONF() /***************************************************************************** int receiveTCINDXREF( NdbApiSignal* aSignal) @@ -1819,7 +1879,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCINDXREF signal. *****************************************************************************/ int -NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) +NdbTransaction::receiveTCINDXREF( NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr()+1)){ theError.code = aSignal->readData(4); // Override any previous errors @@ -1831,8 +1891,9 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) /* and we only need to report completion and return with the */ /* error code to the application. */ /**********************************************************************/ - theCompletionStatus = NdbConnection::CompletedFailure; - theCommitStatus = NdbConnection::Aborted; + theCompletionStatus = NdbTransaction::CompletedFailure; + theCommitStatus = NdbTransaction::Aborted; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1841,7 +1902,7 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCINDXREF() +}//NdbTransaction::receiveTCINDXREF() /******************************************************************************* int OpCompletedFailure(); @@ -1852,12 +1913,12 @@ Parameters: aErrorCode: The error code. Remark: An operation was completed with failure. *******************************************************************************/ int -NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure) +NdbTransaction::OpCompleteFailure(Uint8 abortOption, bool setFailure) { Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; if (setFailure) - theCompletionStatus = NdbConnection::CompletedFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; tNoComp++; theNoOfOpCompleted = tNoComp; if (tNoComp == tNoSent) { @@ -1882,7 +1943,7 @@ NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure) } else { return -1; // Continue waiting for more signals }//if -}//NdbConnection::OpCompleteFailure() +}//NdbTransaction::OpCompleteFailure() /****************************************************************************** int OpCompleteSuccess(); @@ -1892,7 +1953,7 @@ Return Value: Return 0 : OpCompleteSuccess was successful. Remark: An operation was completed with success. *******************************************************************************/ int -NdbConnection::OpCompleteSuccess() +NdbTransaction::OpCompleteSuccess() { Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; @@ -1905,10 +1966,11 @@ NdbConnection::OpCompleteSuccess() } else { setOperationErrorCodeAbort(4113); // Too many operations, // stop waiting for more - theCompletionStatus = NdbConnection::CompletedFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; }//if -}//NdbConnection::OpCompleteSuccess() +}//NdbTransaction::OpCompleteSuccess() /****************************************************************************** int getGCI(); @@ -1916,13 +1978,13 @@ NdbConnection::OpCompleteSuccess() Remark: Get global checkpoint identity of the transaction *******************************************************************************/ int -NdbConnection::getGCI() +NdbTransaction::getGCI() { - if (theCommitStatus == NdbConnection::Committed) { + if (theCommitStatus == NdbTransaction::Committed) { return theGlobalCheckpointId; }//if return 0; -}//NdbConnection::getGCI() +}//NdbTransaction::getGCI() /******************************************************************************* Uint64 getTransactionId(void); @@ -1930,31 +1992,31 @@ Uint64 getTransactionId(void); Remark: Get the transaction identity. *******************************************************************************/ Uint64 -NdbConnection::getTransactionId() +NdbTransaction::getTransactionId() { return theTransactionId; -}//NdbConnection::getTransactionId() +}//NdbTransaction::getTransactionId() -NdbConnection::CommitStatusType -NdbConnection::commitStatus() +NdbTransaction::CommitStatusType +NdbTransaction::commitStatus() { return theCommitStatus; -}//NdbConnection::commitStatus() +}//NdbTransaction::commitStatus() int -NdbConnection::getNdbErrorLine() +NdbTransaction::getNdbErrorLine() { return theErrorLine; } NdbOperation* -NdbConnection::getNdbErrorOperation() +NdbTransaction::getNdbErrorOperation() { return theErrorOperation; -}//NdbConnection::getNdbErrorOperation() +}//NdbTransaction::getNdbErrorOperation() const NdbOperation * -NdbConnection::getNextCompletedOperation(const NdbOperation * current) const { +NdbTransaction::getNextCompletedOperation(const NdbOperation * current) const { if(current == 0) return theCompletedFirstOp; return current->theNext; @@ -1963,7 +2025,7 @@ NdbConnection::getNextCompletedOperation(const NdbOperation * current) const { #ifdef VM_TRACE #define CASE(x) case x: ndbout << " " << #x; break void -NdbConnection::printState() +NdbTransaction::printState() { ndbout << "con=" << hex << this << dec; ndbout << " node=" << getConnectedNodeId(); @@ -2016,7 +2078,7 @@ NdbConnection::printState() #endif int -NdbConnection::report_node_failure(Uint32 id){ +NdbTransaction::report_node_failure(Uint32 id){ NdbNodeBitmask::set(m_failed_db_nodes, id); if(!NdbNodeBitmask::get(m_db_nodes, id)) { @@ -2035,22 +2097,28 @@ NdbConnection::report_node_failure(Uint32 id){ const Uint32 len = TcKeyConf::SimpleReadBit | id; Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; + Uint32 count = 0; while(tmp != 0) { if(tmp->theReceiver.m_expected_result_length == len && tmp->theReceiver.m_received_result_length == 0) { - tNoComp++; + count++; tmp->theError.code = 4119; } tmp = tmp->next(); } + tNoComp += count; theNoOfOpCompleted = tNoComp; - if(tNoComp == tNoSent) + if(count) { - theError.code = 4119; - theCompletionStatus = NdbConnection::CompletedFailure; - return 1; + theReturnStatus = NdbTransaction::ReturnFailure; + if(tNoComp == tNoSent) + { + theError.code = 4119; + theCompletionStatus = NdbTransaction::CompletedFailure; + return 1; + } } return 0; } diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbTransactionScan.cpp index b0c546c512a..4c507f6ab8c 100644 --- a/ndb/src/ndbapi/NdbConnectionScan.cpp +++ b/ndb/src/ndbapi/NdbTransactionScan.cpp @@ -15,22 +15,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/***************************************************************************** - * Name: NdbConnectionScan.cpp - * Include: - * Link: - * Author: UABRONM MikaelRonström UAB/M/MT - * QABJKAM Jonas Kamf UAB/M/MT - * Date: 2000-06-12 - * Version: 0.1 - * Description: Interface between Application and NDB - * Documentation: - * Adjust: 2000-06-12 UABRONM First version. - ****************************************************************************/ #include <ndb_global.h> #include <Ndb.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbScanOperation.hpp> #include "NdbApiSignal.hpp" @@ -52,7 +40,7 @@ * ****************************************************************************/ int -NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ +NdbTransaction::receiveSCAN_TABREF(NdbApiSignal* aSignal){ const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr()); if(checkState_TransId(&ref->transId1)){ @@ -93,7 +81,7 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ * *****************************************************************************/ int -NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal, +NdbTransaction::receiveSCAN_TABCONF(NdbApiSignal* aSignal, const Uint32 * ops, Uint32 len) { const ScanTabConf * conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr()); diff --git a/ndb/src/ndbapi/Ndberr.cpp b/ndb/src/ndbapi/Ndberr.cpp index a8b968da03f..b05818de6f1 100644 --- a/ndb/src/ndbapi/Ndberr.cpp +++ b/ndb/src/ndbapi/Ndberr.cpp @@ -19,9 +19,9 @@ #include "NdbImpl.hpp" #include "NdbDictionaryImpl.hpp" #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbBlob.hpp> - +#include "NdbEventOperationImpl.hpp" static void update(const NdbError & _err){ @@ -55,7 +55,7 @@ NdbDictionaryImpl::getNdbError() const { const NdbError & -NdbConnection::getNdbError() const { +NdbTransaction::getNdbError() const { update(theError); return theError; } @@ -73,3 +73,10 @@ NdbBlob::getNdbError() const { update(theError); return theError; } + +const +NdbError & +NdbEventOperationImpl::getNdbError() const { + update(m_error); + return m_error; +} diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index a4f233709c4..40aaa1e3daa 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -19,12 +19,12 @@ #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" -#include "NdbOperation.hpp" -#include "NdbIndexOperation.hpp" -#include "NdbScanOperation.hpp" -#include "NdbConnection.hpp" -#include "NdbRecAttr.hpp" -#include "NdbReceiver.hpp" +#include <NdbTransaction.hpp> +#include <NdbOperation.hpp> +#include <NdbIndexOperation.hpp> +#include <NdbScanOperation.hpp> +#include <NdbRecAttr.hpp> +#include <NdbReceiver.hpp> #include "API.hpp" #include <signaldata/TcCommit.hpp> @@ -113,9 +113,9 @@ Ndb::init(int aMaxNoOfTransactions) }//if theMaxNoOfTransactions = tMaxNoOfTransactions; - thePreparedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; - theSentTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; - theCompletedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; + thePreparedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; + theSentTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; + theCompletedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; if ((thePreparedTransactionsArray == NULL) || (theSentTransactionsArray == NULL) || @@ -272,11 +272,11 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) { Uint32 tNoSentTransactions = theNoOfSentTransactions; for (int i = tNoSentTransactions - 1; i >= 0; i--) { - NdbConnection* localCon = theSentTransactionsArray[i]; + NdbTransaction* localCon = theSentTransactionsArray[i]; if (localCon->getConnectedNodeId() == aNodeId) { - const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus; - if (sendStatus == NdbConnection::sendTC_OP || - sendStatus == NdbConnection::sendTC_COMMIT) { + const NdbTransaction::SendStatusType sendStatus = localCon->theSendStatus; + if (sendStatus == NdbTransaction::sendTC_OP || + sendStatus == NdbTransaction::sendTC_COMMIT) { /* A transaction was interrupted in the prepare phase by a node failure. Since the transaction was not found in the phase @@ -284,13 +284,13 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) we report a normal node failure abort. */ localCon->setOperationErrorCodeAbort(4010); - localCon->theCompletionStatus = NdbConnection::CompletedFailure; - } else if (sendStatus == NdbConnection::sendTC_ROLLBACK) { + localCon->theCompletionStatus = NdbTransaction::CompletedFailure; + } else if (sendStatus == NdbTransaction::sendTC_ROLLBACK) { /* We aimed for abort and abort we got even if it was by a node failure. We will thus report it as a success. */ - localCon->theCompletionStatus = NdbConnection::CompletedSuccess; + localCon->theCompletionStatus = NdbTransaction::CompletedSuccess; } else { #ifdef VM_TRACE printState("abortTransactionsAfterNodeFailure %x", this); @@ -302,7 +302,8 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) intact since the node was failing and they were aborted. Thus we set commit state to Aborted and set state to release on close. */ - localCon->theCommitStatus = NdbConnection::Aborted; + localCon->theReturnStatus = NdbTransaction::ReturnFailure; + localCon->theCommitStatus = NdbTransaction::Aborted; localCon->theReleaseOnClose = true; completedTransaction(localCon); } @@ -325,7 +326,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) { NdbOperation* tOp; NdbIndexOperation* tIndexOp; - NdbConnection* tCon; + NdbTransaction* tCon; int tReturnCode = -1; const Uint32* tDataPtr = aSignal->getDataPtr(); const Uint32 tWaitState = theImpl->theWaiter.m_state; @@ -355,14 +356,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { + (tCon->theSendStatus == NdbTransaction::sendTC_OP)) { tReturnCode = tCon->receiveTCKEYCONF(keyConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); }//if if(TcKeyConf::getMarkerFlag(keyConf->confInfo)){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, keyConf->transId1, keyConf->transId2, aTCRef); @@ -387,24 +388,24 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) com = tRec->execTRANSID_AI(tDataPtr + TransIdAI::HeaderLength, tLen - TransIdAI::HeaderLength); } + + if(com == 0) + return; - if(com == 1){ - switch(tRec->getType()){ - case NdbReceiver::NDB_OPERATION: - case NdbReceiver::NDB_INDEX_OPERATION: - if(tCon->OpCompleteSuccess() != -1){ - completedTransaction(tCon); - return; - } - break; - case NdbReceiver::NDB_SCANRECEIVER: - tCon->theScanningOp->receiver_delivered(tRec); - theImpl->theWaiter.m_state = (((WaitSignalType) tWaitState) == WAIT_SCAN ? - (Uint32) NO_WAIT : tWaitState); - break; - default: - goto InvalidSignal; + switch(tRec->getType()){ + case NdbReceiver::NDB_OPERATION: + case NdbReceiver::NDB_INDEX_OPERATION: + if(tCon->OpCompleteSuccess() != -1){ + completedTransaction(tCon); } + return; + case NdbReceiver::NDB_SCANRECEIVER: + tCon->theScanningOp->receiver_delivered(tRec); + theImpl->theWaiter.m_state = (((WaitSignalType) tWaitState) == WAIT_SCAN ? + (Uint32) NO_WAIT : tWaitState); + break; + default: + goto InvalidSignal; } break; } else { @@ -426,8 +427,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber(false) == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) || + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf); if (tReturnCode != -1) { completedTransaction(tCon); @@ -441,7 +442,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) #endif } if(tFirstData & 1){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, failConf->transId1, failConf->transId2, aTCRef); @@ -456,8 +457,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) || + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -482,7 +483,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == NdbTransaction::sendTC_OP) { tReturnCode = tOp->receiveTCKEYREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -505,14 +506,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITCONF(commitConf); if (tReturnCode != -1) { completedTransaction(tCon); }//if if(tFirstData & 1){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, commitConf->transId1, commitConf->transId2, aTCRef); @@ -530,7 +531,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -545,7 +546,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKCONF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -560,7 +561,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -797,7 +798,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) const BlockReference aTCRef = aSignal->theSendersBlockRef; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { + (tCon->theSendStatus == NdbTransaction::sendTC_OP)) { tReturnCode = tCon->receiveTCINDXCONF(indxConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); @@ -805,7 +806,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) }//if if(TcIndxConf::getMarkerFlag(indxConf->confInfo)){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, indxConf->transId1, indxConf->transId2, aTCRef); @@ -820,7 +821,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tIndexOp->checkMagicNumber() == 0) { tCon = tIndexOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == NdbTransaction::sendTC_OP) { tReturnCode = tIndexOp->receiveTCINDXREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -861,7 +862,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) /***************************************************************************** -void completedTransaction(NdbConnection* aCon); +void completedTransaction(NdbTransaction* aCon); Remark: One transaction has been completed. Remove it from send array and put it into the completed @@ -869,14 +870,14 @@ Remark: One transaction has been completed. up a poller. ******************************************************************************/ void -Ndb::completedTransaction(NdbConnection* aCon) +Ndb::completedTransaction(NdbTransaction* aCon) { Uint32 tTransArrayIndex = aCon->theTransArrayIndex; Uint32 tNoSentTransactions = theNoOfSentTransactions; Uint32 tNoCompletedTransactions = theNoOfCompletedTransactions; - if ((tNoSentTransactions > 0) && (aCon->theListState == NdbConnection::InSendList) && + if ((tNoSentTransactions > 0) && (aCon->theListState == NdbTransaction::InSendList) && (tTransArrayIndex < tNoSentTransactions)) { - NdbConnection* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1]; + NdbTransaction* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1]; theCompletedTransactionsArray[tNoCompletedTransactions] = aCon; aCon->theTransArrayIndex = tNoCompletedTransactions; @@ -888,7 +889,7 @@ Ndb::completedTransaction(NdbConnection* aCon) theNoOfCompletedTransactions = tNoCompletedTransactions + 1; theNoOfSentTransactions = tNoSentTransactions - 1; - aCon->theListState = NdbConnection::InCompletedList; + aCon->theListState = NdbTransaction::InCompletedList; aCon->handleExecuteCompletion(); if ((theMinNoOfEventsToWakeUp != 0) && (theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) { @@ -909,12 +910,12 @@ Ndb::completedTransaction(NdbConnection* aCon) }//Ndb::completedTransaction() /***************************************************************************** -void reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans); +void reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans); Remark: Call the callback methods of the completed transactions. ******************************************************************************/ void -Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) +Ndb::reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans) { Uint32 i; if (aNoOfCompletedTrans > 0) { @@ -923,7 +924,7 @@ Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) NdbAsynchCallback aCallback = aCopyArray[i]->theCallbackFunction; int tResult = 0; if (aCallback != NULL) { - if (aCopyArray[i]->theReturnStatus == NdbConnection::ReturnFailure) { + if (aCopyArray[i]->theReturnStatus == NdbTransaction::ReturnFailure) { tResult = -1; }//if (*aCallback)(tResult, aCopyArray[i], anyObject); @@ -933,13 +934,13 @@ Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) }//Ndb::reportCallback() /***************************************************************************** -Uint32 pollCompleted(NdbConnection** aCopyArray); +Uint32 pollCompleted(NdbTransaction** aCopyArray); Remark: Transfer the data from the completed transaction to a local array. This support is used by a number of the poll-methods. ******************************************************************************/ Uint32 -Ndb::pollCompleted(NdbConnection** aCopyArray) +Ndb::pollCompleted(NdbTransaction** aCopyArray) { check_send_timeout(); Uint32 i; @@ -947,13 +948,13 @@ Ndb::pollCompleted(NdbConnection** aCopyArray) if (tNoCompletedTransactions > 0) { for (i = 0; i < tNoCompletedTransactions; i++) { aCopyArray[i] = theCompletedTransactionsArray[i]; - if (aCopyArray[i]->theListState != NdbConnection::InCompletedList) { + if (aCopyArray[i]->theListState != NdbTransaction::InCompletedList) { ndbout << "pollCompleted error "; ndbout << (int) aCopyArray[i]->theListState << endl; abort(); }//if theCompletedTransactionsArray[i] = NULL; - aCopyArray[i]->theListState = NdbConnection::NotInList; + aCopyArray[i]->theListState = NdbTransaction::NotInList; }//for }//if theNoOfCompletedTransactions = 0; @@ -968,7 +969,7 @@ Ndb::check_send_timeout() the_last_check_time = current_time; Uint32 no_of_sent = theNoOfSentTransactions; for (Uint32 i = 0; i < no_of_sent; i++) { - NdbConnection* a_con = theSentTransactionsArray[i]; + NdbTransaction* a_con = theSentTransactionsArray[i]; if ((current_time - a_con->theStartTransTime) > WAITFOR_RESPONSE_TIMEOUT) { #ifdef VM_TRACE @@ -979,8 +980,8 @@ Ndb::check_send_timeout() abort(); #endif a_con->setOperationErrorCodeAbort(4012); - a_con->theCommitStatus = NdbConnection::Aborted; - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theCommitStatus = NdbTransaction::Aborted; + a_con->theCompletionStatus = NdbTransaction::CompletedFailure; a_con->handleExecuteCompletion(); remove_sent_list(i); insert_completed_list(a_con); @@ -996,7 +997,7 @@ Ndb::remove_sent_list(Uint32 list_index) { Uint32 last_index = theNoOfSentTransactions - 1; if (list_index < last_index) { - NdbConnection* t_con = theSentTransactionsArray[last_index]; + NdbTransaction* t_con = theSentTransactionsArray[last_index]; theSentTransactionsArray[list_index] = t_con; }//if theNoOfSentTransactions = last_index; @@ -1004,23 +1005,23 @@ Ndb::remove_sent_list(Uint32 list_index) } Uint32 -Ndb::insert_completed_list(NdbConnection* a_con) +Ndb::insert_completed_list(NdbTransaction* a_con) { Uint32 no_of_comp = theNoOfCompletedTransactions; theCompletedTransactionsArray[no_of_comp] = a_con; theNoOfCompletedTransactions = no_of_comp + 1; - a_con->theListState = NdbConnection::InCompletedList; + a_con->theListState = NdbTransaction::InCompletedList; a_con->theTransArrayIndex = no_of_comp; return no_of_comp; } Uint32 -Ndb::insert_sent_list(NdbConnection* a_con) +Ndb::insert_sent_list(NdbTransaction* a_con) { Uint32 no_of_sent = theNoOfSentTransactions; theSentTransactionsArray[no_of_sent] = a_con; theNoOfSentTransactions = no_of_sent + 1; - a_con->theListState = NdbConnection::InSendList; + a_con->theListState = NdbTransaction::InSendList; a_con->theTransArrayIndex = no_of_sent; return no_of_sent; } @@ -1052,16 +1053,16 @@ Ndb::sendPrepTrans(int forceSend) TransporterFacade* tp = TransporterFacade::instance(); Uint32 no_of_prep_trans = theNoOfPreparedTransactions; for (i = 0; i < no_of_prep_trans; i++) { - NdbConnection * a_con = thePreparedTransactionsArray[i]; + NdbTransaction * a_con = thePreparedTransactionsArray[i]; thePreparedTransactionsArray[i] = NULL; Uint32 node_id = a_con->getConnectedNodeId(); if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) && tp->get_node_alive(node_id) || (tp->get_node_stopping(node_id) && - ((a_con->theSendStatus == NdbConnection::sendABORT) || - (a_con->theSendStatus == NdbConnection::sendABORTfail) || - (a_con->theSendStatus == NdbConnection::sendCOMMITstate) || - (a_con->theSendStatus == NdbConnection::sendCompleted)))) { + ((a_con->theSendStatus == NdbTransaction::sendABORT) || + (a_con->theSendStatus == NdbTransaction::sendABORTfail) || + (a_con->theSendStatus == NdbTransaction::sendCOMMITstate) || + (a_con->theSendStatus == NdbTransaction::sendCompleted)))) { /* We will send if 1) Node is alive and sequences are correct OR @@ -1093,13 +1094,13 @@ Ndb::sendPrepTrans(int forceSend) again and will thus set the state to Aborted to avoid a more or less eternal loop of tries. */ - if (a_con->theSendStatus == NdbConnection::sendOperations) { + if (a_con->theSendStatus == NdbTransaction::sendOperations) { a_con->setOperationErrorCodeAbort(4021); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NdbTransaction::NeedAbort; TRACE_DEBUG("Send buffer full and sendOperations"); } else { a_con->setOperationErrorCodeAbort(4026); - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = NdbTransaction::Aborted; TRACE_DEBUG("Send buffer full, set state to Aborted"); }//if }//if @@ -1116,7 +1117,7 @@ Ndb::sendPrepTrans(int forceSend) */ TRACE_DEBUG("Abort a transaction when stopping a node"); a_con->setOperationErrorCodeAbort(4023); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NdbTransaction::NeedAbort; } else { /* The node is hard dead and we cannot continue. We will also release @@ -1126,10 +1127,11 @@ Ndb::sendPrepTrans(int forceSend) a_con->setOperationErrorCodeAbort(4025); a_con->theReleaseOnClose = true; a_con->theTransactionIsStarted = false; - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = NdbTransaction::Aborted; }//if }//if - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theReturnStatus = NdbTransaction::ReturnFailure; + a_con->theCompletionStatus = NdbTransaction::CompletedFailure; a_con->handleExecuteCompletion(); insert_completed_list(a_con); }//for @@ -1203,7 +1205,7 @@ Remark: First send all prepared operations and then check if there are any int Ndb::sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup, int forceSend) { - NdbConnection* tConArray[1024]; + NdbTransaction* tConArray[1024]; Uint32 tNoCompletedTransactions; //theCurrentConnectCounter = 0; @@ -1236,7 +1238,7 @@ Remark: Check if there are any transactions already completed. Wait for not int Ndb::pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup) { - NdbConnection* tConArray[1024]; + NdbTransaction* tConArray[1024]; Uint32 tNoCompletedTransactions; //theCurrentConnectCounter = 0; @@ -1343,7 +1345,7 @@ Ndb::sendRecSignal(Uint16 node_id, }//Ndb::sendRecSignal() void -NdbConnection::sendTC_COMMIT_ACK(NdbApiSignal * aSignal, +NdbTransaction::sendTC_COMMIT_ACK(NdbApiSignal * aSignal, Uint32 transId1, Uint32 transId2, Uint32 aTCRef){ #ifdef MARKER_TRACE diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index a11dd842495..4db9d05b59c 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -19,12 +19,12 @@ #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" -#include "NdbOperation.hpp" -#include "NdbConnection.hpp" -#include "NdbRecAttr.hpp" -#include "IPCConfig.hpp" +#include <NdbOperation.hpp> +#include <NdbTransaction.hpp> +#include <NdbRecAttr.hpp> +#include <IPCConfig.hpp> #include "TransporterFacade.hpp" -#include "ConfigRetriever.hpp" +#include <ConfigRetriever.hpp> #include <ndb_limits.h> #include <NdbOut.hpp> #include <NdbSleep.h> @@ -34,48 +34,12 @@ class NdbGlobalEventBufferHandle; NdbGlobalEventBufferHandle *NdbGlobalEventBuffer_init(int); void NdbGlobalEventBuffer_drop(NdbGlobalEventBufferHandle *); -/** - * Static object for NDB - */ - -// only needed for backwards compatability, before ndb_cluster_connection -static char *ndbConnectString = 0; -static int theNoOfNdbObjects = 0; -static Ndb_cluster_connection *global_ndb_cluster_connection= 0; - - -/*************************************************************************** -Ndb(const char* aDataBase); - -Parameters: aDataBase : Name of the database. -Remark: Connect to the database. -***************************************************************************/ -Ndb::Ndb( const char* aDataBase , const char* aSchema) - : theImpl(NULL) -{ - DBUG_ENTER("Ndb::Ndb()"); - DBUG_PRINT("enter",("(old)Ndb::Ndb this=0x%x", this)); - if (theNoOfNdbObjects < 0) - abort(); // old and new Ndb constructor used mixed - theNoOfNdbObjects++; - if (global_ndb_cluster_connection == 0) { - global_ndb_cluster_connection= new Ndb_cluster_connection(ndbConnectString); - global_ndb_cluster_connection->connect(12,5,1); - } - setup(global_ndb_cluster_connection, aDataBase, aSchema); - DBUG_VOID_RETURN; -} - Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection, const char* aDataBase , const char* aSchema) : theImpl(NULL) { DBUG_ENTER("Ndb::Ndb()"); DBUG_PRINT("enter",("Ndb::Ndb this=0x%x", this)); - if (global_ndb_cluster_connection != 0 && - global_ndb_cluster_connection != ndb_cluster_connection) - abort(); // old and new Ndb constructor used mixed - theNoOfNdbObjects= -1; setup(ndb_cluster_connection, aDataBase, aSchema); DBUG_VOID_RETURN; } @@ -177,16 +141,6 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, } -void Ndb::setConnectString(const char * connectString) -{ - if (ndbConnectString != 0) { - free(ndbConnectString); - ndbConnectString = 0; - } - if (connectString) - ndbConnectString = strdup(connectString); -} - /***************************************************************************** * ~Ndb(); * @@ -241,19 +195,6 @@ Ndb::~Ndb() delete theImpl; - /** - * This needs to be put after delete theImpl - * as TransporterFacade::instance is delete by global_ndb_cluster_connection - * and used by theImpl - */ - if (global_ndb_cluster_connection != 0) { - theNoOfNdbObjects--; - if(theNoOfNdbObjects == 0){ - delete global_ndb_cluster_connection; - global_ndb_cluster_connection= 0; - } - }//if - /** * This sleep is to make sure that the transporter * send thread will come in and send any diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index 5902aa413dc..df90f3378ab 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -19,7 +19,6 @@ #include <NdbOperation.hpp> #include <NdbIndexOperation.hpp> #include <NdbIndexScanOperation.hpp> -#include <NdbConnection.hpp> #include "NdbApiSignal.hpp" #include <NdbRecAttr.hpp> #include "NdbUtil.hpp" @@ -51,10 +50,10 @@ Ndb::checkFailedNode() /** * Release all connections in idle list (for node) */ - NdbConnection * tNdbCon = theConnectionArray[node_id]; + NdbTransaction * tNdbCon = theConnectionArray[node_id]; theConnectionArray[node_id] = NULL; while (tNdbCon != NULL) { - NdbConnection* tempNdbCon = tNdbCon; + NdbTransaction* tempNdbCon = tNdbCon; tNdbCon = tNdbCon->next(); releaseNdbCon(tempNdbCon); } @@ -71,14 +70,14 @@ Ndb::checkFailedNode() * if createConIdleList was succesful * Return -1: In all other case. * Parameters: aNrOfCon : Number of connections offered to the application. - * Remark: Create connection idlelist with NdbConnection objects. + * Remark: Create connection idlelist with NdbTransaction objects. ***************************************************************************/ int Ndb::createConIdleList(int aNrOfCon) { for (int i = 0; i < aNrOfCon; i++) { - NdbConnection* tNdbCon = new NdbConnection(this); + NdbTransaction* tNdbCon = new NdbTransaction(this); if (tNdbCon == NULL) { return -1; @@ -92,7 +91,7 @@ Ndb::createConIdleList(int aNrOfCon) tNdbCon->next(theConIdleList); theConIdleList = tNdbCon; } - tNdbCon->Status(NdbConnection::NotConnected); + tNdbCon->Status(NdbTransaction::NotConnected); } theNoOfAllocatedTransactions = aNrOfCon; return aNrOfCon; @@ -183,19 +182,19 @@ Ndb::getNdbCall() } /*************************************************************************** - * NdbConnection* getNdbCon(); + * NdbTransaction* getNdbCon(); * * Return Value: Return a connection if the getNdbCon was successful. * Return NULL : In all other case. * Remark: Get a connection from theConIdleList and return the object . ***************************************************************************/ -NdbConnection* +NdbTransaction* Ndb::getNdbCon() { - NdbConnection* tNdbCon; + NdbTransaction* tNdbCon; if ( theConIdleList == NULL ) { if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) { - tNdbCon = new NdbConnection(this); + tNdbCon = new NdbTransaction(this); if (tNdbCon == NULL) { return NULL; }//if @@ -467,13 +466,13 @@ Ndb::releaseNdbCall(NdbCall* aNdbCall) } /*************************************************************************** -void releaseNdbCon(NdbConnection* aNdbCon); +void releaseNdbCon(NdbTransaction* aNdbCon); -Parameters: aNdbCon: The NdbConnection object. +Parameters: aNdbCon: The NdbTransaction object. Remark: Add a Connection object into the signal idlelist. ***************************************************************************/ void -Ndb::releaseNdbCon(NdbConnection* aNdbCon) +Ndb::releaseNdbCon(NdbTransaction* aNdbCon) { aNdbCon->next(theConIdleList); aNdbCon->theMagicNumber = 0xFE11DD; @@ -703,7 +702,7 @@ Remark: Always release the first item in the free list void Ndb::freeNdbCon() { - NdbConnection* tNdbCon = theConIdleList; + NdbTransaction* tNdbCon = theConIdleList; theConIdleList = theConIdleList->next(); delete tNdbCon; } @@ -772,14 +771,14 @@ Ndb::freeNdbBlob() } /**************************************************************************** -int releaseConnectToNdb(NdbConnection* aConnectConnection); +int releaseConnectToNdb(NdbTransaction* aConnectConnection); Return Value: -1 if error Parameters: aConnectConnection : Seized schema connection to DBTC Remark: Release and disconnect from DBTC a connection and seize it to theConIdleList. *****************************************************************************/ void -Ndb::releaseConnectToNdb(NdbConnection* a_con) +Ndb::releaseConnectToNdb(NdbTransaction* a_con) { DBUG_ENTER("Ndb::releaseConnectToNdb"); NdbApiSignal tSignal(theMyRef); @@ -797,7 +796,7 @@ Ndb::releaseConnectToNdb(NdbConnection* a_con) tSignal.setData((tConPtr = a_con->getTC_ConnectPtr()), 1); tSignal.setData(theMyRef, 2); tSignal.setData(a_con->ptr2int(), 3); - a_con->Status(NdbConnection::DisConnecting); + a_con->Status(NdbTransaction::DisConnecting); a_con->theMagicNumber = 0x37412619; int ret_code = sendRecSignal(node_id, WAIT_TC_RELEASE, diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index 5582143be44..7f1e68a42d3 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -509,43 +509,32 @@ TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props) iter.first(); theClusterMgr->init(iter); - /** - * Unless there is a "Name", the initiated transporter is within - * an NDB Cluster. (If "Name" is defined, then the transporter - * is used to connect to a different system, i.e. NDB Cluster.) - */ -#if 0 - if (!props->contains("Name")) { -#endif - iter.first(); - if(iter.find(CFG_NODE_ID, nodeId)){ - TRP_DEBUG( "Node info missing from config." ); - return false; - } - - Uint32 rank = 0; - if(!iter.get(CFG_NODE_ARBIT_RANK, &rank) && rank>0){ - theArbitMgr = new ArbitMgr(* this); - theArbitMgr->setRank(rank); - Uint32 delay = 0; - iter.get(CFG_NODE_ARBIT_DELAY, &delay); - theArbitMgr->setDelay(delay); - } - Uint32 scan_batch_size= 0; - if (!iter.get(CFG_MAX_SCAN_BATCH_SIZE, &scan_batch_size)) { - m_scan_batch_size= scan_batch_size; - } - Uint32 batch_byte_size= 0; - if (!iter.get(CFG_BATCH_BYTE_SIZE, &batch_byte_size)) { - m_batch_byte_size= batch_byte_size; - } - Uint32 batch_size= 0; - if (!iter.get(CFG_BATCH_SIZE, &batch_size)) { - m_batch_size= batch_size; - } -#if 0 + iter.first(); + if(iter.find(CFG_NODE_ID, nodeId)){ + TRP_DEBUG( "Node info missing from config." ); + return false; + } + + Uint32 rank = 0; + if(!iter.get(CFG_NODE_ARBIT_RANK, &rank) && rank>0){ + theArbitMgr = new ArbitMgr(* this); + theArbitMgr->setRank(rank); + Uint32 delay = 0; + iter.get(CFG_NODE_ARBIT_DELAY, &delay); + theArbitMgr->setDelay(delay); + } + Uint32 scan_batch_size= 0; + if (!iter.get(CFG_MAX_SCAN_BATCH_SIZE, &scan_batch_size)) { + m_scan_batch_size= scan_batch_size; + } + Uint32 batch_byte_size= 0; + if (!iter.get(CFG_BATCH_BYTE_SIZE, &batch_byte_size)) { + m_batch_byte_size= batch_byte_size; + } + Uint32 batch_size= 0; + if (!iter.get(CFG_BATCH_SIZE, &batch_size)) { + m_batch_size= batch_size; } -#endif if (!theTransporterRegistry->start_service(m_socket_server)){ ndbout_c("Unable to start theTransporterRegistry->start_service"); diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 99edea846c1..e74f4b51e00 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -24,6 +24,7 @@ #include <NdbMutex.h> #include "DictCache.hpp" #include <BlockNumbers.h> +#include <mgmapi.h> class ClusterMgr; class ArbitMgr; @@ -43,10 +44,6 @@ extern "C" { void atexit_stop_instance(); } -/** - * Max number of Ndb objects in different threads. - * (Ndb objects should not be shared by different threads.) - */ class TransporterFacade { public: @@ -115,6 +112,8 @@ public: Uint32 get_batch_byte_size(); Uint32 get_batch_size(); + TransporterRegistry* get_registry() { return theTransporterRegistry;}; + private: /** * Send a signal unconditional of node status (used by ClusterMgr) @@ -133,7 +132,7 @@ private: bool isConnected(NodeId aNodeId); void doStop(); - + TransporterRegistry* theTransporterRegistry; SocketServer m_socket_server; int sendPerformedLastInterval; @@ -171,6 +170,10 @@ private: * Block number handling */ public: + /** + * Max number of Ndb objects. + * (Ndb objects should not be shared by different threads.) + */ STATIC_CONST( MAX_NO_THREADS = 4711 ); private: diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 4fcf4d08396..49aded8e0ac 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -28,7 +28,8 @@ #include <ndb_limits.h> #include <ConfigRetriever.hpp> #include <ndb_version.h> -#include <Vector.hpp> +#include <mgmapi_debug.h> +#include <mgmapi_internal.h> #include <md5_hash.hpp> #include <EventLogger.hpp> @@ -180,6 +181,12 @@ Ndb_cluster_connection::no_db_nodes() return m_impl.m_all_nodes.size(); } +unsigned +Ndb_cluster_connection::node_id() +{ + return m_impl.m_transporter_facade->ownId(); +} + int Ndb_cluster_connection::wait_until_ready(int timeout, @@ -253,9 +260,6 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NdbApi"); g_eventLogger.enable(Logger::LL_ON, Logger::LL_ERROR); - - m_transporter_facade= - TransporterFacade::theFacadeInstance= new TransporterFacade(); m_connect_thread= 0; m_connect_callback= 0; @@ -280,6 +284,10 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * m_config_retriever= 0; } + m_transporter_facade= + TransporterFacade::theFacadeInstance= + new TransporterFacade(); + DBUG_VOID_RETURN; } @@ -465,6 +473,8 @@ Ndb_cluster_connection_impl::do_test() int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, int verbose) { + struct ndb_mgm_reply mgm_reply; + DBUG_ENTER("Ndb_cluster_connection::connect"); const char* error = 0; do { @@ -482,10 +492,24 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, ndb_mgm_configuration * props = m_impl.m_config_retriever->getConfig(); if(props == 0) break; - m_impl.m_transporter_facade->start_instance(nodeId, props); + m_impl.m_transporter_facade->start_instance(nodeId, props); m_impl.init_nodes_vector(nodeId, *props); + for(unsigned i=0; + i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size(); + i++) + ndb_mgm_set_connection_int_parameter(m_impl.m_config_retriever->get_mgmHandle(), + nodeId, + m_impl.m_transporter_facade->get_registry() + ->m_transporter_interface[i] + .m_remote_nodeId, + CFG_CONNECTION_SERVER_PORT, + m_impl.m_transporter_facade->get_registry() + ->m_transporter_interface[i] + .m_s_service_port, + &mgm_reply); + ndb_mgm_destroy_configuration(props); m_impl.m_transporter_facade->connected(); DBUG_RETURN(0); @@ -522,110 +546,5 @@ void Ndb_cluster_connection_impl::connect_thread() DBUG_VOID_RETURN; } -/* - * Hint handling to select node - * ToDo: fix this - */ - -void -Ndb_cluster_connection_impl::FragmentToNodeMap::init(Uint32 noOfNodes, - Uint8 nodeIds[]) -{ - kValue = 6; - noOfFragments = 2 * noOfNodes; - - /** - * Compute hashValueMask and hashpointerValue - */ - { - Uint32 topBit = (1 << 31); - for(int i = 31; i>=0; i--){ - if((noOfFragments & topBit) != 0) - break; - topBit >>= 1; - } - hashValueMask = topBit - 1; - hashpointerValue = noOfFragments - (hashValueMask + 1); - } - - /** - * This initialization depends on - * the fact that: - * primary node for fragment i = i % noOfNodes - * - * This algorithm should be implemented in Dbdih - */ - { - if (fragment2PrimaryNodeMap != 0) - abort(); - - fragment2PrimaryNodeMap = new Uint32[noOfFragments]; - Uint32 i; - for(i = 0; i<noOfNodes; i++){ - fragment2PrimaryNodeMap[i] = nodeIds[i]; - } - - // Sort them (bubble sort) - for(i = 0; i<noOfNodes-1; i++) - for(Uint32 j = i+1; j<noOfNodes; j++) - if(fragment2PrimaryNodeMap[i] > fragment2PrimaryNodeMap[j]){ - Uint32 tmp = fragment2PrimaryNodeMap[i]; - fragment2PrimaryNodeMap[i] = fragment2PrimaryNodeMap[j]; - fragment2PrimaryNodeMap[j] = tmp; - } - - for(i = 0; i<noOfNodes; i++){ - fragment2PrimaryNodeMap[i+noOfNodes] = fragment2PrimaryNodeMap[i]; - } - } -} - -void -Ndb_cluster_connection_impl::FragmentToNodeMap::release(){ - delete [] fragment2PrimaryNodeMap; - fragment2PrimaryNodeMap = 0; -} - -static const Uint32 MAX_KEY_LEN_64_WORDS = 4; -Uint32 -Ndb_cluster_connection_impl::guess_primary_node(const char *keyData, - Uint32 keyLen) -{ - Uint64 tempData[MAX_KEY_LEN_64_WORDS]; - - const Uint32 usedKeyLen = (keyLen + 3) >> 2; // In words - const char * usedKeyData = 0; - - /** - * If key data buffer is not aligned (on 64 bit boundary) - * or key len is not a multiple of 4 - * Use temp data - */ - if(((((UintPtr)keyData) & 7) == 0) && ((keyLen & 3) == 0)) { - usedKeyData = keyData; - } else { - memcpy(&tempData[0], keyData, keyLen); - const int slack = keyLen & 3; - if(slack > 0) { - memset(&((char *)&tempData[0])[keyLen], 0, (4 - slack)); - }//if - usedKeyData = (char *)&tempData[0]; - }//if - - Uint32 hashValue = md5_hash((Uint64 *)usedKeyData, usedKeyLen); - - hashValue >>= fragmentToNodeMap.kValue; - - Uint32 fragmentId = hashValue & - fragmentToNodeMap.hashValueMask; - - if(fragmentId < fragmentToNodeMap.hashpointerValue) { - fragmentId = hashValue & - ((fragmentToNodeMap.hashValueMask << 1) + 1); - }//if - return fragmentId; -} - - template class Vector<Ndb_cluster_connection_impl::Node>; diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp index 620eac296a3..05652f3316a 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp +++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp @@ -54,22 +54,6 @@ private: friend class NdbImpl; friend void* run_ndb_cluster_connection_connect_thread(void*); friend class Ndb_cluster_connection; - - /** - * Structure containing values for guessing primary node - */ - struct FragmentToNodeMap { - FragmentToNodeMap(): - fragment2PrimaryNodeMap(0) {}; - Uint32 kValue; - Uint32 hashValueMask; - Uint32 hashpointerValue; - Uint32 noOfFragments; - Uint32 *fragment2PrimaryNodeMap; - - void init(Uint32 noOfNodes, Uint8 nodeIds[]); - void release(); - } fragmentToNodeMap; struct Node { @@ -85,8 +69,6 @@ private: Vector<Node> m_all_nodes; void init_nodes_vector(Uint32 nodeid, const ndb_mgm_configuration &config); - Uint32 guess_primary_node(const char * keyData, Uint32 keyLen); - void connect_thread(); TransporterFacade *m_transporter_facade; diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index d4ad9cd6f1c..b033d81fa33 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -55,6 +55,8 @@ typedef struct ErrorBundle { #define NI ndberror_cl_function_not_implemented #define UE ndberror_cl_unknown_error_code +#define OE ndberror_cl_schema_object_already_exists + static const char REDO_BUFFER_MSG[]= "REDO log buffers overloaded, consult online manual (increase RedoBuffer, and|or decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)"; @@ -69,6 +71,7 @@ static const char* empty_string = ""; * 600 - ACC * 700 - DICT * 800 - TUP + * 900 - TUX * 1200 - LQH * 1300 - BACKUP * 4000 - API @@ -78,6 +81,7 @@ static const char* empty_string = ""; * 4400 - "" * 4500 - "" * 4600 - "" + * 4700 - "" Event * 5000 - Management server */ @@ -176,10 +180,13 @@ ErrorBundle ErrorCodes[] = { { 623, IS, "623" }, { 624, IS, "624" }, { 625, IS, "Out of memory in Ndb Kernel, index part (increase IndexMemory)" }, - { 800, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" }, + { 640, IS, "Too many hash indexes (should not happen)" }, { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes or MaxNoOfTables)" }, { 827, IS, "Out of memory in Ndb Kernel, data part (increase DataMemory)" }, - { 832, IS, "832" }, + { 902, IS, "Out of memory in Ndb Kernel, data part (increase DataMemory)" }, + { 903, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" }, + { 904, IS, "Out of fragment records (increase MaxNoOfOrderedIndexes)" }, + { 905, IS, "Out of attribute records (increase MaxNoOfAttributes)" }, /** * TimeoutExpired @@ -205,7 +212,8 @@ ErrorBundle ErrorCodes[] = { * Internal errors */ { 892, IE, "Inconsistent hash index. The index needs to be dropped and recreated" }, - { 895, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" }, + { 896, IE, "Tuple corrupted - wrong checksum or column data in invalid format" }, + { 901, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" }, { 202, IE, "202" }, { 203, IE, "203" }, { 207, IE, "207" }, @@ -260,6 +268,7 @@ ErrorBundle ErrorCodes[] = { * Application error */ { 823, AE, "Too much attrinfo from application in tuple manager" }, + { 831, AE, "Too many nullable/bitfields in table definition" }, { 876, AE, "876" }, { 877, AE, "877" }, { 878, AE, "878" }, @@ -271,7 +280,7 @@ ErrorBundle ErrorCodes[] = { { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" }, { 4256, AE, "Must call Ndb::init() before this function" }, { 4257, AE, "Tried to read too much - too many getValue calls" }, - + /** * Scan application errors */ @@ -290,6 +299,30 @@ ErrorBundle ErrorCodes[] = { { 4232, AE, "Parallelism can only be between 1 and 240" }, { 290, AE, "Scan not started or has been closed by kernel due to timeout" }, + /** + * Event schema errors + */ + + { 4713, SE, "Column defined in event does not exist in table"}, + + /** + * Event application errors + */ + + { 4707, AE, "Too many event have been defined"}, + { 4708, AE, "Event name is too long"}, + { 4709, AE, "Can't accept more subscribers"}, + { 746, OE, "Event name already exists"}, + { 4710, AE, "Event not found"}, + { 4711, AE, "Creation of event failed"}, + { 4712, AE, "Stopped event operation does not exist. Already stopped?"}, + + /** + * Event internal errors + */ + + { 4731, IE, "Event not found"}, + /** * SchemaError */ @@ -300,22 +333,25 @@ ErrorBundle ErrorCodes[] = { { 707, SE, "No more table metadata records" }, { 708, SE, "No more attribute metadata records" }, { 709, SE, "No such table existed" }, - { 721, SE, "Table or index with given name already exists" }, + { 721, OE, "Table or index with given name already exists" }, { 723, SE, "No such table existed" }, - { 736, SE, "Wrong attribute size" }, + { 736, SE, "Unsupported array size" }, { 737, SE, "Attribute array size too big" }, { 738, SE, "Record too big" }, { 739, SE, "Unsupported primary key length" }, { 740, SE, "Nullable primary key not supported" }, { 741, SE, "Unsupported alter table" }, - { 742, SE, "Unsupported attribute type in index" }, { 743, SE, "Unsupported character set in table or index" }, { 744, SE, "Character string is invalid for given character set" }, + { 745, SE, "Distribution key not supported for char attribute (use binary attribute)" }, { 241, SE, "Invalid schema object version" }, { 283, SE, "Table is being dropped" }, { 284, SE, "Table not defined in transaction coordinator" }, { 285, SE, "Unknown table error in transaction coordinator" }, { 881, SE, "Unable to create table, out of data pages (increase DataMemory) " }, + { 906, SE, "Unsupported attribute type in index" }, + { 907, SE, "Unsupported character set in table or index" }, + { 908, IS, "Invalid ordered index tree node size" }, { 1225, SE, "Table not defined in local query handler" }, { 1226, SE, "Table is being dropped" }, { 1228, SE, "Cannot use drop table for drop index" }, @@ -457,8 +493,7 @@ ErrorBundle ErrorCodes[] = { { 4241, AE, "Index name too long" }, { 4242, AE, "Too many indexes" }, { 4243, AE, "Index not found" }, - { 4244, AE, "Index or table with given name already exists" }, - { 4245, AE, "Index attribute must be defined as stored, i.e. the StorageAttributeType must be defined as NormalStorageAttribute"}, + { 4244, OE, "Index or table with given name already exists" }, { 4247, AE, "Illegal index/trigger create/drop/alter request" }, { 4248, AE, "Trigger/index name invalid" }, { 4249, AE, "Invalid table" }, @@ -479,9 +514,10 @@ ErrorBundle ErrorCodes[] = { { 4266, AE, "Invalid blob seek position" }, { 4267, IE, "Corrupted blob value" }, { 4268, IE, "Error in blob head update forced rollback of transaction" }, - { 4268, IE, "Unknown blob error" }, { 4269, IE, "No connection to ndb management server" }, - { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" } + { 4270, IE, "Unknown blob error" }, + { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" }, + { 4271, AE, "Invalid index object, not retrieved via getIndex()" } }; static |