Commit 35f0faf4 authored by unknown's avatar unknown

MWL#89: Cost-based choice between Materialization and IN->EXISTS transformation

- Corrected a wrong result that was recorded by the MySQL fix for BUG#39069.

- Removed Item_func_isnull::cached_value and all the logic around this custom-made
  caching of the NULL result because MWL#89 optimizes subqueries before the outer
  query is being executed, and this cache cannot be made easily to work for all
  kinds of Items (specifically Item_sum_sum, but others too).
parent 22a2cce3
......@@ -843,8 +843,8 @@ x ROW(11, 12) = (SELECT MAX(x), 22) ROW(11, 12) IN (SELECT MAX(x), 22)
# 2nd and 3rd columns should be same for x == 11 only
SELECT a AS x, ROW(11, 12) = (SELECT MAX(x), 12), ROW(11, 12) IN (SELECT MAX(x), 12) FROM t1;
x ROW(11, 12) = (SELECT MAX(x), 12) ROW(11, 12) IN (SELECT MAX(x), 12)
1 0 1
2 0 1
1 0 0
2 0 0
11 1 1
DROP TABLE t1;
# both columns should be same
......
......@@ -4631,12 +4631,6 @@ Item *and_expressions(Item *a, Item *b, Item **org_item)
longlong Item_func_isnull::val_int()
{
DBUG_ASSERT(fixed == 1);
/*
Handle optimization if the argument can't be null
This has to be here because of the test in update_used_tables().
*/
if (!used_tables_cache && !with_subselect)
return cached_value;
return args[0]->is_null() ? 1: 0;
}
......@@ -4644,12 +4638,6 @@ longlong Item_is_not_null_test::val_int()
{
DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_is_not_null_test::val_int");
if (!used_tables_cache && !with_subselect)
{
owner->was_null|= (!cached_value);
DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
DBUG_RETURN(cached_value);
}
if (args[0]->is_null())
{
DBUG_PRINT("info", ("null"));
......@@ -4666,19 +4654,9 @@ longlong Item_is_not_null_test::val_int()
void Item_is_not_null_test::update_used_tables()
{
if (!args[0]->maybe_null)
{
used_tables_cache= 0; /* is always true */
cached_value= (longlong) 1;
}
else
{
args[0]->update_used_tables();
if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
{
/* Remember if the value is always NULL or never NULL */
cached_value= (longlong) !args[0]->is_null();
}
}
}
......
......@@ -1304,8 +1304,6 @@ class in_row :public in_vector
class Item_func_isnull :public Item_bool_func
{
protected:
longlong cached_value;
public:
Item_func_isnull(Item *a) :Item_bool_func(a) {}
longlong val_int();
......@@ -1323,18 +1321,9 @@ class Item_func_isnull :public Item_bool_func
{
used_tables_cache= 0; /* is always false */
const_item_cache= 1;
cached_value= (longlong) 0;
}
else
{
args[0]->update_used_tables();
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
!with_subselect)
{
/* Remember if the value is always NULL or never NULL */
cached_value= (longlong) args[0]->is_null();
}
}
}
table_map not_null_tables() const { return 0; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
......
......@@ -3543,12 +3543,17 @@ bool JOIN::choose_subquery_plan()
select_lex->master_unit()->item;
/* Always revert to IN->EXISTS. */
mat_strategy_cost= 1;
in_exists_strategy_cost= 0;
mat_strategy_cost= 0;
in_exists_strategy_cost= 1;
if (mat_strategy_cost < in_exists_strategy_cost)
/*
If (1) materialization is a possible strategy based on static analysis, and
(2) it is cheaper strategy than the IN->EXISTS transformation, then compute
in_subs via the materialization trategy.
*/
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION && // 1
mat_strategy_cost < in_exists_strategy_cost) // 2
{
in_subs->exec_method = Item_in_subselect::MATERIALIZATION;
if (in_subs->setup_mat_engine())
{
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment