summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc178
1 files changed, 122 insertions, 56 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7aa3bbbdd7b..07c894dc8c1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -36,6 +36,9 @@
#endif
#include <mysys_err.h>
+#include "sp_rcontext.h"
+#include "sp_cache.h"
+
/*
The following is used to initialise Table_ident with a internal
table name
@@ -155,18 +158,20 @@ bool foreign_key_prefix(Key *a, Key *b)
** Thread specific functions
****************************************************************************/
-THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
+THD::THD():user_time(0), current_arena(0), is_fatal_error(0),
last_insert_id_used(0),
insert_id_used(0), rand_used(0), time_zone_used(0),
- in_lock_tables(0), global_read_lock(0), bootstrap(0)
+ in_lock_tables(0), global_read_lock(0), bootstrap(0),
+ spcont(NULL)
{
- host= user= priv_user= db= ip=0;
+ host= user= priv_user= db= ip= 0;
+ catalog= (char*)"std"; // the only catalog we have for now
host_or_ip= "connecting host";
locked=some_tables_deleted=no_errors=password= 0;
- killed=0;
query_start_used= 0;
count_cuted_fields= CHECK_FIELD_IGNORE;
- db_length= col_access= 0;
+ killed= NOT_KILLED;
+ db_length= col_access=0;
query_error= tmp_table_used= 0;
next_insert_id=last_insert_id=0;
open_tables= temporary_tables= handler_tables= derived_tables= 0;
@@ -222,9 +227,12 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
clear_alloc_root(&transaction.mem_root);
init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
user_connect=(USER_CONN *)0;
- hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
+ hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
- (hash_free_key) free_user_var,0);
+ (hash_free_key) free_user_var, 0);
+
+ sp_proc_cache= NULL;
+ sp_func_cache= NULL;
/* For user vars replication*/
if (opt_bin_log)
@@ -252,7 +260,7 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME)))
- killed=1;
+ killed= KILL_CONNECTION;
transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif
@@ -325,9 +333,11 @@ void THD::change_user(void)
cleanup();
cleanup_done= 0;
init();
- hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
+ hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(hash_free_key) free_user_var, 0);
+ sp_cache_clear(&sp_proc_cache);
+ sp_cache_clear(&sp_func_cache);
}
@@ -353,6 +363,8 @@ void THD::cleanup(void)
my_free((char*) variables.datetime_format, MYF(MY_ALLOW_ZERO_PTR));
delete_dynamic(&user_var_events);
hash_free(&user_vars);
+ sp_cache_clear(&sp_proc_cache);
+ sp_cache_clear(&sp_func_cache);
if (global_read_lock)
unlock_global_read_lock(this);
if (ull)
@@ -362,6 +374,7 @@ void THD::cleanup(void)
pthread_mutex_unlock(&LOCK_user_locks);
ull= 0;
}
+
cleanup_done=1;
DBUG_VOID_RETURN;
}
@@ -393,6 +406,9 @@ THD::~THD()
}
#endif
+ sp_cache_clear(&sp_proc_cache);
+ sp_cache_clear(&sp_func_cache);
+
DBUG_PRINT("info", ("freeing host"));
if (host != my_localhost) // If not pointer to constant
safeFree(host);
@@ -405,7 +421,7 @@ THD::~THD()
mysys_var=0; // Safety (shouldn't be needed)
pthread_mutex_destroy(&LOCK_delete);
#ifndef DBUG_OFF
- dbug_sentry = THD_SENTRY_GONE;
+ dbug_sentry= THD_SENTRY_GONE;
#endif
/* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */
clear_alloc_root(&stmt_backup.mem_root);
@@ -413,14 +429,14 @@ THD::~THD()
}
-void THD::awake(bool prepare_to_die)
+void THD::awake(THD::killed_state state_to_set)
{
THD_CHECK_SENTRY(this);
safe_mutex_assert_owner(&LOCK_delete);
- if (prepare_to_die)
- killed = 1;
- thr_alarm_kill(real_id);
+ killed= state_to_set;
+ if (state_to_set != THD::KILL_QUERY)
+ thr_alarm_kill(real_id);
#ifdef SIGNAL_WITH_VIO_CLOSE
close_active_vio();
#endif
@@ -624,7 +640,7 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length)
{
my_error(EE_OUTOFMEMORY, MYF(ME_BELL),
ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1);
- killed= 1;
+ killed= KILL_CONNECTION;
return 0;
}
@@ -649,8 +665,8 @@ int THD::send_explain_fields(select_result *result)
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("key",NAME_LEN));
item->maybe_null=1;
- field_list.push_back(item=new Item_return_int("key_len",3,
- MYSQL_TYPE_LONGLONG));
+ field_list.push_back(item=new Item_empty_string("key_len",
+ NAME_LEN*MAX_KEY));
item->maybe_null=1;
field_list.push_back(item=new Item_empty_string("ref",
NAME_LEN*MAX_REF_PARTS));
@@ -1263,49 +1279,82 @@ bool select_exists_subselect::send_data(List<Item> &items)
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
List_iterator_fast<Item> li(list);
- List_iterator_fast<LEX_STRING> gl(var_list);
+ List_iterator_fast<my_var> gl(var_list);
Item *item;
- LEX_STRING *ls;
+
+ local_vars.empty(); // Clear list if SP
+ unit= u;
+ row_count= 0;
+
if (var_list.elements != list.elements)
{
my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0));
return 1;
}
- unit=u;
while ((item=li++))
{
- ls= gl++;
- Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item);
- /*
- Item_func_set_user_var can't substitute something else on its place =>
- 0 can be passed as last argument (reference on item)
- */
- xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first,
- 0);
- xx->fix_length_and_dec();
- vars.push_back(xx);
+ my_var *mv= gl++;
+ if (mv->local)
+ (void)local_vars.push_back(new Item_splocal(mv->s, mv->offset));
+ else
+ {
+ Item_func_set_user_var *xx = new Item_func_set_user_var(mv->s, item);
+ /*
+ Item_func_set_user_var can't substitute something else on its place =>
+ 0 can be passed as last argument (reference on item)
+ */
+ xx->fix_fields(thd, (TABLE_LIST*) thd->lex->select_lex.table_list.first,
+ 0);
+ xx->fix_length_and_dec();
+ vars.push_back(xx);
+ }
}
return 0;
}
+Item_arena::Item_arena(THD* thd)
+ :free_list(0)
+{
+ init_sql_alloc(&mem_root,
+ thd->variables.query_alloc_block_size,
+ thd->variables.query_prealloc_size);
+}
+
+
+Item_arena::Item_arena()
+ :free_list(0)
+{
+ bzero((char *) &mem_root, sizeof(mem_root));
+}
+
+
+Item_arena::Item_arena(bool init_mem_root)
+ :free_list(0)
+{
+ if (init_mem_root)
+ bzero((char *) &mem_root, sizeof(mem_root));
+}
+
+
+Item_arena::~Item_arena()
+{}
+
+
/*
Statement functions
*/
Statement::Statement(THD *thd)
- :id(++thd->statement_id_counter),
+ :Item_arena(thd),
+ id(++thd->statement_id_counter),
set_query_id(1),
allow_sum_func(0),
lex(&main_lex),
query(0),
- query_length(0),
- free_list(0)
+ query_length(0)
{
name.str= NULL;
- init_sql_alloc(&mem_root,
- thd->variables.query_alloc_block_size,
- thd->variables.query_prealloc_size);
}
/*
@@ -1315,15 +1364,14 @@ Statement::Statement(THD *thd)
*/
Statement::Statement()
- :id(0),
+ :Item_arena(),
+ id(0),
set_query_id(1),
allow_sum_func(0), /* initialized later */
lex(&main_lex),
query(0), /* these two are set */
- query_length(0), /* in alloc_query() */
- free_list(0)
+ query_length(0) /* in alloc_query() */
{
- bzero((char *) &mem_root, sizeof(mem_root));
}
@@ -1344,14 +1392,14 @@ void Statement::set_statement(Statement *stmt)
}
-void Statement::set_n_backup_item_arena(Statement *set, Statement *backup)
+void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup)
{
backup->set_item_arena(this);
set_item_arena(set);
}
-void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
+void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup)
{
set->set_item_arena(this);
set_item_arena(backup);
@@ -1359,7 +1407,7 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup)
init_alloc_root(&backup->mem_root, 0, 0);
}
-void Statement::set_item_arena(Statement *set)
+void Item_arena::set_item_arena(Item_arena *set)
{
mem_root= set->mem_root;
free_list= set->free_list;
@@ -1435,8 +1483,19 @@ int Statement_map::insert(Statement *statement)
bool select_dumpvar::send_data(List<Item> &items)
{
List_iterator_fast<Item_func_set_user_var> li(vars);
+ List_iterator_fast<Item_splocal> var_li(local_vars);
+ List_iterator_fast<my_var> my_li(var_list);
+ List_iterator_fast<Item> it(items);
Item_func_set_user_var *xx;
+ Item_splocal *yy;
+ Item *item;
+ my_var *zz;
DBUG_ENTER("send_data");
+ if (unit->offset_limit_cnt)
+ { // using limit offset,count
+ unit->offset_limit_cnt--;
+ DBUG_RETURN(0);
+ }
if (unit->offset_limit_cnt)
{ // Using limit offset,count
@@ -1448,26 +1507,33 @@ bool select_dumpvar::send_data(List<Item> &items)
my_error(ER_TOO_MANY_ROWS, MYF(0));
DBUG_RETURN(1);
}
- while ((xx=li++))
+ while ((zz=my_li++) && (item=it++))
{
- xx->check();
- xx->update();
+ if (zz->local)
+ {
+ if ((yy=var_li++))
+ {
+ thd->spcont->set_item_eval(yy->get_offset(), item, zz->type);
+ }
+ }
+ else
+ {
+ if ((xx=li++))
+ {
+ xx->check();
+ xx->update();
+ }
+ }
}
DBUG_RETURN(0);
}
bool select_dumpvar::send_eof()
{
- if (row_count)
- {
- ::send_ok(thd,row_count);
- return 0;
- }
- else
- {
- my_error(ER_EMPTY_QUERY,MYF(0));
- return 1;
- }
+ if (! row_count)
+ send_warning(thd, ER_SP_FETCH_NO_DATA);
+ ::send_ok(thd,row_count);
+ return 0;
}
/****************************************************************************