Commit e6ce543f authored by unknown's avatar unknown
Browse files

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).
parent 8ebd64bb
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1617,6 +1617,13 @@ longlong Item_func_bit_count::val_int()
#ifdef HAVE_DLOPEN

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)
  {
@@ -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()
{
+1 −0
Original line number Diff line number Diff line
@@ -786,6 +786,7 @@ class Item_udf_func :public Item_func
    fixed= 1;
    return res;
  }
  void cleanup();
  Item_result result_type () const { return udf.result_type(); }
  table_map not_null_tables() const { return 0; }
};
+11 −0
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -550,6 +550,7 @@ class Item_udf_sum : public Item_sum
  bool add();
  void reset_field() {};
  void update_field() {};
  void cleanup();
};


+1 −0
Original line number Diff line number Diff line
@@ -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())