#include <sp_head.h>
Collaboration diagram for sp_head:

Definition at line 101 of file sp_head.h.
| anonymous enum |
| HAS_RETURN | |
| IN_SIMPLE_CASE | |
| IN_HANDLER | |
| MULTI_RESULTS | |
| CONTAINS_DYNAMIC_SQL | |
| IS_INVOKED | |
| HAS_SET_AUTOCOMMIT_STMT | |
| HAS_COMMIT_OR_ROLLBACK | |
| LOG_SLOW_STATEMENTS | |
| LOG_GENERAL_LOG | |
| BINLOG_ROW_BASED_IF_MIXED |
Definition at line 109 of file sp_head.h.
00109 { 00110 HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN 00111 IN_SIMPLE_CASE= 2, // Is set if parsing a simple CASE 00112 IN_HANDLER= 4, // Is set if the parser is in a handler body 00113 MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s) 00114 CONTAINS_DYNAMIC_SQL= 16, // Is set if a procedure with PREPARE/EXECUTE 00115 IS_INVOKED= 32, // Is set if this sp_head is being used 00116 HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit' 00117 /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */ 00118 HAS_COMMIT_OR_ROLLBACK= 128, 00119 LOG_SLOW_STATEMENTS= 256, // Used by events 00120 LOG_GENERAL_LOG= 512, // Used by events 00121 BINLOG_ROW_BASED_IF_MIXED= 1024 00122 };
| sp_head::sp_head | ( | const sp_head & | ) | [private] |
| sp_head::sp_head | ( | ) |
Definition at line 452 of file sp_head.cc.
References create_field::charset, DBUG_ENTER, DBUG_VOID_RETURN, base_list::empty(), hash_init, m_backpatch, m_cont_backpatch, m_db, m_lex, m_name, m_qname, m_return_field_def, m_sptabs, m_sroutines, NULL, sp_sroutine_key(), sp_table_key(), and system_charset_info.
00453 :Query_arena(&main_mem_root, INITIALIZED_FOR_SP), 00454 m_flags(0), m_recursion_level(0), m_next_cached_sp(0), 00455 m_first_instance(this), m_first_free_instance(this), m_last_cached_sp(this), 00456 m_cont_level(0) 00457 { 00458 const LEX_STRING str_reset= { NULL, 0 }; 00459 m_return_field_def.charset = NULL; 00460 /* 00461 FIXME: the only use case when name is NULL is events, and it should 00462 be rewritten soon. Remove the else part and replace 'if' with 00463 an assert when this is done. 00464 */ 00465 m_db= m_name= m_qname= str_reset; 00466 00467 extern byte * 00468 sp_table_key(const byte *ptr, uint *plen, my_bool first); 00469 DBUG_ENTER("sp_head::sp_head"); 00470 00471 m_backpatch.empty(); 00472 m_cont_backpatch.empty(); 00473 m_lex.empty(); 00474 hash_init(&m_sptabs, system_charset_info, 0, 0, 0, sp_table_key, 0, 0); 00475 hash_init(&m_sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0); 00476 DBUG_VOID_RETURN; 00477 }
Here is the call graph for this function:

| sp_head::~sp_head | ( | ) | [virtual] |
Definition at line 653 of file sp_head.cc.
References destroy(), m_next_cached_sp, m_thd, and restore_thd_mem_root().
00654 { 00655 destroy(); 00656 delete m_next_cached_sp; 00657 if (m_thd) 00658 restore_thd_mem_root(m_thd); 00659 }
Here is the call graph for this function:

| void sp_head::add_cont_backpatch | ( | sp_instr_opt_meta * | i | ) |
Definition at line 1955 of file sp_head.cc.
References m_cont_backpatch, sp_instr_opt_meta::m_cont_dest, m_cont_level, and List< T >::push_front().
01956 { 01957 i->m_cont_dest= m_cont_level; 01958 (void)m_cont_backpatch.push_front(i); 01959 }
Here is the call graph for this function:

| void sp_head::add_instr | ( | sp_instr * | instr | ) |
Definition at line 2140 of file sp_head.cc.
References insert_dynamic(), m_instr, m_thd, and main_mem_root.
02141 { 02142 instr->free_list= m_thd->free_list; 02143 m_thd->free_list= 0; 02144 /* 02145 Memory root of every instruction is designated for permanent 02146 transformations (optimizations) made on the parsed tree during 02147 the first execution. It points to the memory root of the 02148 entire stored procedure, as their life span is equal. 02149 */ 02150 instr->mem_root= &main_mem_root; 02151 insert_dynamic(&m_instr, (gptr)&instr); 02152 }
Here is the call graph for this function:

| bool sp_head::add_used_tables_to_table_list | ( | THD * | thd, | |
| TABLE_LIST *** | query_tables_last_ptr, | |||
| TABLE_LIST * | belong_to_view | |||
| ) |
Definition at line 3535 of file sp_head.cc.
References st_table_list::alias, ALIGN_SIZE, backup, st_table_list::belong_to_view, st_table_list::cacheable_table, st_table_list::db, st_sp_table::db_length, st_table_list::db_length, DBUG_ENTER, DBUG_RETURN, FALSE, hash_element(), LEX_STRING::length, st_sp_table::lock_count, st_sp_table::lock_type, st_table_list::lock_type, m_sptabs, st_table_list::next_global, st_table_list::prelocking_placeholder, st_table_list::prev_global, st_sp_table::qname, st_hash::records, LEX_STRING::str, st_table_list::table_name, st_sp_table::table_name_length, st_table_list::table_name_length, st_sp_table::temp, and TRUE.
03538 { 03539 uint i; 03540 Query_arena *arena, backup; 03541 bool result= FALSE; 03542 DBUG_ENTER("sp_head::add_used_tables_to_table_list"); 03543 03544 /* 03545 Use persistent arena for table list allocation to be PS/SP friendly. 03546 Note that we also have to copy database/table names and alias to PS/SP 03547 memory since current instance of sp_head object can pass away before 03548 next execution of PS/SP for which tables are added to prelocking list. 03549 This will be fixed by introducing of proper invalidation mechanism 03550 once new TDC is ready. 03551 */ 03552 arena= thd->activate_stmt_arena_if_needed(&backup); 03553 03554 for (i=0 ; i < m_sptabs.records ; i++) 03555 { 03556 char *tab_buff, *key_buff; 03557 TABLE_LIST *table; 03558 SP_TABLE *stab= (SP_TABLE *)hash_element(&m_sptabs, i); 03559 if (stab->temp) 03560 continue; 03561 03562 if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) * 03563 stab->lock_count)) || 03564 !(key_buff= (char*)thd->memdup(stab->qname.str, 03565 stab->qname.length + 1))) 03566 DBUG_RETURN(FALSE); 03567 03568 for (uint j= 0; j < stab->lock_count; j++) 03569 { 03570 table= (TABLE_LIST *)tab_buff; 03571 03572 table->db= key_buff; 03573 table->db_length= stab->db_length; 03574 table->table_name= table->db + table->db_length + 1; 03575 table->table_name_length= stab->table_name_length; 03576 table->alias= table->table_name + table->table_name_length + 1; 03577 table->lock_type= stab->lock_type; 03578 table->cacheable_table= 1; 03579 table->prelocking_placeholder= 1; 03580 table->belong_to_view= belong_to_view; 03581 03582 /* Everyting else should be zeroed */ 03583 03584 **query_tables_last_ptr= table; 03585 table->prev_global= *query_tables_last_ptr; 03586 *query_tables_last_ptr= &table->next_global; 03587 03588 tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST)); 03589 result= TRUE; 03590 } 03591 } 03592 03593 if (arena) 03594 thd->restore_active_arena(arena, &backup); 03595 03596 DBUG_RETURN(result); 03597 }
Here is the call graph for this function:

| void sp_head::backpatch | ( | struct sp_label * | ) |
Definition at line 1877 of file sp_head.cc.
References sp_instr::backpatch(), sp_label::ctx, sp_head::bp_t::instr, instructions(), sp_head::bp_t::lab, and m_backpatch.
01878 { 01879 bp_t *bp; 01880 uint dest= instructions(); 01881 List_iterator_fast<bp_t> li(m_backpatch); 01882 01883 while ((bp= li++)) 01884 { 01885 if (bp->lab == lab) 01886 bp->instr->backpatch(dest, lab->ctx); 01887 } 01888 }
Here is the call graph for this function:

