diff options
author | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-11-14 22:20:31 +0400 |
---|---|---|
committer | unknown <holyfoot/hf@mysql.com/hfmain.(none)> | 2007-11-14 22:20:31 +0400 |
commit | c33c92d0f2d94e796aa403b80b29477e3400659b (patch) | |
tree | 9915b8eef2d14bebd9f577b361e1dd99b46f9d13 /mysys/queues.c | |
parent | d68b313dbc9af3f5924db977c12eff5e88f296be (diff) | |
download | mariadb-git-c33c92d0f2d94e796aa403b80b29477e3400659b.tar.gz |
Bug #31890 Partitions: ORDER BY DESC in InnoDB not working.
It's not InnoDB specific bug.
Error is in QUEUE code, about the way we handle queue->max_at_top.
It's either '0' or '-2' and we do '^' operation to get the proper
direction. Though queue->compare() function can return '-2' as
a result of comparison sometimes. So we'll get
queue->compare() ^ queue->max_at_top == 0 (when max_at_top is -2)
and _downheap() function code will go wrong way here:
...
if (next_index < elements &&
(queue->compare(queue->first_cmp_arg,
queue->root[next_index]+offset_to_key,
queue->root[next_index+1]+offset_to_key) ^
queue->max_at_top) > 0)
next_index++;
...
Fixed by changing max_at_top to be either 1 or -1, doing
'* max_at_top' to get proper direction.
include/queues.h:
Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
max_at_top policy changed
mysql-test/r/partition.result:
Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
test result
mysql-test/t/partition.test:
Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
test case
mysys/queues.c:
Bug #31890 Partitions: ORDER BY DESC in InnoDB not working.
queue->max_at_top policy changed - now it can either be '1' or '-1'.
We multiply comparison result on max_at_top to get the proper
direction.
Diffstat (limited to 'mysys/queues.c')
-rw-r--r-- | mysys/queues.c | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/mysys/queues.c b/mysys/queues.c index d8a7ca19bee..c0561e41dce 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -61,7 +61,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key, queue->first_cmp_arg=first_cmp_arg; queue->max_elements=max_elements; queue->offset_to_key=offset_to_key; - queue->max_at_top= max_at_top ? (-1 ^ 1) : 0; + queue_set_max_at_top(queue, max_at_top); DBUG_RETURN(0); } @@ -137,7 +137,7 @@ int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key, queue->compare=compare; queue->first_cmp_arg=first_cmp_arg; queue->offset_to_key=offset_to_key; - queue->max_at_top= max_at_top ? (-1 ^ 1) : 0; + queue_set_max_at_top(queue, max_at_top); resize_queue(queue, max_elements); DBUG_RETURN(0); } @@ -208,16 +208,14 @@ void delete_queue(QUEUE *queue) void queue_insert(register QUEUE *queue, uchar *element) { reg2 uint idx, next; - int cmp; 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) + while ((queue->compare(queue->first_cmp_arg, + element + queue->offset_to_key, + queue->root[(next= idx >> 1)] + + queue->offset_to_key) * queue->max_at_top) < 0) { queue->root[idx]= queue->root[next]; idx= next; @@ -287,19 +285,17 @@ void _downheap(register QUEUE *queue, uint idx) while (idx <= half_queue) { - int cmp; next_index=idx+idx; if (next_index < elements && (queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - queue->root[next_index+1]+offset_to_key) ^ + queue->root[next_index+1]+offset_to_key) * queue->max_at_top) > 0) next_index++; if (first && - (((cmp=queue->compare(queue->first_cmp_arg, - queue->root[next_index]+offset_to_key, - element+offset_to_key)) == 0) || - ((cmp ^ queue->max_at_top) > 0))) + (((queue->compare(queue->first_cmp_arg, + queue->root[next_index]+offset_to_key, + element+offset_to_key) * queue->max_at_top) >= 0))) { queue->root[idx]= element; return; @@ -314,7 +310,7 @@ void _downheap(register QUEUE *queue, uint idx) { if ((queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - element+offset_to_key) ^ + element+offset_to_key) * queue->max_at_top) < 0) break; queue->root[idx]=queue->root[next_index]; @@ -334,7 +330,6 @@ void _downheap(register QUEUE *queue, uint idx) { uchar *element; uint elements,half_queue,next_index,offset_to_key; - int cmp; offset_to_key=queue->offset_to_key; element=queue->root[idx]; @@ -346,13 +341,12 @@ void _downheap(register QUEUE *queue, uint idx) if (next_index < elements && (queue->compare(queue->first_cmp_arg, queue->root[next_index]+offset_to_key, - queue->root[next_index+1]+offset_to_key) ^ + queue->root[next_index+1]+offset_to_key) * queue->max_at_top) > 0) next_index++; - if ((cmp=queue->compare(queue->first_cmp_arg, - queue->root[next_index]+offset_to_key, - element+offset_to_key)) == 0 || - (cmp ^ queue->max_at_top) > 0) + if ((queue->compare(queue->first_cmp_arg, + queue->root[next_index]+offset_to_key, + element+offset_to_key) * queue->max_at_top) >= 0) break; queue->root[idx]=queue->root[next_index]; idx=next_index; |