summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <dlenev@brandersnatch.localdomain>2005-04-30 20:23:40 +0400
committerunknown <dlenev@brandersnatch.localdomain>2005-04-30 20:23:40 +0400
commite6ce543f051a2d9dc3ddfaecc4397cdd526701bd (patch)
tree2531ee01896fe3400fbbf89a3673a17ba54fd42f
parent8ebd64bb464d34c51e218fd7024f8140e28da4b2 (diff)
downloadmariadb-git-e6ce543f051a2d9dc3ddfaecc4397cdd526701bd.tar.gz
Fix for Bug #9913 "udf_deinit is not called after execution of PS"
(aka "deinit is not called when calling udf from trigger"). We should call udf_deinit() function during cleanup phase after prepared (or ordinary) statement execution instead of calling it from Item's desctructor. No test case is provided since it is hard to test UDF's from our test suite. sql/item_func.cc: udf_handler: Moved all functionality from udf_handler::~udf_handler() to udf_handler::cleanup() method which will be called after each PS execution, thus allowing udf_deinit() to be executed symetrically with udf_init() (which is executed for each execution of PS). Added Item_udf_func::cleanup() which performs proper cleanup after execution of PS with UDF function. sql/item_func.h: Added Item_udf_func::cleanup() method to perform cleanup properly after execution of PS with UDF function. sql/item_sum.cc: Added Item_udf_sum::cleanup() method to perform cleanup properly after execution of PS with aggregate UDF function. sql/item_sum.h: Added Item_udf_sum::cleanup() method to perform cleanup properly after execution of PS with aggregate UDF function. sql/sql_udf.h: Added udf_handler::cleanup() method declaration which is responsible for cleaning up UDF execution context at the end of execution of statement (using ~udf_handler() for this purprose did not worked for PS).
-rw-r--r--sql/item_func.cc15
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_sum.cc11
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/sql_udf.h1
5 files changed, 29 insertions, 0 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 2b38584fe23..d1d89b70d10 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1618,6 +1618,13 @@ longlong Item_func_bit_count::val_int()
udf_handler::~udf_handler()
{
+ /* Everything should be properly cleaned up by this moment. */
+ DBUG_ASSERT(not_original || !(initialized || buffers));
+}
+
+
+void udf_handler::cleanup()
+{
if (!not_original)
{
if (initialized)
@@ -1629,9 +1636,11 @@ udf_handler::~udf_handler()
(*deinit)(&initid);
}
free_udf(u_d);
+ initialized= FALSE;
}
if (buffers) // Because of bug in ecc
delete [] buffers;
+ buffers= 0;
}
}
@@ -1871,6 +1880,12 @@ String *udf_handler::val_str(String *str,String *save_str)
}
+void Item_udf_func::cleanup()
+{
+ udf.cleanup();
+ Item_func::cleanup();
+}
+
double Item_func_udf_float::val()
{
diff --git a/sql/item_func.h b/sql/item_func.h
index 3a309f4ae99..7244fc73a42 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -786,6 +786,7 @@ public:
fixed= 1;
return res;
}
+ void cleanup();
Item_result result_type () const { return udf.result_type(); }
table_map not_null_tables() const { return 0; }
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 7e9c5d09136..dd4cda4ff91 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1449,6 +1449,17 @@ bool Item_udf_sum::add()
DBUG_RETURN(0);
}
+void Item_udf_sum::cleanup()
+{
+ /*
+ udf_handler::cleanup() nicely handles case when we have not
+ original item but one created by copy_or_same() method.
+ */
+ udf.cleanup();
+ Item_sum::cleanup();
+}
+
+
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_sum_udf_float(thd, this);
diff --git a/sql/item_sum.h b/sql/item_sum.h
index dab136e4716..040d9395e3a 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -550,6 +550,7 @@ public:
bool add();
void reset_field() {};
void update_field() {};
+ void cleanup();
};
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index d1f99a6d232..acb04e949a3 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -67,6 +67,7 @@ class udf_handler :public Sql_alloc
bool get_arguments();
bool fix_fields(THD *thd,struct st_table_list *tlist,Item_result_field *item,
uint arg_count,Item **args);
+ void cleanup();
double val(my_bool *null_value)
{
if (get_arguments())