diff options
author | unknown <evgen@moonbone.local> | 2007-07-28 22:47:03 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2007-07-28 22:47:03 +0400 |
commit | d86f0a1382c71a6e1bb4f7d8d42cf2b8336c02cc (patch) | |
tree | 88affb6cda94fab5d43d3f977e2ee2f96524d981 /sql/sp_head.cc | |
parent | ba9e6a56734608f97378d5a13aec5100f23080ba (diff) | |
parent | 40d596c200bd03b5fb01ba5b9af5912d65cc586d (diff) | |
download | mariadb-git-d86f0a1382c71a6e1bb4f7d8d42cf2b8336c02cc.tar.gz |
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into moonbone.local:/mnt/gentoo64/work/29856-bug-5.0-opt-mysql
sql/sp_head.cc:
Auto merged
mysql-test/r/query_cache.result:
SCCS merged
mysql-test/t/query_cache.test:
SCCS merged
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 144 |
1 files changed, 78 insertions, 66 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 0ac1db336d0..fd8724b2171 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -795,7 +795,8 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b) /* - Replace thd->query{_length} with a string that one can write to the binlog. + Replace thd->query{_length} with a string that one can write to the binlog + or the query cache. SYNOPSIS subst_spvars() @@ -807,7 +808,9 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b) DESCRIPTION The binlog-suitable string is produced by replacing references to SP local - variables with NAME_CONST('sp_var_name', value) calls. + variables with NAME_CONST('sp_var_name', value) calls. To make this string + suitable for the query cache this function allocates some additional space + for the query cache flags. RETURN FALSE on success @@ -820,80 +823,89 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) { DBUG_ENTER("subst_spvars"); - if (thd->prelocked_mode == NON_PRELOCKED && mysql_bin_log.is_open()) - { - Dynamic_array<Item_splocal*> sp_vars_uses; - char *pbuf, *cur, buffer[512]; - String qbuf(buffer, sizeof(buffer), &my_charset_bin); - int prev_pos, res; - /* Find all instances of Item_splocal used in this statement */ - for (Item *item= instr->free_list; item; item= item->next) - { - if (item->is_splocal()) - { - Item_splocal *item_spl= (Item_splocal*)item; - if (item_spl->pos_in_query) - sp_vars_uses.append(item_spl); - } - } - if (!sp_vars_uses.elements()) - DBUG_RETURN(FALSE); - - /* Sort SP var refs by their occurences in the query */ - sp_vars_uses.sort(cmp_splocal_locations); + Dynamic_array<Item_splocal*> sp_vars_uses; + char *pbuf, *cur, buffer[512]; + String qbuf(buffer, sizeof(buffer), &my_charset_bin); + int prev_pos, res, buf_len; - /* - Construct a statement string where SP local var refs are replaced - with "NAME_CONST(name, value)" - */ - qbuf.length(0); - cur= query_str->str; - prev_pos= res= 0; - for (Item_splocal **splocal= sp_vars_uses.front(); - splocal < sp_vars_uses.back(); splocal++) + /* Find all instances of Item_splocal used in this statement */ + for (Item *item= instr->free_list; item; item= item->next) + { + if (item->is_splocal()) { - Item *val; + Item_splocal *item_spl= (Item_splocal*)item; + if (item_spl->pos_in_query) + sp_vars_uses.append(item_spl); + } + } + if (!sp_vars_uses.elements()) + DBUG_RETURN(FALSE); + + /* Sort SP var refs by their occurences in the query */ + sp_vars_uses.sort(cmp_splocal_locations); - char str_buffer[STRING_BUFFER_USUAL_SIZE]; - String str_value_holder(str_buffer, sizeof(str_buffer), - &my_charset_latin1); - String *str_value; - - /* append the text between sp ref occurences */ - res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos); - prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length; - - /* append the spvar substitute */ - res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('")); - res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length); - res|= qbuf.append(STRING_WITH_LEN("',")); - res|= (*splocal)->fix_fields(thd, (Item **) splocal); + /* + Construct a statement string where SP local var refs are replaced + with "NAME_CONST(name, value)" + */ + qbuf.length(0); + cur= query_str->str; + prev_pos= res= 0; + for (Item_splocal **splocal= sp_vars_uses.front(); + splocal < sp_vars_uses.back(); splocal++) + { + Item *val; - if (res) - break; + char str_buffer[STRING_BUFFER_USUAL_SIZE]; + String str_value_holder(str_buffer, sizeof(str_buffer), + &my_charset_latin1); + String *str_value; + + /* append the text between sp ref occurences */ + res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos); + prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length; + + /* append the spvar substitute */ + res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('")); + res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length); + res|= qbuf.append(STRING_WITH_LEN("',")); + res|= (*splocal)->fix_fields(thd, (Item **) splocal); - val= (*splocal)->this_item(); - DBUG_PRINT("info", ("print %p", val)); - str_value= sp_get_item_value(thd, val, &str_value_holder); - if (str_value) - res|= qbuf.append(*str_value); - else - res|= qbuf.append(STRING_WITH_LEN("NULL")); - res|= qbuf.append(')'); - if (res) - break; - } - res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos); if (res) - DBUG_RETURN(TRUE); + break; - if (!(pbuf= thd->strmake(qbuf.ptr(), qbuf.length()))) - DBUG_RETURN(TRUE); + val= (*splocal)->this_item(); + DBUG_PRINT("info", ("print %p", val)); + str_value= sp_get_item_value(thd, val, &str_value_holder); + if (str_value) + res|= qbuf.append(*str_value); + else + res|= qbuf.append(STRING_WITH_LEN("NULL")); + res|= qbuf.append(')'); + if (res) + break; + } + res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos); + if (res) + DBUG_RETURN(TRUE); - thd->query= pbuf; - thd->query_length= qbuf.length(); + /* + Allocate additional space at the end of the new query string for the + query_cache_send_result_to_client function. + */ + buf_len= qbuf.length() + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE + 1; + if ((pbuf= alloc_root(thd->mem_root, buf_len))) + { + memcpy(pbuf, qbuf.ptr(), qbuf.length()); + pbuf[qbuf.length()]= 0; } + else + DBUG_RETURN(TRUE); + + thd->query= pbuf; + thd->query_length= qbuf.length(); + DBUG_RETURN(FALSE); } |