From f8be48bb4f27e4472346987dde341f393dc7d944 Mon Sep 17 00:00:00 2001
From: "anozdrin/alik@ibm." <>
Date: Thu, 14 Jun 2007 18:49:17 +0400
Subject: [PATCH] This is the 3-rd part of patch for BUG#11986: remove
 redundant "body" from Event_parse_data (use sp_head::m_body).

---
 sql/event_data_objects.cc  | 157 +++++++++++++------------------------
 sql/event_data_objects.h   |  14 ++--
 sql/event_db_repository.cc |  28 +++++--
 sql/sql_yacc.yy            |   5 +-
 4 files changed, 82 insertions(+), 122 deletions(-)

diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 727aecfa7bb..757cf7f93fb 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -94,17 +94,18 @@ Event_parse_data::Event_parse_data()
   :on_completion(Event_basic::ON_COMPLETION_DROP),
   status(Event_basic::ENABLED),
   do_not_create(FALSE),
-   item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
-   starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
-   item_expression(NULL), expression(0)
+  body_changed(FALSE),
+  item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
+  starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
+  item_expression(NULL), expression(0)
 {
   DBUG_ENTER("Event_parse_data::Event_parse_data");
 
   /* Actually in the parser STARTS is always set */
   starts= ends= execute_at= 0;
 
-  body.str= comment.str= NULL;
-  body.length= comment.length= 0;
+  comment.str= NULL;
+  comment.length= 0;
 
   DBUG_VOID_RETURN;
 }
@@ -137,36 +138,6 @@ Event_parse_data::init_name(THD *thd, sp_name *spn)
 }
 
 
-/*
-  Set body of the event - what should be executed.
-
-  SYNOPSIS
-    Event_parse_data::init_body()
-      thd   THD
-
-  NOTE
-    The body is extracted by copying all data between the
-    start of the body set by another method and the current pointer in Lex.
-
-    See related code in sp_head::init_strings().
-*/
-
-void
-Event_parse_data::init_body(THD *thd)
-{
-  DBUG_ENTER("Event_parse_data::init_body");
-
-  /* This method is called from within the parser, from sql_yacc.yy */
-  DBUG_ASSERT(thd->m_lip != NULL);
-
-  body.length= thd->m_lip->get_cpp_ptr() - body_begin;
-  body.str= thd->strmake(body_begin, body.length);
-  trim_whitespace(thd->charset(), & body);
-
-  DBUG_VOID_RETURN;
-}
-
-
 /*
   This function is called on CREATE EVENT or ALTER EVENT.  When either
   ENDS or AT is in the past, we are trying to create an event that
@@ -788,36 +759,32 @@ Event_timed::init()
 }
 
 
-/*
-  Loads an event's body from a row from mysql.event
-
-  SYNOPSIS
-    Event_job_data::load_from_row(THD *thd, TABLE *table)
-
-  RETURN VALUE
-    0                      OK
-    EVEX_GET_FIELD_FAILED  Error
-
-  NOTES
-    This method is silent on errors and should behave like that. Callers
-    should handle throwing of error messages. The reason is that the class
-    should not know about how to deal with communication.
+/**
+  Load an event's body from a row from mysql.event.
+  @details This method is silent on errors and should behave like that.
+  Callers should handle throwing of error messages. The reason is that the
+  class should not know about how to deal with communication.
+
+  @return Operation status
+    @retval FALSE OK
+    @retval TRUE  Error
 */
 
