summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorChaithra Gopalareddy <chaithra.gopalareddy@oracle.com>2013-05-10 19:18:21 +0530
committerChaithra Gopalareddy <chaithra.gopalareddy@oracle.com>2013-05-10 19:18:21 +0530
commit07ef11b2cce540ccc09cb6ef8cf3d080a1c28926 (patch)
treedb11819a163b702f380e02bc410e0d0d167354d2 /sql/sql_select.cc
parent3df10469a211e9ec7b33c740018d01d2c9150bbb (diff)
downloadmariadb-git-07ef11b2cce540ccc09cb6ef8cf3d080a1c28926.tar.gz
Bug#16119355:PREPARED STATEMENT: READ OF FREED MEMORY WITH STRING CONVERSION FUNCTIONS
Reverting fix for Bug#16119355 in 5.1 as this needs two patches from 5.5+ to work for a certain case
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc104
1 files changed, 40 insertions, 64 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index fabf2c81cc1..7b1a8cf9e82 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -15779,88 +15779,64 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
res_selected_fields.empty();
res_all_fields.empty();
- uint border= all_fields.elements - elements;
- for (uint i= 0; (item= it++); i++)
+ uint i, border= all_fields.elements - elements;
+ for (i= 0; (item= it++); i++)
{
Field *field;
- if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
+
+ if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) ||
+ (item->type() == Item::FUNC_ITEM &&
+ ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC))
item_field= item;
- else if (item->type() == Item::FIELD_ITEM)
- item_field= item->get_tmp_table_item(thd);
- else if (item->type() == Item::FUNC_ITEM &&
- ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)
+ else
{
- field= item->get_tmp_table_field();
- if( field != NULL)
+ if (item->type() == Item::FIELD_ITEM)
{
- /*
- Replace "@:=<expression>" with "@:=<tmp table column>". Otherwise, we
- would re-evaluate <expression>, and if expression were a subquery, this
- would access already-unlocked tables.
- */
- Item_func_set_user_var* suv=
- new Item_func_set_user_var(thd, (Item_func_set_user_var*) item);
- Item_field *new_field= new Item_field(field);
- if (!suv || !new_field)
- DBUG_RETURN(true); // Fatal error
- /*
- We are replacing the argument of Item_func_set_user_var after its value
- has been read. The argument's null_value should be set by now, so we
- must set it explicitly for the replacement argument since the null_value
- may be read without any preceeding call to val_*().
- */
- new_field->update_null_value();
- List<Item> list;
- list.push_back(new_field);
- suv->set_arguments(list);
- item_field= suv;
+ item_field= item->get_tmp_table_item(thd);
}
- else
- item_field= item;
- }
- else if ((field= item->get_tmp_table_field()))
- {
- if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
- item_field= ((Item_sum*) item)->result_item(field);
- else
- item_field= (Item*) new Item_field(field);
- if (!item_field)
- DBUG_RETURN(true); // Fatal error
-
- if (item->real_item()->type() != Item::FIELD_ITEM)
- field->orig_table= 0;
- item_field->name= item->name;
- if (item->type() == Item::REF_ITEM)
+ else if ((field= item->get_tmp_table_field()))
{
- Item_field *ifield= (Item_field *) item_field;
- Item_ref *iref= (Item_ref *) item;
- ifield->table_name= iref->table_name;
- ifield->db_name= iref->db_name;
- }
+ if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
+ item_field= ((Item_sum*) item)->result_item(field);
+ else
+ item_field= (Item*) new Item_field(field);
+ if (!item_field)
+ DBUG_RETURN(TRUE); // Fatal error
+
+ if (item->real_item()->type() != Item::FIELD_ITEM)
+ field->orig_table= 0;
+ item_field->name= item->name;
+ if (item->type() == Item::REF_ITEM)
+ {
+ Item_field *ifield= (Item_field *) item_field;
+ Item_ref *iref= (Item_ref *) item;
+ ifield->table_name= iref->table_name;
+ ifield->db_name= iref->db_name;
+ }
#ifndef DBUG_OFF
- if (!item_field->name)
- {
- char buff[256];
- String str(buff,sizeof(buff),&my_charset_bin);
- str.length(0);
- item->print(&str, QT_ORDINARY);
- item_field->name= sql_strmake(str.ptr(),str.length());
- }
+ if (!item_field->name)
+ {
+ char buff[256];
+ String str(buff,sizeof(buff),&my_charset_bin);
+ str.length(0);
+ item->print(&str, QT_ORDINARY);
+ item_field->name= sql_strmake(str.ptr(),str.length());
+ }
#endif
+ }
+ else
+ item_field= item;
}
- else
- item_field= item;
-
res_all_fields.push_back(item_field);
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
item_field;
}
List_iterator_fast<Item> itr(res_all_fields);
- for (uint i= 0; i < border; i++)
+ for (i= 0; i < border; i++)
itr++;
itr.sublist(res_selected_fields, elements);
- DBUG_RETURN(false);
+ DBUG_RETURN(FALSE);
}