My Project
Public Member Functions
Item_in_optimizer Class Reference
Inheritance diagram for Item_in_optimizer:
Item_bool_func Item_int_func Item_func Item_result_field Item

List of all members.

Public Member Functions

 Item_in_optimizer (Item *a, Item_in_subselect *b)
bool fix_fields (THD *, Item **)
bool fix_left (THD *thd, Item **ref)
void fix_after_pullout (st_select_lex *parent_select, st_select_lex *removed_select)
bool is_null ()
longlong val_int ()
void cleanup ()
const char * func_name () const
Item_cache ** get_cache ()
void keep_top_level_cache ()
Itemtransform (Item_transformer transformer, uchar *arg)

Member Function Documentation

void Item_in_optimizer::fix_after_pullout ( st_select_lex *  parent_select,
st_select_lex *  removed_select 
) [virtual]

Fix after tables have been moved from one select_lex level to the parent level, e.g by semijoin conversion. Basically re-calculate all attributes dependent on the tables.

parent_selectselect_lex that tables are moved to.
removed_selectselect_lex that tables are moved away from, child of parent_select.

Reimplemented from Item_func.

Item * Item_in_optimizer::transform ( Item_transformer  transformer,
uchar *  argument 
) [virtual]

Transform an Item_in_optimizer and its arguments with a callback function.

transformerthe transformer callback function to be applied to the nodes of the tree of the object
parameterto be passed to the transformer

Recursively transform the left and the right operand of this Item. The Right operand is an Item_in_subselect or its subclass. To avoid the creation of new Items, we use the fact the the left operand of the Item_in_subselect is the same as the one of 'this', so instead of transforming its operand, we just assign the left operand of the Item_in_subselect to be equal to the left operand of 'this'. The transformation is not applied further to the subquery operand if the IN predicate.

Return values:
pointerto the transformed item
NULLif an error occurred

Reimplemented from Item_func.

longlong Item_in_optimizer::val_int ( void  ) [virtual]

The implementation of optimized <outer expression> [NOT] IN <subquery> predicates. It applies to predicates which have gone through the IN->EXISTS transformation in in_to_exists_transformer functions; not to subquery materialization (which has no triggered conditions).

The implementation works as follows. For the current value of the outer expression

  • If it contains only NULL values, the original (before rewrite by the Item_in_subselect rewrite methods) inner subquery is non-correlated and was previously executed, there is no need to re-execute it, and the previous return value is returned.
  • If it contains NULL values, check if there is a partial match for the inner query block by evaluating it. For clarity we repeat here the transformation previously performed on the sub-query. The expression

( oc_1, ..., oc_n ) <in predicate> ( SELECT ic_1, ..., ic_n FROM <table> WHERE <inner where> )

was transformed into

( oc_1, ..., oc_n ) <in predicate> ( SELECT ic_1, ..., ic_n FROM <table> WHERE <inner where> AND ... ( ic_k = oc_k OR ic_k IS NULL ) HAVING ... NOT ic_k IS NULL )

The evaluation will now proceed according to special rules set up elsewhere. These rules include:

  • The HAVING NOT <inner column> IS NULL conditions added by the aforementioned rewrite methods will detect whether they evaluated (and rejected) a NULL value and if so, will cause the subquery to evaluate to NULL.
  • The added WHERE and HAVING conditions are present only for those inner columns that correspond to outer column that are not NULL at the moment.
  • If there is an eligible index for executing the subquery, the special access method "Full scan on NULL key" is employed which ensures that the inner query will detect if there are NULL values resulting from the inner query. This access method will quietly resort to table scan if it needs to find NULL values as well.
  • Under these conditions, the sub-query need only be evaluated in order to find out whether it produced any rows.
  • If it did, we know that there was a partial match since there are NULL values in the outer row expression.
  • If it did not, the result is FALSE or UNKNOWN. If at least one of the HAVING sub-predicates rejected a NULL value corresponding to an outer non-NULL, and hence the inner query block returns UNKNOWN upon evaluation, there was a partial match and the result is UNKNOWN.
  • If it contains no NULL values, the call is forwarded to the inner query block.
See also:

Implements Item.

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines