From: Evgeny Potemkin Date: December 1 2009 7:42pm Subject: bzr commit into mysql-5.6-next-mr-bugfixing branch (epotemkin:2911) Bug#34384 List-Archive: http://lists.mysql.com/commits/92346 X-Bug: 34384 Message-Id: <0KTZ002Q4O1IR150@fe-emea-10.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_8dMztbplXQcIVJQCZETNyg)" --Boundary_(ID_8dMztbplXQcIVJQCZETNyg) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///work/bzrroot/33546-bug-next-mr-bugfixing/ based on revid:mattias.jonsson@stripped 2911 Evgeny Potemkin 2009-12-01 [merge] Auto-merged fix for the bug#34384. modified: sql/item.cc sql/item.h sql/item_cmpfunc.cc sql/item_cmpfunc.h sql/item_subselect.cc sql/item_xmlfunc.cc sql/sp_rcontext.cc === modified file 'sql/item.cc' --- a/sql/item.cc 2009-11-25 15:03:05 +0000 +++ b/sql/item.cc 2009-12-01 19:41:39 +0000 @@ -7104,7 +7104,22 @@ int stored_field_cmp_to_item(THD *thd, F Item_cache* Item_cache::get_cache(const Item *item) { - switch (item->result_type()) { + return get_cache(item, item->result_type()); +} + + +/** + Get a cache item of given type. + + @param item value to be cached + @param type required type of cache + + @return cache item +*/ + +Item_cache* Item_cache::get_cache(const Item *item, const Item_result type) +{ + switch (type) { case INT_RESULT: return new Item_cache_int(); case REAL_RESULT: @@ -7122,6 +7137,12 @@ Item_cache* Item_cache::get_cache(const } } +void Item_cache::store(Item *item) +{ + if (item) + example= item; + value_cached= FALSE; +} void Item_cache::print(String *str, enum_query_type query_type) { @@ -7133,17 +7154,19 @@ void Item_cache::print(String *str, enum str->append(')'); } - -void Item_cache_int::store(Item *item) +void Item_cache_int::cache_value() { - value= item->val_int_result(); - null_value= item->null_value; - unsigned_flag= item->unsigned_flag; + value_cached= TRUE; + value= example->val_int_result(); + null_value= example->null_value; + unsigned_flag= example->unsigned_flag; } void Item_cache_int::store(Item *item, longlong val_arg) { + /* An explicit values is given, save it. */ + value_cached= TRUE; value= val_arg; null_value= item->null_value; unsigned_flag= item->unsigned_flag; @@ -7153,6 +7176,8 @@ void Item_cache_int::store(Item *item, l String *Item_cache_int::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); str->set(value, default_charset()); return str; } @@ -7161,21 +7186,49 @@ String *Item_cache_int::val_str(String * my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); int2my_decimal(E_DEC_FATAL_ERROR, value, unsigned_flag, decimal_val); return decimal_val; } +double Item_cache_int::val_real() +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return (double) value; +} -void Item_cache_real::store(Item *item) +longlong Item_cache_int::val_int() { - value= item->val_result(); - null_value= item->null_value; + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; } +void Item_cache_real::cache_value() +{ + value_cached= TRUE; + value= example->val_result(); + null_value= example->null_value; +} + + +double Item_cache_real::val_real() +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; +} longlong Item_cache_real::val_int() { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); return (longlong) rint(value); } @@ -7183,6 +7236,8 @@ longlong Item_cache_real::val_int() String* Item_cache_real::val_str(String *str) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); str->set_real(value, decimals, default_charset()); return str; } @@ -7191,15 +7246,18 @@ String* Item_cache_real::val_str(String my_decimal *Item_cache_real::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val); return decimal_val; } -void Item_cache_decimal::store(Item *item) +void Item_cache_decimal::cache_value() { - my_decimal *val= item->val_decimal_result(&decimal_value); - if (!(null_value= item->null_value) && val != &decimal_value) + value_cached= TRUE; + my_decimal *val= example->val_decimal_result(&decimal_value); + if (!(null_value= example->null_value) && val != &decimal_value) my_decimal2decimal(val, &decimal_value); } @@ -7207,6 +7265,8 @@ double Item_cache_decimal::val_real() { DBUG_ASSERT(fixed); double res; + if (!value_cached) + cache_value(); my_decimal2double(E_DEC_FATAL_ERROR, &decimal_value, &res); return res; } @@ -7215,6 +7275,8 @@ longlong Item_cache_decimal::val_int() { DBUG_ASSERT(fixed); longlong res; + if (!value_cached) + cache_value(); my_decimal2int(E_DEC_FATAL_ERROR, &decimal_value, unsigned_flag, &res); return res; } @@ -7222,6 +7284,8 @@ longlong Item_cache_decimal::val_int() String* Item_cache_decimal::val_str(String *str) { DBUG_ASSERT(fixed); + if (!value_cached) + cache_value(); my_decimal_round(E_DEC_FATAL_ERROR, &decimal_value, decimals, FALSE, &decimal_value); my_decimal2string(E_DEC_FATAL_ERROR, &decimal_value, 0, 0, 0, str); @@ -7231,15 +7295,18 @@ String* Item_cache_decimal::val_str(Stri my_decimal *Item_cache_decimal::val_decimal(my_decimal *val) { DBUG_ASSERT(fixed); + if (!value_cached) + cache_value(); return &decimal_value; } -void Item_cache_str::store(Item *item) +void Item_cache_str::cache_value() { - value_buff.set(buffer, sizeof(buffer), item->collation.collation); - value= item->str_result(&value_buff); - if ((null_value= item->null_value)) + value_cached= TRUE; + value_buff.set(buffer, sizeof(buffer), example->collation.collation); + value= example->str_result(&value_buff); + if ((null_value= example->null_value)) value= 0; else if (value != &value_buff) { @@ -7261,6 +7328,8 @@ double Item_cache_str::val_real() DBUG_ASSERT(fixed == 1); int err_not_used; char *end_not_used; + if (!value_cached) + cache_value(); if (value) return my_strntod(value->charset(), (char*) value->ptr(), value->length(), &end_not_used, &err_not_used); @@ -7272,6 +7341,8 @@ longlong Item_cache_str::val_int() { DBUG_ASSERT(fixed == 1); int err; + if (!value_cached) + cache_value(); if (value) return my_strntoll(value->charset(), value->ptr(), value->length(), 10, (char**) 0, &err); @@ -7279,9 +7350,21 @@ longlong Item_cache_str::val_int() return (longlong)0; } + +String* Item_cache_str::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); + return value; +} + + my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val) { DBUG_ASSERT(fixed == 1); + if (!value_cached) + cache_value(); if (value) string2my_decimal(E_DEC_FATAL_ERROR, value, decimal_val); else @@ -7292,6 +7375,8 @@ my_decimal *Item_cache_str::val_decimal( int Item_cache_str::save_in_field(Field *field, bool no_conversions) { + if (!value_cached) + cache_value(); int res= Item_cache::save_in_field(field, no_conversions); return (is_varbinary && field->type() == MYSQL_TYPE_STRING && value->length() < field->field_length) ? 1 : res; @@ -7326,11 +7411,19 @@ bool Item_cache_row::setup(Item * item) void Item_cache_row::store(Item * item) { + for (uint i= 0; i < item_count; i++) + values[i]->store(item->element_index(i)); +} + + +void Item_cache_row::cache_value() +{ + value_cached= TRUE; null_value= 0; - item->bring_value(); + example->bring_value(); for (uint i= 0; i < item_count; i++) { - values[i]->store(item->element_index(i)); + values[i]->cache_value(); null_value|= values[i]->null_value; } } === modified file 'sql/item.h' --- a/sql/item.h 2009-11-06 14:20:27 +0000 +++ b/sql/item.h 2009-12-01 19:41:39 +0000 @@ -1032,7 +1032,11 @@ class sp_head; class Item_basic_constant :public Item { + table_map used_table_map; public: + Item_basic_constant(): Item(), used_table_map(0) {}; + void set_used_tables(table_map map) { used_table_map= map; } + table_map used_tables() const { return used_table_map; } /* to prevent drop fixed flag (no need parent cleanup call) */ void cleanup() { @@ -2918,15 +2922,25 @@ protected: */ Field *cached_field; enum enum_field_types cached_field_type; -public: - Item_cache(): - example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING) + /* + TRUE <=> cache holds value of the last stored item (i.e actual value). + store() stores item to be cached and sets this flag to FALSE. + On the first call of val_xxx function if this flag is set to FALSE the + cache_value() will be called to actually cache value of saved item. + cache_value() will set this flag to TRUE. + */ + bool value_cached; +public: + Item_cache(): + example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING), + value_cached(0) { fixed= 1; null_value= 1; } Item_cache(enum_field_types field_type_arg): - example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg) + example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg), + value_cached(0) { fixed= 1; null_value= 1; @@ -2946,10 +2960,10 @@ public: cached_field= ((Item_field *)item)->field; return 0; }; - virtual void store(Item *)= 0; enum Type type() const { return CACHE_ITEM; } enum_field_types field_type() const { return cached_field_type; } static Item_cache* get_cache(const Item *item); + static Item_cache* get_cache(const Item* item, const Item_result type); table_map used_tables() const { return used_table_map; } virtual void keep_array() {} virtual void print(String *str, enum_query_type query_type); @@ -2961,6 +2975,8 @@ public: { return this == item; } + virtual void store(Item *item); + virtual void cache_value()= 0; }; @@ -2969,18 +2985,19 @@ class Item_cache_int: public Item_cache protected: longlong value; public: - Item_cache_int(): Item_cache(), value(0) {} + Item_cache_int(): Item_cache(), + value(0) {} Item_cache_int(enum_field_types field_type_arg): Item_cache(field_type_arg), value(0) {} - void store(Item *item); void store(Item *item, longlong val_arg); - double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } - longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } + double val_real(); + longlong val_int(); String* val_str(String *str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return INT_RESULT; } bool result_as_longlong() { return TRUE; } + void cache_value(); }; @@ -2988,14 +3005,15 @@ class Item_cache_real: public Item_cache { double value; public: - Item_cache_real(): Item_cache(), value(0) {} + Item_cache_real(): Item_cache(), + value(0) {} - void store(Item *item); - double val_real() { DBUG_ASSERT(fixed == 1); return value; } + double val_real(); longlong val_int(); String* val_str(String *str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return REAL_RESULT; } + void cache_value(); }; @@ -3006,12 +3024,12 @@ protected: public: Item_cache_decimal(): Item_cache() {} - void store(Item *item); double val_real(); longlong val_int(); String* val_str(String *str); my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return DECIMAL_RESULT; } + void cache_value(); }; @@ -3029,14 +3047,14 @@ public: MYSQL_TYPE_VARCHAR && !((const Item_field *) item)->field->has_charset()) {} - void store(Item *item); double val_real(); longlong val_int(); - String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; } + String* val_str(String *); my_decimal *val_decimal(my_decimal *); enum Item_result result_type() const { return STRING_RESULT; } CHARSET_INFO *charset() const { return value->charset(); }; int save_in_field(Field *field, bool no_conversions); + void cache_value(); }; class Item_cache_row: public Item_cache @@ -3046,7 +3064,8 @@ class Item_cache_row: public Item_cache bool save_array; public: Item_cache_row() - :Item_cache(), values(0), item_count(2), save_array(0) {} + :Item_cache(), values(0), item_count(2), + save_array(0) {} /* 'allocate' used only in row transformer, to preallocate space for row @@ -3104,6 +3123,7 @@ public: values= 0; DBUG_VOID_RETURN; } + void cache_value(); }; === modified file 'sql/item_cmpfunc.cc' --- a/sql/item_cmpfunc.cc 2009-11-24 13:54:59 +0000 +++ b/sql/item_cmpfunc.cc 2009-12-01 19:41:39 +0000 @@ -882,13 +882,13 @@ int Arg_comparator::set_cmp_func(Item_bo { enum enum_date_cmp_type cmp_type; ulonglong const_value= (ulonglong)-1; + thd= current_thd; + owner= owner_arg; a= a1; b= a2; if ((cmp_type= can_compare_as_dates(*a, *b, &const_value))) { - thd= current_thd; - owner= owner_arg; a_type= (*a)->field_type(); b_type= (*b)->field_type(); a_cache= 0; @@ -896,6 +896,10 @@ int Arg_comparator::set_cmp_func(Item_bo if (const_value != (ulonglong)-1) { + /* + cache_converted_constant can't be used here because it can't + correctly convert a DATETIME value from string to int representation. + */ Item_cache_int *cache= new Item_cache_int(); /* Mark the cache as non-const to prevent re-caching. */ cache->set_used_tables(1); @@ -921,8 +925,6 @@ int Arg_comparator::set_cmp_func(Item_bo (*b)->field_type() == MYSQL_TYPE_TIME) { /* Compare TIME values as integers. */ - thd= current_thd; - owner= owner_arg; a_cache= 0; b_cache= 0; is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); @@ -941,10 +943,46 @@ int Arg_comparator::set_cmp_func(Item_bo return 1; } + a= cache_converted_constant(thd, a, &a_cache, type); + b= cache_converted_constant(thd, b, &b_cache, type); return set_compare_func(owner_arg, type); } +/** + Convert and cache a constant. + + @param value [in] An item to cache + @param cache_item [out] Placeholder for the cache item + @param type [in] Comparison type + + @details + When given item is a constant and its type differs from comparison type + then cache its value to avoid type conversion of this constant on each + evaluation. In this case the value is cached and the reference to the cache + is returned. + Original value is returned otherwise. + + @return cache item or original value. +*/ + +Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value, + Item **cache_item, + Item_result type) +{ + /* Don't need cache if doing context analysis only. */ + if (!thd->is_context_analysis_only() && + (*value)->const_item() && type != (*value)->result_type()) + { + Item_cache *cache= Item_cache::get_cache(*value, type); + cache->store(*value); + *cache_item= cache; + return cache_item; + } + return value; +} + + void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) { thd= current_thd; @@ -1583,6 +1621,7 @@ longlong Item_in_optimizer::val_int() bool tmp; DBUG_ASSERT(fixed == 1); cache->store(args[0]); + cache->cache_value(); if (cache->null_value) { === modified file 'sql/item_cmpfunc.h' --- a/sql/item_cmpfunc.h 2009-11-06 14:20:27 +0000 +++ b/sql/item_cmpfunc.h 2009-12-01 19:41:39 +0000 @@ -97,6 +97,8 @@ public: ulonglong *const_val_arg); void set_datetime_cmp_func(Item **a1, Item **b1); + Item** cache_converted_constant(THD *thd, Item **value, Item **cache, + Item_result type); static arg_cmp_func comparator_matrix [5][2]; friend class Item_func; === modified file 'sql/item_subselect.cc' --- a/sql/item_subselect.cc 2009-11-19 23:48:08 +0000 +++ b/sql/item_subselect.cc 2009-12-01 19:41:39 +0000 @@ -480,6 +480,7 @@ Item_singlerow_subselect::select_transfo void Item_singlerow_subselect::store(uint i, Item *item) { row[i]->store(item); + row[i]->cache_value(); } enum Item_result Item_singlerow_subselect::result_type() const @@ -1826,6 +1827,7 @@ void subselect_engine::set_row(Listsetup(sel_item); + row[i]->store(sel_item); } if (item_list.elements > 1) res_type= ROW_RESULT; === modified file 'sql/item_xmlfunc.cc' --- a/sql/item_xmlfunc.cc 2009-09-23 13:21:29 +0000 +++ b/sql/item_xmlfunc.cc 2009-11-06 19:34:25 +0000 @@ -941,14 +941,16 @@ static Item *create_comparator(MY_XPATH in a loop through all of the nodes in the node set. */ - Item *fake= new Item_string("", 0, xpath->cs); + Item_string *fake= new Item_string("", 0, xpath->cs); + /* Don't cache fake because its value will be changed during comparison.*/ + fake->set_used_tables(RAND_TABLE_BIT); Item_nodeset_func *nodeset; Item *scalar, *comp; if (a->type() == Item::XPATH_NODESET) { nodeset= (Item_nodeset_func*) a; scalar= b; - comp= eq_func(oper, fake, scalar); + comp= eq_func(oper, (Item*)fake, scalar); } else { === modified file 'sql/sp_rcontext.cc' --- a/sql/sp_rcontext.cc 2009-09-10 09:18:29 +0000 +++ b/sql/sp_rcontext.cc 2009-12-01 19:41:39 +0000 @@ -669,7 +669,7 @@ sp_rcontext::set_case_expr(THD *thd, int } m_case_expr_holders[case_expr_id]->store(case_expr_item); - + m_case_expr_holders[case_expr_id]->cache_value(); return FALSE; } --Boundary_(ID_8dMztbplXQcIVJQCZETNyg) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/epotemkin@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/epotemkin@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: epotemkin@stripped # target_branch: file:///work/bzrroot/33546-bug-next-mr-bugfixing/ # testament_sha1: 00e7a603eb78c086eca88d280596e8d0944a9476 # timestamp: 2009-12-01 22:42:05 +0300 # source_branch: file:///work/bzrroot/34384-bug-5.1-bugteam/ # base_revision_id: mattias.jonsson@stripped\ # eyfrwja34w9mcgtz # # Begin bundle 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 --Boundary_(ID_8dMztbplXQcIVJQCZETNyg)--