Skip to content

Commit 1a23610

Browse files
author
Ole John Aske
committed
Bug#35293781 testNdbApi TestFragmentedSend times out in autotest since Mar 29th
Regression caused by patch for Bug#35185670 mysqld crashes on expensive query Original patch introduced a bug in FragmentedSectionIterator if we as part of FragmentedSectionIterator::setRange(start,len) attempted to set up a range of 'len == 0' starting at a position past the end of the data being available from the underlying iterator. As part of the setRange(), ::moveToPos(start) attempted to iterate to the specified start position. As that position could never be reached, it ended up in an infinite loop instead, or hit an assert with debug compiled binaries. Patch introduce a check+return of we reached the end of the underlying iterator breaking out of this loop. Note that this would also leave us with a 'lastReadPtr == NULL'. That state was already an accepted invariant of the FragmentedSectionIterator class - but only if the underlying iterator contained no data, and we were positioned 'pos == 0'. Patch extend the 'lastReadPtr == NULL' state to also be allowed when we have positioned past the end of the underlying iterator. This also allows us to slightly simplify the getNextWords() iteration within moveToPos(). Change-Id: Ie5290a862d20a80cc225af61685af017d3c0d3c4 (cherry picked from commit 6c0680d27848d6fe4ecbe215f26cefd34b01a0e6)
1 parent 81b118c commit 1a23610

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

storage/ndb/src/ndbapi/SectionIterators.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ FragmentedSectionIterator::checkInvariants()
142142
assert( rangeRemain <= rangeLen );
143143

144144
/* Can only have a null readptr if nothing is left */
145+
assert( (lastReadPtr != NULL) || (lastReadAvail == 0));
145146
assert( (lastReadPtr != NULL) || (rangeRemain == 0));
146147

147148
/* If we have a non-null readptr and some remaining
@@ -158,7 +159,17 @@ void
158159
FragmentedSectionIterator::moveToPos(Uint32 pos)
159160
{
160161
assert(pos <= realIterWords);
161-
162+
if (realIterWords == 0)
163+
{
164+
/**
165+
* Iterator is empty, 'realIterator' could even be NULL.
166+
* We are allowed to position at the end only. (With nothing available)
167+
*/
168+
assert(pos == 0);
169+
assert(lastReadTotal == 0 && lastReadAvail == 0);
170+
assert(realCurrPos == 0);
171+
return;
172+
}
162173
if (pos < realCurrPos)
163174
{
164175
/* Need to reset, and advance from the start */
@@ -169,25 +180,19 @@ FragmentedSectionIterator::moveToPos(Uint32 pos)
169180
lastReadAvail= 0;
170181
}
171182

172-
if ((lastReadPtr == NULL) &&
173-
(realIterWords != 0) &&
174-
(pos != realIterWords)) {
175-
lastReadPtr= realIterator->getNextWords(lastReadTotal);
176-
lastReadAvail = lastReadTotal;
177-
}
178-
179-
if (pos == realCurrPos) {
180-
lastReadAvail = lastReadTotal;
181-
return;
182-
}
183-
184183
/* Advance until we get a chunk which contains the pos */
185184
while (pos >= realCurrPos + lastReadTotal)
186185
{
187186
realCurrPos+= lastReadTotal;
188187
lastReadPtr= realIterator->getNextWords(lastReadTotal);
189-
assert(lastReadPtr != NULL);
190188
lastReadAvail = lastReadTotal;
189+
if (lastReadPtr == NULL)
190+
{
191+
// Advanced past the end
192+
assert(pos == realIterWords && realCurrPos == realIterWords);
193+
assert(lastReadAvail == 0);
194+
return;
195+
}
191196
}
192197

193198
const Uint32 chunkOffset= pos - realCurrPos;

0 commit comments

Comments
 (0)