From 7d6ffa8e6f6de9c91653957fb2f75ee3b073a63d Mon Sep 17 00:00:00 2001
From: "ram@mysql.r18.ru" <>
Date: Fri, 15 Nov 2002 16:45:08 +0400
Subject: [PATCH] fix for NULL processing

---
 heap/heapdef.h |  3 ++-
 heap/hp_hash.c | 29 +++++++++++++++++------------
 heap/hp_rkey.c |  6 ++----
 3 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/heap/heapdef.h b/heap/heapdef.h
index b651bf4bcb1..63109badb05 100644
--- a/heap/heapdef.h
+++ b/heap/heapdef.h
@@ -97,7 +97,8 @@ extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key);
 extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record);
 extern int hp_close(register HP_INFO *info);
 extern void hp_clear(HP_SHARE *info);
-extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old);
+extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, 
+			   uint k_len);
 #ifdef THREAD
 extern pthread_mutex_t THR_LOCK_heap;
 #else
diff --git a/heap/hp_hash.c b/heap/hp_hash.c
index e28f4725caf..946659621fe 100644
--- a/heap/hp_hash.c
+++ b/heap/hp_hash.c
@@ -30,27 +30,27 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key,
   TREE *rb_tree = &keyinfo->rb_tree;
   heap_rb_param custom_arg;
 
-  info->lastinx = inx;
-  custom_arg.keyseg = keyinfo->seg;
-  custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME;
-  custom_arg.key_length = start_key_len;
+  info->lastinx= inx;
+  custom_arg.keyseg= keyinfo->seg;
+  custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
   if (start_key)
   {
-    hp_rb_pack_key(keyinfo, info->recbuf, start_key);
+    custom_arg.key_length= hp_rb_pack_key(keyinfo, info->recbuf, start_key, 
+					  start_key_len);
     start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag, 
-				&custom_arg);
+			       &custom_arg);
   }
   else
   {
     start_pos= 0;
   }
   
-  custom_arg.key_length = end_key_len;
   if (end_key)
   {
-    hp_rb_pack_key(keyinfo, info->recbuf, end_key);
+    custom_arg.key_length= hp_rb_pack_key(keyinfo, info->recbuf, end_key,
+					  end_key_len);
     end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag, 
-				&custom_arg);
+			     &custom_arg);
   }
   else
   {
@@ -450,21 +450,26 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
   return key - start_key;
 }
 
-uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old)
+uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
 {
   HA_KEYSEG *seg, *endseg;
   uchar *start_key= key;
   
-  for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; 
-       old+= seg->length, seg++)
+  for (seg= keydef->seg, endseg= seg + keydef->keysegs;
+       seg < endseg && (int) k_len > 0; old+= seg->length, seg++)
   {
     if (seg->null_bit)
     {
+      k_len--;
       if (!(*key++= (char) 1 - *old++))
+      {
+        k_len-= seg->length;
         continue;
+      }
     }
     memcpy((byte*) key, old, seg->length);
     key+= seg->length;
+    k_len-= seg->length;
   }
   return key - start_key;
 }
diff --git a/heap/hp_rkey.c b/heap/hp_rkey.c
index 4e47fd52e9b..92d2982a457 100644
--- a/heap/hp_rkey.c
+++ b/heap/hp_rkey.c
@@ -36,10 +36,9 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
   {
     heap_rb_param custom_arg;
 
-    hp_rb_pack_key(keyinfo, info->recbuf, key);
-
     custom_arg.keyseg= info->s->keydef[inx].seg;
-    custom_arg.key_length= key_len;
+    custom_arg.key_length= info->lastkey_len= 
+			hp_rb_pack_key(keyinfo, info->recbuf, key, key_len);
     custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME;
     /* for next rkey() after deletion */
     if (find_flag == HA_READ_AFTER_KEY)
@@ -48,7 +47,6 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key,
       info->last_find_flag= HA_READ_KEY_OR_PREV;
     else
       info->last_find_flag= find_flag;
-    info->lastkey_len= key_len;
     if (!(pos= tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents,
 			       &info->last_pos, find_flag, &custom_arg)))
     {
-- 
2.30.9