| int sp_head::create | ( | THD * | thd | ) |
Definition at line 616 of file sp_head.cc.
References String::append(), buf, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, get_instr(), m_body, m_name, m_params, m_qname, m_type, optimize(), sp_instr::print(), String::ptr(), sp_create_function(), sp_create_procedure(), LEX_STRING::str, and TYPE_ENUM_FUNCTION.
00617 { 00618 DBUG_ENTER("sp_head::create"); 00619 int ret; 00620 00621 DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s", 00622 m_type, m_name.str, m_params.str, m_body.str)); 00623 00624 #ifndef DBUG_OFF 00625 optimize(); 00626 { 00627 String s; 00628 sp_instr *i; 00629 uint ip= 0; 00630 while ((i = get_instr(ip))) 00631 { 00632 char buf[8]; 00633 00634 sprintf(buf, "%4u: ", ip); 00635 s.append(buf); 00636 i->print(&s); 00637 s.append('\n'); 00638 ip+= 1; 00639 } 00640 s.append('\0'); 00641 DBUG_PRINT("info", ("Code %s\n%s", m_qname.str, s.ptr())); 00642 } 00643 #endif 00644 00645 if (m_type == TYPE_ENUM_FUNCTION) 00646 ret= sp_create_function(thd, this); 00647 else 00648 ret= sp_create_procedure(thd, this); 00649 00650 DBUG_RETURN(ret); 00651 }
Here is the call graph for this function:

| Field * sp_head::create_result_field | ( | uint | field_max_length, | |
| const char * | field_name, | |||
| TABLE * | table | |||
| ) |
Definition at line 703 of file sp_head.cc.
References create_field::charset, DBUG_ENTER, DBUG_RETURN, create_field::geom_type, Field::init(), create_field::interval, create_field::length, m_name, m_return_field_def, make_field(), Field::NONE, create_field::pack_flag, st_table::s, create_field::sql_type, and LEX_STRING::str.
Referenced by Item_func_sp::sp_result_field(), sp_returns_type(), and Item_func_sp::tmp_table_field().
00705 { 00706 uint field_length; 00707 Field *field; 00708 00709 DBUG_ENTER("sp_head::create_result_field"); 00710 00711 field_length= !m_return_field_def.length ? 00712 field_max_length : m_return_field_def.length; 00713 00714 field= ::make_field(table->s, /* TABLE_SHARE ptr */ 00715 (char*) 0, /* field ptr */ 00716 field_length, /* field [max] length */ 00717 (uchar*) "", /* null ptr */ 00718 0, /* null bit */ 00719 m_return_field_def.pack_flag, 00720 m_return_field_def.sql_type, 00721 m_return_field_def.charset, 00722 m_return_field_def.geom_type, 00723 Field::NONE, /* unreg check */ 00724 m_return_field_def.interval, 00725 field_name ? field_name : (const char *) m_name.str); 00726 00727 if (field) 00728 field->init(table); 00729 00730 DBUG_RETURN(field); 00731 }
Here is the call graph for this function:

Here is the caller graph for this function:

| char* sp_head::create_string | ( | THD * | thd, | |
| ulong * | lenp | |||
| ) |
| void sp_head::destroy | ( | ) |
Definition at line 662 of file sp_head.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, delete_dynamic(), sp_pcontext::destroy(), free_items(), get_instr(), hash_free(), base_list::is_empty(), lex_end(), m_instr, m_lex, m_name, m_pcont, m_sptabs, m_sroutines, m_thd, List< T >::pop(), and LEX_STRING::str.
Referenced by ~sp_head().
00663 { 00664 sp_instr *i; 00665 LEX *lex; 00666 DBUG_ENTER("sp_head::destroy"); 00667 DBUG_PRINT("info", ("name: %s", m_name.str)); 00668 00669 for (uint ip = 0 ; (i = get_instr(ip)) ; ip++) 00670 delete i; 00671 delete_dynamic(&m_instr); 00672 m_pcont->destroy(); 00673 free_items(); 00674 00675 /* 00676 If we have non-empty LEX stack then we just came out of parser with 00677 error. Now we should delete all auxilary LEXes and restore original 00678 THD::lex (In this case sp_head::restore_thd_mem_root() was not called 00679 too, so m_thd points to the current thread context). 00680 It is safe to not update LEX::ptr because further query string parsing 00681 and execution will be stopped anyway. 00682 */ 00683 DBUG_ASSERT(m_lex.is_empty() || m_thd); 00684 while ((lex= (LEX *)m_lex.pop())) 00685 { 00686 lex_end(m_thd->lex); 00687 delete m_thd->lex; 00688 m_thd->lex= lex; 00689 } 00690 00691 hash_free(&m_sptabs); 00692 hash_free(&m_sroutines); 00693 DBUG_VOID_RETURN; 00694 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::do_cont_backpatch | ( | ) |
Definition at line 1962 of file sp_head.cc.
References List< T >::head(), instructions(), m_cont_backpatch, sp_instr_opt_meta::m_cont_dest, m_cont_level, and List< T >::pop().
01963 { 01964 uint dest= instructions(); 01965 uint lev= m_cont_level--; 01966 sp_instr_opt_meta *i; 01967 01968 while ((i= m_cont_backpatch.head()) && i->m_cont_dest == lev) 01969 { 01970 i->m_cont_dest= dest; 01971 (void)m_cont_backpatch.pop(); 01972 } 01973 }
Here is the call graph for this function:

| bool sp_head::execute | ( | THD * | thd | ) | [private] |
Definition at line 948 of file sp_head.cc.
References check_stack_overrun(), cleanup_items(), ctx, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, sp_instr::execute(), FALSE, free_root(), get_instr(), init_alloc_root(), IS_INVOKED, LEX_STRING::length, m_db, m_first_free_instance, m_first_instance, m_flags, m_last_cached_sp, m_next_cached_sp, m_recursion_level, m_sql_mode, MEM_ROOT_BLOCK_SIZE, MODE_STRICT_ALL_TABLES, MODE_STRICT_TRANS_TABLES, MYF, mysql_change_db(), NAME_LEN, NULL, reset_dynamic, SP_HANDLER_CONTINUE, SP_HANDLER_NONE, sp_use_new_db(), STACK_MIN_SIZE, LEX_STRING::str, and TRUE.
Referenced by execute_function(), execute_procedure(), and execute_trigger().
00949 { 00950 DBUG_ENTER("sp_head::execute"); 00951 char old_db_buf[NAME_LEN+1]; 00952 LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; 00953 bool dbchanged; 00954 sp_rcontext *ctx; 00955 bool err_status= FALSE; 00956 uint ip= 0; 00957 ulong save_sql_mode; 00958 bool save_abort_on_warning; 00959 Query_arena *old_arena; 00960 /* per-instruction arena */ 00961 MEM_ROOT execute_mem_root; 00962 Query_arena execute_arena(&execute_mem_root, INITIALIZED_FOR_SP), 00963 backup_arena; 00964 query_id_t old_query_id; 00965 TABLE *old_derived_tables; 00966 LEX *old_lex; 00967 Item_change_list old_change_list; 00968 String old_packet; 00969 00970 /* Use some extra margin for possible SP recursion and functions */ 00971 if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char*)&old_packet)) 00972 DBUG_RETURN(TRUE); 00973 00974 /* init per-instruction memroot */ 00975 init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); 00976 00977 DBUG_ASSERT(!(m_flags & IS_INVOKED)); 00978 m_flags|= IS_INVOKED; 00979 m_first_instance->m_first_free_instance= m_next_cached_sp; 00980 if (m_next_cached_sp) 00981 { 00982 DBUG_PRINT("info", 00983 ("first free for 0x%lx ++: 0x%lx->0x%lx level: %lu flags %x", 00984 (ulong)m_first_instance, (ulong) this, 00985 (ulong) m_next_cached_sp, 00986 m_next_cached_sp->m_recursion_level, 00987 m_next_cached_sp->m_flags)); 00988 } 00989 /* 00990 Check that if there are not any instances after this one then 00991 pointer to the last instance points on this instance or if there are 00992 some instances after this one then recursion level of next instance 00993 greater then recursion level of current instance on 1 00994 */ 00995 DBUG_ASSERT((m_next_cached_sp == 0 && 00996 m_first_instance->m_last_cached_sp == this) || 00997 (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level)); 00998 00999 if (m_db.length && 01000 (err_status= sp_use_new_db(thd, m_db, &old_db, 0, &dbchanged))) 01001 goto done; 01002 01003 if ((ctx= thd->spcont)) 01004 ctx->clear_handler(); 01005 thd->query_error= 0; 01006 old_arena= thd->stmt_arena; 01007 01008 /* 01009 We have to save/restore this info when we are changing call level to 01010 be able properly do close_thread_tables() in instructions. 01011 */ 01012 old_query_id= thd->query_id; 01013 old_derived_tables= thd->derived_tables; 01014 thd->derived_tables= 0; 01015 save_sql_mode= thd->variables.sql_mode; 01016 thd->variables.sql_mode= m_sql_mode; 01017 save_abort_on_warning= thd->abort_on_warning; 01018 thd->abort_on_warning= 01019 (m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)); 01020 01021 /* 01022 It is also more efficient to save/restore current thd->lex once when 01023 do it in each instruction 01024 */ 01025 old_lex= thd->lex; 01026 /* 01027 We should also save Item tree change list to avoid rollback something 01028 too early in the calling query. 01029 */ 01030 old_change_list= thd->change_list; 01031 thd->change_list.empty(); 01032 /* 01033 Cursors will use thd->packet, so they may corrupt data which was prepared 01034 for sending by upper level. OTOH cursors in the same routine can share this 01035 buffer safely so let use use routine-local packet instead of having own 01036 packet buffer for each cursor. 01037 01038 It is probably safe to use same thd->convert_buff everywhere. 01039 */ 01040 old_packet.swap(thd->packet); 01041 01042 /* 01043 Switch to per-instruction arena here. We can do it since we cleanup 01044 arena after every instruction. 01045 */ 01046 thd->set_n_backup_active_arena(&execute_arena, &backup_arena); 01047 01048 /* 01049 Save callers arena in order to store instruction results and out 01050 parameters in it later during sp_eval_func_item() 01051 */ 01052 thd->spcont->callers_arena= &backup_arena; 01053 01054 do 01055 { 01056 sp_instr *i; 01057 uint hip; // Handler ip 01058 01059 i = get_instr(ip); // Returns NULL when we're done. 01060 if (i == NULL) 01061 break; 01062 DBUG_PRINT("execute", ("Instruction %u", ip)); 01063 /* Don't change NOW() in FUNCTION or TRIGGER */ 01064 if (!thd->in_sub_stmt) 01065 thd->set_time(); // Make current_time() et al work 01066 01067 /* 01068 We have to set thd->stmt_arena before executing the instruction 01069 to store in the instruction free_list all new items, created 01070 during the first execution (for example expanding of '*' or the 01071 items made during other permanent subquery transformations). 01072 */ 01073 thd->stmt_arena= i; 01074 01075 /* 01076 Will write this SP statement into binlog separately 01077 (TODO: consider changing the condition to "not inside event union") 01078 */ 01079 if (thd->prelocked_mode == NON_PRELOCKED) 01080 thd->user_var_events_alloc= thd->mem_root; 01081 01082 err_status= i->execute(thd, &ip); 01083 01084 /* 01085 If this SP instruction have sent eof, it has caused no_send_error to be 01086 set. Clear it back to allow the next instruction to send error. (multi- 01087 statement execution code clears no_send_error between statements too) 01088 */ 01089 thd->net.no_send_error= 0; 01090 if (i->free_list) 01091 cleanup_items(i->free_list); 01092 01093 /* 01094 If we've set thd->user_var_events_alloc to mem_root of this SP 01095 statement, clean all the events allocated in it. 01096 */ 01097 if (thd->prelocked_mode == NON_PRELOCKED) 01098 { 01099 reset_dynamic(&thd->user_var_events); 01100 thd->user_var_events_alloc= NULL;//DEBUG 01101 } 01102 01103 /* we should cleanup free_list and memroot, used by instruction */ 01104 thd->cleanup_after_query(); 01105 free_root(&execute_mem_root, MYF(0)); 01106 01107 /* 01108 Check if an exception has occurred and a handler has been found 01109 Note: We have to check even if err_status == FALSE, since warnings (and 01110 some errors) don't return a non-zero value. We also have to check even 01111 if thd->killed != 0, since some errors return with this even when a 01112 handler has been found (e.g. "bad data"). 01113 */ 01114 if (ctx) 01115 { 01116 uint hf; 01117 01118 switch (ctx->found_handler(&hip, &hf)) { 01119 case SP_HANDLER_NONE: 01120 break; 01121 case SP_HANDLER_CONTINUE: 01122 thd->restore_active_arena(&execute_arena, &backup_arena); 01123 thd->set_n_backup_active_arena(&execute_arena, &backup_arena); 01124 ctx->push_hstack(ip); 01125 // Fall through 01126 default: 01127 ip= hip; 01128 err_status= FALSE; 01129 ctx->clear_handler(); 01130 ctx->enter_handler(hip); 01131 thd->clear_error(); 01132 thd->killed= THD::NOT_KILLED; 01133 continue; 01134 } 01135 } 01136 } while (!err_status && !thd->killed); 01137 01138 thd->restore_active_arena(&execute_arena, &backup_arena); 01139 01140 thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error 01141 01142 /* Restore all saved */ 01143 old_packet.swap(thd->packet); 01144 DBUG_ASSERT(thd->change_list.is_empty()); 01145 thd->change_list= old_change_list; 01146 /* To avoid wiping out thd->change_list on old_change_list destruction */ 01147 old_change_list.empty(); 01148 thd->lex= old_lex; 01149 thd->query_id= old_query_id; 01150 DBUG_ASSERT(!thd->derived_tables); 01151 thd->derived_tables= old_derived_tables; 01152 thd->variables.sql_mode= save_sql_mode; 01153 thd->abort_on_warning= save_abort_on_warning; 01154 01155 thd->stmt_arena= old_arena; 01156 state= EXECUTED; 01157 01158 done: 01159 DBUG_PRINT("info", ("err_status: %d killed: %d query_error: %d", 01160 err_status, thd->killed, thd->query_error)); 01161 01162 if (thd->killed) 01163 err_status= TRUE; 01164 /* 01165 If the DB has changed, the pointer has changed too, but the 01166 original thd->db will then have been freed 01167 */ 01168 if (dbchanged) 01169 { 01170 /* 01171 No access check when changing back to where we came from. 01172 (It would generate an error from mysql_change_db() when old_db=="") 01173 */ 01174 if (! thd->killed) 01175 err_status|= mysql_change_db(thd, old_db.str, 1); 01176 } 01177 m_flags&= ~IS_INVOKED; 01178 DBUG_PRINT("info", 01179 ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x", 01180 (ulong) m_first_instance, 01181 (ulong) m_first_instance->m_first_free_instance, 01182 (ulong) this, m_recursion_level, m_flags)); 01183 /* 01184 Check that we have one of following: 01185 01186 1) there are not free instances which means that this instance is last 01187 in the list of instances (pointer to the last instance point on it and 01188 ther are not other instances after this one in the list) 01189 01190 2) There are some free instances which mean that first free instance 01191 should go just after this one and recursion level of that free instance 01192 should be on 1 more then recursion level of this instance. 01193 */ 01194 DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 && 01195 this == m_first_instance->m_last_cached_sp && 01196 m_next_cached_sp == 0) || 01197 (m_first_instance->m_first_free_instance != 0 && 01198 m_first_instance->m_first_free_instance == m_next_cached_sp && 01199 m_first_instance->m_first_free_instance->m_recursion_level == 01200 m_recursion_level + 1)); 01201 m_first_instance->m_first_free_instance= this; 01202 01203 DBUG_RETURN(err_status); 01204 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1360 of file sp_head.cc.
References String::append(), append_identifier(), buf, sp_pcontext::context_var_count(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_SP_NORETURNEND, ER_SP_WRONG_NO_OF_ARGS, ER_UNKNOWN_ERROR, execute(), FALSE, free_root(), sp_rcontext::get_item(), sp_rcontext::init(), init_sql_alloc(), MYSQL_LOG::is_open(), sp_rcontext::is_return_value_set(), LEX_STRING::length, String::length(), LINT_INIT, m_name, m_pcont, m_qname, MEM_ROOT_BLOCK_SIZE, my_charset_bin, my_error(), MYF, mysql_bin_log, NULL, OPTION_BIN_LOG, String::ptr(), push_warning(), reset_dynamic, set_routine_security_ctx(), sp_rcontext::set_variable(), sp_rcontext::sp, sp_get_item_value(), sp_restore_security_context(), MYSQL_BIN_LOG::start_union_events(), MYSQL_BIN_LOG::stop_union_events(), LEX_STRING::str, STRING_BUFFER_USUAL_SIZE, STRING_WITH_LEN, TRUE, MYSQL_ERROR::WARN_LEVEL_WARN, and MYSQL_BIN_LOG::write().
Referenced by Item_func_sp::execute_impl().
01362 { 01363 ulonglong binlog_save_options; 01364 bool need_binlog_call; 01365 uint arg_no; 01366 sp_rcontext *octx = thd->spcont; 01367 sp_rcontext *nctx = NULL; 01368 char buf[STRING_BUFFER_USUAL_SIZE]; 01369 String binlog_buf(buf, sizeof(buf), &my_charset_bin); 01370 bool err_status= FALSE; 01371 MEM_ROOT call_mem_root; 01372 Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); 01373 Query_arena backup_arena; 01374 01375 DBUG_ENTER("sp_head::execute_function"); 01376 DBUG_PRINT("info", ("function %s", m_name.str)); 01377 01378 LINT_INIT(binlog_save_options); 01379 01380 /* 01381 Check that the function is called with all specified arguments. 01382 01383 If it is not, use my_error() to report an error, or it will not terminate 01384 the invoking query properly. 01385 */ 01386 if (argcount != m_pcont->context_var_count()) 01387 { 01388 /* 01389 Need to use my_error here, or it will not terminate the 01390 invoking query properly. 01391 */ 01392 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), 01393 "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount); 01394 DBUG_RETURN(TRUE); 01395 } 01396 /* 01397 Prepare arena and memroot for objects which lifetime is whole 01398 duration of function call (sp_rcontext, it's tables and items, 01399 sp_cursor and Item_cache holders for case expressions). 01400 We can't use caller's arena/memroot for those objects because 01401 in this case some fixed amount of memory will be consumed for 01402 each function/trigger invocation and so statements which involve 01403 lot of them will hog memory. 01404 TODO: we should create sp_rcontext once per command and reuse 01405 it on subsequent executions of a function/trigger. 01406 */ 01407 init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); 01408 thd->set_n_backup_active_arena(&call_arena, &backup_arena); 01409 01410 if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) || 01411 nctx->init(thd)) 01412 { 01413 thd->restore_active_arena(&call_arena, &backup_arena); 01414 err_status= TRUE; 01415 goto err_with_cleanup; 01416 } 01417 01418 /* 01419 We have to switch temporarily back to callers arena/memroot. 01420 Function arguments belong to the caller and so the may reference 01421 memory which they will allocate during calculation long after 01422 this function call will be finished (e.g. in Item::cleanup()). 01423 */ 01424 thd->restore_active_arena(&call_arena, &backup_arena); 01425 01426 #ifndef DBUG_OFF 01427 nctx->sp= this; 01428 #endif 01429 01430 /* Pass arguments. */ 01431 for (arg_no= 0; arg_no < argcount; arg_no++) 01432 { 01433 /* Arguments must be fixed in Item_func_sp::fix_fields */ 01434 DBUG_ASSERT(argp[arg_no]->fixed); 01435 01436 if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no])))) 01437 goto err_with_cleanup; 01438 } 01439 01440 /* 01441 If row-based binlogging, we don't need to binlog the function's call, let 01442 each substatement be binlogged its way. 01443 */ 01444 need_binlog_call= mysql_bin_log.is_open() && 01445 (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based; 01446 01447 /* 01448 Remember the original arguments for unrolled replication of functions 01449 before they are changed by execution. 01450 */ 01451 if (need_binlog_call) 01452 { 01453 binlog_buf.length(0); 01454 binlog_buf.append(STRING_WITH_LEN("SELECT ")); 01455 append_identifier(thd, &binlog_buf, m_name.str, m_name.length); 01456 binlog_buf.append('('); 01457 for (arg_no= 0; arg_no < argcount; arg_no++) 01458 { 01459 String str_value_holder; 01460 String *str_value; 01461 01462 if (arg_no) 01463 binlog_buf.append(','); 01464 01465 str_value= sp_get_item_value(nctx->get_item(arg_no), 01466 &str_value_holder); 01467 01468 if (str_value) 01469 binlog_buf.append(*str_value); 01470 else 01471 binlog_buf.append(STRING_WITH_LEN("NULL")); 01472 } 01473 binlog_buf.append(')'); 01474 } 01475 thd->spcont= nctx; 01476 01477 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01478 Security_context *save_security_ctx; 01479 if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx)) 01480 { 01481 err_status= TRUE; 01482 goto err_with_cleanup; 01483 } 01484 #endif 01485 01486 if (need_binlog_call) 01487 { 01488 reset_dynamic(&thd->user_var_events); 01489 mysql_bin_log.start_union_events(thd); 01490 binlog_save_options= thd->options; 01491 thd->options&= ~OPTION_BIN_LOG; 01492 } 01493 01494 /* 01495 Switch to call arena/mem_root so objects like sp_cursor or 01496 Item_cache holders for case expressions can be allocated on it. 01497 01498 TODO: In future we should associate call arena/mem_root with 01499 sp_rcontext and allocate all these objects (and sp_rcontext 01500 itself) on it directly rather than juggle with arenas. 01501 */ 01502 thd->set_n_backup_active_arena(&call_arena, &backup_arena); 01503 01504 err_status= execute(thd); 01505 01506 thd->restore_active_arena(&call_arena, &backup_arena); 01507 01508 if (need_binlog_call) 01509 { 01510 mysql_bin_log.stop_union_events(thd); 01511 thd->options= binlog_save_options; 01512 if (thd->binlog_evt_union.unioned_events) 01513 { 01514 Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(), 01515 thd->binlog_evt_union.unioned_events_trans, FALSE); 01516 if (mysql_bin_log.write(&qinfo) && 01517 thd->binlog_evt_union.unioned_events_trans) 01518 { 01519 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, 01520 "Invoked ROUTINE modified a transactional table but MySQL " 01521 "failed to reflect this change in the binary log"); 01522 } 01523 reset_dynamic(&thd->user_var_events); 01524 } 01525 } 01526 01527 if (!err_status) 01528 { 01529 /* We need result only in function but not in trigger */ 01530 01531 if (!nctx->is_return_value_set()) 01532 { 01533 my_error(ER_SP_NORETURNEND, MYF(0), m_name.str); 01534 err_status= TRUE; 01535 } 01536 } 01537 01538 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01539 sp_restore_security_context(thd, save_security_ctx); 01540 #endif 01541 01542 err_with_cleanup: 01543 delete nctx; 01544 call_arena.free_items(); 01545 free_root(&call_mem_root, MYF(0)); 01546 thd->spcont= octx; 01547 01548 DBUG_RETURN(err_status); 01549 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1574 of file sp_head.cc.
References args, sp_rcontext::callers_arena, close_thread_tables(), sp_pcontext::context_var_count(), DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_SP_NOT_VAR_ARG, ER_SP_WRONG_NO_OF_ARGS, execute(), FALSE, sp_rcontext::get_item_addr(), sp_rcontext::init(), LEX_STRING::length, LOG_GENERAL_LOG, LOG_SLOW_STATEMENTS, m_flags, m_name, m_pcont, m_qname, sp_variable::mode, my_error(), MYF, NULL, OPTION_LOG_OFF, List_iterator< T >::ref(), Settable_routine_parameter::set_required_privilege(), set_routine_security_ctx(), Settable_routine_parameter::set_value(), sp_rcontext::set_variable(), sp_rcontext::sp, sp_param_in, sp_param_inout, sp_param_out, sp_restore_security_context(), LEX_STRING::str, and TRUE.
Referenced by Event_timed::execute(), and mysql_execute_command().
01575 { 01576 bool err_status= FALSE; 01577 uint params = m_pcont->context_var_count(); 01578 sp_rcontext *save_spcont, *octx; 01579 sp_rcontext *nctx = NULL; 01580 bool save_enable_slow_log= false; 01581 bool save_log_general= false; 01582 DBUG_ENTER("sp_head::execute_procedure"); 01583 DBUG_PRINT("info", ("procedure %s", m_name.str)); 01584 01585 if (args->elements != params) 01586 { 01587 my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE", 01588 m_qname.str, params, args->elements); 01589 DBUG_RETURN(TRUE); 01590 } 01591 01592 save_spcont= octx= thd->spcont; 01593 if (! octx) 01594 { // Create a temporary old context 01595 if (!(octx= new sp_rcontext(m_pcont, NULL, octx)) || 01596 octx->init(thd)) 01597 { 01598 delete octx; /* Delete octx if it was init() that failed. */ 01599 DBUG_RETURN(TRUE); 01600 } 01601 01602 #ifndef DBUG_OFF 01603 octx->sp= 0; 01604 #endif 01605 thd->spcont= octx; 01606 01607 /* set callers_arena to thd, for upper-level function to work */ 01608 thd->spcont->callers_arena= thd; 01609 } 01610 01611 if (!(nctx= new sp_rcontext(m_pcont, NULL, octx)) || 01612 nctx->init(thd)) 01613 { 01614 delete nctx; /* Delete nctx if it was init() that failed. */ 01615 thd->spcont= save_spcont; 01616 DBUG_RETURN(TRUE); 01617 } 01618 #ifndef DBUG_OFF 01619 nctx->sp= this; 01620 #endif 01621 01622 if (params > 0) 01623 { 01624 List_iterator<Item> it_args(*args); 01625 01626 DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str)); 01627 01628 for (uint i= 0 ; i < params ; i++) 01629 { 01630 Item *arg_item= it_args++; 01631 01632 if (!arg_item) 01633 break; 01634 01635 sp_variable_t *spvar= m_pcont->find_variable(i); 01636 01637 if (!spvar) 01638 continue; 01639 01640 if (spvar->mode != sp_param_in) 01641 { 01642 Settable_routine_parameter *srp= 01643 arg_item->get_settable_routine_parameter(); 01644 01645 if (!srp) 01646 { 01647 my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str); 01648 err_status= TRUE; 01649 break; 01650 } 01651 01652 srp->set_required_privilege(spvar->mode == sp_param_inout); 01653 } 01654 01655 if (spvar->mode == sp_param_out) 01656 { 01657 Item_null *null_item= new Item_null(); 01658 01659 if (!null_item || 01660 nctx->set_variable(thd, i, (struct Item **)&null_item)) 01661 { 01662 err_status= TRUE; 01663 break; 01664 } 01665 } 01666 else 01667 { 01668 if (nctx->set_variable(thd, i, it_args.ref())) 01669 { 01670 err_status= TRUE; 01671 break; 01672 } 01673 } 01674 } 01675 01676 /* 01677 Okay, got values for all arguments. Close tables that might be used by 01678 arguments evaluation. If arguments evaluation required prelocking mode, 01679 we'll leave it here. 01680 */ 01681 if (!thd->in_sub_stmt) 01682 close_thread_tables(thd, 0, 0); 01683 01684 DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str)); 01685 } 01686 if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log) 01687 { 01688 DBUG_PRINT("info", ("Disabling slow log for the execution")); 01689 save_enable_slow_log= true; 01690 thd->enable_slow_log= FALSE; 01691 } 01692 if (!(m_flags & LOG_GENERAL_LOG) && !(thd->options & OPTION_LOG_OFF)) 01693 { 01694 DBUG_PRINT("info", ("Disabling general log for the execution")); 01695 save_log_general= true; 01696 /* disable this bit */ 01697 thd->options |= OPTION_LOG_OFF; 01698 } 01699 thd->spcont= nctx; 01700 01701 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01702 Security_context *save_security_ctx= 0; 01703 if (!err_status) 01704 err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx); 01705 #endif 01706 01707 if (!err_status) 01708 err_status= execute(thd); 01709 01710 if (save_log_general) 01711 thd->options &= ~OPTION_LOG_OFF; 01712 if (save_enable_slow_log) 01713 thd->enable_slow_log= true; 01714 /* 01715 In the case when we weren't able to employ reuse mechanism for 01716 OUT/INOUT paranmeters, we should reallocate memory. This 01717 allocation should be done on the arena which will live through 01718 all execution of calling routine. 01719 */ 01720 thd->spcont->callers_arena= octx->callers_arena; 01721 01722 if (!err_status && params > 0) 01723 { 01724 List_iterator<Item> it_args(*args); 01725 01726 /* 01727 Copy back all OUT or INOUT values to the previous frame, or 01728 set global user variables 01729 */ 01730 for (uint i= 0 ; i < params ; i++) 01731 { 01732 Item *arg_item= it_args++; 01733 01734 if (!arg_item) 01735 break; 01736 01737 sp_variable_t *spvar= m_pcont->find_variable(i); 01738 01739 if (spvar->mode == sp_param_in) 01740 continue; 01741 01742 Settable_routine_parameter *srp= 01743 arg_item->get_settable_routine_parameter(); 01744 01745 DBUG_ASSERT(srp); 01746 01747 if (srp->set_value(thd, octx, nctx->get_item_addr(i))) 01748 { 01749 err_status= TRUE; 01750 break; 01751 } 01752 } 01753 } 01754 01755 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01756 if (save_security_ctx) 01757 sp_restore_security_context(thd, save_security_ctx); 01758 #endif 01759 01760 if (!save_spcont) 01761 delete octx; 01762 01763 delete nctx; 01764 thd->spcont= save_spcont; 01765 01766 DBUG_RETURN(err_status); 01767 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool sp_head::execute_trigger | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table, | |||
| GRANT_INFO * | grant_onfo | |||
| ) |
Definition at line 1281 of file sp_head.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, execute(), FALSE, free_root(), sp_rcontext::init(), init_sql_alloc(), m_name, m_pcont, MEM_ROOT_BLOCK_SIZE, MYF, NULL, sp_rcontext::sp, LEX_STRING::str, and TRUE.
Referenced by Table_triggers_list::process_triggers().
01283 { 01284 sp_rcontext *octx = thd->spcont; 01285 sp_rcontext *nctx = NULL; 01286 bool err_status= FALSE; 01287 MEM_ROOT call_mem_root; 01288 Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); 01289 Query_arena backup_arena; 01290 01291 DBUG_ENTER("sp_head::execute_trigger"); 01292 DBUG_PRINT("info", ("trigger %s", m_name.str)); 01293 01294 /* 01295 Prepare arena and memroot for objects which lifetime is whole 01296 duration of trigger call (sp_rcontext, it's tables and items, 01297 sp_cursor and Item_cache holders for case expressions). We can't 01298 use caller's arena/memroot for those objects because in this case 01299 some fixed amount of memory will be consumed for each trigger 01300 invocation and so statements which involve lot of them will hog 01301 memory. 01302 01303 TODO: we should create sp_rcontext once per command and reuse it 01304 on subsequent executions of a trigger. 01305 */ 01306 init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); 01307 thd->set_n_backup_active_arena(&call_arena, &backup_arena); 01308 01309 if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) || 01310 nctx->init(thd)) 01311 { 01312 err_status= TRUE; 01313 goto err_with_cleanup; 01314 } 01315 01316 #ifndef DBUG_OFF 01317 nctx->sp= this; 01318 #endif 01319 01320 thd->spcont= nctx; 01321 01322 err_status= execute(thd); 01323 01324 err_with_cleanup: 01325 thd->restore_active_arena(&call_arena, &backup_arena); 01326 delete nctx; 01327 call_arena.free_items(); 01328 free_root(&call_mem_root, MYF(0)); 01329 thd->spcont= octx; 01330 01331 DBUG_RETURN(err_status); 01332 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool sp_head::fill_field_definition | ( | THD * | thd, | |
| LEX * | lex, | |||
| enum enum_field_types | field_type, | |||
| create_field * | field_def | |||
| ) |
Definition at line 1907 of file sp_head.cc.
References create_typelib(), st_ha_create_information::default_table_charset, base_list::elements, FALSE, HA_CAN_GEOMETRY, create_field::init(), create_field::interval, create_field::interval_list, load_db_opt_by_name(), m_db, prepare_create_field(), sp_prepare_create_field(), LEX_STRING::str, and TRUE.
01910 { 01911 HA_CREATE_INFO sp_db_info; 01912 LEX_STRING cmt = { 0, 0 }; 01913 uint unused1= 0; 01914 int unused2= 0; 01915 01916 load_db_opt_by_name(thd, m_db.str, &sp_db_info); 01917 01918 if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec, 01919 lex->type, (Item*) 0, (Item*) 0, &cmt, 0, 01920 &lex->interval_list, 01921 (lex->charset ? lex->charset : 01922 sp_db_info.default_table_charset), 01923 lex->uint_geom_type)) 01924 return TRUE; 01925 01926 if (field_def->interval_list.elements) 01927 field_def->interval= create_typelib(mem_root, field_def, 01928 &field_def->interval_list); 01929 01930 sp_prepare_create_field(thd, field_def); 01931 01932 if (prepare_create_field(field_def, &unused1, &unused2, &unused2, 01933 HA_CAN_GEOMETRY)) 01934 { 01935 return TRUE; 01936 } 01937 01938 return FALSE; 01939 }
Here is the call graph for this function:

Definition at line 311 of file sp_head.h.
References st_dynamic_array::elements, get_dynamic(), m_instr, and NULL.
Referenced by create(), destroy(), execute(), sp_instr_set_case_expr::opt_mark(), sp_instr_hpush_jump::opt_mark(), sp_instr_jump_if_not::opt_mark(), sp_instr_jump::opt_mark(), opt_mark(), sp_instr_jump::opt_shortcut_jump(), optimize(), and show_routine_code().
00312 { 00313 sp_instr *ip; 00314 00315 if (i < m_instr.elements) 00316 get_dynamic(&m_instr, (gptr)&ip, i); 00317 else 00318 ip= NULL; 00319 return ip; 00320 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::init | ( | LEX * | lex | ) |
Definition at line 481 of file sp_head.cc.
References create_field::charset, DBUG_ENTER, DBUG_VOID_RETURN, LEX_STRING::length, m_body, m_body_begin, m_db, m_defstr, m_instr, m_name, m_param_begin, m_param_end, m_params, m_pcont, m_qname, m_return_field_def, my_init_dynamic_array, NULL, and LEX_STRING::str.
00482 { 00483 DBUG_ENTER("sp_head::init"); 00484 00485 lex->spcont= m_pcont= new sp_pcontext(NULL); 00486 00487 /* 00488 Altough trg_table_fields list is used only in triggers we init for all 00489 types of stored procedures to simplify reset_lex()/restore_lex() code. 00490 */ 00491 lex->trg_table_fields.empty(); 00492 my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); 00493 m_param_begin= m_param_end= m_body_begin= 0; 00494 m_qname.str= m_db.str= m_name.str= m_params.str= 00495 m_body.str= m_defstr.str= 0; 00496 m_qname.length= m_db.length= m_name.length= m_params.length= 00497 m_body.length= m_defstr.length= 0; 00498 m_return_field_def.charset= NULL; 00499 DBUG_VOID_RETURN; 00500 }
| void sp_head::init_sp_name | ( | THD * | thd, | |
| sp_name * | spname | |||
| ) |
Definition at line 504 of file sp_head.cc.
References DBUG_ASSERT, DBUG_ENTER, DBUG_VOID_RETURN, sp_name::init_qname(), LEX_STRING::length, m_db, sp_name::m_db, sp_name::m_name, m_name, m_qname, sp_name::m_qname, LEX_STRING::str, and strmake_root().
00505 { 00506 DBUG_ENTER("sp_head::init_sp_name"); 00507 00508 /* Must be initialized in the parser. */ 00509 00510 DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length); 00511 00512 /* We have to copy strings to get them into the right memroot. */ 00513 00514 m_db.length= spname->m_db.length; 00515 m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length); 00516 00517 m_name.length= spname->m_name.length; 00518 m_name.str= strmake_root(thd->mem_root, spname->m_name.str, 00519 spname->m_name.length); 00520 00521 if (spname->m_qname.length == 0) 00522 spname->init_qname(thd); 00523 00524 m_qname.length= spname->m_qname.length; 00525 m_qname.str= strmake_root(thd->mem_root, spname->m_qname.str, 00526 m_qname.length); 00527 00528 DBUG_VOID_RETURN; 00529 }
Here is the call graph for this function:

