Loading sql/item.cc +15 −4 Original line number Diff line number Diff line Loading @@ -307,8 +307,14 @@ Item::Item(): /* Put item in free list so that we can free all items at end */ THD *thd= current_thd; if (reused) next= reuse_next; else { next= thd->free_list; thd->free_list= this; } /* Item constructor can be called during execution other then SQL_COM command => we should check thd->lex->current_select on zero (thd->lex Loading Loading @@ -342,10 +348,15 @@ Item::Item(THD *thd, Item *item): with_sum_func(item->with_sum_func), fixed(item->fixed), collation(item->collation) { if (reused) next= reuse_next; else { next= thd->free_list; // Put in free list thd->free_list= this; } } uint Item::decimal_precision() const Loading sql/item.h +52 −2 Original line number Diff line number Diff line Loading @@ -229,9 +229,59 @@ class Item { Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } /* For SP reuse mechanism */ bool reused; size_t reuse_slot_size; Item *reuse_next; static void *operator new(size_t size) { Item *me= (Item *)sql_alloc((uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } return (void*)me; } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } { Item *me= (Item *)alloc_root(mem_root, (uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } return (void*)me; } static void *operator new(size_t size, MEM_ROOT *mem_root, Item *reuse) { Item *me; if (!reuse || size > reuse->reuse_slot_size) { me= (Item *)alloc_root(mem_root, (uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } } else { /* Reuse old item */ size_t slot_size= reuse->reuse_slot_size; reuse->delete_self(); me= reuse; me->reuse_slot_size= slot_size; /* For the constructor */ me->reuse_next= reuse->next; me->reused= TRUE; } return (void *)me; } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} Loading sql/sp_head.cc +22 −15 Original line number Diff line number Diff line Loading @@ -131,7 +131,9 @@ sp_prepare_func_item(THD* thd, Item **it_addr) ** if nothing else. */ Item * sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, MEM_ROOT *mem_root, Item *reuse) { DBUG_ENTER("sp_eval_func_item"); Item *it= sp_prepare_func_item(thd, it_addr); Loading @@ -144,7 +146,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) /* QQ How do we do this? Is there some better way? */ if (type == MYSQL_TYPE_NULL) it= new Item_null(); it= new(mem_root, reuse) Item_null(); else { switch (sp_map_result_type(type)) { Loading @@ -155,12 +157,12 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("INT_RESULT: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { DBUG_PRINT("info", ("INT_RESULT: %d", i)); it= new Item_int(i); it= new(mem_root, reuse) Item_int(i); } break; } Loading @@ -171,7 +173,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("REAL_RESULT: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { Loading @@ -180,7 +182,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) uint8 decimals= it->decimals; uint32 max_length= it->max_length; DBUG_PRINT("info", ("REAL_RESULT: %g", d)); it= new Item_float(d); it= new(mem_root, reuse) Item_float(d); it->decimals= decimals; it->max_length= max_length; } Loading @@ -190,9 +192,9 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) { my_decimal value, *val= it->val_decimal(&value); if (it->null_value) it= new Item_null(); it= new(mem_root, reuse) Item_null(); else it= new Item_decimal(val); it= new(mem_root, reuse) Item_decimal(val); #ifndef DBUG_OFF char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; DBUG_PRINT("info", ("DECIMAL_RESULT: %s", dbug_decimal_as_string(dbug_buff, val))); Loading @@ -208,14 +210,16 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("default result: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { DBUG_PRINT("info",("default result: %*s", s->length(), s->c_ptr_quick())); it= new Item_string(thd->strmake(s->ptr(), s->length()), s->length(), it->collation.collation); it= new(mem_root, reuse) Item_string(thd->strmake(s->ptr(), s->length()), s->length(), it->collation.collation); } break; } Loading Loading @@ -708,7 +712,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) for (i= 0 ; i < params && i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); Item *it= sp_eval_func_item(thd, argp++, pvar->type); Item *it= sp_eval_func_item(thd, argp++, pvar->type, thd->mem_root, NULL); if (it) nctx->push_item(it); Loading Loading @@ -823,7 +827,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } else { Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type); Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type, thd->mem_root, NULL); if (it2) nctx->push_item(it2); // IN or INOUT Loading Loading @@ -1469,7 +1474,9 @@ sp_instr_set::exec_core(THD *thd, uint *nextp) Item *it; int res; it= sp_eval_func_item(thd, &m_value, m_type); it= sp_eval_func_item(thd, &m_value, m_type, thd->mem_root, thd->spcont->get_item(m_offset)); if (! it) res= -1; else Loading Loading @@ -1715,7 +1722,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp) Item *it; int res; it= sp_eval_func_item(thd, &m_value, m_type); it= sp_eval_func_item(thd, &m_value, m_type, thd->mem_root, NULL); if (! it) res= -1; else Loading sql/sp_rcontext.cc +11 −3 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax) int sp_rcontext::set_item_eval(uint idx, Item **item_addr, enum_field_types type) { extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type); Item *it= sp_eval_func_item(current_thd, item_addr, type); extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type, MEM_ROOT *mem_root, Item *reuse); THD *thd= current_thd; Item *it= sp_eval_func_item(thd, item_addr, type, thd->mem_root, NULL); if (! it) return -1; Loading Loading @@ -111,7 +114,12 @@ void sp_rcontext::save_variables(uint fp) { while (fp < m_count) m_saved.push_front(m_frame[fp++]); { Item *it= m_frame[fp]; m_frame[fp++]= NULL; // Prevent reuse m_saved.push_front(it); } } void Loading Loading
sql/item.cc +15 −4 Original line number Diff line number Diff line Loading @@ -307,8 +307,14 @@ Item::Item(): /* Put item in free list so that we can free all items at end */ THD *thd= current_thd; if (reused) next= reuse_next; else { next= thd->free_list; thd->free_list= this; } /* Item constructor can be called during execution other then SQL_COM command => we should check thd->lex->current_select on zero (thd->lex Loading Loading @@ -342,10 +348,15 @@ Item::Item(THD *thd, Item *item): with_sum_func(item->with_sum_func), fixed(item->fixed), collation(item->collation) { if (reused) next= reuse_next; else { next= thd->free_list; // Put in free list thd->free_list= this; } } uint Item::decimal_precision() const Loading
sql/item.h +52 −2 Original line number Diff line number Diff line Loading @@ -229,9 +229,59 @@ class Item { Item(const Item &); /* Prevent use of these */ void operator=(Item &); public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } /* For SP reuse mechanism */ bool reused; size_t reuse_slot_size; Item *reuse_next; static void *operator new(size_t size) { Item *me= (Item *)sql_alloc((uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } return (void*)me; } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } { Item *me= (Item *)alloc_root(mem_root, (uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } return (void*)me; } static void *operator new(size_t size, MEM_ROOT *mem_root, Item *reuse) { Item *me; if (!reuse || size > reuse->reuse_slot_size) { me= (Item *)alloc_root(mem_root, (uint) size); if (me) { me->reuse_slot_size= size; me->reused= FALSE; } } else { /* Reuse old item */ size_t slot_size= reuse->reuse_slot_size; reuse->delete_self(); me= reuse; me->reuse_slot_size= slot_size; /* For the constructor */ me->reuse_next= reuse->next; me->reused= TRUE; } return (void *)me; } static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } static void operator delete(void *ptr, MEM_ROOT *mem_root) {} Loading
sql/sp_head.cc +22 −15 Original line number Diff line number Diff line Loading @@ -131,7 +131,9 @@ sp_prepare_func_item(THD* thd, Item **it_addr) ** if nothing else. */ Item * sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, MEM_ROOT *mem_root, Item *reuse) { DBUG_ENTER("sp_eval_func_item"); Item *it= sp_prepare_func_item(thd, it_addr); Loading @@ -144,7 +146,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) /* QQ How do we do this? Is there some better way? */ if (type == MYSQL_TYPE_NULL) it= new Item_null(); it= new(mem_root, reuse) Item_null(); else { switch (sp_map_result_type(type)) { Loading @@ -155,12 +157,12 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("INT_RESULT: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { DBUG_PRINT("info", ("INT_RESULT: %d", i)); it= new Item_int(i); it= new(mem_root, reuse) Item_int(i); } break; } Loading @@ -171,7 +173,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("REAL_RESULT: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { Loading @@ -180,7 +182,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) uint8 decimals= it->decimals; uint32 max_length= it->max_length; DBUG_PRINT("info", ("REAL_RESULT: %g", d)); it= new Item_float(d); it= new(mem_root, reuse) Item_float(d); it->decimals= decimals; it->max_length= max_length; } Loading @@ -190,9 +192,9 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) { my_decimal value, *val= it->val_decimal(&value); if (it->null_value) it= new Item_null(); it= new(mem_root, reuse) Item_null(); else it= new Item_decimal(val); it= new(mem_root, reuse) Item_decimal(val); #ifndef DBUG_OFF char dbug_buff[DECIMAL_MAX_STR_LENGTH+1]; DBUG_PRINT("info", ("DECIMAL_RESULT: %s", dbug_decimal_as_string(dbug_buff, val))); Loading @@ -208,14 +210,16 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type) if (it->null_value) { DBUG_PRINT("info", ("default result: null")); it= new Item_null(); it= new(mem_root, reuse) Item_null(); } else { DBUG_PRINT("info",("default result: %*s", s->length(), s->c_ptr_quick())); it= new Item_string(thd->strmake(s->ptr(), s->length()), s->length(), it->collation.collation); it= new(mem_root, reuse) Item_string(thd->strmake(s->ptr(), s->length()), s->length(), it->collation.collation); } break; } Loading Loading @@ -708,7 +712,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) for (i= 0 ; i < params && i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); Item *it= sp_eval_func_item(thd, argp++, pvar->type); Item *it= sp_eval_func_item(thd, argp++, pvar->type, thd->mem_root, NULL); if (it) nctx->push_item(it); Loading Loading @@ -823,7 +827,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } else { Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type); Item *it2= sp_eval_func_item(thd, li.ref(), pvar->type, thd->mem_root, NULL); if (it2) nctx->push_item(it2); // IN or INOUT Loading Loading @@ -1469,7 +1474,9 @@ sp_instr_set::exec_core(THD *thd, uint *nextp) Item *it; int res; it= sp_eval_func_item(thd, &m_value, m_type); it= sp_eval_func_item(thd, &m_value, m_type, thd->mem_root, thd->spcont->get_item(m_offset)); if (! it) res= -1; else Loading Loading @@ -1715,7 +1722,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp) Item *it; int res; it= sp_eval_func_item(thd, &m_value, m_type); it= sp_eval_func_item(thd, &m_value, m_type, thd->mem_root, NULL); if (! it) res= -1; else Loading
sql/sp_rcontext.cc +11 −3 Original line number Diff line number Diff line Loading @@ -43,8 +43,11 @@ sp_rcontext::sp_rcontext(uint fsize, uint hmax, uint cmax) int sp_rcontext::set_item_eval(uint idx, Item **item_addr, enum_field_types type) { extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type); Item *it= sp_eval_func_item(current_thd, item_addr, type); extern Item *sp_eval_func_item(THD *thd, Item **it, enum_field_types type, MEM_ROOT *mem_root, Item *reuse); THD *thd= current_thd; Item *it= sp_eval_func_item(thd, item_addr, type, thd->mem_root, NULL); if (! it) return -1; Loading Loading @@ -111,7 +114,12 @@ void sp_rcontext::save_variables(uint fp) { while (fp < m_count) m_saved.push_front(m_frame[fp++]); { Item *it= m_frame[fp]; m_frame[fp++]= NULL; // Prevent reuse m_saved.push_front(it); } } void Loading