mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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.
This commit is contained in:
@ -31,8 +31,8 @@ typedef struct st_queue {
|
|||||||
void *first_cmp_arg;
|
void *first_cmp_arg;
|
||||||
uint elements;
|
uint elements;
|
||||||
uint max_elements;
|
uint max_elements;
|
||||||
uint offset_to_key; /* compare is done on element+offset */
|
uint offset_to_key; /* compare is done on element+offset */
|
||||||
int max_at_top; /* Set if queue_top gives max */
|
int max_at_top; /* Normally 1, set to -1 if queue_top gives max */
|
||||||
int (*compare)(void *, uchar *,uchar *);
|
int (*compare)(void *, uchar *,uchar *);
|
||||||
uint auto_extent;
|
uint auto_extent;
|
||||||
} QUEUE;
|
} QUEUE;
|
||||||
@ -43,7 +43,7 @@ typedef struct st_queue {
|
|||||||
#define queue_replaced(queue) _downheap(queue,1)
|
#define queue_replaced(queue) _downheap(queue,1)
|
||||||
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
|
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
|
||||||
#define queue_set_max_at_top(queue, set_arg) \
|
#define queue_set_max_at_top(queue, set_arg) \
|
||||||
(queue)->max_at_top= set_arg ? (-1 ^ 1) : 0
|
(queue)->max_at_top= set_arg ? -1 : 1
|
||||||
typedef int (*queue_compare)(void *,uchar *, uchar *);
|
typedef int (*queue_compare)(void *,uchar *, uchar *);
|
||||||
|
|
||||||
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
|
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
|
||||||
|
@ -1296,4 +1296,39 @@ create table t1
|
|||||||
partition by key(s1) partitions 3;
|
partition by key(s1) partitions 3;
|
||||||
insert into t1 values (null,null);
|
insert into t1 values (null,null);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1
|
||||||
|
(int_column INT, char_column CHAR(5),
|
||||||
|
PRIMARY KEY(char_column,int_column))
|
||||||
|
PARTITION BY KEY(char_column,int_column)
|
||||||
|
PARTITIONS 101;
|
||||||
|
INSERT INTO t1 (int_column, char_column) VALUES
|
||||||
|
( 39868 ,'zZZRW'),
|
||||||
|
( 545592 ,'zZzSD'),
|
||||||
|
( 4936 ,'zzzsT'),
|
||||||
|
( 9274 ,'ZzZSX'),
|
||||||
|
( 970185 ,'ZZzTN'),
|
||||||
|
( 786036 ,'zZzTO'),
|
||||||
|
( 37240 ,'zZzTv'),
|
||||||
|
( 313801 ,'zzzUM'),
|
||||||
|
( 782427 ,'ZZZva'),
|
||||||
|
( 907955 ,'zZZvP'),
|
||||||
|
( 453491 ,'zzZWV'),
|
||||||
|
( 756594 ,'ZZZXU'),
|
||||||
|
( 718061 ,'ZZzZH');
|
||||||
|
SELECT * FROM t1 ORDER BY char_column DESC;
|
||||||
|
int_column char_column
|
||||||
|
718061 ZZzZH
|
||||||
|
756594 ZZZXU
|
||||||
|
453491 zzZWV
|
||||||
|
907955 zZZvP
|
||||||
|
782427 ZZZva
|
||||||
|
313801 zzzUM
|
||||||
|
37240 zZzTv
|
||||||
|
786036 zZzTO
|
||||||
|
970185 ZZzTN
|
||||||
|
9274 ZzZSX
|
||||||
|
4936 zzzsT
|
||||||
|
545592 zZzSD
|
||||||
|
39868 zZZRW
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -1549,4 +1549,31 @@ while ($cnt)
|
|||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1
|
||||||
|
(int_column INT, char_column CHAR(5),
|
||||||
|
PRIMARY KEY(char_column,int_column))
|
||||||
|
PARTITION BY KEY(char_column,int_column)
|
||||||
|
PARTITIONS 101;
|
||||||
|
INSERT INTO t1 (int_column, char_column) VALUES
|
||||||
|
( 39868 ,'zZZRW'),
|
||||||
|
( 545592 ,'zZzSD'),
|
||||||
|
( 4936 ,'zzzsT'),
|
||||||
|
( 9274 ,'ZzZSX'),
|
||||||
|
( 970185 ,'ZZzTN'),
|
||||||
|
( 786036 ,'zZzTO'),
|
||||||
|
( 37240 ,'zZzTv'),
|
||||||
|
( 313801 ,'zzzUM'),
|
||||||
|
( 782427 ,'ZZZva'),
|
||||||
|
( 907955 ,'zZZvP'),
|
||||||
|
( 453491 ,'zzZWV'),
|
||||||
|
( 756594 ,'ZZZXU'),
|
||||||
|
( 718061 ,'ZZzZH');
|
||||||
|
SELECT * FROM t1 ORDER BY char_column DESC;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -61,7 +61,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
|
|||||||
queue->first_cmp_arg=first_cmp_arg;
|
queue->first_cmp_arg=first_cmp_arg;
|
||||||
queue->max_elements=max_elements;
|
queue->max_elements=max_elements;
|
||||||
queue->offset_to_key=offset_to_key;
|
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);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
|
|||||||
queue->compare=compare;
|
queue->compare=compare;
|
||||||
queue->first_cmp_arg=first_cmp_arg;
|
queue->first_cmp_arg=first_cmp_arg;
|
||||||
queue->offset_to_key=offset_to_key;
|
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);
|
resize_queue(queue, max_elements);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@ -208,16 +208,14 @@ void delete_queue(QUEUE *queue)
|
|||||||
void queue_insert(register QUEUE *queue, uchar *element)
|
void queue_insert(register QUEUE *queue, uchar *element)
|
||||||
{
|
{
|
||||||
reg2 uint idx, next;
|
reg2 uint idx, next;
|
||||||
int cmp;
|
|
||||||
DBUG_ASSERT(queue->elements < queue->max_elements);
|
DBUG_ASSERT(queue->elements < queue->max_elements);
|
||||||
queue->root[0]= element;
|
queue->root[0]= element;
|
||||||
idx= ++queue->elements;
|
idx= ++queue->elements;
|
||||||
/* max_at_top swaps the comparison if we want to order by desc */
|
/* max_at_top swaps the comparison if we want to order by desc */
|
||||||
while ((cmp= queue->compare(queue->first_cmp_arg,
|
while ((queue->compare(queue->first_cmp_arg,
|
||||||
element + queue->offset_to_key,
|
element + queue->offset_to_key,
|
||||||
queue->root[(next= idx >> 1)] +
|
queue->root[(next= idx >> 1)] +
|
||||||
queue->offset_to_key)) &&
|
queue->offset_to_key) * queue->max_at_top) < 0)
|
||||||
(cmp ^ queue->max_at_top) < 0)
|
|
||||||
{
|
{
|
||||||
queue->root[idx]= queue->root[next];
|
queue->root[idx]= queue->root[next];
|
||||||
idx= next;
|
idx= next;
|
||||||
@ -287,19 +285,17 @@ void _downheap(register QUEUE *queue, uint idx)
|
|||||||
|
|
||||||
while (idx <= half_queue)
|
while (idx <= half_queue)
|
||||||
{
|
{
|
||||||
int cmp;
|
|
||||||
next_index=idx+idx;
|
next_index=idx+idx;
|
||||||
if (next_index < elements &&
|
if (next_index < elements &&
|
||||||
(queue->compare(queue->first_cmp_arg,
|
(queue->compare(queue->first_cmp_arg,
|
||||||
queue->root[next_index]+offset_to_key,
|
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)
|
queue->max_at_top) > 0)
|
||||||
next_index++;
|
next_index++;
|
||||||
if (first &&
|
if (first &&
|
||||||
(((cmp=queue->compare(queue->first_cmp_arg,
|
(((queue->compare(queue->first_cmp_arg,
|
||||||
queue->root[next_index]+offset_to_key,
|
queue->root[next_index]+offset_to_key,
|
||||||
element+offset_to_key)) == 0) ||
|
element+offset_to_key) * queue->max_at_top) >= 0)))
|
||||||
((cmp ^ queue->max_at_top) > 0)))
|
|
||||||
{
|
{
|
||||||
queue->root[idx]= element;
|
queue->root[idx]= element;
|
||||||
return;
|
return;
|
||||||
@ -314,7 +310,7 @@ void _downheap(register QUEUE *queue, uint idx)
|
|||||||
{
|
{
|
||||||
if ((queue->compare(queue->first_cmp_arg,
|
if ((queue->compare(queue->first_cmp_arg,
|
||||||
queue->root[next_index]+offset_to_key,
|
queue->root[next_index]+offset_to_key,
|
||||||
element+offset_to_key) ^
|
element+offset_to_key) *
|
||||||
queue->max_at_top) < 0)
|
queue->max_at_top) < 0)
|
||||||
break;
|
break;
|
||||||
queue->root[idx]=queue->root[next_index];
|
queue->root[idx]=queue->root[next_index];
|
||||||
@ -334,7 +330,6 @@ void _downheap(register QUEUE *queue, uint idx)
|
|||||||
{
|
{
|
||||||
uchar *element;
|
uchar *element;
|
||||||
uint elements,half_queue,next_index,offset_to_key;
|
uint elements,half_queue,next_index,offset_to_key;
|
||||||
int cmp;
|
|
||||||
|
|
||||||
offset_to_key=queue->offset_to_key;
|
offset_to_key=queue->offset_to_key;
|
||||||
element=queue->root[idx];
|
element=queue->root[idx];
|
||||||
@ -346,13 +341,12 @@ void _downheap(register QUEUE *queue, uint idx)
|
|||||||
if (next_index < elements &&
|
if (next_index < elements &&
|
||||||
(queue->compare(queue->first_cmp_arg,
|
(queue->compare(queue->first_cmp_arg,
|
||||||
queue->root[next_index]+offset_to_key,
|
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)
|
queue->max_at_top) > 0)
|
||||||
next_index++;
|
next_index++;
|
||||||
if ((cmp=queue->compare(queue->first_cmp_arg,
|
if ((queue->compare(queue->first_cmp_arg,
|
||||||
queue->root[next_index]+offset_to_key,
|
queue->root[next_index]+offset_to_key,
|
||||||
element+offset_to_key)) == 0 ||
|
element+offset_to_key) * queue->max_at_top) >= 0)
|
||||||
(cmp ^ queue->max_at_top) > 0)
|
|
||||||
break;
|
break;
|
||||||
queue->root[idx]=queue->root[next_index];
|
queue->root[idx]=queue->root[next_index];
|
||||||
idx=next_index;
|
idx=next_index;
|
||||||
|
Reference in New Issue
Block a user