List:Commits« Previous MessageNext Message »
From:holyfoot Date:November 14 2007 6:20pm
Subject:bk commit into 5.1 tree (holyfoot:1.2648) BUG#31890
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of hf. When hf does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-14 22:20:31+04:00, holyfoot@stripped +4 -0
  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@stripped, 2007-11-14 22:20:28+04:00, holyfoot@stripped +3 -3
    Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
    
    max_at_top policy changed

  mysql-test/r/partition.result@stripped, 2007-11-14 22:20:28+04:00, holyfoot@stripped +35 -0
    Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
    
    test result

  mysql-test/t/partition.test@stripped, 2007-11-14 22:20:29+04:00, holyfoot@stripped +27 -0
    Bug #31890 Partitions: ORDER BY DESC in InnoDB not working
    
    test case

  mysys/queues.c@stripped, 2007-11-14 22:20:29+04:00, holyfoot@stripped +15 -21
    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.

diff -Nrup a/include/queues.h b/include/queues.h
--- a/include/queues.h	2007-05-10 14:59:24 +05:00
+++ b/include/queues.h	2007-11-14 22:20:28 +04:00
@@ -31,8 +31,8 @@ typedef struct st_queue {
   void *first_cmp_arg;
   uint elements;
   uint max_elements;
-  uint offset_to_key;			/* compare is done on element+offset */
-  int max_at_top;			/* Set if queue_top gives max */
+  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;
@@ -43,7 +43,7 @@ typedef struct st_queue {
 #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) : 0
+  (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,
diff -Nrup a/mysql-test/r/partition.result b/mysql-test/r/partition.result
--- a/mysql-test/r/partition.result	2007-11-13 23:16:45 +04:00
+++ b/mysql-test/r/partition.result	2007-11-14 22:20:28 +04:00
@@ -1296,4 +1296,39 @@ create table t1
 partition by key(s1) partitions 3;
 insert into t1 values (null,null);
 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
diff -Nrup a/mysql-test/t/partition.test b/mysql-test/t/partition.test
--- a/mysql-test/t/partition.test	2007-11-13 23:16:45 +04:00
+++ b/mysql-test/t/partition.test	2007-11-14 22:20:29 +04:00
@@ -1549,4 +1549,31 @@ while ($cnt)
 --enable_query_log
 
 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
diff -Nrup a/mysys/queues.c b/mysys/queues.c
--- a/mysys/queues.c	2007-05-10 14:59:26 +05:00
+++ b/mysys/queues.c	2007-11-14 22:20:29 +04:00
@@ -61,7 +61,7 @@ int init_queue(QUEUE *queue, uint max_el
   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_
   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, ui
 
   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, ui
   {
     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, ui
 {
   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, ui
     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;
Thread
bk commit into 5.1 tree (holyfoot:1.2648) BUG#31890holyfoot14 Nov