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