diff options
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 187 |
1 files changed, 93 insertions, 94 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2f78f0b24dd..3d5f2f0f50d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -385,13 +385,13 @@ void sp_name::init_qname(THD *thd) { m_sroutines_key.length= m_db.length + m_name.length + 2; - if (!(m_sroutines_key.str= thd->alloc(m_sroutines_key.length + 1))) + if (!(m_sroutines_key.str= (char*) thd->alloc(m_sroutines_key.length + 1))) return; m_qname.length= m_sroutines_key.length - 1; m_qname.str= m_sroutines_key.str + 1; sprintf(m_qname.str, "%.*s.%.*s", - m_db.length, (m_db.length ? m_db.str : ""), - m_name.length, m_name.str); + (int) m_db.length, (m_db.length ? m_db.str : ""), + (int) m_name.length, m_name.str); } @@ -485,8 +485,7 @@ sp_head::sp_head() */ m_db= m_name= m_qname= str_reset; - extern byte * - sp_table_key(const byte *ptr, uint *plen, my_bool first); + extern uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first); DBUG_ENTER("sp_head::sp_head"); m_backpatch.empty(); @@ -571,7 +570,7 @@ sp_head::init_strings(THD *thd, LEX *lex) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - endp= skip_rear_comments(m_body_begin, endp); + endp= skip_rear_comments(thd->charset(), m_body_begin, endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, m_body_begin, m_body.length); @@ -637,17 +636,10 @@ int sp_head::create(THD *thd) { DBUG_ENTER("sp_head::create"); - int ret; - DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s", m_type, m_name.str, m_params.str, m_body.str)); - if (m_type == TYPE_ENUM_FUNCTION) - ret= sp_create_function(thd, this); - else - ret= sp_create_procedure(thd, this); - - DBUG_RETURN(ret); + DBUG_RETURN(sp_create_routine(thd, m_type, this)); } sp_head::~sp_head() @@ -714,7 +706,7 @@ sp_head::create_result_field(uint field_max_length, const char *field_name, field_max_length : m_return_field_def.length; field= ::make_field(table->s, /* TABLE_SHARE ptr */ - (char*) 0, /* field ptr */ + (uchar*) 0, /* field ptr */ field_length, /* field [max] length */ (uchar*) "", /* null ptr */ 0, /* null bit */ @@ -978,7 +970,7 @@ sp_head::execute(THD *thd) String old_packet; /* Use some extra margin for possible SP recursion and functions */ - if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char*)&old_packet)) + if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet)) DBUG_RETURN(TRUE); /* init per-instruction memroot */ @@ -1665,7 +1657,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) { List_iterator<Item> it_args(*args); - DBUG_PRINT("info",(" %.*s: eval args", m_name.length, m_name.str)); + DBUG_PRINT("info",(" %.*s: eval args", (int) m_name.length, m_name.str)); for (uint i= 0 ; i < params ; i++) { @@ -1723,7 +1715,8 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) if (!thd->in_sub_stmt) close_thread_tables(thd, 0, 0); - DBUG_PRINT("info",(" %.*s: eval args done", m_name.length, m_name.str)); + DBUG_PRINT("info",(" %.*s: eval args done", + (int) m_name.length, m_name.str)); } if (!(m_flags & LOG_SLOW_STATEMENTS) && thd->enable_slow_log) { @@ -2104,49 +2097,97 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) } -int -sp_head::show_create_procedure(THD *thd) +/** + Implement SHOW CREATE statement for stored routines. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + + @return Error status. + @retval FALSE on success + @retval TRUE on error +*/ + +bool +sp_head::show_create_routine(THD *thd, int type) { + const char *col1_caption= type == TYPE_ENUM_PROCEDURE ? + "Procedure" : "Function"; + + const char *col3_caption= type == TYPE_ENUM_PROCEDURE ? + "Create Procedure" : "Create Function"; + + bool err_status; + Protocol *protocol= thd->protocol; - char buff[2048]; - String buffer(buff, sizeof(buff), system_charset_info); - int res; - List<Item> field_list; + List<Item> fields; + LEX_STRING sql_mode; + bool full_access; - DBUG_ENTER("sp_head::show_create_procedure"); - DBUG_PRINT("info", ("procedure %s", m_name.str)); + + DBUG_ENTER("sp_head::show_create_routine"); + DBUG_PRINT("info", ("routine %s", m_name.str)); + + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); if (check_show_routine_access(thd, this, &full_access)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); - sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode, - &sql_mode); - field_list.push_back(new Item_empty_string("Procedure", NAME_CHAR_LEN)); - field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length)); - // 1024 is for not to confuse old clients - Item_empty_string *definition= - new Item_empty_string("Create Procedure", max(buffer.length(),1024)); - definition->maybe_null= TRUE; - field_list.push_back(definition); + sys_var_thd_sql_mode::symbolic_mode_representation( + thd, m_sql_mode, &sql_mode); + + /* Send header. */ + + fields.push_back(new Item_empty_string(col1_caption, NAME_CHAR_LEN)); + fields.push_back(new Item_empty_string("sql_mode", sql_mode.length)); + + { + /* + NOTE: SQL statement field must be not less than 1024 in order not to + confuse old clients. + */ + + Item_empty_string *stmt_fld= + new Item_empty_string(col3_caption, + max(m_defstr.length, 1024)); + + stmt_fld->maybe_null= TRUE; + + fields.push_back(stmt_fld); + } + + if (protocol->send_fields(&fields, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) + { + DBUG_RETURN(TRUE); + } + + /* Send data. */ - if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF)) - DBUG_RETURN(1); protocol->prepare_for_resend(); + protocol->store(m_name.str, m_name.length, system_charset_info); - protocol->store((char*) sql_mode.str, sql_mode.length, system_charset_info); + protocol->store(sql_mode.str, sql_mode.length, system_charset_info); + if (full_access) - protocol->store(m_defstr.str, m_defstr.length, system_charset_info); + protocol->store(m_defstr.str, m_defstr.length, &my_charset_bin); else protocol->store_null(); - res= protocol->write(); - send_eof(thd); - DBUG_RETURN(res); + err_status= protocol->write(); + + if (!err_status) + send_eof(thd); + + DBUG_RETURN(err_status); } + + /* Add instruction to SP @@ -2166,49 +2207,7 @@ void sp_head::add_instr(sp_instr *instr) entire stored procedure, as their life span is equal. */ instr->mem_root= &main_mem_root; - insert_dynamic(&m_instr, (gptr)&instr); -} - - -int -sp_head::show_create_function(THD *thd) -{ - Protocol *protocol= thd->protocol; - char buff[2048]; - String buffer(buff, sizeof(buff), system_charset_info); - int res; - List<Item> field_list; - LEX_STRING sql_mode; - bool full_access; - DBUG_ENTER("sp_head::show_create_function"); - DBUG_PRINT("info", ("procedure %s", m_name.str)); - - if (check_show_routine_access(thd, this, &full_access)) - DBUG_RETURN(1); - - sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode, - &sql_mode); - field_list.push_back(new Item_empty_string("Function",NAME_CHAR_LEN)); - field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length)); - Item_empty_string *definition= - new Item_empty_string("Create Function", max(buffer.length(),1024)); - definition->maybe_null= TRUE; - field_list.push_back(definition); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - protocol->prepare_for_resend(); - protocol->store(m_name.str, m_name.length, system_charset_info); - protocol->store(sql_mode.str, sql_mode.length, system_charset_info); - if (full_access) - protocol->store(m_defstr.str, m_defstr.length, system_charset_info); - else - protocol->store_null(); - res= protocol->write(); - send_eof(thd); - - DBUG_RETURN(res); + insert_dynamic(&m_instr, (uchar*)&instr); } @@ -2252,7 +2251,7 @@ void sp_head::optimize() sp_instr *ibp; List_iterator_fast<sp_instr> li(bp); - set_dynamic(&m_instr, (gptr)&i, dst); + set_dynamic(&m_instr, (uchar*)&i, dst); while ((ibp= li++)) { sp_instr_opt_meta *im= static_cast<sp_instr_opt_meta *>(ibp); @@ -3453,12 +3452,12 @@ typedef struct st_sp_table uint query_lock_count; } SP_TABLE; -byte * -sp_table_key(const byte *ptr, uint *plen, my_bool first) +uchar * +sp_table_key(const uchar *ptr, size_t *plen, my_bool first) { SP_TABLE *tab= (SP_TABLE *)ptr; *plen= tab->qname.length; - return (byte *)tab->qname.str; + return (uchar *)tab->qname.str; } @@ -3527,8 +3526,8 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) (and therefore should not be prelocked). Otherwise we will erroneously treat table with same name but with different alias as non-temporary. */ - if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, tlen)) || - ((tab= (SP_TABLE *)hash_search(&m_sptabs, (byte *)tname, + if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen)) || + ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen - alen - 1)) && tab->temp)) { @@ -3558,7 +3557,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) tab->db_length= table->db_length; tab->lock_type= table->lock_type; tab->lock_count= tab->query_lock_count= 1; - my_hash_insert(&m_sptabs, (byte *)tab); + my_hash_insert(&m_sptabs, (uchar *)tab); } } return TRUE; |