-int
+bool
 Event_job_data::load_from_row(THD *thd, TABLE *table)
 {
   char *ptr;
   uint len;
+  LEX_STRING tz_name;
+
   DBUG_ENTER("Event_job_data::load_from_row");
 
   if (!table)
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (table->s->fields < ET_FIELD_COUNT)
-    goto error;
+    DBUG_RETURN(TRUE);
 
-  LEX_STRING tz_name;
   if (load_string_fields(table->field,
                          ET_FIELD_DB, &dbname,
                          ET_FIELD_NAME, &name,
@@ -825,10 +792,10 @@ Event_job_data::load_from_row(THD *thd, TABLE *table)
                          ET_FIELD_DEFINER, &definer,
                          ET_FIELD_TIME_ZONE, &tz_name,
                          ET_FIELD_COUNT))
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (load_time_zone(thd, tz_name))
-    goto error;
+    DBUG_RETURN(TRUE);
 
   ptr= strchr(definer.str, '@');
 
@@ -845,29 +812,23 @@ Event_job_data::load_from_row(THD *thd, TABLE *table)
 
   sql_mode= (ulong) table->field[ET_FIELD_SQL_MODE]->val_int();
 
-  DBUG_RETURN(0);
-error:
-  DBUG_RETURN(EVEX_GET_FIELD_FAILED);
+  DBUG_RETURN(FALSE);
 }
 
 
-/*
-  Loads an event from a row from mysql.event
-
-  SYNOPSIS
-    Event_queue_element::load_from_row(THD *thd, TABLE *table)
+/**
+  Load an event's body from a row from mysql.event.
 
-  RETURN VALUE
-    0                      OK
-    EVEX_GET_FIELD_FAILED  Error
+  @details This method is silent on errors and should behave like that.
+  Callers should handle throwing of error messages. The reason is that the
+  class should not know about how to deal with communication.
 
-  NOTES
-    This method is silent on errors and should behave like that. Callers
-    should handle throwing of error messages. The reason is that the class
-    should not know about how to deal with communication.
+  @return Operation status
+    @retval FALSE OK
+    @retval TRUE  Error
 */
 
-int
+bool
 Event_queue_element::load_from_row(THD *thd, TABLE *table)
 {
   char *ptr;
@@ -877,10 +838,10 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
   DBUG_ENTER("Event_queue_element::load_from_row");
 
   if (!table)
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (table->s->fields < ET_FIELD_COUNT)
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (load_string_fields(table->field,
                          ET_FIELD_DB, &dbname,
@@ -888,10 +849,10 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
                          ET_FIELD_DEFINER, &definer,
                          ET_FIELD_TIME_ZONE, &tz_name,
                          ET_FIELD_COUNT))
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (load_time_zone(thd, tz_name))
-    goto error;
+    DBUG_RETURN(TRUE);
 
   starts_null= table->field[ET_FIELD_STARTS]->is_null();
   if (!starts_null)
@@ -921,7 +882,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
   {
     if (table->field[ET_FIELD_EXECUTE_AT]->get_date(&time,
                                                     TIME_NO_ZERO_DATE))
-      goto error;
+      DBUG_RETURN(TRUE);
     execute_at= sec_since_epoch_TIME(&time);
   }
 
@@ -940,13 +901,13 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
 
     table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_str(&str);
     if (!(tmp.length= str.length()))
-      goto error;
+      DBUG_RETURN(TRUE);
 
     tmp.str= str.c_ptr_safe();
 
     i= find_string_in_array(interval_type_to_name, &tmp, system_charset_info);
     if (i < 0)
-      goto error;
+      DBUG_RETURN(TRUE);
     interval= (interval_type) i;
   }
 
@@ -959,7 +920,7 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
   last_executed_changed= FALSE;
 
   if ((ptr= get_field(&mem_root, table->field[ET_FIELD_STATUS])) == NullS)
-    goto error;
+    DBUG_RETURN(TRUE);
 
   DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", name.str, ptr));
 
@@ -978,40 +939,34 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
     break;
   }
   if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS)
-    goto error;
+    DBUG_RETURN(TRUE);
   originator = table->field[ET_FIELD_ORIGINATOR]->val_int(); 
 
   /* ToDo : Andrey . Find a way not to allocate ptr on event_mem_root */
   if ((ptr= get_field(&mem_root,
                       table->field[ET_FIELD_ON_COMPLETION])) == NullS)
-    goto error;
+    DBUG_RETURN(TRUE);
 
   on_completion= (ptr[0]=='D'? Event_queue_element::ON_COMPLETION_DROP:
                                Event_queue_element::ON_COMPLETION_PRESERVE);
 
-  DBUG_RETURN(0);
-error:
-  DBUG_RETURN(EVEX_GET_FIELD_FAILED);
+  DBUG_RETURN(FALSE);
 }
 
 
-/*
-  Loads an event from a row from mysql.event
-
-  SYNOPSIS
-    Event_timed::load_from_row(THD *thd, TABLE *table)
+/**
+  Load an event's body from a row from mysql.event.
 
-  RETURN VALUE
-    0                      OK
-    EVEX_GET_FIELD_FAILED  Error
+  @details This method is silent on errors and should behave like that.
+  Callers should handle throwing of error messages. The reason is that the
+  class should not know about how to deal with communication.
 
-  NOTES
-    This method is silent on errors and should behave like that. Callers
-    should handle throwing of error messages. The reason is that the class
-    should not know about how to deal with communication.
+  @return Operation status
+    @retval FALSE OK
+    @retval TRUE  Error
 */
 
-int
+bool
 Event_timed::load_from_row(THD *thd, TABLE *table)
 {
   char *ptr;
@@ -1020,12 +975,12 @@ Event_timed::load_from_row(THD *thd, TABLE *table)
   DBUG_ENTER("Event_timed::load_from_row");
 
   if (Event_queue_element::load_from_row(thd, table))
-    goto error;
+    DBUG_RETURN(TRUE);
 
   if (load_string_fields(table->field,
                          ET_FIELD_BODY, &body,
                          ET_FIELD_COUNT))
-    goto error;
+    DBUG_RETURN(TRUE);
 
 
   ptr= strchr(definer.str, '@');
@@ -1052,9 +1007,7 @@ Event_timed::load_from_row(THD *thd, TABLE *table)
 
   sql_mode= (ulong) table->field[ET_FIELD_SQL_MODE]->val_int();
 
-  DBUG_RETURN(0);
-error:
-  DBUG_RETURN(EVEX_GET_FIELD_FAILED);
+  DBUG_RETURN(FALSE);
 }
 
 
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index 8e03ab19602..d79732780ff 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -77,7 +77,7 @@ class Event_basic
   Event_basic();
   virtual ~Event_basic();
 
-  virtual int
+  virtual bool
   load_from_row(THD *thd, TABLE *table) = 0;
 
 protected:
@@ -119,7 +119,7 @@ class Event_queue_element : public Event_basic
   Event_queue_element();
   virtual ~Event_queue_element();
 
-  virtual int
+  virtual bool
   load_from_row(THD *thd, TABLE *table);
 
   bool
@@ -157,7 +157,7 @@ class Event_timed : public Event_queue_element
   void
   init();
 
-  virtual int
+  virtual bool
   load_from_row(THD *thd, TABLE *table);
 
   int
@@ -176,7 +176,7 @@ class Event_job_data : public Event_basic
 
   Event_job_data();
 
-  virtual int
+  virtual bool
   load_from_row(THD *thd, TABLE *table);
 
   bool
@@ -205,12 +205,11 @@ class Event_parse_data : public Sql_alloc
   */
   bool do_not_create;
 
-  const char *body_begin;
+  bool body_changed;
 
   LEX_STRING dbname;
   LEX_STRING name;
   LEX_STRING definer;// combination of user and host
-  LEX_STRING body;
   LEX_STRING comment;
 
   Item* item_starts;
@@ -235,9 +234,6 @@ class Event_parse_data : public Sql_alloc
   bool
   check_parse_data(THD *thd);
 
-  void
-  init_body(THD *thd);
-
 private:
 
   void
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index fa17ee8a380..703c4160216 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -15,6 +15,7 @@
 
 #include "mysql_priv.h"
 #include "event_db_repository.h"
