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) ...@@ -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 # 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; 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) x ROW(11, 12) = (SELECT MAX(x), 12) ROW(11, 12) IN (SELECT MAX(x), 12)
1 0 1 1 0 0
2 0 1 2 0 0
11 1 1 11 1 1
DROP TABLE t1; DROP TABLE t1;
# both columns should be same # both columns should be same
......
...@@ -4631,12 +4631,6 @@ Item *and_expressions(Item *a, Item *b, Item **org_item) ...@@ -4631,12 +4631,6 @@ Item *and_expressions(Item *a, Item *b, Item **org_item)
longlong Item_func_isnull::val_int() longlong Item_func_isnull::val_int()
{ {
DBUG_ASSERT(fixed == 1); 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; return args[0]->is_null() ? 1: 0;
} }
...@@ -4644,12 +4638,6 @@ longlong Item_is_not_null_test::val_int() ...@@ -4644,12 +4638,6 @@ longlong Item_is_not_null_test::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_is_not_null_test::val_int"); 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()) if (args[0]->is_null())
{ {
DBUG_PRINT("info", ("null")); DBUG_PRINT("info", ("null"));
...@@ -4666,19 +4654,9 @@ longlong Item_is_not_null_test::val_int() ...@@ -4666,19 +4654,9 @@ longlong Item_is_not_null_test::val_int()
void Item_is_not_null_test::update_used_tables() void Item_is_not_null_test::update_used_tables()
{ {
if (!args[0]->maybe_null) if (!args[0]->maybe_null)
{
used_tables_cache= 0; /* is always true */ used_tables_cache= 0; /* is always true */
cached_value= (longlong) 1;
}
else else
{
args[0]->update_used_tables(); 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 @@ public: ...@@ -1304,8 +1304,6 @@ public:
class Item_func_isnull :public Item_bool_func class Item_func_isnull :public Item_bool_func
{ {
protected:
longlong cached_value;
public: public:
Item_func_isnull(Item *a) :Item_bool_func(a) {} Item_func_isnull(Item *a) :Item_bool_func(a) {}
longlong val_int(); longlong val_int();
...@@ -1323,18 +1321,9 @@ public: ...@@ -1323,18 +1321,9 @@ public:
{ {
used_tables_cache= 0; /* is always false */ used_tables_cache= 0; /* is always false */
const_item_cache= 1; const_item_cache= 1;
cached_value= (longlong) 0;
} }
else else
{
args[0]->update_used_tables(); 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; } table_map not_null_tables() const { return 0; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; } optimize_type select_optimize() const { return OPTIMIZE_NULL; }
......
...@@ -3543,12 +3543,17 @@ bool JOIN::choose_subquery_plan() ...@@ -3543,12 +3543,17 @@ bool JOIN::choose_subquery_plan()
select_lex->master_unit()->item; select_lex->master_unit()->item;
/* Always revert to IN->EXISTS. */ /* Always revert to IN->EXISTS. */
mat_strategy_cost= 1; mat_strategy_cost= 0;
in_exists_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()) 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