diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 665bb9a2bde..cfc18413ee0 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -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 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 75ffdf6f400..f8c46420035 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -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(); - } - } } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index e161c1baa84..33407a161b8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1304,8 +1304,6 @@ public: 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 @@ public: { 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; } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 13b8bb40ea7..46d8591aaf1 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -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()) { /*