Commit eb5abc14 authored by unknown's avatar unknown
Browse files

BUG#8804: Incorrect results for NULL IN (SELECT ...): review fixes:

- Better comments
- Remove redundant and dead code.

parent 84526c67
Loading
Loading
Loading
Loading
+18 −20
Original line number Diff line number Diff line
@@ -769,43 +769,47 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)

  SYNOPSIS
    Item_in_subselect::single_value_transformer()
      join
      func
      join  Join object of the subquery (i.e. 'child' join).
      func  Subquery comparison creator

  DESCRIPTION
    Rewrite a single-column subquery using rule-based approach. The subquery
    
       oe $cmp$ (SELECT sel FROM ... WHERE subq_where HAVING subq_having)
       oe $cmp$ (SELECT ie FROM ... WHERE subq_where ... HAVING subq_having)
    
    First, try to convert the subquery to scalar-result subquery in one of
    the forms:
    
       - oe $cmp$ (SELECT MAX(...) )  // handled by Item_singlerow_subselect
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxminsubselect
       - oe $cmp$ <max>(SELECT ...)   // handled by Item_maxmin_subselect
   
    If that fails, the subquery will be handled with class Item_in_optimizer, 
    Inject the predicates into subquery, i.e. convert it to:

    - If the subquery has aggregates, GROUP BY, or HAVING, convert to

       SELECT sel FROM ...  HAVING subq_having AND 
       SELECT ie FROM ...  HAVING subq_having AND 
                                   trigcond(oe $cmp$ ref_or_null_helper<ie>)
                                   
      the addition is wrapped into trigger only when we want to distinguish
      between NULL and FALSE results.

    - Else, if we don't care if subquery result is NULL or FALSE, convert to
    - Otherwise (no aggregates/GROUP BY/HAVING) convert it to one of the
      following:

       SELECT 1 ... WHERE (oe $CMP$ ie) AND subq_where
      = If we don't need to distinguish between NULL and FALSE subquery:
        
    - Else convert to:
        SELECT 1 FROM ... WHERE (oe $cmp$ ie) AND subq_where

       SELECT 1 WHERE ...
         WHERE  subq_where  AND trigcond((oe $CMP$ ie) OR ie IS NULL)
         HAVING subq_having AND trigcond(<is_not_null_test>(ie))
      = If we need to distinguish between those:

        SELECT 1 FROM ...
          WHERE  subq_where AND trigcond((oe $cmp$ ie) OR (ie IS NULL))
          HAVING trigcond(<is_not_null_test>(ie))

  RETURN
    RES_OK     - Transformed successfully (or done nothing?)
    RES_OK     - OK, either subquery was transformed, or appopriate
                 predicates where injected into it.
    RES_REDUCE - The subquery was reduced to non-subquery
    RES_ERROR  - Error
*/
@@ -1010,10 +1014,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
	  we can assign select_lex->having here, and pass 0 as last
	  argument (reference) to fix_fields()
	*/
	select_lex->having=
	  join->having= (join->having ?
			 new Item_cond_and(having, join->having) :
			 having);
	select_lex->having= join->having= having;
	select_lex->having_fix_field= 1;
        /*
          we do not check join->having->fixed, because Item_and (from
@@ -1608,7 +1609,6 @@ int subselect_uniquesubquery_engine::prepare()

bool subselect_single_select_engine::no_rows()
{ 
//  return test(!join->send_records);
  return !item->assigned();
}

@@ -1791,9 +1791,7 @@ int subselect_uniquesubquery_engine::scan_table()
  int error;
  TABLE *table= tab->table;
  DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");

  empty_result_set= TRUE;
  bool is_uncorrelated= !cond || !(cond->used_tables() & OUTER_REF_TABLE_BIT);

  if (table->file->inited)
    table->file->ha_index_end();