Below is the list of changes that have just been committed into a local
5.1 repository of marty. When marty does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-02-06 23:42:24+01:00, mskold@stripped +7 -0
Merge mysql.com:/windows/Linux_space/MySQL/mysql-5.0
into mysql.com:/windows/Linux_space/MySQL/mysql-5.1
MERGE: 1.1810.2386.14
mysql-test/r/ndb_read_multi_range.result@stripped, 2007-02-06 23:40:34+01:00, mskold@stripped +0 -0
Auto merged
MERGE: 1.3.2.3
mysql-test/t/ndb_read_multi_range.test@stripped, 2007-02-06 23:40:34+01:00, mskold@stripped +0 -0
Auto merged
MERGE: 1.4.2.3
sql/ha_ndbcluster.cc@stripped, 2007-02-06 23:40:35+01:00, mskold@stripped +1 -2
Auto merged
MERGE: 1.175.61.9
sql/ha_ndbcluster.h@stripped, 2007-02-06 23:41:43+01:00, mskold@stripped +0 -1
MERGE: 1.82.6.1
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp@stripped, 2007-02-06 23:40:35+01:00, mskold@stripped +0 -0
Auto merged
MERGE: 1.17.6.2
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp@stripped, 2007-02-06 23:40:34+01:00, mskold@stripped +0 -0
Merge rename: ndb/include/ndbapi/NdbIndexScanOperation.hpp -> storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
storage/ndb/include/ndbapi/NdbScanOperation.hpp@stripped, 2007-02-06 23:42:20+01:00, mskold@stripped +0 -0
SCCS merged
MERGE: 1.32.7.2
storage/ndb/include/ndbapi/NdbScanOperation.hpp@stripped, 2007-02-06 23:40:34+01:00, mskold@stripped +0 -0
Merge rename: ndb/include/ndbapi/NdbScanOperation.hpp -> storage/ndb/include/ndbapi/NdbScanOperation.hpp
storage/ndb/src/ndbapi/NdbScanOperation.cpp@stripped, 2007-02-06 23:40:35+01:00, mskold@stripped +0 -0
Auto merged
MERGE: 1.66.20.2
storage/ndb/src/ndbapi/NdbScanOperation.cpp@stripped, 2007-02-06 23:40:34+01:00, mskold@stripped +0 -0
Merge rename: ndb/src/ndbapi/NdbScanOperation.cpp -> storage/ndb/src/ndbapi/NdbScanOperation.cpp
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mskold
# Host: linux.site
# Root: /windows/Linux_space/MySQL/mysql-5.1/RESYNC
--- 1.17.6.1/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2007-02-06 23:42:33 +01:00
+++ 1.28/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp 2007-02-06 23:42:33 +01:00
@@ -2,8 +2,7 @@
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,6 +29,7 @@ class NdbIndexScanOperation : public Ndb
friend class NdbResultSet;
friend class NdbOperation;
friend class NdbScanOperation;
+ friend class NdbIndexStat;
#endif
public:
@@ -118,17 +118,23 @@ public:
* @param attr Attribute name, alternatively:
* @param type Type of bound
* @param value Pointer to bound value, 0 for NULL
- * @param len Value length in bytes.
- * Fixed per datatype and can be omitted
* @return 0 if successful otherwise -1
+ *
+ * @note See comment under equal() about data format and length.
*/
- int setBound(const char* attr, int type, const void* value, Uint32 len = 0);
+#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
+ int setBound(const char* attr, int type, const void* value, Uint32 len);
+#endif
+ int setBound(const char* attr, int type, const void* value);
/**
* Define bound on index key in range scan using index column id.
* See the other setBound() method for details.
*/
- int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0);
+#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
+ int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len);
+#endif
+ int setBound(Uint32 anAttrId, int type, const void* aValue);
/**
* Reset bounds and put operation in list that will be
@@ -156,19 +162,21 @@ public:
* Is current scan sorted descending
*/
bool getDescending() const { return m_descending; }
+
private:
NdbIndexScanOperation(Ndb* aNdb);
virtual ~NdbIndexScanOperation();
- int setBound(const NdbColumnImpl*, int type, const void* aValue, Uint32 len);
+ int setBound(const NdbColumnImpl*, int type, const void* aValue);
int insertBOUNDS(Uint32 * data, Uint32 sz);
+ Uint32 getKeyFromSCANTABREQ(Uint32* data, Uint32 size);
- virtual int equal_impl(const NdbColumnImpl*, const char*, Uint32);
+ virtual int equal_impl(const NdbColumnImpl*, const char*);
virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*);
void fix_get_values();
int next_result_ordered(bool fetchAllowed, bool forceSend = false);
- int send_next_scan_ordered(Uint32 idx, bool forceSend = false);
+ int send_next_scan_ordered(Uint32 idx);
int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
Uint32 m_sort_columns;
@@ -177,5 +185,21 @@ private:
friend struct Ndb_free_list_t<NdbIndexScanOperation>;
};
+
+inline
+int
+NdbIndexScanOperation::setBound(const char* attr, int type, const void* value,
+ Uint32 len)
+{
+ return setBound(attr, type, value);
+}
+
+inline
+int
+NdbIndexScanOperation::setBound(Uint32 anAttrId, int type, const void* value,
+ Uint32 len)
+{
+ return setBound(anAttrId, type, value);
+}
#endif
--- 1.32.7.1/ndb/include/ndbapi/NdbScanOperation.hpp 2007-02-06 23:42:33 +01:00
+++ 1.45/storage/ndb/include/ndbapi/NdbScanOperation.hpp 2007-02-06 23:42:33 +01:00
@@ -2,8 +2,7 @@
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -21,6 +20,7 @@
class NdbBlob;
class NdbResultSet;
+class PollGuard;
/**
* @class NdbScanOperation
@@ -41,7 +41,8 @@ public:
* readTuples.
*/
enum ScanFlag {
- SF_TupScan = (1 << 16), // scan TUP
+ SF_TupScan = (1 << 16), // scan TUP order
+ SF_DiskScan = (2 << 16), // scan in DISK order
SF_OrderBy = (1 << 24), // index scan in order
SF_Descending = (2 << 24), // index scan in descending order
SF_ReadRangeNo = (4 << 24), // enable @ref get_range_no
@@ -202,7 +203,8 @@ protected:
int nextResultImpl(bool fetchAllowed = true, bool forceSend = false);
virtual void release();
- int close_impl(class TransporterFacade*, bool forceSend = false);
+ int close_impl(class TransporterFacade*, bool forceSend,
+ PollGuard *poll_guard);
// Overloaded methods from NdbCursorOperation
int executeCursor(int ProcessorId);
@@ -211,7 +213,6 @@ protected:
int init(const NdbTableImpl* tab, NdbTransaction*);
int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId);
int doSend(int ProcessorId);
- void checkForceSend(bool forceSend);
virtual void setErrorCode(int aErrorCode);
virtual void setErrorCodeAbort(int aErrorCode);
@@ -253,12 +254,12 @@ protected:
Uint32 m_sent_receivers_count; // NOTE needs mutex to access
NdbReceiver** m_sent_receivers; // receive thread puts them here
- int send_next_scan(Uint32 cnt, bool close, bool forceSend = false);
+ int send_next_scan(Uint32 cnt, bool close);
void receiver_delivered(NdbReceiver*);
void receiver_completed(NdbReceiver*);
void execCLOSE_SCAN_REP();
- int getKeyFromKEYINFO20(Uint32* data, unsigned size);
+ int getKeyFromKEYINFO20(Uint32* data, Uint32 & size);
NdbOperation* takeOverScanOp(OperationType opType, NdbTransaction*);
bool m_ordered;
@@ -266,6 +267,7 @@ protected:
Uint32 m_read_range_no;
NdbRecAttr *m_curr_row; // Pointer to last returned row
bool m_multi_range; // Mark if operation is part of multi-range scan
+ bool m_executed; // Marker if operation should be released at close
};
inline
--- 1.66.20.1/ndb/src/ndbapi/NdbScanOperation.cpp 2007-02-06 23:42:33 +01:00
+++ 1.105/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2007-02-06 23:42:33 +01:00
@@ -2,8 +2,7 @@
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -50,6 +49,7 @@ NdbScanOperation::NdbScanOperation(Ndb*
m_receivers = 0;
m_array = new Uint32[1]; // skip if on delete in fix_receivers
theSCAN_TABREQ = 0;
+ m_executed = false;
}
NdbScanOperation::~NdbScanOperation()
@@ -111,6 +111,7 @@ NdbScanOperation::init(const NdbTableImp
theNdbCon->theMagicNumber = 0xFE11DF;
theNoOfTupKeyLeft = tab->m_noOfDistributionKeys;
m_read_range_no = 0;
+ m_executed = false;
return 0;
}
@@ -162,9 +163,25 @@ NdbScanOperation::readTuples(NdbScanOper
}
m_keyInfo = ((scan_flags & SF_KeyInfo) || lockExcl) ? 1 : 0;
+ bool tupScan = (scan_flags & SF_TupScan);
+#if 1 // XXX temp for testing
+ { char* p = getenv("NDB_USE_TUPSCAN");
+ if (p != 0) {
+ unsigned n = atoi(p); // 0-10
+ if ((unsigned int) (::time(0) % 10) < n) tupScan = true;
+ }
+ }
+#endif
+ if (scan_flags & SF_DiskScan)
+ {
+ tupScan = true;
+ m_no_disk_flag = false;
+ }
+
bool rangeScan = false;
- if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex)
+ if ( (int) m_accessTable->m_indexType ==
+ (int) NdbDictionary::Index::OrderedIndex)
{
if (m_currentTable == m_accessTable){
// Old way of scanning indexes, should not be allowed
@@ -177,12 +194,9 @@ NdbScanOperation::readTuples(NdbScanOper
theStatus = GetValue;
theOperationType = OpenRangeScanRequest;
rangeScan = true;
- }
-
- bool tupScan = (scan_flags & SF_TupScan);
- if (tupScan && rangeScan)
tupScan = false;
-
+ }
+
if (rangeScan && (scan_flags & SF_OrderBy))
parallel = fragCount;
@@ -202,7 +216,7 @@ NdbScanOperation::readTuples(NdbScanOper
theSCAN_TABREQ->setSignal(GSN_SCAN_TABREQ);
ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
req->apiConnectPtr = theNdbCon->theTCConPtr;
- req->tableId = m_accessTable->m_tableId;
+ req->tableId = m_accessTable->m_id;
req->tableSchemaVersion = m_accessTable->m_version;
req->storedProcId = 0xFFFF;
req->buddyConPtr = theNdbCon->theBuddyConPtr;
@@ -363,7 +377,7 @@ NdbScanOperation::getFirstATTRINFOScan()
int
NdbScanOperation::executeCursor(int nodeId){
NdbTransaction * tCon = theNdbCon;
- TransporterFacade* tp = TransporterFacade::instance();
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
Guard guard(tp->theMutexPtr);
Uint32 magic = tCon->theMagicNumber;
@@ -385,6 +399,7 @@ NdbScanOperation::executeCursor(int node
if (doSendScan(nodeId) == -1)
return -1;
+ m_executed= true; // Mark operation as executed
return 0;
} else {
if (!(tp->get_node_stopping(nodeId) &&
@@ -464,18 +479,28 @@ int NdbScanOperation::nextResultImpl(boo
}
Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade* tp = TransporterFacade::instance();
- Guard guard(tp->theMutexPtr);
- if(theError.code)
- return -1;
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
+ theNdb->theNdbBlockNumber);
- Uint32 seq = theNdbCon->theNodeSequence;
- if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false,
- forceSend) == 0){
+ const Uint32 seq = theNdbCon->theNodeSequence;
+
+ if(theError.code)
+ {
+ goto err4;
+ }
+
+ if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0)
+ {
idx = m_current_api_receiver;
last = m_api_receivers_count;
-
Uint32 timeout = tp->m_waitfor_timeout;
do {
@@ -502,12 +527,10 @@ int NdbScanOperation::nextResultImpl(boo
/**
* No completed...
*/
- theNdb->theImpl->theWaiter.m_node = nodeId;
- theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(3*timeout);
- if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) {
+ int ret_code= poll_guard.wait_scan(3*timeout, nodeId, forceSend);
+ if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
continue;
- } else if(return_code == -1){
+ } else if(ret_code == -1){
retVal = -1;
} else {
idx = last;
@@ -557,17 +580,21 @@ int NdbScanOperation::nextResultImpl(boo
if(theError.code == 0)
setErrorCode(4028); // seq changed = Node fail
break;
+ case -4:
+err4:
+ setErrorCode(theError.code);
+ break;
}
theNdbCon->theTransactionIsStarted = false;
theNdbCon->theReleaseOnClose = true;
- if(DEBUG_NEXT_RESULT) ndbout_c("return -1", retVal);
+ if(DEBUG_NEXT_RESULT) ndbout_c("return %d", retVal);
return -1;
}
int
-NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag,
- bool forceSend){
+NdbScanOperation::send_next_scan(Uint32 cnt, bool stopScanFlag)
+{
if(cnt > 0){
NdbApiSignal tSignal(theNdb->theMyRef);
tSignal.setSignal(GSN_SCAN_NEXTREQ);
@@ -602,7 +629,7 @@ NdbScanOperation::send_next_scan(Uint32
if(sent)
{
Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade * tp = TransporterFacade::instance();
+ TransporterFacade * tp = theNdb->theImpl->m_transporter_facade;
if(cnt > 21){
tSignal.setLength(4);
LinearSectionPtr ptr[3];
@@ -614,9 +641,6 @@ NdbScanOperation::send_next_scan(Uint32
ret = tp->sendSignal(&tSignal, nodeId);
}
}
-
- if (!ret) checkForceSend(forceSend);
-
m_sent_receivers_count = last + sent;
m_api_receivers_count -= cnt;
m_current_api_receiver = 0;
@@ -626,15 +650,6 @@ NdbScanOperation::send_next_scan(Uint32
return 0;
}
-void NdbScanOperation::checkForceSend(bool forceSend)
-{
- if (forceSend) {
- TransporterFacade::instance()->forceSend(theNdb->theNdbBlockNumber);
- } else {
- TransporterFacade::instance()->checkForceSend(theNdb->theNdbBlockNumber);
- }//if
-}
-
int
NdbScanOperation::prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId)
{
@@ -653,9 +668,9 @@ NdbScanOperation::doSend(int ProcessorId
void NdbScanOperation::close(bool forceSend, bool releaseOp)
{
DBUG_ENTER("NdbScanOperation::close");
- DBUG_PRINT("enter", ("this=%x tcon=%x con=%x force=%d release=%d",
- (UintPtr)this,
- (UintPtr)m_transConnection, (UintPtr)theNdbCon,
+ DBUG_PRINT("enter", ("this: 0x%lx tcon: 0x%lx con: 0x%lx force: %d release: %d",
+ (long) this,
+ (long) m_transConnection, (long) theNdbCon,
forceSend, releaseOp));
if(m_transConnection){
@@ -669,10 +684,16 @@ void NdbScanOperation::close(bool forceS
m_conf_receivers_count,
m_sent_receivers_count);
- TransporterFacade* tp = TransporterFacade::instance();
- Guard guard(tp->theMutexPtr);
- close_impl(tp, forceSend);
-
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
+ theNdb->theNdbBlockNumber);
+ close_impl(tp, forceSend, &poll_guard);
}
NdbConnection* tCon = theNdbCon;
@@ -795,6 +816,7 @@ int NdbScanOperation::prepareSendScan(Ui
*/
Uint32 reqInfo = req->requestInfo;
ScanTabReq::setKeyinfoFlag(reqInfo, keyInfo);
+ ScanTabReq::setNoDiskFlag(reqInfo, m_no_disk_flag);
req->requestInfo = reqInfo;
for(Uint32 i = 0; i<theParallelism; i++){
@@ -845,7 +867,7 @@ NdbScanOperation::doSendScan(int aProces
req->requestInfo = tmp;
tSignal->setLength(ScanTabReq::StaticLength + theDistrKeyIndicator_);
- TransporterFacade *tp = TransporterFacade::instance();
+ TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
LinearSectionPtr ptr[3];
ptr[0].p = m_prepared_receivers;
ptr[0].sz = theParallelism;
@@ -929,13 +951,20 @@ NdbScanOperation::doSendScan(int aProces
* the scan process.
****************************************************************************/
int
-NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size)
+NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, Uint32 & size)
{
NdbRecAttr * tRecAttr = m_curr_row;
if(tRecAttr)
{
const Uint32 * src = (Uint32*)tRecAttr->aRef();
- memcpy(data, src, 4*size);
+
+ assert(tRecAttr->get_size_in_bytes() > 0);
+ assert(tRecAttr->get_size_in_bytes() < 65536);
+ const Uint32 len = (tRecAttr->get_size_in_bytes() + 3)/4-1;
+
+ assert(size >= len);
+ memcpy(data, src, 4*len);
+ size = len;
return 0;
}
return -1;
@@ -960,8 +989,10 @@ NdbScanOperation::takeOverScanOp(Operati
}
pTrans->theSimpleState = 0;
- const Uint32 len = (tRecAttr->attrSize() * tRecAttr->arraySize() + 3)/4-1;
-
+ assert(tRecAttr->get_size_in_bytes() > 0);
+ assert(tRecAttr->get_size_in_bytes() < 65536);
+ const Uint32 len = (tRecAttr->get_size_in_bytes() + 3)/4-1;
+
newOp->theTupKeyLen = len;
newOp->theOperationType = opType;
switch (opType) {
@@ -1059,23 +1090,23 @@ NdbIndexScanOperation::~NdbIndexScanOper
int
NdbIndexScanOperation::setBound(const char* anAttrName, int type,
- const void* aValue, Uint32 len)
+ const void* aValue)
{
- return setBound(m_accessTable->getColumn(anAttrName), type, aValue, len);
+ return setBound(m_accessTable->getColumn(anAttrName), type, aValue);
}
int
NdbIndexScanOperation::setBound(Uint32 anAttrId, int type,
- const void* aValue, Uint32 len)
+ const void* aValue)
{
- return setBound(m_accessTable->getColumn(anAttrId), type, aValue, len);
+ return setBound(m_accessTable->getColumn(anAttrId), type, aValue);
}
int
NdbIndexScanOperation::equal_impl(const NdbColumnImpl* anAttrObject,
- const char* aValue,
- Uint32 len){
- return setBound(anAttrObject, BoundEQ, aValue, len);
+ const char* aValue)
+{
+ return setBound(anAttrObject, BoundEQ, aValue);
}
NdbRecAttr*
@@ -1085,7 +1116,7 @@ NdbIndexScanOperation::getValue_impl(con
return NdbScanOperation::getValue_impl(attrInfo, aValue);
}
- int id = attrInfo->m_attrId; // In "real" table
+ int id = attrInfo->getColumnNo(); // In "real" table
assert(m_accessTable->m_index);
int sz = (int)m_accessTable->m_index->m_key_ids.size();
if(id >= sz || (id = m_accessTable->m_index->m_key_ids[id]) == -1){
@@ -1122,7 +1153,7 @@ NdbIndexScanOperation::getValue_impl(con
*/
int
NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
- int type, const void* aValue, Uint32 len)
+ int type, const void* aValue)
{
if (!tAttrInfo)
{
@@ -1130,24 +1161,23 @@ NdbIndexScanOperation::setBound(const Nd
return -1;
}
if (theOperationType == OpenRangeScanRequest &&
- (0 <= type && type <= 4) &&
- len <= 8000) {
+ (0 <= type && type <= 4)) {
// insert bound type
Uint32 currLen = theTotalNrOfKeyWordInSignal;
Uint32 remaining = KeyInfo::DataLength - currLen;
- Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
bool tDistrKey = tAttrInfo->m_distributionKey;
- len = aValue != NULL ? sizeInBytes : 0;
- if (len != sizeInBytes && (len != 0)) {
- setErrorCodeAbort(4209);
- return -1;
- }
+ Uint32 len = 0;
+ if (aValue != NULL)
+ if (! tAttrInfo->get_var_length(aValue, len)) {
+ setErrorCodeAbort(4209);
+ return -1;
+ }
// insert attribute header
Uint32 tIndexAttrId = tAttrInfo->m_attrId;
Uint32 sizeInWords = (len + 3) / 4;
- AttributeHeader ah(tIndexAttrId, sizeInWords);
+ AttributeHeader ah(tIndexAttrId, sizeInWords << 2);
const Uint32 ahValue = ah.m_value;
const Uint32 align = (UintPtr(aValue) & 7);
@@ -1241,6 +1271,31 @@ error:
return -1;
}
+Uint32
+NdbIndexScanOperation::getKeyFromSCANTABREQ(Uint32* data, Uint32 size)
+{
+ DBUG_ENTER("NdbIndexScanOperation::getKeyFromSCANTABREQ");
+ assert(size >= theTotalNrOfKeyWordInSignal);
+ size = theTotalNrOfKeyWordInSignal;
+ NdbApiSignal* tSignal = theSCAN_TABREQ->next();
+ Uint32 pos = 0;
+ while (pos < size) {
+ assert(tSignal != NULL);
+ Uint32* tData = tSignal->getDataPtrSend();
+ Uint32 rem = size - pos;
+ if (rem > KeyInfo::DataLength)
+ rem = KeyInfo::DataLength;
+ Uint32 i = 0;
+ while (i < rem) {
+ data[pos + i] = tData[KeyInfo::HeaderLength + i];
+ i++;
+ }
+ pos += rem;
+ }
+ DBUG_DUMP("key", (char*)data, size << 2);
+ DBUG_RETURN(size);
+}
+
int
NdbIndexScanOperation::readTuples(LockMode lm,
Uint32 scan_flags,
@@ -1341,10 +1396,11 @@ NdbIndexScanOperation::compare(Uint32 sk
return (r1_null ? -1 : 1) * jdir;
}
const NdbColumnImpl & col = NdbColumnImpl::getImpl(* r1->m_column);
- Uint32 len = r1->theAttrSize * r1->theArraySize;
+ Uint32 len1 = r1->get_size_in_bytes();
+ Uint32 len2 = r2->get_size_in_bytes();
if(!r1_null){
const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_type);
- int r = (*sqlType.m_cmp)(col.m_cs, d1, len, d2, len, true);
+ int r = (*sqlType.m_cmp)(col.m_cs, d1, len1, d2, len2, true);
if(r){
assert(r != NdbSqlUtil::CmpUnknown);
return r * jdir;
@@ -1382,26 +1438,31 @@ NdbIndexScanOperation::next_result_order
if(fetchNeeded){
if(fetchAllowed){
if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch...");
- TransporterFacade* tp = TransporterFacade::instance();
- Guard guard(tp->theMutexPtr);
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
+ theNdb->theNdbBlockNumber);
if(theError.code)
return -1;
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
Uint32 timeout = tp->m_waitfor_timeout;
if(seq == tp->getNodeSequence(nodeId) &&
- !send_next_scan_ordered(s_idx, forceSend)){
+ !send_next_scan_ordered(s_idx)){
Uint32 tmp = m_sent_receivers_count;
s_idx = m_current_api_receiver;
while(m_sent_receivers_count > 0 && !theError.code){
- theNdb->theImpl->theWaiter.m_node = nodeId;
- theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(3*timeout);
- if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) {
+ int ret_code= poll_guard.wait_scan(3*timeout, nodeId, forceSend);
+ if (ret_code == 0 && seq == tp->getNodeSequence(nodeId)) {
continue;
}
if(DEBUG_NEXT_RESULT) ndbout_c("return -1");
- if(return_code == -1){
+ if(ret_code == -1){
setErrorCode(4008);
} else {
setErrorCode(4028);
@@ -1488,7 +1549,8 @@ NdbIndexScanOperation::next_result_order
}
int
-NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx, bool forceSend){
+NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx)
+{
if(idx == theParallelism)
return 0;
@@ -1523,15 +1585,16 @@ NdbIndexScanOperation::send_next_scan_or
m_sent_receivers_count = last + 1;
Uint32 nodeId = theNdbCon->theDBnode;
- TransporterFacade * tp = TransporterFacade::instance();
+ TransporterFacade * tp = theNdb->theImpl->m_transporter_facade;
tSignal.setLength(4+1);
int ret= tp->sendSignal(&tSignal, nodeId);
- if (!ret) checkForceSend(forceSend);
return ret;
}
int
-NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
+NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend,
+ PollGuard *poll_guard)
+{
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
@@ -1542,15 +1605,12 @@ NdbScanOperation::close_impl(Transporter
}
Uint32 timeout = tp->m_waitfor_timeout;
-
/**
* Wait for outstanding
*/
while(theError.code == 0 && m_sent_receivers_count)
{
- theNdb->theImpl->theWaiter.m_node = nodeId;
- theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(3*timeout);
+ int return_code= poll_guard->wait_scan(3*timeout, nodeId, forceSend);
switch(return_code){
case 0:
break;
@@ -1607,7 +1667,7 @@ NdbScanOperation::close_impl(Transporter
}
// Send close scan
- if(send_next_scan(api+conf, true, forceSend) == -1)
+ if(send_next_scan(api+conf, true) == -1)
{
theNdbCon->theReleaseOnClose = true;
return -1;
@@ -1618,9 +1678,7 @@ NdbScanOperation::close_impl(Transporter
*/
while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count)
{
- theNdb->theImpl->theWaiter.m_node = nodeId;
- theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(3*timeout);
+ int return_code= poll_guard->wait_scan(3*timeout, nodeId, forceSend);
switch(return_code){
case 0:
break;
@@ -1659,13 +1717,20 @@ int
NdbScanOperation::restart(bool forceSend)
{
- TransporterFacade* tp = TransporterFacade::instance();
- Guard guard(tp->theMutexPtr);
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
+ theNdb->theNdbBlockNumber);
Uint32 nodeId = theNdbCon->theDBnode;
{
int res;
- if((res= close_impl(tp, forceSend)))
+ if((res= close_impl(tp, forceSend, &poll_guard)))
{
return res;
}
@@ -1679,7 +1744,6 @@ NdbScanOperation::restart(bool forceSend
theError.code = 0;
if (doSendScan(nodeId) == -1)
return -1;
-
return 0;
}
@@ -1688,9 +1752,16 @@ NdbIndexScanOperation::reset_bounds(bool
int res;
{
- TransporterFacade* tp = TransporterFacade::instance();
- Guard guard(tp->theMutexPtr);
- res= close_impl(tp, forceSend);
+ TransporterFacade* tp = theNdb->theImpl->m_transporter_facade;
+ /*
+ The PollGuard has an implicit call of unlock_and_signal through the
+ ~PollGuard method. This method is called implicitly by the compiler
+ in all places where the object is out of context due to a return,
+ break, continue or simply end of statement block
+ */
+ PollGuard poll_guard(tp, &theNdb->theImpl->theWaiter,
+ theNdb->theNdbBlockNumber);
+ res= close_impl(tp, forceSend, &poll_guard);
}
if(!res)
--- 1.387/sql/ha_ndbcluster.cc 2007-02-06 23:42:33 +01:00
+++ 1.388/sql/ha_ndbcluster.cc 2007-02-06 23:42:33 +01:00
@@ -8066,7 +8066,7 @@ ha_ndbcluster::read_multi_range_first(KE
}
else if ((scanOp= m_active_trans->getNdbIndexScanOperation(idx, tab))
&&!scanOp->readTuples(lm, 0, parallelism, sorted,
- FALSE, TRUE, need_pk)
+ FALSE, TRUE, need_pk, TRUE)
&&!generate_scan_filter(m_cond_stack, scanOp)
&&!define_read_attrs(end_of_buffer-reclength, scanOp))
{
--- 1.10/mysql-test/r/ndb_read_multi_range.result 2007-02-06 23:42:33 +01:00
+++ 1.11/mysql-test/r/ndb_read_multi_range.result 2007-02-06 23:42:33 +01:00
@@ -459,3 +459,10 @@ INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
UPDATE t1 SET var2 = 9 WHERE var1 IN(1,2,3);
DROP TRIGGER testtrigger;
DROP TABLE t1, t2;
+create table t2 (a int, b int, primary key (a), key ab (a,b)) engine=ndbcluster;
+insert into t2 values (1,1), (10,10);
+select * from t2 use index (ab) where a in(1,10) order by a;
+a b
+1 1
+10 10
+drop table t2;
--- 1.12/mysql-test/t/ndb_read_multi_range.test 2007-02-06 23:42:33 +01:00
+++ 1.13/mysql-test/t/ndb_read_multi_range.test 2007-02-06 23:42:33 +01:00
@@ -301,3 +301,12 @@ UPDATE t1 SET var2 = 9 WHERE var1 IN(1,2
DROP TRIGGER testtrigger;
DROP TABLE t1, t2;
+
+#bug#25821
+create table t2 (a int, b int, primary key (a), key ab (a,b)) engine=ndbcluster;
+
+insert into t2 values (1,1), (10,10);
+
+select * from t2 use index (ab) where a in(1,10) order by a;
+
+drop table t2;
| Thread |
|---|
| • bk commit into 5.1 tree (mskold:1.2380) | Martin Skold | 7 Feb |