summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2005-11-18 16:30:27 +0100
committerunknown <pem@mysql.com>2005-11-18 16:30:27 +0100
commit6726a6b8b9cc6059f8080846185114e42f248556 (patch)
tree511c72f417c8aa02f30a0a354d4641217c9c1dca
parent91ab707678870966b9410cd3bdd783eb2a7c19e4 (diff)
downloadmariadb-git-6726a6b8b9cc6059f8080846185114e42f248556.tar.gz
Post-review fixes, mainly fixing all print() methods for sp_instr* classes.
Also added mysql-test files: include/is_debug_build.inc r/is_debug_build.require r/sp-code.result t/sp-code.test sql/sp_head.cc: Review fixes: - Some minor editorial changes - Fixed all print() methods for instructions: - reserve() enough space - check return value from reserve() - use qs_append, with length arg, whenever possible sql/sp_pcontext.cc: Review fixes. Also fixed bug in find_cursor(). sql/sp_pcontext.h: Changed parameter names (review fix). sql/sql_parse.cc: Moved comment. (Review fix) mysql-test/include/is_debug_build.inc: New BitKeeper file ``mysql-test/include/is_debug_build.inc'' mysql-test/r/is_debug_build.require: New BitKeeper file ``mysql-test/r/is_debug_build.require'' mysql-test/r/sp-code.result: New BitKeeper file ``mysql-test/r/sp-code.result'' mysql-test/t/sp-code.test: New BitKeeper file ``mysql-test/t/sp-code.test''
-rw-r--r--mysql-test/include/is_debug_build.inc4
-rw-r--r--mysql-test/r/is_debug_build.require2
-rw-r--r--mysql-test/r/sp-code.result65
-rw-r--r--mysql-test/t/sp-code.test50
-rw-r--r--sql/sp_head.cc160
-rw-r--r--sql/sp_pcontext.cc26
-rw-r--r--sql/sp_pcontext.h8
-rw-r--r--sql/sql_parse.cc3
8 files changed, 234 insertions, 84 deletions
diff --git a/mysql-test/include/is_debug_build.inc b/mysql-test/include/is_debug_build.inc
new file mode 100644
index 00000000000..23a2814e2bb
--- /dev/null
+++ b/mysql-test/include/is_debug_build.inc
@@ -0,0 +1,4 @@
+-- require r/is_debug_build.require
+--disable_query_log
+select instr(version(), "debug") > 0;
+--enable_query_log
diff --git a/mysql-test/r/is_debug_build.require b/mysql-test/r/is_debug_build.require
new file mode 100644
index 00000000000..4d77bcdc1ed
--- /dev/null
+++ b/mysql-test/r/is_debug_build.require
@@ -0,0 +1,2 @@
+instr(version(), "debug") > 0
+1
diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result
new file mode 100644
index 00000000000..e9597af10ee
--- /dev/null
+++ b/mysql-test/r/sp-code.result
@@ -0,0 +1,65 @@
+select version(), substring_index(version(), "-", -1);
+version() substring_index(version(), "-", -1)
+5.0.17-debug-log log
+create procedure empty()
+begin
+end;
+show procedure code empty;
+Pos Instruction
+drop procedure empty;
+create function almost_empty()
+returns int
+return 0;
+show function code almost_empty;
+Pos Instruction
+0 freturn 3 0
+drop function almost_empty;
+create procedure code_sample(x int, out err int, out nulls int)
+begin
+declare count int default 0;
+set nulls = 0;
+begin
+declare c cursor for select name from t1;
+declare exit handler for not found close c;
+open c;
+loop
+begin
+declare n varchar(20);
+declare continue handler for sqlexception set err=1;
+fetch c into n;
+if isnull(n) then
+set nulls = nulls + 1;
+else
+set count = count + 1;
+update t2 set idx = count where name=n;
+end if;
+end;
+end loop;
+end;
+select t.name, t.idx from t2 t order by idx asc;
+end//
+show procedure code code_sample;
+Pos Instruction
+0 set count@3 0
+1 set nulls@2 0
+2 cpush c@0
+3 hpush_jump 6 4 EXIT
+4 cclose c@0
+5 hreturn 0 19
+6 copen c@0
+7 set n@4 NULL
+8 hpush_jump 11 5 CONTINUE
+9 set err@1 1
+10 hreturn 5
+11 cfetch c@0 n@4
+12 jump_if_not 15 isnull(n@4)
+13 set nulls@2 (nulls@2 + 1)
+14 jump 17
+15 set count@3 (count@3 + 1)
+16 stmt 4 "update t2 set idx = count where name=n"
+17 hpop 1
+18 jump 7
+19 hpop 1
+20 cpop 1
+21 stmt 0 "select t.name, t.idx from t2 t order ..."
+drop procedure code_sample;
diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test
new file mode 100644
index 00000000000..a40d86f9d4a
--- /dev/null
+++ b/mysql-test/t/sp-code.test
@@ -0,0 +1,50 @@
+#
+# Test the debugging feature "show procedure/function code <name>"
+#
+
+-- source include/is_debug_build.inc
+select version(), substring_index(version(), "-", -1);
+
+create procedure empty()
+begin
+end;
+show procedure code empty;
+drop procedure empty;
+
+create function almost_empty()
+ returns int
+ return 0;
+show function code almost_empty;
+drop function almost_empty;
+
+delimiter //;
+create procedure code_sample(x int, out err int, out nulls int)
+begin
+ declare count int default 0;
+
+ set nulls = 0;
+ begin
+ declare c cursor for select name from t1;
+ declare exit handler for not found close c;
+
+ open c;
+ loop
+ begin
+ declare n varchar(20);
+ declare continue handler for sqlexception set err=1;
+
+ fetch c into n;
+ if isnull(n) then
+ set nulls = nulls + 1;
+ else
+ set count = count + 1;
+ update t2 set idx = count where name=n;
+ end if;
+ end;
+ end loop;
+ end;
+ select t.name, t.idx from t2 t order by idx asc;
+end//
+delimiter ;//
+show procedure code code_sample;
+drop procedure code_sample;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1ab562b53fc..b11260ab999 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1853,14 +1853,13 @@ sp_head::show_routine_code(THD *thd)
Protocol *protocol= thd->protocol;
char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info);
- int res;
List<Item> field_list;
+ sp_instr *i;
bool full_access;
+ int res;
uint ip;
- sp_instr *i;
-
DBUG_ENTER("sp_head::show_routine_code");
- DBUG_PRINT("info", ("procedure %s", m_name.str));
+ DBUG_PRINT("info", ("procedure: %s", m_name.str));
if (check_show_routine_access(thd, this, &full_access) || !full_access)
DBUG_RETURN(1);
@@ -1880,7 +1879,7 @@ sp_head::show_routine_code(THD *thd)
buffer.set("", 0, system_charset_info);
i->print(&buffer);
- protocol->store(buffer.c_ptr_quick(), buffer.length(), system_charset_info);
+ protocol->store(buffer.ptr(), buffer.length(), system_charset_info);
if ((res= protocol->write()))
break;
}
@@ -2055,10 +2054,12 @@ sp_instr_stmt::print(String *str)
{
uint i, len;
- str->reserve(STMT_PRINT_MAXLEN+20);
- str->append("stmt ");
+ /* Reserve enough space for 'stmt CMD "..."'; max+20 is more than enough. */
+ if (str->reserve(STMT_PRINT_MAXLEN+20))
+ return;
+ str->qs_append("stmt ", 5);
str->qs_append((uint)m_lex_keeper.sql_command());
- str->append(" \"");
+ str->qs_append(" \"", 2);
len= m_query.length;
/*
Print the query string (but not too much of it), just to indicate which
@@ -2068,13 +2069,15 @@ sp_instr_stmt::print(String *str)
len= 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->append(' ');
+ str->qs_append(' ');
else
- str->append(m_query.str[i]);
+ str->qs_append(m_query.str[i]);
+ }
if (m_query.length > STMT_PRINT_MAXLEN)
- str->append("..."); /* Indicate truncated string */
- str->append('"');
+ str->qs_append("...", 3); /* Indicate truncated string */
+ str->qs_append('"');
}
#undef STMT_PRINT_MAXLEN
@@ -2119,15 +2122,16 @@ sp_instr_set::print(String *str)
/* 'var' should always be non-null, but just in case... */
if (var)
rsrv+= var->name.length;
- str->reserve(rsrv);
- str->append("set ");
+ if (str->reserve(rsrv))
+ return;
+ str->qs_append("set ", 4);
if (var)
{
- str->append(var->name.str, var->name.length);
- str->append('@');
+ 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);
}
@@ -2184,8 +2188,9 @@ sp_instr_jump::execute(THD *thd, uint *nextp)
void
sp_instr_jump::print(String *str)
{
- str->reserve(12);
- str->append("jump ");
+ if (str->reserve(12))
+ return;
+ str->qs_append("jump ", 5);
str->qs_append(m_dest);
}
@@ -2266,10 +2271,11 @@ 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 ");
+ if (str->reserve(32))
+ return;
+ str->qs_append("jump_if ", 8);
str->qs_append(m_dest);
- str->append(' ');
+ str->qs_append(' ');
m_expr->print(str);
}
@@ -2327,10 +2333,11 @@ 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 ");
+ if (str->reserve(32))
+ return;
+ str->qs_append("jump_if_not ", 12);
str->qs_append(m_dest);
- str->append(' ');
+ str->qs_append(' ');
m_expr->print(str);
}
@@ -2385,10 +2392,11 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp)
void
sp_instr_freturn::print(String *str)
{
- str->reserve(12);
- str->append("freturn ");
+ if (str->reserve(32))
+ return;
+ str->qs_append("freturn ", 8);
str->qs_append((uint)m_type);
- str->append(' ');
+ str->qs_append(' ');
m_value->print(str);
}
@@ -2413,27 +2421,28 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
void
sp_instr_hpush_jump::print(String *str)
{
- str->reserve(32);
- str->append("hpush_jump ");
+ if (str->reserve(32))
+ return;
+ str->qs_append("hpush_jump ", 11);
str->qs_append(m_dest);
- str->append(' ');
+ str->qs_append(' ');
str->qs_append(m_frame);
switch (m_type)
{
case SP_HANDLER_NONE:
- str->append(" NONE"); // This would be a bug
+ str->qs_append(" NONE", 5); // This would be a bug
break;
case SP_HANDLER_EXIT:
- str->append(" EXIT");
+ str->qs_append(" EXIT", 5);
break;
case SP_HANDLER_CONTINUE:
- str->append(" CONTINUE");
+ str->qs_append(" CONTINUE", 9);
break;
case SP_HANDLER_UNDO:
- str->append(" UNDO");
+ str->qs_append(" UNDO", 5);
break;
default:
- str->append(" UNKNOWN:"); // This would be a bug as well
+ str->qs_append(" UNKNOWN:", 9); // This would be a bug as well
str->qs_append(m_type);
}
}
@@ -2470,8 +2479,9 @@ sp_instr_hpop::execute(THD *thd, uint *nextp)
void
sp_instr_hpop::print(String *str)
{
- str->reserve(12);
- str->append("hpop ");
+ if (str->reserve(12))
+ return;
+ str->qs_append("hpop ", 5);
str->qs_append(m_count);
}
@@ -2505,12 +2515,13 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp)
void
sp_instr_hreturn::print(String *str)
{
- str->reserve(16);
- str->append("hreturn ");
+ if (str->reserve(20))
+ return;
+ str->qs_append("hreturn ", 8);
str->qs_append(m_frame);
if (m_dest)
{
- str->append(' ');
+ str->qs_append(' ');
str->qs_append(m_dest);
}
}
@@ -2559,14 +2570,18 @@ void
sp_instr_cpush::print(String *str)
{
LEX_STRING n;
+ uint rsrv= 12;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
- str->reserve(32);
- str->append("cpush ");
+ if (found)
+ rsrv+= n.length;
+ if (str->reserve(rsrv))
+ return;
+ str->qs_append("cpush ", 6);
if (found)
{
- str->append(n.str, n.length);
- str->append('@');
+ str->qs_append(n.str, n.length);
+ str->qs_append('@');
}
str->qs_append(m_cursor);
}
@@ -2589,8 +2604,9 @@ sp_instr_cpop::execute(THD *thd, uint *nextp)
void
sp_instr_cpop::print(String *str)
{
- str->reserve(12);
- str->append("cpop ");
+ if (str->reserve(12))
+ return;
+ str->qs_append("cpop ", 5);
str->qs_append(m_count);
}
@@ -2665,14 +2681,18 @@ void
sp_instr_copen::print(String *str)
{
LEX_STRING n;
+ uint rsrv= 16;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
- str->reserve(32);
- str->append("copen ");
+ if (found)
+ rsrv+= n.length;
+ if (str->reserve(rsrv))
+ return;
+ str->qs_append("copen ", 6);
if (found)
{
- str->append(n.str, n.length);
- str->append('@');
+ str->qs_append(n.str, n.length);
+ str->qs_append('@');
}
str->qs_append(m_cursor);
}
@@ -2702,14 +2722,18 @@ void
sp_instr_cclose::print(String *str)
{
LEX_STRING n;
+ uint rsrv= 16;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
- str->reserve(32);
- str->append("cclose ");
+ if (found)
+ rsrv+= n.length;
+ if (str->reserve(rsrv))
+ return;
+ str->qs_append("cclose ", 7);
if (found)
{
- str->append(n.str, n.length);
- str->append('@');
+ str->qs_append(n.str, n.length);
+ str->qs_append('@');
}
str->qs_append(m_cursor);
}
@@ -2740,22 +2764,27 @@ sp_instr_cfetch::print(String *str)
List_iterator_fast<struct sp_pvar> li(m_varlist);
sp_pvar_t *pv;
LEX_STRING n;
+ uint rsrv= 16;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
- str->reserve(32);
- str->append("cfetch ");
+ if (found)
+ rsrv+= n.length;
+ if (str->reserve(rsrv))
+ return;
+ str->qs_append("cfetch ", 7);
if (found)
{
- str->append(n.str, n.length);
- str->append('@');
+ str->qs_append(n.str, n.length);
+ str->qs_append('@');
}
str->qs_append(m_cursor);
while ((pv= li++))
{
- str->reserve(16);
- str->append(' ');
- str->append(pv->name.str, pv->name.length);
- str->append('@');
+ if (str->reserve(pv->name.length+10))
+ return;
+ str->qs_append(' ');
+ str->qs_append(pv->name.str, pv->name.length);
+ str->qs_append('@');
str->qs_append(pv->offset);
}
}
@@ -2779,8 +2808,9 @@ sp_instr_error::execute(THD *thd, uint *nextp)
void
sp_instr_error::print(String *str)
{
- str->reserve(12);
- str->append("error ");
+ if (str->reserve(12))
+ return;
+ str->qs_append("error ", 6);
str->qs_append(m_errcode);
}
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 32824b75847..147173ab4d8 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -177,19 +177,18 @@ sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped)
- For printing of sp_instr_set. (Debug mode only.)
*/
sp_pvar_t *
-sp_pcontext::find_pvar(uint i)
+sp_pcontext::find_pvar(uint offset)
{
- if (m_poffset <= i && i < m_poffset + m_pvar.elements)
+ if (m_poffset <= offset && offset < m_poffset + m_pvar.elements)
{ // This frame
sp_pvar_t *p;
- get_dynamic(&m_pvar, (gptr)&p, i - m_poffset);
+ get_dynamic(&m_pvar, (gptr)&p, offset - m_poffset);
return p;
}
- else if (m_parent)
- return m_parent->find_pvar(i); // Some previous frame
- else
- return NULL; // index out of bounds
+ if (m_parent)
+ return m_parent->find_pvar(offset); // Some previous frame
+ return NULL; // index out of bounds
}
void
@@ -360,16 +359,15 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
This is only used for debugging.
*/
my_bool
-sp_pcontext::find_cursor(uint i, LEX_STRING *n)
+sp_pcontext::find_cursor(uint offset, LEX_STRING *n)
{
- if (m_coffset <= i && i < m_coffset + m_cursor.elements)
+ if (m_coffset <= offset && offset < m_coffset + m_cursor.elements)
{ // This frame
- get_dynamic(&m_cursor, (gptr)n, i - m_poffset);
+ get_dynamic(&m_cursor, (gptr)n, offset - m_coffset);
return TRUE;
}
- else if (m_parent)
- return m_parent->find_cursor(i, n); // Some previous frame
- else
- return FALSE; // index out of bounds
+ if (m_parent)
+ return m_parent->find_cursor(offset, n); // Some previous frame
+ return FALSE; // index out of bounds
}
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 77e749fe3ad..b8dd1742f7e 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -170,9 +170,9 @@ class sp_pcontext : public Sql_alloc
sp_pvar_t *
find_pvar(LEX_STRING *name, my_bool scoped=0);
- // Find by index
+ // Find by offset
sp_pvar_t *
- find_pvar(uint i);
+ find_pvar(uint offset);
//
// Labels
@@ -252,9 +252,9 @@ class sp_pcontext : public Sql_alloc
my_bool
find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0);
- /* Find by index (for debugging only) */
+ /* Find by offset (for debugging only) */
my_bool
- find_cursor(uint i, LEX_STRING *n);
+ find_cursor(uint offset, LEX_STRING *n);
inline uint
max_cursors()
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f46f0d3e5a1..5eafda5f685 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4576,7 +4576,8 @@ end_with_restore_list:
else
sp= sp_find_function(thd, lex->spname);
if (!sp || !sp->show_routine_code(thd))
- { /* We don't distinguish between errors for now */
+ {
+ /* We don't distinguish between errors for now */
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
SP_COM_STRING(lex), lex->spname->m_name.str);
goto error;