List:Bugs« Previous MessageNext Message »
From:Michael Widenius Date:October 19 2001 6:56pm
Subject:Re: Incorrect results with LEFT JOIN and indexes
View as plain text  
Hi!

>>>>> "Bradley" == Bradley Baetz <bbaetz@stripped> writes:

Bradley> On Wed, 17 Oct 2001, Michael Widenius wrote:
bbaetz> SELECT bugs.bug_id FROM bugs LEFT JOIN cc ON (bugs.bug_id =
bbaetz> cc.bug_id AND cc.who = 2) WHERE (bugs.reporter = 2 OR cc.who =
bbaetz> 2);
>> 

Bradley> <snip>

>> In other words:
>> 
>> The The cc.who = 2 restriction in the ON clause does NOT affect the
>> rows that is considered from the LEFT table.  It only affects if the
>> rows should be considered from the RIGHT table or if we should
>> generate a NULL row for the right table.
>> 
>> Fix:  Move all tests that only affects the 'cc' table from the ON
>> clause to the WHERE part..

Bradley> I realise this, and want the behaviour, since I still want bugs with no
Bradley> people cc'd to match if the reporter matches.

Bradley> However, the above query _does_ have the restriction in the WHERE part (as
Bradley> well as the on part - this is a simplified version of a more complicated,
Bradley> partly autogenerated, query). And removing the index changes the result,
Bradley> which seems really strange. Also, if you change the index on the cc table
Bradley> to be unique(bug_id,who), then the result changes based on whether or not
Bradley> the who column is NOT NULL.

Here is a patch that fixes this problem and also the field=NULL
problem that was reported yesterday.  This will be in 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 <monty@stripped>
 / /|_/ / // /\ \/ /_/ / /__   MySQL AB, CTO
/_/  /_/\_, /___/\___\_\___/   Helsinki, Finland
       <___/   www.mysql.com
Thread
Incorrect results with LEFT JOIN and indexesbbaetz17 Oct
  • Incorrect results with LEFT JOIN and indexesMichael Widenius17 Oct
    • Re: Incorrect results with LEFT JOIN and indexesBradley Baetz17 Oct
      • Re: Incorrect results with LEFT JOIN and indexesSinisa Milivojevic18 Oct
        • Re: Incorrect results with LEFT JOIN and indexesBradley Baetz18 Oct
      • Re: Incorrect results with LEFT JOIN and indexesMichael Widenius20 Oct
        • Re: Incorrect results with LEFT JOIN and indexesBradley Baetz20 Oct