| void sp_head::init_strings | ( | THD * | thd, | |
| LEX * | lex | |||
| ) |
Definition at line 533 of file sp_head.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, LEX_STRING::length, m_body, m_body_begin, m_defstr, m_param_begin, m_param_end, m_params, skip_rear_comments(), LEX_STRING::str, and strmake_root().
00534 { 00535 DBUG_ENTER("sp_head::init_strings"); 00536 const uchar *endp; /* Used to trim the end */ 00537 /* During parsing, we must use thd->mem_root */ 00538 MEM_ROOT *root= thd->mem_root; 00539 00540 if (m_param_begin && m_param_end) 00541 { 00542 m_params.length= m_param_end - m_param_begin; 00543 m_params.str= strmake_root(root, 00544 (char *)m_param_begin, m_params.length); 00545 } 00546 00547 /* If ptr has overrun end_of_query then end_of_query is the end */ 00548 endp= (lex->ptr > lex->end_of_query ? lex->end_of_query : lex->ptr); 00549 /* 00550 Trim "garbage" at the end. This is sometimes needed with the 00551 "/ * ! VERSION... * /" wrapper in dump files. 00552 */ 00553 endp= skip_rear_comments(m_body_begin, endp); 00554 00555 m_body.length= endp - m_body_begin; 00556 m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length); 00557 m_defstr.length= endp - lex->buf; 00558 m_defstr.str= strmake_root(root, (char *)lex->buf, m_defstr.length); 00559 DBUG_VOID_RETURN; 00560 }
Here is the call graph for this function:

| uint sp_head::instructions | ( | ) | [inline] |
Definition at line 235 of file sp_head.h.
References st_dynamic_array::elements, and m_instr.
Referenced by backpatch(), and do_cont_backpatch().
Here is the caller graph for this function:

| bool sp_head::is_not_allowed_in_function | ( | const char * | where | ) | [inline] |
Definition at line 332 of file sp_head.h.
References CONTAINS_DYNAMIC_SQL, ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, ER_SP_CANT_SET_AUTOCOMMIT, ER_SP_NO_RETSET, ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, HAS_COMMIT_OR_ROLLBACK, HAS_SET_AUTOCOMMIT_STMT, m_flags, m_type, MULTI_RESULTS, my_error(), MYF, test, TRUE, and TYPE_ENUM_PROCEDURE.
Referenced by mysql_execute_command().
00333 { 00334 if (m_flags & CONTAINS_DYNAMIC_SQL) 00335 my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "Dynamic SQL"); 00336 else if (m_flags & MULTI_RESULTS) 00337 my_error(ER_SP_NO_RETSET, MYF(0), where); 00338 else if (m_flags & HAS_SET_AUTOCOMMIT_STMT) 00339 my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0)); 00340 else if (m_type != TYPE_ENUM_PROCEDURE && 00341 (m_flags & sp_head::HAS_COMMIT_OR_ROLLBACK)) 00342 { 00343 my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); 00344 return TRUE; 00345 } 00346 return test(m_flags & 00347 (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT)); 00348 }
Here is the call graph for this function:

Here is the caller graph for this function:

| sp_instr* sp_head::last_instruction | ( | ) | [inline] |
Definition at line 241 of file sp_head.h.
References st_dynamic_array::elements, get_dynamic(), and m_instr.
00242 { 00243 sp_instr *i; 00244 00245 get_dynamic(&m_instr, (gptr)&i, m_instr.elements-1); 00246 return i; 00247 }
Here is the call graph for this function:

