mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	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.
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Copyright (C) 2000 MySQL AB
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or modify
 | 
						|
   it under the terms of the GNU General Public License as published by
 | 
						|
   the Free Software Foundation; version 2 of the License.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
   GNU General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software
 | 
						|
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 | 
						|
 | 
						|
/*
 | 
						|
  Code for generell handling of priority Queues.
 | 
						|
  Implemention of queues from "Algoritms in C" by Robert Sedgewick.
 | 
						|
  Copyright Monty Program KB.
 | 
						|
  By monty.
 | 
						|
*/
 | 
						|
 | 
						|
#ifndef _queues_h
 | 
						|
#define _queues_h
 | 
						|
#ifdef	__cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
typedef struct st_queue {
 | 
						|
  uchar **root;
 | 
						|
  void *first_cmp_arg;
 | 
						|
  uint elements;
 | 
						|
  uint max_elements;
 | 
						|
  uint offset_to_key;	/* compare is done on element+offset */
 | 
						|
  int max_at_top;	/* Normally 1, set to -1 if queue_top gives max */
 | 
						|
  int  (*compare)(void *, uchar *,uchar *);
 | 
						|
  uint auto_extent;
 | 
						|
} QUEUE;
 | 
						|
 | 
						|
#define queue_top(queue) ((queue)->root[1])
 | 
						|
#define queue_element(queue,index) ((queue)->root[index+1])
 | 
						|
#define queue_end(queue) ((queue)->root[(queue)->elements])
 | 
						|
#define queue_replaced(queue) _downheap(queue,1)
 | 
						|
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
 | 
						|
#define queue_set_max_at_top(queue, set_arg) \
 | 
						|
  (queue)->max_at_top= set_arg ? -1 : 1
 | 
						|
typedef int (*queue_compare)(void *,uchar *, uchar *);
 | 
						|
 | 
						|
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
 | 
						|
	       pbool max_at_top, queue_compare compare,
 | 
						|
	       void *first_cmp_arg);
 | 
						|
int init_queue_ex(QUEUE *queue,uint max_elements,uint offset_to_key,
 | 
						|
	       pbool max_at_top, queue_compare compare,
 | 
						|
	       void *first_cmp_arg, uint auto_extent);
 | 
						|
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
 | 
						|
                 pbool max_at_top, queue_compare compare,
 | 
						|
                 void *first_cmp_arg);
 | 
						|
int resize_queue(QUEUE *queue, uint max_elements);
 | 
						|
void delete_queue(QUEUE *queue);
 | 
						|
void queue_insert(QUEUE *queue,uchar *element);
 | 
						|
int queue_insert_safe(QUEUE *queue, uchar *element);
 | 
						|
uchar *queue_remove(QUEUE *queue,uint idx);
 | 
						|
#define queue_remove_all(queue) { (queue)->elements= 0; }
 | 
						|
#define queue_is_full(queue) (queue->elements == queue->max_elements)
 | 
						|
void _downheap(QUEUE *queue,uint idx);
 | 
						|
void queue_fix(QUEUE *queue);
 | 
						|
#define is_queue_inited(queue) ((queue)->root != 0)
 | 
						|
 | 
						|
#ifdef	__cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif
 |