diff options
author | unknown <jani@a193-229-222-105.elisa-laajakaista.fi> | 2005-11-23 14:57:00 +0200 |
---|---|---|
committer | unknown <jani@a193-229-222-105.elisa-laajakaista.fi> | 2005-11-23 14:57:00 +0200 |
commit | 33a2716a8539d9189622a6a5deef0d798c01b427 (patch) | |
tree | ee73c0781d75c64d0c74007e2d2a68f9de4b9a29 /sql/sp_head.cc | |
parent | 817ee181c34d53caf2179a978c35c685437fb756 (diff) | |
parent | 056d7266c7f3b10b2a054cb5bb534981e49408ee (diff) | |
download | mariadb-git-33a2716a8539d9189622a6a5deef0d798c01b427.tar.gz |
Merge a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.0
into a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-new
Makefile.am:
Auto merged
client/mysqltest.c:
Auto merged
configure.in:
Auto merged
extra/Makefile.am:
Auto merged
include/Makefile.am:
Auto merged
include/my_global.h:
Auto merged
libmysqld/examples/Makefile.am:
Auto merged
mysql-test/Makefile.am:
Auto merged
mysql-test/r/ndb_alter_table.result:
Auto merged
mysql-test/t/ndb_alter_table.test:
Auto merged
scripts/Makefile.am:
Auto merged
sql/Makefile.am:
Auto merged
sql/field.cc:
Auto merged
sql/ha_federated.cc:
Auto merged
sql/ha_federated.h:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_myisammrg.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/key.cc:
Auto merged
sql/log.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysqld.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/repl_failsafe.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/sp.cc:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_cache.h:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_load.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/structs.h:
Auto merged
sql/table.cc:
Auto merged
sql/tztime.cc:
Auto merged
storage/myisam/myisamchk.c:
Auto merged
storage/myisam/myisampack.c:
Auto merged
storage/ndb/docs/Makefile.am:
Auto merged
support-files/mysql.spec.sh:
Auto merged
libmysqld/Makefile.am:
Merged from 5.0 to 5.1.
sql/ha_berkeley.cc:
Merged from 5.0 to 5.1.
sql/lex.h:
Merged from 5.0 to 5.1.
sql/set_var.cc:
Merged from 5.0 to 5.1.
sql/share/errmsg.txt:
Merged from 5.0 to 5.1.
sql/sql_lex.h:
Merged from 5.0 to 5.1.
sql/sql_show.cc:
Merged from 5.0 to 5.1.
sql/sql_yacc.yy:
Merged from 5.0 to 5.1.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 393 |
1 files changed, 307 insertions, 86 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc index c76ed813bc6..ab564cef7c1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -105,6 +105,8 @@ sp_get_flags_for_command(LEX *lex) case SQLCOM_SHOW_TABLES: case SQLCOM_SHOW_VARIABLES: case SQLCOM_SHOW_WARNS: + case SQLCOM_SHOW_PROC_CODE: + case SQLCOM_SHOW_FUNC_CODE: flags= sp_head::MULTI_RESULTS; break; /* @@ -476,7 +478,8 @@ sp_head::operator delete(void *ptr, size_t size) sp_head::sp_head() :Query_arena(&main_mem_root, INITIALIZED_FOR_SP), - m_flags(0), m_returns_cs(NULL) + m_flags(0), m_returns_cs(NULL), m_recursion_level(0), m_next_cached_sp(0), + m_first_instance(this), m_first_free_instance(this), m_last_cached_sp(this) { extern byte * sp_table_key(const byte *ptr, uint *plen, my_bool first); @@ -657,6 +660,7 @@ sp_head::create(THD *thd) sp_head::~sp_head() { destroy(); + delete m_next_cached_sp; if (m_thd) restore_thd_mem_root(m_thd); } @@ -858,9 +862,9 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length; /* append the spvar substitute */ - res|= qbuf.append(" NAME_CONST('"); + res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('")); res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length); - res|= qbuf.append("',"); + res|= qbuf.append(STRING_WITH_LEN("',")); val= (*splocal)->this_item(); DBUG_PRINT("info", ("print %p", val)); val->print(&qbuf); @@ -883,6 +887,31 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) /* + Return appropriate error about recursion limit reaching + + SYNOPSIS + sp_head::recursion_level_error() + + NOTE + For functions and triggers we return error about prohibited recursion. + For stored procedures we return about reaching recursion limit. +*/ + +void sp_head::recursion_level_error() +{ + if (m_type == TYPE_ENUM_PROCEDURE) + { + THD *thd= current_thd; + my_error(ER_SP_RECURSION_LIMIT, MYF(0), + thd->variables.max_sp_recursion_depth, + m_name); + } + else + my_error(ER_SP_NO_RECURSION, MYF(0)); +} + + +/* Execute the routine. The main instruction jump loop is there Assume the parameters already set. @@ -911,37 +940,31 @@ int sp_head::execute(THD *thd) Item_change_list old_change_list; String old_packet; - /* init per-instruction memroot */ - init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); - - /* Use some extra margin for possible SP recursion and functions */ - if (check_stack_overrun(thd, 4*STACK_MIN_SIZE, olddb)) + if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char*)&old_packet)) { DBUG_RETURN(-1); } - if (m_flags & IS_INVOKED) - { - /* - We have to disable recursion for stored routines since in - many cases LEX structure and many Item's can't be used in - reentrant way now. - - TODO: We can circumvent this problem by using separate - sp_head instances for each recursive invocation. - - NOTE: Theoretically arguments of procedure can be evaluated - before its invocation so there should be no problem with - recursion. But since we perform cleanup for CALL statement - as for any other statement only after its execution, its LEX - structure is not reusable for recursive calls. Thus we have - to prohibit recursion for stored procedures too. - */ - my_error(ER_SP_NO_RECURSION, MYF(0)); - DBUG_RETURN(-1); - } + /* init per-instruction memroot */ + init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + + DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; + m_first_instance->m_first_free_instance= m_next_cached_sp; + DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x", + (ulong)m_first_instance, this, m_next_cached_sp, + m_next_cached_sp->m_recursion_level, + m_next_cached_sp->m_flags)); + /* + Check that if there are not any instances after this one then + pointer to the last instance points on this instance or if there are + some instances after this one then recursion level of next instance + greater then recursion level of current instance on 1 + */ + DBUG_ASSERT((m_next_cached_sp == 0 && + m_first_instance->m_last_cached_sp == this) || + (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level)); dbchanged= FALSE; if (m_db.length && @@ -1116,6 +1139,29 @@ int sp_head::execute(THD *thd) ret= mysql_change_db(thd, olddb, 1); } m_flags&= ~IS_INVOKED; + DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x", + (ulong)m_first_instance, + m_first_instance->m_first_free_instance, this, + m_recursion_level, m_flags)); + /* + Check that we have one of following: + + 1) there are not free instances which means that this instance is last + in the list of instances (pointer to the last instance point on it and + ther are not other instances after this one in the list) + + 2) There are some free instances which mean that first free instance + should go just after this one and recursion level of that free instance + should be on 1 more then recursion leven of this instance. + */ + DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 && + this == m_first_instance->m_last_cached_sp && + m_next_cached_sp == 0) || + (m_first_instance->m_first_free_instance != 0 && + m_first_instance->m_first_free_instance == m_next_cached_sp && + m_first_instance->m_first_free_instance->m_recursion_level == + m_recursion_level + 1)); + m_first_instance->m_first_free_instance= this; DBUG_RETURN(ret); } @@ -1173,6 +1219,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) // QQ Should have some error checking here? (types, etc...) if (!(nctx= new sp_rcontext(octx, csize, hmax, cmax))) goto end; +#ifndef DBUG_OFF + nctx->owner= this; +#endif for (i= 0 ; i < argcount ; i++) { sp_pvar_t *pvar = m_pcont->find_pvar(i); @@ -1215,7 +1264,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) char buf[256]; String bufstr(buf, sizeof(buf), &my_charset_bin); bufstr.length(0); - bufstr.append("DO ", 3); + bufstr.append(STRING_WITH_LEN("DO ")); append_identifier(thd, &bufstr, m_name.str, m_name.length); bufstr.append('('); for (uint i=0; i < argcount; i++) @@ -1317,6 +1366,9 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args) { // Create a temporary old context if (!(octx= new sp_rcontext(octx, csize, hmax, cmax))) DBUG_RETURN(-1); +#ifndef DBUG_OFF + octx->owner= 0; +#endif thd->spcont= octx; /* set callers_arena to thd, for upper-level function to work */ @@ -1328,6 +1380,9 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args) thd->spcont= save_spcont; DBUG_RETURN(-1); } +#ifndef DBUG_OFF + nctx->owner= this; +#endif if (csize > 0 || hmax > 0 || cmax > 0) { @@ -1740,7 +1795,7 @@ sp_head::show_create_procedure(THD *thd) LINT_INIT(sql_mode_len); if (check_show_routine_access(thd, this, &full_access)) - return 1; + DBUG_RETURN(1); sql_mode_str= sys_var_thd_sql_mode::symbolic_mode_representation(thd, @@ -1753,10 +1808,7 @@ sp_head::show_create_procedure(THD *thd) max(buffer.length(), 1024))); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - { - res= 1; - goto done; - } + 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_len, system_charset_info); @@ -1765,7 +1817,6 @@ sp_head::show_create_procedure(THD *thd) res= protocol->write(); send_eof(thd); - done: DBUG_RETURN(res); } @@ -1810,7 +1861,7 @@ sp_head::show_create_function(THD *thd) LINT_INIT(sql_mode_len); if (check_show_routine_access(thd, this, &full_access)) - return 1; + DBUG_RETURN(1); sql_mode_str= sys_var_thd_sql_mode::symbolic_mode_representation(thd, @@ -1822,10 +1873,7 @@ sp_head::show_create_function(THD *thd) max(buffer.length(),1024))); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - { - res= 1; - goto done; - } + 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_len, system_charset_info); @@ -1834,7 +1882,6 @@ sp_head::show_create_function(THD *thd) res= protocol->write(); send_eof(thd); - done: DBUG_RETURN(res); } @@ -1894,6 +1941,50 @@ sp_head::opt_mark(uint ip) } +#ifndef DBUG_OFF +int +sp_head::show_routine_code(THD *thd) +{ + Protocol *protocol= thd->protocol; + char buff[2048]; + String buffer(buff, sizeof(buff), system_charset_info); + List<Item> field_list; + sp_instr *i; + bool full_access; + int res= 0; + uint ip; + DBUG_ENTER("sp_head::show_routine_code"); + DBUG_PRINT("info", ("procedure: %s", m_name.str)); + + if (check_show_routine_access(thd, this, &full_access) || !full_access) + DBUG_RETURN(1); + + field_list.push_back(new Item_uint("Pos", 9)); + // 1024 is for not to confuse old clients + field_list.push_back(new Item_empty_string("Instruction", + max(buffer.length(), 1024))); + if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | + Protocol::SEND_EOF)) + DBUG_RETURN(1); + + for (ip= 0; (i = get_instr(ip)) ; ip++) + { + protocol->prepare_for_resend(); + protocol->store((longlong)ip); + + buffer.set("", 0, system_charset_info); + i->print(&buffer); + protocol->store(buffer.ptr(), buffer.length(), system_charset_info); + if ((res= protocol->write())) + break; + } + send_eof(thd); + + DBUG_RETURN(res); +} +#endif // ifndef DBUG_OFF + + /* Prepare LEX and thread for execution of instruction, if requested open and lock LEX's tables, execute instruction's core function, perform @@ -2052,14 +2143,43 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +/* + Sufficient max length of printed destinations and frame offsets (all uints). +*/ +#define SP_INSTR_UINT_MAXLEN 8 + +#define SP_STMT_PRINT_MAXLEN 40 void sp_instr_stmt::print(String *str) { - str->reserve(12); - str->append("stmt "); + uint i, len; + + /* stmt CMD "..." */ + if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8)) + return; + str->qs_append(STRING_WITH_LEN("stmt ")); str->qs_append((uint)m_lex_keeper.sql_command()); + str->qs_append(STRING_WITH_LEN(" \"")); + len= m_query.length; + /* + Print the query string (but not too much of it), just to indicate which + statement it is. + */ + if (len > SP_STMT_PRINT_MAXLEN) + len= SP_STMT_PRINT_MAXLEN-3; + /* Copy the query string and replace '\n' with ' ' in the process */ + for (i= 0 ; i < len ; i++) + { + if (m_query.str[i] == '\n') + str->qs_append(' '); + else + str->qs_append(m_query.str[i]); + } + if (m_query.length > SP_STMT_PRINT_MAXLEN) + str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */ + str->qs_append('"'); } - +#undef SP_STMT_PRINT_MAXLEN int sp_instr_stmt::exec_core(THD *thd, uint *nextp) @@ -2096,10 +2216,23 @@ sp_instr_set::exec_core(THD *thd, uint *nextp) void sp_instr_set::print(String *str) { - str->reserve(12); - str->append("set "); + /* set name@offset ... */ + int rsrv = SP_INSTR_UINT_MAXLEN+6; + sp_pvar_t *var = m_ctx->find_pvar(m_offset); + + /* 'var' should always be non-null, but just in case... */ + if (var) + rsrv+= var->name.length; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("set ")); + if (var) + { + str->qs_append(var->name.str, var->name.length); + str->qs_append('@'); + } str->qs_append(m_offset); - str->append(' '); + str->qs_append(' '); m_value->print(str); } @@ -2132,9 +2265,9 @@ sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp) void sp_instr_set_trigger_field::print(String *str) { - str->append("set ", 4); + str->append(STRING_WITH_LEN("set_trigger_field ")); trigger_field->print(str); - str->append(":=", 2); + str->append(STRING_WITH_LEN(":=")); value->print(str); } @@ -2156,8 +2289,10 @@ sp_instr_jump::execute(THD *thd, uint *nextp) void sp_instr_jump::print(String *str) { - str->reserve(12); - str->append("jump "); + /* jump dest */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+5)) + return; + str->qs_append(STRING_WITH_LEN("jump ")); str->qs_append(m_dest); } @@ -2238,10 +2373,12 @@ sp_instr_jump_if::exec_core(THD *thd, uint *nextp) void sp_instr_jump_if::print(String *str) { - str->reserve(12); - str->append("jump_if "); + /* jump_if dest ... */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+8+32)) // Add some for the expr. too + return; + str->qs_append(STRING_WITH_LEN("jump_if ")); str->qs_append(m_dest); - str->append(' '); + str->qs_append(' '); m_expr->print(str); } @@ -2299,10 +2436,12 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp) void sp_instr_jump_if_not::print(String *str) { - str->reserve(16); - str->append("jump_if_not "); + /* jump_if_not dest ... */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+12+32)) // Add some for the expr. too + return; + str->qs_append(STRING_WITH_LEN("jump_if_not ")); str->qs_append(m_dest); - str->append(' '); + str->qs_append(' '); m_expr->print(str); } @@ -2357,10 +2496,12 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp) void sp_instr_freturn::print(String *str) { - str->reserve(12); - str->append("freturn "); + /* freturn type expr... */ + if (str->reserve(UINT_MAX+8+32)) // Add some for the expr. too + return; + str->qs_append(STRING_WITH_LEN("freturn ")); str->qs_append((uint)m_type); - str->append(' '); + str->qs_append(' '); m_value->print(str); } @@ -2385,15 +2526,31 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp) void sp_instr_hpush_jump::print(String *str) { - str->reserve(32); - str->append("hpush_jump "); + /* hpush_jump dest fsize type */ + if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21)) + return; + str->qs_append(STRING_WITH_LEN("hpush_jump ")); str->qs_append(m_dest); - str->append(" t="); - str->qs_append(m_type); - str->append(" f="); + str->qs_append(' '); str->qs_append(m_frame); - str->append(" h="); - str->qs_append(m_ip+1); + switch (m_type) + { + case SP_HANDLER_NONE: + str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug + break; + case SP_HANDLER_EXIT: + str->qs_append(STRING_WITH_LEN(" EXIT")); + break; + case SP_HANDLER_CONTINUE: + str->qs_append(STRING_WITH_LEN(" CONTINUE")); + break; + case SP_HANDLER_UNDO: + str->qs_append(STRING_WITH_LEN(" UNDO")); + break; + default: + str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); // This would be a bug as well + str->qs_append(m_type); + } } uint @@ -2428,8 +2585,10 @@ sp_instr_hpop::execute(THD *thd, uint *nextp) void sp_instr_hpop::print(String *str) { - str->reserve(12); - str->append("hpop "); + /* hpop count */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+5)) + return; + str->qs_append(STRING_WITH_LEN("hpop ")); str->qs_append(m_count); } @@ -2463,12 +2622,14 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp) void sp_instr_hreturn::print(String *str) { - str->reserve(16); - str->append("hreturn "); + /* hreturn framesize dest */ + if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9)) + return; + str->qs_append(STRING_WITH_LEN("hreturn ")); str->qs_append(m_frame); if (m_dest) { - str->append(' '); + str->qs_append(' '); str->qs_append(m_dest); } } @@ -2516,7 +2677,22 @@ sp_instr_cpush::execute(THD *thd, uint *nextp) void sp_instr_cpush::print(String *str) { - str->append("cpush"); + LEX_STRING n; + my_bool found= m_ctx->find_cursor(m_cursor, &n); + /* cpush name@offset */ + uint rsrv= SP_INSTR_UINT_MAXLEN+7; + + if (found) + rsrv+= n.length; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("cpush ")); + if (found) + { + str->qs_append(n.str, n.length); + str->qs_append('@'); + } + str->qs_append(m_cursor); } @@ -2537,8 +2713,10 @@ sp_instr_cpop::execute(THD *thd, uint *nextp) void sp_instr_cpop::print(String *str) { - str->reserve(12); - str->append("cpop "); + /* cpop count */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+5)) + return; + str->qs_append(STRING_WITH_LEN("cpop ")); str->qs_append(m_count); } @@ -2612,8 +2790,21 @@ sp_instr_copen::exec_core(THD *thd, uint *nextp) void sp_instr_copen::print(String *str) { - str->reserve(12); - str->append("copen "); + LEX_STRING n; + my_bool found= m_ctx->find_cursor(m_cursor, &n); + /* copen name@offset */ + uint rsrv= SP_INSTR_UINT_MAXLEN+7; + + if (found) + rsrv+= n.length; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("copen ")); + if (found) + { + str->qs_append(n.str, n.length); + str->qs_append('@'); + } str->qs_append(m_cursor); } @@ -2641,8 +2832,21 @@ sp_instr_cclose::execute(THD *thd, uint *nextp) void sp_instr_cclose::print(String *str) { - str->reserve(12); - str->append("cclose "); + LEX_STRING n; + my_bool found= m_ctx->find_cursor(m_cursor, &n); + /* cclose name@offset */ + uint rsrv= SP_INSTR_UINT_MAXLEN+8; + + if (found) + rsrv+= n.length; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("cclose ")); + if (found) + { + str->qs_append(n.str, n.length); + str->qs_append('@'); + } str->qs_append(m_cursor); } @@ -2671,14 +2875,29 @@ sp_instr_cfetch::print(String *str) { List_iterator_fast<struct sp_pvar> li(m_varlist); sp_pvar_t *pv; - - str->reserve(12); - str->append("cfetch "); + LEX_STRING n; + my_bool found= m_ctx->find_cursor(m_cursor, &n); + /* cfetch name@offset vars... */ + uint rsrv= SP_INSTR_UINT_MAXLEN+8; + + if (found) + rsrv+= n.length; + if (str->reserve(rsrv)) + return; + str->qs_append(STRING_WITH_LEN("cfetch ")); + if (found) + { + str->qs_append(n.str, n.length); + str->qs_append('@'); + } str->qs_append(m_cursor); while ((pv= li++)) { - str->reserve(8); - str->append(' '); + if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2)) + return; + str->qs_append(' '); + str->qs_append(pv->name.str, pv->name.length); + str->qs_append('@'); str->qs_append(pv->offset); } } @@ -2702,8 +2921,10 @@ sp_instr_error::execute(THD *thd, uint *nextp) void sp_instr_error::print(String *str) { - str->reserve(12); - str->append("error "); + /* error code */ + if (str->reserve(SP_INSTR_UINT_MAXLEN+6)) + return; + str->qs_append(STRING_WITH_LEN("error ")); str->qs_append(m_errcode); } |