Commit 672c50e4 authored by mskold@mysql.com's avatar mskold@mysql.com

Fix for bug#17891 Partitions: NDB, crash on select .. where col is null or col = value

parent 5e77d287
...@@ -247,6 +247,7 @@ protected: ...@@ -247,6 +247,7 @@ protected:
bool m_descending; bool m_descending;
Uint32 m_read_range_no; Uint32 m_read_range_no;
NdbRecAttr *m_curr_row; // Pointer to last returned row NdbRecAttr *m_curr_row; // Pointer to last returned row
bool m_executed; // Marker if operation should be released at close
}; };
inline inline
......
...@@ -657,7 +657,7 @@ private: ...@@ -657,7 +657,7 @@ private:
// Release all cursor operations in connection // Release all cursor operations in connection
void releaseOps(NdbOperation*); void releaseOps(NdbOperation*);
void releaseScanOperations(NdbIndexScanOperation*); void releaseScanOperations(NdbIndexScanOperation*);
void releaseExecutedScanOperation(NdbIndexScanOperation*); void releaseScanOperation(NdbIndexScanOperation*);
// Set the transaction identity of the transaction // Set the transaction identity of the transaction
void setTransactionId(Uint64 aTransactionId); void setTransactionId(Uint64 aTransactionId);
......
...@@ -50,6 +50,7 @@ NdbScanOperation::NdbScanOperation(Ndb* aNdb) : ...@@ -50,6 +50,7 @@ NdbScanOperation::NdbScanOperation(Ndb* aNdb) :
m_receivers = 0; m_receivers = 0;
m_array = new Uint32[1]; // skip if on delete in fix_receivers m_array = new Uint32[1]; // skip if on delete in fix_receivers
theSCAN_TABREQ = 0; theSCAN_TABREQ = 0;
m_executed = false;
} }
NdbScanOperation::~NdbScanOperation() NdbScanOperation::~NdbScanOperation()
...@@ -111,6 +112,7 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection) ...@@ -111,6 +112,7 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection)
theNdbCon->theMagicNumber = 0xFE11DF; theNdbCon->theMagicNumber = 0xFE11DF;
theNoOfTupKeyLeft = tab->m_noOfDistributionKeys; theNoOfTupKeyLeft = tab->m_noOfDistributionKeys;
m_read_range_no = 0; m_read_range_no = 0;
m_executed = false;
return 0; return 0;
} }
...@@ -371,6 +373,7 @@ NdbScanOperation::executeCursor(int nodeId){ ...@@ -371,6 +373,7 @@ NdbScanOperation::executeCursor(int nodeId){
Uint32 magic = tCon->theMagicNumber; Uint32 magic = tCon->theMagicNumber;
Uint32 seq = tCon->theNodeSequence; Uint32 seq = tCon->theNodeSequence;
m_executed= true; // Mark operation as executed
if (tp->get_node_alive(nodeId) && if (tp->get_node_alive(nodeId) &&
(tp->getNodeSequence(nodeId) == seq)) { (tp->getNodeSequence(nodeId) == seq)) {
...@@ -680,7 +683,7 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp) ...@@ -680,7 +683,7 @@ void NdbScanOperation::close(bool forceSend, bool releaseOp)
if (releaseOp && tTransCon) { if (releaseOp && tTransCon) {
NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this; NdbIndexScanOperation* tOp = (NdbIndexScanOperation*)this;
tTransCon->releaseExecutedScanOperation(tOp); tTransCon->releaseScanOperation(tOp);
} }
tCon->theScanningOp = 0; tCon->theScanningOp = 0;
......
...@@ -970,17 +970,19 @@ NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp) ...@@ -970,17 +970,19 @@ NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp)
}//NdbTransaction::releaseScanOperations() }//NdbTransaction::releaseScanOperations()
/***************************************************************************** /*****************************************************************************
void releaseExecutedScanOperation(); void releaseScanOperation();
Remark: Release scan op when hupp'ed trans closed (save memory) Remark: Release scan op when hupp'ed trans closed (save memory)
******************************************************************************/ ******************************************************************************/
void void
NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) NdbTransaction::releaseScanOperation(NdbIndexScanOperation* cursorOp)
{ {
DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation"); DBUG_ENTER("NdbTransaction::releaseScanOperation");
DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)); DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp));
// here is one reason to make op lists doubly linked // here is one reason to make op lists doubly linked
if (cursorOp->m_executed)
{
if (m_firstExecutedScanOp == cursorOp) { if (m_firstExecutedScanOp == cursorOp) {
m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext; m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext;
cursorOp->release(); cursorOp->release();
...@@ -997,8 +999,28 @@ NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) ...@@ -997,8 +999,28 @@ NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
tOp = (NdbIndexScanOperation*)tOp->theNext; tOp = (NdbIndexScanOperation*)tOp->theNext;
} }
} }
}
else
{
if (m_theFirstScanOperation == cursorOp) {
m_theFirstScanOperation = (NdbIndexScanOperation*)cursorOp->theNext;
cursorOp->release();
theNdb->releaseScanOperation(cursorOp);
} else if (m_theFirstScanOperation != NULL) {
NdbIndexScanOperation* tOp = m_theFirstScanOperation;
while (tOp->theNext != NULL) {
if (tOp->theNext == cursorOp) {
tOp->theNext = cursorOp->theNext;
cursorOp->release();
theNdb->releaseScanOperation(cursorOp);
break;
}
tOp = (NdbIndexScanOperation*)tOp->theNext;
}
}
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
}//NdbTransaction::releaseExecutedScanOperation() }//NdbTransaction::releaseScanOperation()
/***************************************************************************** /*****************************************************************************
NdbOperation* getNdbOperation(const char* aTableName); NdbOperation* getNdbOperation(const char* aTableName);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment