My Project
|
#include <item_subselect.h>
Public Member Functions | |
subselect_indexsubquery_engine (THD *thd_arg, st_join_table *tab_arg, Item_subselect *subs, Item *where, Item *having_arg, bool chk_null, bool unique_arg) | |
virtual bool | exec () |
virtual void | print (String *str, enum_query_type query_type) |
virtual enum_engine_type | engine_type () const |
virtual void | cleanup () |
virtual bool | prepare () |
virtual void | fix_length_and_dec (Item_cache **row) |
virtual uint | cols () const |
virtual uint8 | uncacheable () const |
virtual void | exclude () |
virtual table_map | upper_select_const_tables () const |
virtual bool | change_result (Item_subselect *si, select_result_interceptor *result) |
virtual bool | no_tables () const |
bool | scan_table () |
void | copy_ref_key (bool *require_scan, bool *convert_error) |
Protected Attributes | |
st_join_table * | tab |
Item * | cond |
A subquery execution engine that evaluates the subquery by doing index lookups in a single table's index.
This engine is used to resolve subqueries in forms
outer_expr IN (SELECT tbl.key FROM tbl WHERE subq_where)
or, row-based:
(oe1, .. oeN) IN (SELECT key_part1, ... key_partK FROM tbl WHERE subqwhere)
i.e. the subquery is a single table SELECT without GROUP BY, aggregate functions, etc.
bool subselect_indexsubquery_engine::change_result | ( | Item_subselect * | si, |
select_result_interceptor * | res | ||
) | [virtual] |
change select_result emulation, never should be called.
si | new subselect Item |
res | new select_result object |
FALSE | OK |
TRUE | error |
Implements subselect_engine.
virtual void subselect_indexsubquery_engine::cleanup | ( | ) | [inline, virtual] |
Cleanup engine after complete query execution, free all resources.
Implements subselect_engine.
Reimplemented in subselect_hash_sj_engine.
void subselect_indexsubquery_engine::copy_ref_key | ( | bool * | require_scan, |
bool * | convert_error | ||
) |
Copy ref key and check for null parts in it
Construct a search tuple to be used for index lookup. If one of the key parts have a NULL value, the following logic applies:
For top level items, e.g.
"WHERE <outer_value_list> IN (SELECT <inner_value_list>...)"
where one of the outer values are NULL, the IN predicate evaluates to false/UNKNOWN (we don't care) and it's not necessary to evaluate the subquery. That shortcut is taken in Item_in_optimizer::val_int(). Thus, if a key part with a NULL value is found here, the NULL is either not outer or this subquery is not top level. Therefore we cannot shortcut subquery execution if a NULL is found here.
Thus, if one of the key parts have a NULL value there are two possibilities:
a) The NULL is from the outer_value_list. Since this is not a top level item (see above) we need to check whether this predicate evaluates to NULL or false. That is done by checking if the subquery has a row if the conditions based on outer NULL values are disabled. Index lookup cannot be used for this, so a table scan must be done.
b) The NULL is local to the subquery, e.g.:
"WHERE ... IN (SELECT ... WHERE inner_col IS NULL)"
In this case we're looking for rows with the exact inner_col value of NULL, not rows that match if the "inner_col IS NULL" condition is disabled. Index lookup can be used for this.
[out] | require_scan | true if a NULL value is found that falls into category a) above, false if index lookup can be used. |
[out] | convert_error | true if an error occured during conversion of values from one type to another, false otherwise. |
bool subselect_indexsubquery_engine::no_tables | ( | ) | const [virtual] |
Report about presence of tables in subquery.
TRUE | there are not tables used in subquery |
FALSE | there are some tables in subquery |
Implements subselect_engine.
Search, using a table scan, for at least one row satisfying select condition.
The caller must set item's 'value' to 'false' before calling this function. This function will set it to 'true' if it finds a matching row.