Hi!

>>>>> "loschert" == loschert  <[EMAIL PROTECTED]> writes:

>> Description:
loschert> Attempting to delete all records in a table containing NULL values in a
loschert> UNIQUE KEY field does not work as expected.  Only a single record is deleted,
loschert> presumably because the server thinks that the table will only have one record
loschert> with a NULL value in it (as it is in a UNIQUE field).

<cut>

Thanks for the very clear bug report!

Here is a patch that fixes this!

===== sql/opt_range.h 1.14 vs edited =====
*** /tmp/opt_range.h-1.14-11069 Tue Nov 28 19:10:41 2000
--- edited/sql/opt_range.h      Tue Apr 10 01:16:12 2001
***************
*** 30,35 ****
--- 30,36 ----
  #define NEAR_MAX      8
  #define UNIQUE_RANGE  16
  #define EQ_RANGE      32
+ #define NULL_RANGE    64
  
  typedef struct st_key_part {
    uint16 key,part,part_length;
===== sql/opt_range.cc 1.40 vs edited =====
*** /tmp/opt_range.cc-1.40-11069        Wed Mar 21 22:34:10 2001
--- edited/sql/opt_range.cc     Tue Apr 10 01:35:31 2001
***************
*** 321,327 ****
  static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
  
  static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
! 
  
  /***************************************************************************
  ** Basic functions for SQL_SELECT and QUICK_SELECT
--- 321,327 ----
  static bool eq_tree(SEL_ARG* a,SEL_ARG *b);
  
  static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE);
! static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length);
  
  /***************************************************************************
  ** Basic functions for SQL_SELECT and QUICK_SELECT
***************
*** 2306,2312 ****
        KEY *table_key=quick->head->key_info+quick->index;
        flag=EQ_RANGE;
        if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1)
!       flag|= UNIQUE_RANGE;
      }
    }
  
--- 2306,2320 ----
        KEY *table_key=quick->head->key_info+quick->index;
        flag=EQ_RANGE;
        if (table_key->flags & HA_NOSAME && key->part == table_key->key_parts-1)
!       {
!       if (!(table_key->flags & HA_NULL_PART_KEY) ||
!           !null_part_in_key(key,
!                             param->min_key,
!                             (uint) (tmp_min_key - param->min_key)))
!         flag|= UNIQUE_RANGE;
!       else
!         flag|= NULL_RANGE;
!       }
      }
    }
  
***************
*** 2339,2349 ****
    if (ranges.elements == 1)
    {
      QUICK_RANGE *tmp;
!     if ((tmp=ranges.head())->flag & EQ_RANGE)
      {
        KEY *key=head->key_info+index;
        return ((key->flags & HA_NOSAME) &&
              key->key_length == tmp->min_length);
      }
    }
    return 0;
--- 2347,2375 ----
    if (ranges.elements == 1)
    {
      QUICK_RANGE *tmp;
!     if (((tmp=ranges.head())->flag & (EQ_RANGE | NULL_RANGE)) == EQ_RANGE)
      {
        KEY *key=head->key_info+index;
        return ((key->flags & HA_NOSAME) &&
              key->key_length == tmp->min_length);
+     }
+   }
+   return 0;
+ }
+ 
+ 
+ /* Returns true if any part of the key is NULL */
+ 
+ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
+ {
+   for (const char *end=key+length ; 
+        key < end;
+        key+= key_part++->part_length)
+   {
+     if (key_part->null_bit)
+     {
+       if (*key++)
+       return 1;
      }
    }
    return 0;

Regards,
Monty

---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to