--- 5.1/libmysqld/Makefile.am	2007-08-04 03:44:46.000000000 +0200
+++ 5.1-procs/libmysqld/Makefile.am	2007-08-26 15:15:46.000000000 +0200
@@ -60,6 +60,7 @@
 	opt_sum.cc procedure.cc records.cc sql_acl.cc \
 	sql_load.cc discover.cc sql_locale.cc \
 	sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
+	procedure_calltrace.cc \
 	sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
 	sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
 	scheduler.cc sql_connect.cc sql_parse.cc \
--- 5.1/sql/Makefile.am	2007-07-04 22:06:26.000000000 +0200
+++ 5.1-procs/sql/Makefile.am	2007-08-26 15:15:30.000000000 +0200
@@ -102,6 +102,7 @@
 			sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
 			sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
 			sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
+			procedure_calltrace.cc procedure_calltrace.h \
 			slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \
 			rpl_utility.cc rpl_injector.cc rpl_rli.cc rpl_mi.cc \
 			rpl_reporting.cc \
--- 5.1/sql/procedure.cc	2006-12-30 21:02:07.000000000 +0100
+++ 5.1-procs/sql/procedure.cc	2007-08-26 15:15:55.000000000 +0200
@@ -23,6 +23,7 @@
 #include "mysql_priv.h"
 #include "procedure.h"
 #include "sql_analyse.h"			// Includes procedure
+#include "procedure_calltrace.h"	// Includes procedure
 #ifdef USE_PROC_RANGE
 #include "proc_range.h"
 #endif
@@ -37,6 +38,7 @@
   { "split_count",proc_count_range_init },	// Internal procedure at TCX
   { "matris_ranges",proc_matris_range_init },	// Internal procedure at TCX
 #endif
+  { "calltrace", proc_calltrace_init }, // Add Calltrace column to result
   { "analyse",proc_analyse_init }		// Analyse a result
 };
 
--- 5.1/sql/procedure_calltrace.cc	1970-01-01 01:00:00.000000000 +0100
+++ 5.1-procs/sql/procedure_calltrace.cc	2007-08-26 14:37:02.000000000 +0200
@@ -0,0 +1,107 @@
+/* Copyright (C) 2000-2006 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+
+/* procedure that creates a call trace of procedure member function calls */
+
+#ifdef USE_PRAGMA_IMPLEMENTATION
+#pragma implementation				// gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "procedure.h"
+
+#include "procedure_calltrace.h"
+
+// Create and register the actual procedure object
+Procedure *proc_calltrace_init(THD *thd, ORDER *param,
+							select_result *result,
+							List<Item> &field_list) 
+{
+  DBUG_ENTER("proc_calltrace_init");
+
+  proc_calltrace *pc = new proc_calltrace(result);
+
+  DBUG_RETURN(pc);
+}
+
+// modify the result set column types here
+bool proc_calltrace::change_columns(List<Item> &field_list)
+{
+  DBUG_ENTER("proc_calltrace::change_columns");
+
+  field_list.empty();
+
+  call_name = new Item_proc_string("Call", 255);
+
+  field_list.push_back(call_name);
+
+  this->field_list = field_list;
+
+  DBUG_RETURN(0);
+}
+
+// not used here and not in ANALYSE() either,
+// probably called for each row before grouping
+void proc_calltrace::add(void)
+{
+  DBUG_ENTER("proc_calltrace::add");
+
+  call_name->set("add");
+
+  result->send_data(field_list);
+
+  DBUG_VOID_RETURN;
+}
+
+// not used here and not in ANALYSE() either,
+// probably called whenever a group rows were fully processed 
+void proc_calltrace::end_group(void)
+{
+  DBUG_ENTER("proc_calltrace::end_group");
+
+  call_name->set("end_group");
+
+  result->send_data(field_list);
+
+  DBUG_VOID_RETURN;
+}
+
+// called before sending result rows, you may modify the results here
+int proc_calltrace::send_row(List<Item> &field_list __attribute__((unused)))
+{
+  DBUG_ENTER("proc_calltrace::send_row");
+
+  call_name->set("send_row");
+
+  if (result->send_data(this->field_list))
+	DBUG_RETURN(-1);
+
+  DBUG_RETURN(0);
+}
+
+// called after sending all result rows, 
+// you may add summary rows here as ANALYSE() does
+bool proc_calltrace::end_of_records(void)
+{
+  DBUG_ENTER("proc_calltrace::end_of_records");
+
+  call_name->set("end_of_records");
+
+  result->send_data(field_list);
+
+  DBUG_RETURN(0);
+}
+
--- 5.1/sql/procedure_calltrace.h	1970-01-01 01:00:00.000000000 +0100
+++ 5.1-procs/sql/procedure_calltrace.h	2007-08-26 14:20:54.000000000 +0200
@@ -0,0 +1,52 @@
+/* Copyright (C) 2000-2006 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+
+/* procedure that adds a RowNum column to any result */
+
+#ifdef USE_PRAGMA_INTERFACE
+#pragma interface				/* gcc class implementation */
+#endif
+
+#ifndef PROCEDURE_CALLTRACE_H
+#define PROCEDURE_CALLTRACE_H
+
+Procedure *proc_calltrace_init(THD *thd, ORDER *param,
+			     select_result *result,
+			     List<Item> &field_list);
+
+
+class proc_calltrace: public Procedure
+{
+protected:
+  Item_proc *call_name;
+  List<Item> field_list;
+
+public:
+  proc_calltrace(select_result *res) :Procedure(res, PROC_NO_SORT)
+  {}
+
+  ~proc_calltrace()
+  {}
+
+  virtual void add(void);
+  virtual bool change_columns(List<Item> &fields);
+  virtual int  send_row(List<Item> &fields);
+  virtual void end_group(void);
+  virtual bool end_of_records(void);
+
+};
+
+#endif