+#include "sp_head.h"
 #include "event_data_objects.h"
 #include "events.h"
 #include "sql_show.h"
@@ -141,7 +142,10 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
 */
 
 static bool
-mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
+mysql_event_fill_row(THD *thd,
+                     TABLE *table,
+                     Event_parse_data *et,
+                     sp_head *sp,
                      my_bool is_update)
 {
   CHARSET_INFO *scs= system_charset_info;
@@ -152,7 +156,6 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
 
   DBUG_PRINT("info", ("dbname=[%s]", et->dbname.str));
   DBUG_PRINT("info", ("name  =[%s]", et->name.str));
-  DBUG_PRINT("info", ("body  =[%s]", et->body.str));
 
   if (table->s->fields < ET_FIELD_COUNT)
   {
@@ -187,11 +190,18 @@ mysql_event_fill_row(THD *thd, TABLE *table, Event_parse_data *et,
     Change the SQL_MODE only if body was present in an ALTER EVENT and of course
     always during CREATE EVENT.
   */
-  if (et->body.str)
+  if (et->body_changed)
   {
+    DBUG_ASSERT(sp->m_body.str);
+
     fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE);
-    if (fields[f_num= ET_FIELD_BODY]->store(et->body.str, et->body.length, scs))
+
+    if (fields[f_num= ET_FIELD_BODY]->store(sp->m_body.str,
+                                            sp->m_body.length,
+                                            scs))
+    {
       goto err_truncate;
+    }
   }
 
   if (et->expression)
@@ -513,10 +523,12 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
 {
   int ret= 1;
   TABLE *table= NULL;
+  sp_head *sp= thd->lex->sphead;
 
   DBUG_ENTER("Event_db_repository::create_event");
 
   DBUG_PRINT("info", ("open mysql.event for update"));
+  DBUG_ASSERT(sp);
 
   if (open_event_table(thd, TL_WRITE, &table))
     goto end;
@@ -561,7 +573,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
     goto end;
   }
 
-  if (parse_data->body.length > table->field[ET_FIELD_BODY]->field_length)
+  if (sp->m_body.length > table->field[ET_FIELD_BODY]->field_length)
   {
     my_error(ER_TOO_LONG_BODY, MYF(0), parse_data->name.str);
     goto end;
@@ -573,7 +585,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
     mysql_event_fill_row() calls my_error() in case of error so no need to
     handle it here
   */
-  if (mysql_event_fill_row(thd, table, parse_data, FALSE))
+  if (mysql_event_fill_row(thd, table, parse_data, sp, FALSE))
     goto end;
 
   table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE);
@@ -617,7 +629,9 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
 {
   CHARSET_INFO *scs= system_charset_info;
   TABLE *table= NULL;
+  sp_head *sp= thd->lex->sphead;
   int ret= 1;
+
   DBUG_ENTER("Event_db_repository::update_event");
 
   /* None or both must be set */
@@ -661,7 +675,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
     mysql_event_fill_row() calls my_error() in case of error so no need to
     handle it here
   */
-  if (mysql_event_fill_row(thd, table, parse_data, TRUE))
+  if (mysql_event_fill_row(thd, table, parse_data, sp, TRUE))
     goto end;
 
   if (new_dbname)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a17a0475ac5..8a4c99b6d00 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1873,9 +1873,6 @@ ev_sql_stmt:
             lex->sphead->m_chistics= &lex->sp_chistics;
 
             lex->sphead->m_body_begin= lip->get_cpp_ptr();
-            
-            lex->event_parse_data->body_begin= lip->get_cpp_ptr();
-
           }
           ev_sql_stmt_inner
           {
@@ -1888,7 +1885,7 @@ ev_sql_stmt:
 
             lex->sp_chistics.suid= SP_IS_SUID;  //always the definer!
 
-            lex->event_parse_data->init_body(thd);
+            lex->event_parse_data->body_changed= TRUE;
           }
       ;
 
-- 
2.30.9