summaryrefslogtreecommitdiff
path: root/mysys/queues.c
diff options
context:
space:
mode:
authorunknown <svoj@mysql.com/april.(none)>2006-09-28 22:10:06 +0500
committerunknown <svoj@mysql.com/april.(none)>2006-09-28 22:10:06 +0500
commit7d915f01934d73cf2500618fc7f5148768cfd1b8 (patch)
tree5b56c6cdb8550603c89fdebaffbeb7bf12678aaa /mysys/queues.c
parent186573b3d6301532b5d5fa9b470335e19f49769c (diff)
downloadmariadb-git-7d915f01934d73cf2500618fc7f5148768cfd1b8.tar.gz
BUG#21617 - crash when selecting from merge table with inconsistent indexes
Crash may happen when selecting from a merge table that has underlying tables with less indexes than in a merge table itself. If number of keys in merge table is not bigger than requested key number, return error. myisammrg/myrg_open.c: Store min(number of keys) in m_info instead of number of keys in last underlying table. myisammrg/myrg_queue.c: Return error if inx passed to _myrg_init_queue function is not less than number of keys. mysql-test/r/merge.result: A test case for bug#21617. mysql-test/t/merge.test: A test case for bug#21617. mysys/queues.c: Replaced annoying ifndef DBUG_OFF with DBUG_ASSERT, fixed coding style. The problem was that having queue overrun in debug build was hidden with this ifdef.
Diffstat (limited to 'mysys/queues.c')
-rw-r--r--mysys/queues.c48
1 files changed, 19 insertions, 29 deletions
diff --git a/mysys/queues.c b/mysys/queues.c
index ecf1058af41..6a285ce7417 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -164,28 +164,22 @@ void delete_queue(QUEUE *queue)
void queue_insert(register QUEUE *queue, byte *element)
{
- reg2 uint idx,next;
+ reg2 uint idx, next;
int cmp;
-
-#ifndef DBUG_OFF
- if (queue->elements < queue->max_elements)
-#endif
+ DBUG_ASSERT(queue->elements < queue->max_elements);
+ queue->root[0]= element;
+ idx= ++queue->elements;
+ /* max_at_top swaps the comparison if we want to order by desc */
+ while ((cmp= queue->compare(queue->first_cmp_arg,
+ element + queue->offset_to_key,
+ queue->root[(next= idx >> 1)] +
+ queue->offset_to_key)) &&
+ (cmp ^ queue->max_at_top) < 0)
{
- queue->root[0]=element;
- idx= ++queue->elements;
-
- /* max_at_top swaps the comparison if we want to order by desc */
- while ((cmp=queue->compare(queue->first_cmp_arg,
- element+queue->offset_to_key,
- queue->root[(next=idx >> 1)] +
- queue->offset_to_key)) &&
- (cmp ^ queue->max_at_top) < 0)
- {
- queue->root[idx]=queue->root[next];
- idx=next;
- }
- queue->root[idx]=element;
+ queue->root[idx]= queue->root[next];
+ idx= next;
}
+ queue->root[idx]= element;
}
/* Remove item from queue */
@@ -193,16 +187,12 @@ void queue_insert(register QUEUE *queue, byte *element)
byte *queue_remove(register QUEUE *queue, uint idx)
{
-#ifndef DBUG_OFF
- if (idx >= queue->max_elements)
- return 0;
-#endif
- {
- byte *element=queue->root[++idx]; /* Intern index starts from 1 */
- queue->root[idx]=queue->root[queue->elements--];
- _downheap(queue,idx);
- return element;
- }
+ byte *element;
+ DBUG_ASSERT(idx < queue->max_elements);
+ element= queue->root[++idx]; /* Intern index starts from 1 */
+ queue->root[idx]= queue->root[queue->elements--];
+ _downheap(queue, idx);
+ return element;
}
/* Fix when element on top has been replaced */