| bool sp_head::merge_table_list | ( | THD * | thd, | |
| TABLE_LIST * | table, | |||
| LEX * | lex_for_tmp_check | |||
| ) | [private] |
Definition at line 3437 of file sp_head.cc.
References st_table_list::alias, st_table_list::db, st_table_list::db_length, st_table_list::derived, hash_element(), hash_search(), st_sp_table::lock_count, st_table_list::lock_type, st_sp_table::lock_type, m_sptabs, memcpy, NAME_LEN, st_table_list::next_global, st_sp_table::query_lock_count, st_hash::records, st_table_list::schema_table, SQLCOM_DROP_TABLE, strlen(), st_table_list::table_name, st_table_list::table_name_length, st_sp_table::temp, and TRUE.
Referenced by restore_lex().
03438 { 03439 SP_TABLE *tab; 03440 03441 if (lex_for_tmp_check->sql_command == SQLCOM_DROP_TABLE && 03442 lex_for_tmp_check->drop_temporary) 03443 return TRUE; 03444 03445 for (uint i= 0 ; i < m_sptabs.records ; i++) 03446 { 03447 tab= (SP_TABLE *)hash_element(&m_sptabs, i); 03448 tab->query_lock_count= 0; 03449 } 03450 03451 for (; table ; table= table->next_global) 03452 if (!table->derived && !table->schema_table) 03453 { 03454 char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0 03455 uint tlen, alen; 03456 03457 tlen= table->db_length; 03458 memcpy(tname, table->db, tlen); 03459 tname[tlen++]= '\0'; 03460 memcpy(tname+tlen, table->table_name, table->table_name_length); 03461 tlen+= table->table_name_length; 03462 tname[tlen++]= '\0'; 03463 alen= strlen(table->alias); 03464 memcpy(tname+tlen, table->alias, alen); 03465 tlen+= alen; 03466 tname[tlen]= '\0'; 03467 03468 /* 03469 We ignore alias when we check if table was already marked as temporary 03470 (and therefore should not be prelocked). Otherwise we will erroneously 03471 treat table with same name but with different alias as non-temporary. 03472 */ 03473 if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)) || 03474 ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, 03475 tlen - alen - 1)) && 03476 tab->temp)) 03477 { 03478 if (tab->lock_type < table->lock_type) 03479 tab->lock_type= table->lock_type; // Use the table with the highest lock type 03480 tab->query_lock_count++; 03481 if (tab->query_lock_count > tab->lock_count) 03482 tab->lock_count++; 03483 } 03484 else 03485 { 03486 if (!(tab= (SP_TABLE *)thd->calloc(sizeof(SP_TABLE)))) 03487 return FALSE; 03488 if (lex_for_tmp_check->sql_command == SQLCOM_CREATE_TABLE && 03489 lex_for_tmp_check->query_tables == table && 03490 lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) 03491 { 03492 tab->temp= TRUE; 03493 tab->qname.length= tlen - alen - 1; 03494 } 03495 else 03496 tab->qname.length= tlen; 03497 tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1); 03498 if (!tab->qname.str) 03499 return FALSE; 03500 tab->table_name_length= table->table_name_length; 03501 tab->db_length= table->db_length; 03502 tab->lock_type= table->lock_type; 03503 tab->lock_count= tab->query_lock_count= 1; 03504 my_hash_insert(&m_sptabs, (byte *)tab); 03505 } 03506 } 03507 return TRUE; 03508 }
Here is the call graph for this function:

Here is the caller graph for this function:

| char* sp_head::name | ( | uint * | lenp = 0 |
) | const [inline] |
Definition at line 279 of file sp_head.h.
References LEX_STRING::length, m_name, and LEX_STRING::str.
| void sp_head::new_cont_backpatch | ( | sp_instr_opt_meta * | i | ) |
Definition at line 1943 of file sp_head.cc.
References m_cont_backpatch, sp_instr_opt_meta::m_cont_dest, m_cont_level, and List< T >::push_front().
01944 { 01945 m_cont_level+= 1; 01946 if (i) 01947 { 01948 /* Use the cont. destination slot to store the level */ 01949 i->m_cont_dest= m_cont_level; 01950 (void)m_cont_backpatch.push_front(i); 01951 } 01952 }
Here is the call graph for this function:

| void sp_head::operator delete | ( | void * | ptr, | |
| size_t | size | |||
| ) | [static] |
Definition at line 436 of file sp_head.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, free_root(), main_mem_root, and MYF.
00437 { 00438 DBUG_ENTER("sp_head::operator delete"); 00439 MEM_ROOT own_root; 00440 sp_head *sp= (sp_head *) ptr; 00441 00442 /* Make a copy of main_mem_root as free_root will free the sp */ 00443 own_root= sp->main_mem_root; 00444 DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx", 00445 (ulong) &sp->mem_root, (ulong) &own_root)); 00446 free_root(&own_root, MYF(0)); 00447 00448 DBUG_VOID_RETURN; 00449 }
Here is the call graph for this function:

| void * sp_head::operator new | ( | size_t | size | ) | [static] |
Definition at line 422 of file sp_head.cc.
References alloc_root(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, init_alloc_root(), main_mem_root, MEM_ROOT_BLOCK_SIZE, and MEM_ROOT_PREALLOC.
00423 { 00424 DBUG_ENTER("sp_head::operator new"); 00425 MEM_ROOT own_root; 00426 sp_head *sp; 00427 00428 init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); 00429 sp= (sp_head *) alloc_root(&own_root, size); 00430 sp->main_mem_root= own_root; 00431 DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); 00432 DBUG_RETURN(sp); 00433 }
Here is the call graph for this function:

| void sp_head::operator= | ( | sp_head & | ) | [private] |
| void sp_head::opt_mark | ( | uint | ip | ) |
Definition at line 2259 of file sp_head.cc.
References get_instr(), sp_instr::marked, and sp_instr::opt_mark().
Referenced by sp_instr_set_case_expr::opt_mark(), sp_instr_hpush_jump::opt_mark(), sp_instr_jump_if_not::opt_mark(), and optimize().
02260 { 02261 sp_instr *i; 02262 02263 while ((i= get_instr(ip)) && !i->marked) 02264 ip= i->opt_mark(this); 02265 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::optimize | ( | ) |
Definition at line 2218 of file sp_head.cc.
References st_dynamic_array::elements, base_list::empty(), get_instr(), m_instr, sp_instr::marked, opt_mark(), sp_instr::opt_move(), sp_instr_opt_meta::set_destination(), and set_dynamic().
Referenced by Event_timed::compile(), and create().
02219 { 02220 List<sp_instr> bp; 02221 sp_instr *i; 02222 uint src, dst; 02223 02224 opt_mark(0); 02225 02226 bp.empty(); 02227 src= dst= 0; 02228 while ((i= get_instr(src))) 02229 { 02230 if (! i->marked) 02231 { 02232 delete i; 02233 src+= 1; 02234 } 02235 else 02236 { 02237 if (src != dst) 02238 { // Move the instruction and update prev. jumps 02239 sp_instr *ibp; 02240 List_iterator_fast<sp_instr> li(bp); 02241 02242 set_dynamic(&m_instr, (gptr)&i, dst); 02243 while ((ibp= li++)) 02244 { 02245 sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp); 02246 im->set_destination(src, dst); 02247 } 02248 } 02249 i->opt_move(dst, &bp); 02250 src+= 1; 02251 dst+= 1; 02252 } 02253 } 02254 m_instr.elements= dst; 02255 bp.empty(); 02256 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::propagate_attributes | ( | LEX * | lex | ) | [inline] |
Definition at line 359 of file sp_head.h.
References BINLOG_ROW_BASED_IF_MIXED, m_flags, and TRUE.
00360 { 00361 #ifdef HAVE_ROW_BASED_REPLICATION 00362 /* 00363 If this routine needs row-based binary logging, the entire top statement 00364 too (we cannot switch from statement-based to row-based only for this 00365 routine, as in statement-based the top-statement may be binlogged and 00366 the substatements not). 00367 */ 00368 if (m_flags & BINLOG_ROW_BASED_IF_MIXED) 00369 lex->binlog_row_based_if_mixed= TRUE; 00370 #endif 00371 }
Definition at line 1864 of file sp_head.cc.
References sp_head::bp_t::instr, sp_head::bp_t::lab, m_backpatch, and sql_alloc().
01865 { 01866 bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t)); 01867 01868 if (bp) 01869 { 01870 bp->lab= lab; 01871 bp->instr= i; 01872 (void)m_backpatch.push_front(bp); 01873 } 01874 }
Here is the call graph for this function:

| void sp_head::recursion_level_error | ( | THD * | thd | ) |
Definition at line 924 of file sp_head.cc.
References ER_SP_NO_RECURSION, ER_SP_RECURSION_LIMIT, m_name, m_type, my_error(), MYF, LEX_STRING::str, and TYPE_ENUM_PROCEDURE.
00925 { 00926 if (m_type == TYPE_ENUM_PROCEDURE) 00927 { 00928 my_error(ER_SP_RECURSION_LIMIT, MYF(0), 00929 thd->variables.max_sp_recursion_depth, 00930 m_name.str); 00931 } 00932 else 00933 my_error(ER_SP_NO_RECURSION, MYF(0)); 00934 }
Here is the call graph for this function:

| void sp_head::reset_lex | ( | THD * | thd | ) |
Definition at line 1772 of file sp_head.cc.
References DBUG_ENTER, DBUG_VOID_RETURN, FALSE, lex_start(), m_lex, NULL, and List< T >::push_front().
01773 { 01774 DBUG_ENTER("sp_head::reset_lex"); 01775 LEX *sublex; 01776 LEX *oldlex= thd->lex; 01777 my_lex_states state= oldlex->next_state; // Keep original next_state 01778 01779 (void)m_lex.push_front(oldlex); 01780 thd->lex= sublex= new st_lex; 01781 01782 /* Reset most stuff. The length arguments doesn't matter here. */ 01783 lex_start(thd, oldlex->buf, (ulong) (oldlex->end_of_query - oldlex->ptr)); 01784 01785 /* 01786 * next_state is normally the same (0), but it happens that we swap lex in 01787 * "mid-sentence", so we must restore it. 01788 */ 01789 sublex->next_state= state; 01790 /* We must reset ptr and end_of_query again */ 01791 sublex->ptr= oldlex->ptr; 01792 sublex->end_of_query= oldlex->end_of_query; 01793 sublex->tok_start= oldlex->tok_start; 01794 sublex->tok_end= oldlex->tok_end; 01795 sublex->yylineno= oldlex->yylineno; 01796 /* And keep the SP stuff too */ 01797 sublex->sphead= oldlex->sphead; 01798 sublex->spcont= oldlex->spcont; 01799 /* And trigger related stuff too */ 01800 sublex->trg_chistics= oldlex->trg_chistics; 01801 sublex->trg_table_fields.empty(); 01802 sublex->sp_lex_in_use= FALSE; 01803 01804 sublex->in_comment= oldlex->in_comment; 01805 01806 /* Reset type info. */ 01807 01808 sublex->charset= NULL; 01809 sublex->length= NULL; 01810 sublex->dec= NULL; 01811 sublex->interval_list.empty(); 01812 sublex->type= 0; 01813 01814 DBUG_VOID_RETURN; 01815 }
Here is the call graph for this function:

| void sp_head::reset_thd_mem_root | ( | THD * | thd | ) |
Definition at line 2021 of file sp_head.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, free_list(), m_thd, m_thd_root, main_mem_root, and NULL.
02022 { 02023 DBUG_ENTER("sp_head::reset_thd_mem_root"); 02024 m_thd_root= thd->mem_root; 02025 thd->mem_root= &main_mem_root; 02026 DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx", 02027 (ulong) &mem_root, (ulong) &thd->mem_root)); 02028 free_list= thd->free_list; // Keep the old list 02029 thd->free_list= NULL; // Start a new one 02030 m_thd= thd; 02031 DBUG_VOID_RETURN; 02032 }
Here is the call graph for this function:

| void sp_head::restore_lex | ( | THD * | thd | ) |
Definition at line 1819 of file sp_head.cc.
References BINLOG_ROW_BASED_IF_MIXED, DBUG_ENTER, DBUG_VOID_RETURN, lex_end(), m_flags, m_lex, m_sroutines, merge_table_list(), List< T >::pop(), and sp_update_sp_used_routines().
01820 { 01821 DBUG_ENTER("sp_head::restore_lex"); 01822 LEX *sublex= thd->lex; 01823 LEX *oldlex= (LEX *)m_lex.pop(); 01824 01825 if (! oldlex) 01826 return; // Nothing to restore 01827 01828 // Update some state in the old one first 01829 oldlex->ptr= sublex->ptr; 01830 oldlex->tok_end= sublex->tok_end; 01831 oldlex->next_state= sublex->next_state; 01832 oldlex->trg_table_fields.push_back(&sublex->trg_table_fields); 01833 01834 #ifdef HAVE_ROW_BASED_REPLICATION 01835 /* 01836 If this substatement needs row-based, the entire routine does too (we 01837 cannot switch from statement-based to row-based only for this 01838 substatement). 01839 */ 01840 if (sublex->binlog_row_based_if_mixed) 01841 m_flags|= BINLOG_ROW_BASED_IF_MIXED; 01842 #endif 01843 01844 /* 01845 Add routines which are used by statement to respective set for 01846 this routine. 01847 */ 01848 sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines); 01849 /* 01850 Merge tables used by this statement (but not by its functions or 01851 procedures) to multiset of tables used by this routine. 01852 */ 01853 merge_table_list(thd, sublex->query_tables, sublex); 01854 if (! sublex->sp_lex_in_use) 01855 { 01856 lex_end(sublex); 01857 delete sublex; 01858 } 01859 thd->lex= oldlex; 01860 DBUG_VOID_RETURN; 01861 }
Here is the call graph for this function:

| void sp_head::restore_thd_mem_root | ( | THD * | thd | ) |
Definition at line 2035 of file sp_head.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_VOID_RETURN, free_list(), m_thd, m_thd_root, and NULL.
Referenced by ~sp_head().
02036 { 02037 DBUG_ENTER("sp_head::restore_thd_mem_root"); 02038 Item *flist= free_list; // The old list 02039 set_query_arena(thd); // Get new free_list and mem_root 02040 state= INITIALIZED_FOR_SP; 02041 02042 DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx", 02043 (ulong) &mem_root, (ulong) &thd->mem_root)); 02044 thd->free_list= flist; // Restore the old one 02045 thd->mem_root= m_thd_root; 02046 m_thd= NULL; 02047 DBUG_VOID_RETURN; 02048 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::set_definer | ( | const LEX_STRING * | user_name, | |
| const LEX_STRING * | host_name | |||
| ) |
Definition at line 2010 of file sp_head.cc.
References LEX_STRING::length, m_definer_host, m_definer_user, LEX_STRING::str, and strmake_root().
02011 { 02012 m_definer_user.str= strmake_root(mem_root, user_name->str, user_name->length); 02013 m_definer_user.length= user_name->length; 02014 02015 m_definer_host.str= strmake_root(mem_root, host_name->str, host_name->length); 02016 m_definer_host.length= host_name->length; 02017 }
Here is the call graph for this function:

| void sp_head::set_definer | ( | const char * | definer, | |
| uint | definerlen | |||
| ) |
Definition at line 1994 of file sp_head.cc.
References HOSTNAME_LENGTH, LEX_STRING::length, parse_user(), LEX_STRING::str, and USERNAME_LENGTH.
Referenced by Event_timed::compile(), and db_load_routine().
01995 { 01996 char user_name_holder[USERNAME_LENGTH + 1]; 01997 LEX_STRING user_name= { user_name_holder, USERNAME_LENGTH }; 01998 01999 char host_name_holder[HOSTNAME_LENGTH + 1]; 02000 LEX_STRING host_name= { host_name_holder, HOSTNAME_LENGTH }; 02001 02002 parse_user(definer, definerlen, user_name.str, &user_name.length, 02003 host_name.str, &host_name.length); 02004 02005 set_definer(&user_name, &host_name); 02006 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void sp_head::set_info | ( | longlong | created, | |
| longlong | modified, | |||
| st_sp_chistics * | chistics, | |||
| ulong | sql_mode | |||
| ) |
Definition at line 1976 of file sp_head.cc.
References m_chistics, m_created, m_modified, m_sql_mode, memdup_root(), and strmake_root().
Referenced by Event_timed::compile().
01978 { 01979 m_created= created; 01980 m_modified= modified; 01981 m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics, 01982 sizeof(*chistics)); 01983 if (m_chistics->comment.length == 0) 01984 m_chistics->comment.str= 0; 01985 else 01986 m_chistics->comment.str= strmake_root(mem_root, 01987 m_chistics->comment.str, 01988 m_chistics->comment.length); 01989 m_sql_mode= sql_mode; 01990 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int sp_head::show_create_function | ( | THD * | thd | ) |
Definition at line 2156 of file sp_head.cc.
References buffer, check_show_routine_access(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, LEX_STRING::length, LINT_INIT, m_defstr, m_name, m_sql_mode, max, Item::maybe_null, NAME_LEN, Protocol::prepare_for_resend(), List< T >::push_back(), send_eof(), Protocol::SEND_EOF, Protocol::send_fields(), Protocol::SEND_NUM_ROWS, sql_mode_str, Protocol::store(), Protocol::store_null(), LEX_STRING::str, sys_var_thd_sql_mode::symbolic_mode_representation(), system_charset_info, TRUE, and Protocol::write().
Referenced by sp_show_create_function().
02157 { 02158 Protocol *protocol= thd->protocol; 02159 char buff[2048]; 02160 String buffer(buff, sizeof(buff), system_charset_info); 02161 int res; 02162 List<Item> field_list; 02163 byte *sql_mode_str; 02164 ulong sql_mode_len; 02165 bool full_access; 02166 DBUG_ENTER("sp_head::show_create_function"); 02167 DBUG_PRINT("info", ("procedure %s", m_name.str)); 02168 LINT_INIT(sql_mode_str); 02169 LINT_INIT(sql_mode_len); 02170 02171 if (check_show_routine_access(thd, this, &full_access)) 02172 DBUG_RETURN(1); 02173 02174 sql_mode_str= 02175 sys_var_thd_sql_mode::symbolic_mode_representation(thd, 02176 m_sql_mode, 02177 &sql_mode_len); 02178 field_list.push_back(new Item_empty_string("Function",NAME_LEN)); 02179 field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len)); 02180 Item_empty_string *definition= 02181 new Item_empty_string("Create Function", max(buffer.length(),1024)); 02182 definition->maybe_null= TRUE; 02183 field_list.push_back(definition); 02184 02185 if (protocol->send_fields(&field_list, 02186 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 02187 DBUG_RETURN(1); 02188 protocol->prepare_for_resend(); 02189 protocol->store(m_name.str, m_name.length, system_charset_info); 02190 protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); 02191 if (full_access) 02192 protocol->store(m_defstr.str, m_defstr.length, system_charset_info); 02193 else 02194 protocol->store_null(); 02195 res= protocol->write(); 02196 send_eof(thd); 02197 02198 DBUG_RETURN(res); 02199 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int sp_head::show_create_procedure | ( | THD * | thd | ) |
Definition at line 2084 of file sp_head.cc.
References buffer, check_show_routine_access(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, LEX_STRING::length, LINT_INIT, m_defstr, m_name, m_sql_mode, max, Item::maybe_null, NAME_LEN, Protocol::prepare_for_resend(), List< T >::push_back(), send_eof(), Protocol::SEND_EOF, Protocol::send_fields(), Protocol::SEND_NUM_ROWS, sql_mode_str, Protocol::store(), Protocol::store_null(), LEX_STRING::str, sys_var_thd_sql_mode::symbolic_mode_representation(), system_charset_info, TRUE, and Protocol::write().
Referenced by sp_show_create_procedure().
02085 { 02086 Protocol *protocol= thd->protocol; 02087 char buff[2048]; 02088 String buffer(buff, sizeof(buff), system_charset_info); 02089 int res; 02090 List<Item> field_list; 02091 byte *sql_mode_str; 02092 ulong sql_mode_len; 02093 bool full_access; 02094 DBUG_ENTER("sp_head::show_create_procedure"); 02095 DBUG_PRINT("info", ("procedure %s", m_name.str)); 02096 02097 LINT_INIT(sql_mode_str); 02098 LINT_INIT(sql_mode_len); 02099 02100 if (check_show_routine_access(thd, this, &full_access)) 02101 DBUG_RETURN(1); 02102 02103 sql_mode_str= 02104 sys_var_thd_sql_mode::symbolic_mode_representation(thd, 02105 m_sql_mode, 02106 &sql_mode_len); 02107 field_list.push_back(new Item_empty_string("Procedure", NAME_LEN)); 02108 field_list.push_back(new Item_empty_string("sql_mode", sql_mode_len)); 02109 // 1024 is for not to confuse old clients 02110 Item_empty_string *definition= 02111 new Item_empty_string("Create Procedure", max(buffer.length(),1024)); 02112 definition->maybe_null= TRUE; 02113 field_list.push_back(definition); 02114 02115 if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | 02116 Protocol::SEND_EOF)) 02117 DBUG_RETURN(1); 02118 protocol->prepare_for_resend(); 02119 protocol->store(m_name.str, m_name.length, system_charset_info); 02120 protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info); 02121 if (full_access) 02122 protocol->store(m_defstr.str, m_defstr.length, system_charset_info); 02123 else 02124 protocol->store_null(); 02125 res= protocol->write(); 02126 send_eof(thd); 02127 02128 DBUG_RETURN(res); 02129 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int sp_head::show_routine_code | ( | THD * | thd | ) |
Definition at line 2274 of file sp_head.cc.
References buffer, check_show_routine_access(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, ER_UNKNOWN_ERROR, format(), get_instr(), sp_instr::m_ip, m_name, max, Protocol::prepare_for_resend(), sp_instr::print(), List< T >::push_back(), push_warning(), send_eof(), Protocol::SEND_EOF, Protocol::send_fields(), Protocol::SEND_NUM_ROWS, SP_INSTR_UINT_MAXLEN, Protocol::store(), LEX_STRING::str, system_charset_info, MYSQL_ERROR::WARN_LEVEL_WARN, and Protocol::write().
Referenced by mysql_execute_command().
02275 { 02276 Protocol *protocol= thd->protocol; 02277 char buff[2048]; 02278 String buffer(buff, sizeof(buff), system_charset_info); 02279 List<Item> field_list; 02280 sp_instr *i; 02281 bool full_access; 02282 int res= 0; 02283 uint ip; 02284 DBUG_ENTER("sp_head::show_routine_code"); 02285 DBUG_PRINT("info", ("procedure: %s", m_name.str)); 02286 02287 if (check_show_routine_access(thd, this, &full_access) || !full_access) 02288 DBUG_RETURN(1); 02289 02290 field_list.push_back(new Item_uint("Pos", 9)); 02291 // 1024 is for not to confuse old clients 02292 field_list.push_back(new Item_empty_string("Instruction", 02293 max(buffer.length(), 1024))); 02294 if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | 02295 Protocol::SEND_EOF)) 02296 DBUG_RETURN(1); 02297 02298 for (ip= 0; (i = get_instr(ip)) ; ip++) 02299 { 02300 /* 02301 Consistency check. If these are different something went wrong 02302 during optimization. 02303 */ 02304 if (ip != i->m_ip) 02305 { 02306 const char *format= "Instruction at position %u has m_ip=%u"; 02307 char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1]; 02308 02309 sprintf(tmp, format, ip, i->m_ip); 02310 /* 02311 Since this is for debugging purposes only, we don't bother to 02312 introduce a special error code for it. 02313 */ 02314 push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, tmp); 02315 } 02316 protocol->prepare_for_resend(); 02317 protocol->store((longlong)ip); 02318 02319 buffer.set("", 0, system_charset_info); 02320 i->print(&buffer); 02321 protocol->store(buffer.ptr(), buffer.length(), system_charset_info); 02322 if ((res= protocol->write())) 02323 break; 02324 } 02325 send_eof(thd); 02326 02327 DBUG_RETURN(res); 02328 }
Here is the call graph for this function:

Here is the caller graph for this function:

List<bp_t> sp_head::m_backpatch [private] |
Definition at line 387 of file sp_head.h.
Referenced by backpatch(), push_backpatch(), and sp_head().
Definition at line 137 of file sp_head.h.
Referenced by create(), db_create_routine(), Table_triggers_list::get_trigger_info(), init(), and init_strings().
| const uchar * sp_head::m_body_begin |
Definition at line 178 of file sp_head.h.
Referenced by db_create_routine(), init(), and init_strings().
| st_sp_chistics* sp_head::m_chistics |
Definition at line 131 of file sp_head.h.
Referenced by db_create_routine(), Table_triggers_list::get_trigger_info(), mysql_execute_command(), set_info(), and sp_change_security_context().
List<sp_instr_opt_meta> sp_head::m_cont_backpatch [private] |
Definition at line 397 of file sp_head.h.
Referenced by add_cont_backpatch(), do_cont_backpatch(), new_cont_backpatch(), and sp_head().
uint sp_head::m_cont_level [private] |
Definition at line 398 of file sp_head.h.
Referenced by add_cont_backpatch(), do_cont_backpatch(), and new_cont_backpatch().
Definition at line 134 of file sp_head.h.
Referenced by check_show_routine_access(), Event_timed::compile(), db_create_routine(), execute(), fill_field_definition(), Item_func_sp::find_and_check_access(), init(), init_sp_name(), mysql_execute_command(), set_routine_security_ctx(), sp_change_security_context(), and sp_head().
Definition at line 140 of file sp_head.h.
Referenced by check_show_routine_access(), Table_triggers_list::get_trigger_info(), set_definer(), and sp_change_security_context().
Definition at line 139 of file sp_head.h.
Referenced by check_show_routine_access(), Table_triggers_list::get_trigger_info(), set_definer(), and sp_change_security_context().
Definition at line 138 of file sp_head.h.
Referenced by init(), init_strings(), show_create_function(), and show_create_procedure().
Definition at line 126 of file sp_head.h.
Referenced by execute(), Event_timed::execute(), execute_procedure(), is_not_allowed_in_function(), mysql_execute_command(), propagate_attributes(), restore_lex(), and Item_func_sp::sp_result_field().
DYNAMIC_ARRAY sp_head::m_instr [private] |
Definition at line 381 of file sp_head.h.
Referenced by add_instr(), destroy(), get_instr(), init(), instructions(), last_instruction(), and optimize().
List<LEX> sp_head::m_lex [private] |
Definition at line 380 of file sp_head.h.
Referenced by destroy(), reset_lex(), restore_lex(), and sp_head().
Definition at line 135 of file sp_head.h.
Referenced by check_show_routine_access(), create(), create_result_field(), db_create_routine(), destroy(), execute_function(), execute_procedure(), execute_trigger(), Item_func_sp::find_and_check_access(), Table_triggers_list::get_trigger_info(), init(), init_sp_name(), mysql_execute_command(), name(), recursion_level_error(), set_routine_security_ctx(), show_create_function(), show_create_procedure(), show_routine_code(), sp_create_function(), sp_create_procedure(), and sp_head().
| const uchar* sp_head::m_param_begin |
| const uchar * sp_head::m_param_end |
Definition at line 136 of file sp_head.h.
Referenced by create(), db_create_routine(), init(), and init_strings().
sp_pcontext* sp_head::m_pcont [private] |
Definition at line 379 of file sp_head.h.
Referenced by destroy(), execute_function(), execute_procedure(), execute_trigger(), and init().
Definition at line 133 of file sp_head.h.
Referenced by create(), execute_function(), execute_procedure(), hash_get_key_for_sp_head(), init(), init_sp_name(), mysql_execute_command(), sp_cache_insert(), and sp_head().
Definition at line 144 of file sp_head.h.
Referenced by execute(), sp_find_routine(), and Item_func_sp::sp_result_field().
Definition at line 128 of file sp_head.h.
Referenced by create_result_field(), init(), and sp_head().
| Security_context sp_head::m_security_ctx |
HASH sp_head::m_sptabs [private] |
Definition at line 408 of file sp_head.h.
Referenced by add_used_tables_to_table_list(), destroy(), merge_table_list(), and sp_head().
Definition at line 132 of file sp_head.h.
Referenced by execute(), Table_triggers_list::get_trigger_info(), set_info(), show_create_function(), show_create_procedure(), and sp_find_routine().
THD* sp_head::m_thd [private] |
Definition at line 377 of file sp_head.h.
Referenced by add_instr(), destroy(), reset_thd_mem_root(), restore_thd_mem_root(), and ~sp_head().
MEM_ROOT* sp_head::m_thd_root [private] |
Definition at line 376 of file sp_head.h.
Referenced by reset_thd_mem_root(), and restore_thd_mem_root().
| const uchar* sp_head::m_tmp_query |
| int sp_head::m_type |
Definition at line 125 of file sp_head.h.
Referenced by check_show_routine_access(), create(), db_create_routine(), is_not_allowed_in_function(), mysql_execute_command(), and recursion_level_error().
MEM_ROOT sp_head::main_mem_root [private] |
Definition at line 106 of file sp_head.h.
Referenced by add_instr(), operator delete(), operator new(), and reset_thd_mem_root().
1.4.7

