At file:///home/bell/maria/bzr/work-maria-5.3-scache2/ ------------------------------------------------------------ revno: 2792 revision-id: sanja@askmonty.org-20100608093610-efg156vu4mi4u9pp parent: sanja@askmonty.org-20100608074734-1m60ib2tac7y9m33 committer: sanja@askmonty.org branch nick: work-maria-5.3-scache2 timestamp: Tue 2010-06-08 12:36:10 +0300 message: Fixed memory management problem (Item can't contain other Item due to way of Items destruction). === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2010-05-31 21:25:54 +0000 +++ b/sql/item_cmpfunc.cc 2010-06-08 09:36:10 +0000 @@ -1737,13 +1737,16 @@ not_null_tables_cache|= args[1]->not_null_tables(); const_item_cache&= args[1]->const_item(); DBUG_ASSERT(scache == NULL); + DBUG_ASSERT(value_for_scache == NULL); if (args[0]->cols() ==1 && thd->variables.optimizer_switch & OPTIMIZER_SWITCH_SUBQUERY_CACHE && !(sub->engine->uncacheable() & (UNCACHEABLE_RAND | UNCACHEABLE_SIDEEFFECT))) { sub->depends_on.push_front((Item**)&cache); - scache= new Subquery_cache_tmptable(thd, sub->depends_on, &result); + value_for_scache= new Item_bool_cache; + scache= new Subquery_cache_tmptable(thd, sub->depends_on, + value_for_scache); } fixed= 1; return FALSE; @@ -1851,8 +1854,8 @@ /* put result in the cache */ if (scache) { - result.set(tmp, null_value); - scache->put_value(&result); + value_for_scache->set(tmp, null_value); + scache->put_value(value_for_scache); } DBUG_RETURN(tmp); } @@ -1876,6 +1879,7 @@ delete scache; scache= 0; } + value_for_scache= 0; DBUG_VOID_RETURN; } === modified file 'sql/item_cmpfunc.h' --- a/sql/item_cmpfunc.h 2010-05-31 21:25:54 +0000 +++ b/sql/item_cmpfunc.h 2010-06-08 09:36:10 +0000 @@ -241,7 +241,7 @@ /* Subquery cache */ Subquery_cache *scache; /* result representation for the subquery cache */ - Item_bool_cache result; + Item_bool_cache *value_for_scache; bool save_cache; /* Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries: @@ -252,7 +252,8 @@ my_bool result_for_null_param; public: Item_in_optimizer(Item *a, Item_in_subselect *b): - Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), scache(NULL), + Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0), + scache(NULL), value_for_scache(NULL), save_cache(0), result_for_null_param(UNKNOWN) {} bool fix_fields(THD *, Item **); === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2010-05-31 21:25:54 +0000 +++ b/sql/item_subselect.cc 2010-06-08 09:36:10 +0000 @@ -34,10 +34,10 @@ Item_subselect::Item_subselect(): Item_result_field(), value_assigned(0), thd(0), substitution(0), - engine(0), old_engine(0), scache(0), used_tables_cache(0), - have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0), - done_first_fix_fields(FALSE), eliminated(FALSE), engine_changed(0), - changed(0), is_correlated(FALSE) + engine(0), old_engine(0), scache(0), value_for_scache(0), + used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1), + inside_first_fix_fields(0), done_first_fix_fields(FALSE), + eliminated(FALSE), engine_changed(0), changed(0), is_correlated(FALSE) { with_subselect= 1; reset(); @@ -121,6 +121,7 @@ delete scache; scache= 0; } + value_for_scache= 0; reset(); value_assigned= 0; DBUG_VOID_RETURN; @@ -129,7 +130,7 @@ void Item_singlerow_subselect::cleanup() { DBUG_ENTER("Item_singlerow_subselect::cleanup"); - value= 0; row= 0; + value= 0; row= 0; null_value_item= 0; Item_subselect::cleanup(); DBUG_VOID_RETURN; } @@ -572,7 +573,7 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) - :Item_subselect(), value(0) + :Item_subselect(), value(0), null_value_item(0) { DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect"); init(select_lex, new select_singlerow_subselect(this)); @@ -760,6 +761,7 @@ (uint)depends_on.elements, (uint)test(thd->variables.optimizer_switch & OPTIMIZER_SWITCH_SUBQUERY_CACHE))); engine->fix_length_and_dec(row= &value); + DBUG_ASSERT(scache == NULL); if (depends_on.elements && optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) && !(engine->uncacheable() & (UNCACHEABLE_RAND | @@ -839,6 +841,22 @@ DBUG_RETURN(NULL); } + +/** + Puts NULL value as result in the cache +*/ + +void Item_singlerow_subselect::put_null_value_in_scache() +{ + if (!value_for_scache) + { + value_for_scache= new Item_bool_cache; + value_for_scache->set(0, TRUE); // NULL + } + DBUG_ASSERT(value_for_scache->null_value); + scache->put_value(value_for_scache); +} + double Item_singlerow_subselect::val_real() { Item *cached_value; @@ -870,7 +888,7 @@ reset(); DBUG_PRINT("info", ("error: %u", (uint)err)); if (scache && !err) - scache->put_value(&const_null_value); + put_null_value_in_scache(); DBUG_RETURN(0); } } @@ -906,7 +924,7 @@ reset(); DBUG_PRINT("info", ("error: %u", (uint)err)); if (scache && !err) - scache->put_value(&const_null_value); + put_null_value_in_scache(); DBUG_RETURN(0); } } @@ -942,7 +960,7 @@ reset(); DBUG_PRINT("info", ("error: %u", (uint)err)); if (scache && !err) - scache->put_value(&const_null_value); + put_null_value_in_scache(); DBUG_RETURN(0); } } @@ -979,7 +997,7 @@ reset(); DBUG_PRINT("info", ("error: %u", (uint)err)); if (scache && !err) - scache->put_value(&const_null_value); + put_null_value_in_scache(); DBUG_RETURN(0); } } @@ -1016,7 +1034,7 @@ reset(); DBUG_PRINT("info", ("error: %u", (uint)err)); if (scache && !err) - scache->put_value(&const_null_value); + put_null_value_in_scache(); DBUG_RETURN(0); } } @@ -1108,13 +1126,16 @@ max_columns= engine->cols(); /* We need only 1 row to determine existence */ unit->global_parameters->select_limit= new Item_int((int32) 1); + + DBUG_ASSERT(scache == NULL); + DBUG_ASSERT(value_for_scache == NULL); if (substype() == EXISTS_SUBS && depends_on.elements && optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) && !(engine->uncacheable() & (UNCACHEABLE_RAND | UNCACHEABLE_SIDEEFFECT))) { - DBUG_ASSERT(scache == NULL); - scache= new Subquery_cache_tmptable(thd, depends_on, &result); + value_for_scache= new Item_bool_cache; + scache= new Subquery_cache_tmptable(thd, depends_on, value_for_scache); DBUG_PRINT("info", ("cache: 0x%lx", (ulong) scache)); } DBUG_VOID_RETURN; @@ -1141,8 +1162,8 @@ if (scache) { - result.set(value, FALSE); - scache->put_value(&result); + value_for_scache->set(value, FALSE); + scache->put_value(value_for_scache); } DBUG_RETURN((double) value); @@ -1170,8 +1191,8 @@ if (scache) { - result.set(value, FALSE); - scache->put_value(&result); + value_for_scache->set(value, FALSE); + scache->put_value(value_for_scache); } DBUG_RETURN(value); @@ -1213,8 +1234,8 @@ if (scache) { - result.set(value, FALSE); - scache->put_value(&result); + value_for_scache->set(value, FALSE); + scache->put_value(value_for_scache); } str->set((ulonglong)value,&my_charset_bin); @@ -1257,8 +1278,8 @@ if (scache) { - result.set(value, FALSE); - scache->put_value(&result); + value_for_scache->set(value, FALSE); + scache->put_value(value_for_scache); } int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value); @@ -1287,8 +1308,8 @@ if (scache) { - result.set(value, FALSE); - scache->put_value(&result); + value_for_scache->set(value, FALSE); + scache->put_value(value_for_scache); } DBUG_RETURN(value != 0); === modified file 'sql/item_subselect.h' --- a/sql/item_subselect.h 2010-05-31 21:25:54 +0000 +++ b/sql/item_subselect.h 2010-06-08 09:36:10 +0000 @@ -60,8 +60,8 @@ subselect_engine *old_engine; /* subquery cache */ Subquery_cache *scache; - /* null consrtant for caching */ - Item_null const_null_value; + /* subquery cache value for NULL and TRUE/FALSE subqueries */ + Item_bool_cache *value_for_scache; /* cache of used external tables */ table_map used_tables_cache; /* allowed number of columns (1 for single value subqueries) */ @@ -217,10 +217,15 @@ { protected: Item_cache *value, **row; + /* null value for subquery cache value */ + Item_null *null_value_item; + + void put_null_value_in_scache(); public: Item_singlerow_subselect(st_select_lex *select_lex); - Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {} + Item_singlerow_subselect() :Item_subselect(), value(0), row (0), + null_value_item(0) {} void cleanup(); subs_type substype() { return SINGLEROW_SUBS; } @@ -284,8 +289,6 @@ { protected: bool value; /* value of this item (boolean: exists/not-exists) */ - /* result representation for the subquery cache */ - Item_bool_cache result; public: Item_exists_subselect(st_select_lex *select_lex);