David> Hi!
David> 
David> When you have a indexed field that allows NULL (as per mysql >= 3.23.2)
David> and there is more than one row that has null in that column,
David> then an equality comparison between that field and NULL returns true
David> if the index is used.
David>  
David> The problem does not occur if the field is not indexed.
David> Comparisons with IS [NOT] NULL continue to function correctly.
David>  
David> >How-To-Repeat:
David>  
David> Simplest reproducing SQL:
David>  
David> DROP TABLE IF EXISTS test_table;
David>  
David> CREATE TABLE test_table (
David>   indexed_field int default NULL,
David>   KEY indexed_field (indexed_field)
David> ) TYPE=MyISAM;
David>  
David> INSERT INTO test_table VALUES (NULL);
David> INSERT INTO test_table VALUES (NULL);
David>  
David> select * from test_table where indexed_field=NULL;
David>  
David> +---------------+
David> | indexed_field |
David> +---------------+
David> |          NULL |
David> |          NULL |
David> +---------------+
David> 2 rows in set (0.00 sec)

Here is a patch that fixes this problem. This will be in the next MySQL
release (both 3.23.44 and 4.0.1)

===== sql/sql_select.cc 1.105 vs edited =====
*** /tmp/sql_select.cc-1.105-21548      Thu Sep 27 22:02:37 2001
--- edited/sql/sql_select.cc    Fri Oct 19 21:44:30 2001
***************
*** 4963,4977 ****
  static bool test_if_ref(Item_field *left_item,Item *right_item)
  {
    Field *field=left_item->field;
!   if (!field->table->const_table)             // No need to change const test
    {
      Item *ref_item=part_of_refkey(field->table,field);
      if (ref_item && ref_item->eq(right_item))
      {
        if (right_item->type() == Item::FIELD_ITEM)
!       return (field->eq_def(((Item_field *) right_item)->field) &&
!               !field->table->maybe_null);
!       if (right_item->const_item())
        {
        // We can remove binary fields and numerical fields except float,
        // as float comparison isn't 100 % secure
--- 4963,4978 ----
  static bool test_if_ref(Item_field *left_item,Item *right_item)
  {
    Field *field=left_item->field;
!   // No need to change const test. We also have to keep tests on LEFT JOIN
!   if (!field->table->const_table && !field->table->maybe_null)
    {
      Item *ref_item=part_of_refkey(field->table,field);
      if (ref_item && ref_item->eq(right_item))
      {
        if (right_item->type() == Item::FIELD_ITEM)
!       return (field->eq_def(((Item_field *) right_item)->field));
!       if (right_item->const_item() &&
!         (right_item->val_int() || !right_item->null_value))
        {
        // We can remove binary fields and numerical fields except float,
        // as float comparison isn't 100 % secure


Both problems was related to the following optimization:

If you use the following construct in MySQL:

WHERE index_column=constant

and MySQL internally uses 'constant' to look up the field through an
index (a 'ref' key), then MySQL will remove the
'index_column=constant' expression from the WHERE clause, because the
test will implicitly done by the index lookup function.

This optimization doesn't however work when you are using a LEFT JOIN
or when comparing with = NULL.

Regards,
Monty

-- 
For technical support contracts, goto https://order.mysql.com/
   __  ___     ___ ____  __
  /  |/  /_ __/ __/ __ \/ /    Mr. Michael Widenius <[EMAIL PROTECTED]>
 / /|_/ / // /\ \/ /_/ / /__   MySQL AB, CTO
/_/  /_/\_, /___/\___\_\___/   Helsinki, Finland
       <___/   www.mysql.com

---------------------------------------------------------------------
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