You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

577 lines
15 KiB

Bug#35997 Event scheduler seems to let the server crash, if it is embedded. The event scheduler was not designed to work in embedded mode. This patch disables and excludes the event scheduler when the server is compiled for embedded build. libmysqld/Makefile.am: Reduce the amount of event code in an embedded build. mysql-test/t/events_trans.test: Disable test if run in embedded mode. sql/Makefile.am: Introduce definition HAVE_EVENT_SCHEDULER and one new source file. sql/event_data_objects.cc: Refactor Event_parse_data to new file. sql/event_data_objects.h: Refactor Event_parse_data to new file. Move global definitions to new file. sql/event_queue.cc: Move all parsed items to Event_parse_data for easier modularization. sql/events.cc: Move all parsed items to Event_parse_data for easier modularization. sql/mysqld.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.h: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_db.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_parse.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_show.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_test.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_yacc.yy: Only include event-code needed for parsing to reduce impact on embedded build. Move all constants to Event_parse_data class. mysql-test/r/events_embedded.result: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/r/is_embedded.require: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/t/events_embedded.test: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. sql/event_parse_data.cc: New file. Extracted Event_parse data into a new file. sql/event_parse_data.h: New file. Extracted Event_parse data into a new file.
18 years ago
Bug#35981: ALTER EVENT causes the server to change the PRESERVE option. If [NOT] PRESERVE was not given, parser always defaulted to NOT PRESERVE, making it impossible for the "not given = no change" rule to work in ALTER EVENT. Leaving out the PRESERVE-clause defaults to NOT PRESERVE on CREATE now, and to "no change" in ALTER. mysql-test/r/events_2.result: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. mysql-test/t/events_2.test: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. sql/event_db_repository.cc: If ALTER EVENT was given no PRESERVE-clause (meaning "no change"), we don't know the previous PRESERVE-setting by the time we check the parse-data. If ALTER EVENT was given dates that are in the past, we don't know how to react, lacking the PRESERVE-setting. Heal this by running the check later when we have actually read the previous EVENT-data. sql/event_parse_data.cc: Change default for ON COMPLETION to indicate, "not specified." Also defer throwing errors when ALTER EVENT is given dates in the past but not PRESERVE-clause until we know the previous PRESERVE-value. sql/event_parse_data.h: Add third state for ON COMPLETION [NOT] PRESERVE (preserve, don't, not specified). Make check_dates() public so we can defer this check until deeper in the callstack where we have all the required data. sql/sql_yacc.yy: If CREATE EVENT is not given ON COMPLETION [NOT] PRESERVE, we default to NOT, as per the docs.
18 years ago
Bug#35997 Event scheduler seems to let the server crash, if it is embedded. The event scheduler was not designed to work in embedded mode. This patch disables and excludes the event scheduler when the server is compiled for embedded build. libmysqld/Makefile.am: Reduce the amount of event code in an embedded build. mysql-test/t/events_trans.test: Disable test if run in embedded mode. sql/Makefile.am: Introduce definition HAVE_EVENT_SCHEDULER and one new source file. sql/event_data_objects.cc: Refactor Event_parse_data to new file. sql/event_data_objects.h: Refactor Event_parse_data to new file. Move global definitions to new file. sql/event_queue.cc: Move all parsed items to Event_parse_data for easier modularization. sql/events.cc: Move all parsed items to Event_parse_data for easier modularization. sql/mysqld.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.h: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_db.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_parse.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_show.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_test.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_yacc.yy: Only include event-code needed for parsing to reduce impact on embedded build. Move all constants to Event_parse_data class. mysql-test/r/events_embedded.result: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/r/is_embedded.require: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/t/events_embedded.test: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. sql/event_parse_data.cc: New file. Extracted Event_parse data into a new file. sql/event_parse_data.h: New file. Extracted Event_parse data into a new file.
18 years ago
Bug#35981: ALTER EVENT causes the server to change the PRESERVE option. If [NOT] PRESERVE was not given, parser always defaulted to NOT PRESERVE, making it impossible for the "not given = no change" rule to work in ALTER EVENT. Leaving out the PRESERVE-clause defaults to NOT PRESERVE on CREATE now, and to "no change" in ALTER. mysql-test/r/events_2.result: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. mysql-test/t/events_2.test: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. sql/event_db_repository.cc: If ALTER EVENT was given no PRESERVE-clause (meaning "no change"), we don't know the previous PRESERVE-setting by the time we check the parse-data. If ALTER EVENT was given dates that are in the past, we don't know how to react, lacking the PRESERVE-setting. Heal this by running the check later when we have actually read the previous EVENT-data. sql/event_parse_data.cc: Change default for ON COMPLETION to indicate, "not specified." Also defer throwing errors when ALTER EVENT is given dates in the past but not PRESERVE-clause until we know the previous PRESERVE-value. sql/event_parse_data.h: Add third state for ON COMPLETION [NOT] PRESERVE (preserve, don't, not specified). Make check_dates() public so we can defer this check until deeper in the callstack where we have all the required data. sql/sql_yacc.yy: If CREATE EVENT is not given ON COMPLETION [NOT] PRESERVE, we default to NOT, as per the docs.
18 years ago
Bug#35997 Event scheduler seems to let the server crash, if it is embedded. The event scheduler was not designed to work in embedded mode. This patch disables and excludes the event scheduler when the server is compiled for embedded build. libmysqld/Makefile.am: Reduce the amount of event code in an embedded build. mysql-test/t/events_trans.test: Disable test if run in embedded mode. sql/Makefile.am: Introduce definition HAVE_EVENT_SCHEDULER and one new source file. sql/event_data_objects.cc: Refactor Event_parse_data to new file. sql/event_data_objects.h: Refactor Event_parse_data to new file. Move global definitions to new file. sql/event_queue.cc: Move all parsed items to Event_parse_data for easier modularization. sql/events.cc: Move all parsed items to Event_parse_data for easier modularization. sql/mysqld.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.h: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_db.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_parse.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_show.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_test.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_yacc.yy: Only include event-code needed for parsing to reduce impact on embedded build. Move all constants to Event_parse_data class. mysql-test/r/events_embedded.result: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/r/is_embedded.require: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/t/events_embedded.test: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. sql/event_parse_data.cc: New file. Extracted Event_parse data into a new file. sql/event_parse_data.h: New file. Extracted Event_parse data into a new file.
18 years ago
Bug#35981: ALTER EVENT causes the server to change the PRESERVE option. If [NOT] PRESERVE was not given, parser always defaulted to NOT PRESERVE, making it impossible for the "not given = no change" rule to work in ALTER EVENT. Leaving out the PRESERVE-clause defaults to NOT PRESERVE on CREATE now, and to "no change" in ALTER. mysql-test/r/events_2.result: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. mysql-test/t/events_2.test: show that giving no PRESERVE-clause to ALTER EVENT results in no change. show that giving no PRESERVE-clause to CREATE EVENT defaults to NOT PRESERVE as per the docs. Show specifically that this is also handled correctly when trying to ALTER EVENTs into the past. sql/event_db_repository.cc: If ALTER EVENT was given no PRESERVE-clause (meaning "no change"), we don't know the previous PRESERVE-setting by the time we check the parse-data. If ALTER EVENT was given dates that are in the past, we don't know how to react, lacking the PRESERVE-setting. Heal this by running the check later when we have actually read the previous EVENT-data. sql/event_parse_data.cc: Change default for ON COMPLETION to indicate, "not specified." Also defer throwing errors when ALTER EVENT is given dates in the past but not PRESERVE-clause until we know the previous PRESERVE-value. sql/event_parse_data.h: Add third state for ON COMPLETION [NOT] PRESERVE (preserve, don't, not specified). Make check_dates() public so we can defer this check until deeper in the callstack where we have all the required data. sql/sql_yacc.yy: If CREATE EVENT is not given ON COMPLETION [NOT] PRESERVE, we default to NOT, as per the docs.
18 years ago
Bug#35997 Event scheduler seems to let the server crash, if it is embedded. The event scheduler was not designed to work in embedded mode. This patch disables and excludes the event scheduler when the server is compiled for embedded build. libmysqld/Makefile.am: Reduce the amount of event code in an embedded build. mysql-test/t/events_trans.test: Disable test if run in embedded mode. sql/Makefile.am: Introduce definition HAVE_EVENT_SCHEDULER and one new source file. sql/event_data_objects.cc: Refactor Event_parse_data to new file. sql/event_data_objects.h: Refactor Event_parse_data to new file. Move global definitions to new file. sql/event_queue.cc: Move all parsed items to Event_parse_data for easier modularization. sql/events.cc: Move all parsed items to Event_parse_data for easier modularization. sql/mysqld.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.h: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_db.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_parse.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_show.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_test.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_yacc.yy: Only include event-code needed for parsing to reduce impact on embedded build. Move all constants to Event_parse_data class. mysql-test/r/events_embedded.result: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/r/is_embedded.require: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/t/events_embedded.test: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. sql/event_parse_data.cc: New file. Extracted Event_parse data into a new file. sql/event_parse_data.h: New file. Extracted Event_parse data into a new file.
18 years ago
Bug#35997 Event scheduler seems to let the server crash, if it is embedded. The event scheduler was not designed to work in embedded mode. This patch disables and excludes the event scheduler when the server is compiled for embedded build. libmysqld/Makefile.am: Reduce the amount of event code in an embedded build. mysql-test/t/events_trans.test: Disable test if run in embedded mode. sql/Makefile.am: Introduce definition HAVE_EVENT_SCHEDULER and one new source file. sql/event_data_objects.cc: Refactor Event_parse_data to new file. sql/event_data_objects.h: Refactor Event_parse_data to new file. Move global definitions to new file. sql/event_queue.cc: Move all parsed items to Event_parse_data for easier modularization. sql/events.cc: Move all parsed items to Event_parse_data for easier modularization. sql/mysqld.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/set_var.h: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_db.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_parse.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_show.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_test.cc: Disable the event schedular subsystem if the server is compiled in embedded mode. sql/sql_yacc.yy: Only include event-code needed for parsing to reduce impact on embedded build. Move all constants to Event_parse_data class. mysql-test/r/events_embedded.result: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/r/is_embedded.require: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. mysql-test/t/events_embedded.test: Add test case to make sure the 'event_scheduler' can't be activated in embedded mode. sql/event_parse_data.cc: New file. Extracted Event_parse data into a new file. sql/event_parse_data.h: New file. Extracted Event_parse data into a new file.
18 years ago
  1. /* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software
  11. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
  12. #include "mysql_priv.h"
  13. #include "sp_head.h"
  14. #include "event_parse_data.h"
  15. /*
  16. Returns a new instance
  17. SYNOPSIS
  18. Event_parse_data::new_instance()
  19. RETURN VALUE
  20. Address or NULL in case of error
  21. NOTE
  22. Created on THD's mem_root
  23. */
  24. Event_parse_data *
  25. Event_parse_data::new_instance(THD *thd)
  26. {
  27. return new (thd->mem_root) Event_parse_data;
  28. }
  29. /*
  30. Constructor
  31. SYNOPSIS
  32. Event_parse_data::Event_parse_data()
  33. */
  34. Event_parse_data::Event_parse_data()
  35. :on_completion(Event_parse_data::ON_COMPLETION_DEFAULT),
  36. status(Event_parse_data::ENABLED),
  37. do_not_create(FALSE),
  38. body_changed(FALSE),
  39. item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
  40. starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
  41. item_expression(NULL), expression(0)
  42. {
  43. DBUG_ENTER("Event_parse_data::Event_parse_data");
  44. /* Actually in the parser STARTS is always set */
  45. starts= ends= execute_at= 0;
  46. comment.str= NULL;
  47. comment.length= 0;
  48. DBUG_VOID_RETURN;
  49. }
  50. /*
  51. Set a name of the event
  52. SYNOPSIS
  53. Event_parse_data::init_name()
  54. thd THD
  55. spn the name extracted in the parser
  56. */
  57. void
  58. Event_parse_data::init_name(THD *thd, sp_name *spn)
  59. {
  60. DBUG_ENTER("Event_parse_data::init_name");
  61. /* We have to copy strings to get them into the right memroot */
  62. dbname.length= spn->m_db.length;
  63. dbname.str= thd->strmake(spn->m_db.str, spn->m_db.length);
  64. name.length= spn->m_name.length;
  65. name.str= thd->strmake(spn->m_name.str, spn->m_name.length);
  66. if (spn->m_qname.length == 0)
  67. spn->init_qname(thd);
  68. DBUG_VOID_RETURN;
  69. }
  70. /*
  71. This function is called on CREATE EVENT or ALTER EVENT. When either
  72. ENDS or AT is in the past, we are trying to create an event that
  73. will never be executed. If it has ON COMPLETION NOT PRESERVE
  74. (default), then it would normally be dropped already, so on CREATE
  75. EVENT we give a warning, and do not create anyting. On ALTER EVENT
  76. we give a error, and do not change the event.
  77. If the event has ON COMPLETION PRESERVE, then we see if the event is
  78. created or altered to the ENABLED (default) state. If so, then we
  79. give a warning, and change the state to DISABLED.
  80. Otherwise it is a valid event in ON COMPLETION PRESERVE DISABLE
  81. state.
  82. */
  83. void
  84. Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
  85. {
  86. if (ltime_utc >= (my_time_t) thd->query_start())
  87. return;
  88. /*
  89. We'll come back later when we have the real on_completion value
  90. */
  91. if (on_completion == Event_parse_data::ON_COMPLETION_DEFAULT)
  92. return;
  93. if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
  94. {
  95. switch (thd->lex->sql_command) {
  96. case SQLCOM_CREATE_EVENT:
  97. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  98. ER_EVENT_CANNOT_CREATE_IN_THE_PAST,
  99. ER(ER_EVENT_CANNOT_CREATE_IN_THE_PAST));
  100. break;
  101. case SQLCOM_ALTER_EVENT:
  102. my_error(ER_EVENT_CANNOT_ALTER_IN_THE_PAST, MYF(0));
  103. break;
  104. default:
  105. DBUG_ASSERT(0);
  106. }
  107. do_not_create= TRUE;
  108. }
  109. else if (status == Event_parse_data::ENABLED)
  110. {
  111. status= Event_parse_data::DISABLED;
  112. push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  113. ER_EVENT_EXEC_TIME_IN_THE_PAST,
  114. ER(ER_EVENT_EXEC_TIME_IN_THE_PAST));
  115. }
  116. }
  117. /*
  118. Check time/dates in ALTER EVENT
  119. We check whether ALTER EVENT was given dates that are in the past.
  120. However to know how to react, we need the ON COMPLETION type. Hence,
  121. the check is deferred until we have the previous ON COMPLETION type
  122. from the event-db to fall back on if nothing was specified in the
  123. ALTER EVENT-statement.
  124. SYNOPSIS
  125. Event_parse_data::check_dates()
  126. thd Thread
  127. on_completion ON COMPLETION value currently in event-db.
  128. Will be overridden by value in ALTER EVENT if given.
  129. RETURN VALUE
  130. TRUE an error occurred, do not ALTER
  131. FALSE OK
  132. */
  133. bool
  134. Event_parse_data::check_dates(THD *thd, int previous_on_completion)
  135. {
  136. if (on_completion == Event_parse_data::ON_COMPLETION_DEFAULT)
  137. {
  138. on_completion= previous_on_completion;
  139. if (!ends_null)
  140. check_if_in_the_past(thd, ends);
  141. if (!execute_at_null)
  142. check_if_in_the_past(thd, execute_at);
  143. }
  144. return do_not_create;
  145. }
  146. /*
  147. Sets time for execution for one-time event.
  148. SYNOPSIS
  149. Event_parse_data::init_execute_at()
  150. thd Thread
  151. RETURN VALUE
  152. 0 OK
  153. ER_WRONG_VALUE Wrong value for execute at (reported)
  154. */
  155. int
  156. Event_parse_data::init_execute_at(THD *thd)
  157. {
  158. my_bool not_used;
  159. MYSQL_TIME ltime;
  160. my_time_t ltime_utc;
  161. DBUG_ENTER("Event_parse_data::init_execute_at");
  162. if (!item_execute_at)
  163. DBUG_RETURN(0);
  164. if (item_execute_at->fix_fields(thd, &item_execute_at))
  165. goto wrong_value;
  166. /* no starts and/or ends in case of execute_at */
  167. DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d",
  168. (starts_null && ends_null)));
  169. DBUG_ASSERT(starts_null && ends_null);
  170. if ((not_used= item_execute_at->get_date(&ltime, TIME_NO_ZERO_DATE)))
  171. goto wrong_value;
  172. ltime_utc= TIME_to_timestamp(thd,&ltime,&not_used);
  173. if (!ltime_utc)
  174. {
  175. DBUG_PRINT("error", ("Execute AT after year 2037"));
  176. goto wrong_value;
  177. }
  178. check_if_in_the_past(thd, ltime_utc);
  179. execute_at_null= FALSE;
  180. execute_at= ltime_utc;
  181. DBUG_RETURN(0);
  182. wrong_value:
  183. report_bad_value("AT", item_execute_at);
  184. DBUG_RETURN(ER_WRONG_VALUE);
  185. }
  186. /*
  187. Sets time for execution of multi-time event.s
  188. SYNOPSIS
  189. Event_parse_data::init_interval()
  190. thd Thread
  191. RETURN VALUE
  192. 0 OK
  193. EVEX_BAD_PARAMS Interval is not positive or MICROSECOND (reported)
  194. ER_WRONG_VALUE Wrong value for interval (reported)
  195. */
  196. int
  197. Event_parse_data::init_interval(THD *thd)
  198. {
  199. String value;
  200. INTERVAL interval_tmp;
  201. DBUG_ENTER("Event_parse_data::init_interval");
  202. if (!item_expression)
  203. DBUG_RETURN(0);
  204. switch (interval) {
  205. case INTERVAL_MINUTE_MICROSECOND:
  206. case INTERVAL_HOUR_MICROSECOND:
  207. case INTERVAL_DAY_MICROSECOND:
  208. case INTERVAL_SECOND_MICROSECOND:
  209. case INTERVAL_MICROSECOND:
  210. my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND");
  211. DBUG_RETURN(EVEX_BAD_PARAMS);
  212. default:
  213. break;
  214. }
  215. if (item_expression->fix_fields(thd, &item_expression))
  216. goto wrong_value;
  217. value.alloc(MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN);
  218. if (get_interval_value(item_expression, interval, &value, &interval_tmp))
  219. goto wrong_value;
  220. expression= 0;
  221. switch (interval) {
  222. case INTERVAL_YEAR:
  223. expression= interval_tmp.year;
  224. break;
  225. case INTERVAL_QUARTER:
  226. case INTERVAL_MONTH:
  227. expression= interval_tmp.month;
  228. break;
  229. case INTERVAL_WEEK:
  230. case INTERVAL_DAY:
  231. expression= interval_tmp.day;
  232. break;
  233. case INTERVAL_HOUR:
  234. expression= interval_tmp.hour;
  235. break;
  236. case INTERVAL_MINUTE:
  237. expression= interval_tmp.minute;
  238. break;
  239. case INTERVAL_SECOND:
  240. expression= interval_tmp.second;
  241. break;
  242. case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
  243. expression= interval_tmp.year* 12 + interval_tmp.month;
  244. break;
  245. case INTERVAL_DAY_HOUR:
  246. expression= interval_tmp.day* 24 + interval_tmp.hour;
  247. break;
  248. case INTERVAL_DAY_MINUTE:
  249. expression= (interval_tmp.day* 24 + interval_tmp.hour) * 60 +
  250. interval_tmp.minute;
  251. break;
  252. case INTERVAL_HOUR_SECOND: /* day is anyway 0 */
  253. case INTERVAL_DAY_SECOND:
  254. /* DAY_SECOND having problems because of leap seconds? */
  255. expression= ((interval_tmp.day* 24 + interval_tmp.hour) * 60 +
  256. interval_tmp.minute)*60
  257. + interval_tmp.second;
  258. break;
  259. case INTERVAL_HOUR_MINUTE:
  260. expression= interval_tmp.hour * 60 + interval_tmp.minute;
  261. break;
  262. case INTERVAL_MINUTE_SECOND:
  263. expression= interval_tmp.minute * 60 + interval_tmp.second;
  264. break;
  265. case INTERVAL_LAST:
  266. DBUG_ASSERT(0);
  267. default:
  268. ;/* these are the microsec stuff */
  269. }
  270. if (interval_tmp.neg || expression == 0 ||
  271. expression > EVEX_MAX_INTERVAL_VALUE)
  272. {
  273. my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0));
  274. DBUG_RETURN(EVEX_BAD_PARAMS);
  275. }
  276. DBUG_RETURN(0);
  277. wrong_value:
  278. report_bad_value("INTERVAL", item_expression);
  279. DBUG_RETURN(ER_WRONG_VALUE);
  280. }
  281. /*
  282. Sets STARTS.
  283. SYNOPSIS
  284. Event_parse_data::init_starts()
  285. expr how much?
  286. NOTES
  287. Note that activation time is not execution time.
  288. EVERY 5 MINUTE STARTS "2004-12-12 10:00:00" means that
  289. the event will be executed every 5 minutes but this will
  290. start at the date shown above. Expressions are possible :
  291. DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tommorow at
  292. same time.
  293. RETURN VALUE
  294. 0 OK
  295. ER_WRONG_VALUE Starts before now
  296. */
  297. int
  298. Event_parse_data::init_starts(THD *thd)
  299. {
  300. my_bool not_used;
  301. MYSQL_TIME ltime;
  302. my_time_t ltime_utc;
  303. DBUG_ENTER("Event_parse_data::init_starts");
  304. if (!item_starts)
  305. DBUG_RETURN(0);
  306. if (item_starts->fix_fields(thd, &item_starts))
  307. goto wrong_value;
  308. if ((not_used= item_starts->get_date(&ltime, TIME_NO_ZERO_DATE)))
  309. goto wrong_value;
  310. ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);
  311. if (!ltime_utc)
  312. goto wrong_value;
  313. DBUG_PRINT("info",("now: %ld starts: %ld",
  314. (long) thd->query_start(), (long) ltime_utc));
  315. starts_null= FALSE;
  316. starts= ltime_utc;
  317. DBUG_RETURN(0);
  318. wrong_value:
  319. report_bad_value("STARTS", item_starts);
  320. DBUG_RETURN(ER_WRONG_VALUE);
  321. }
  322. /*
  323. Sets ENDS (deactivation time).
  324. SYNOPSIS
  325. Event_parse_data::init_ends()
  326. thd THD
  327. NOTES
  328. Note that activation time is not execution time.
  329. EVERY 5 MINUTE ENDS "2004-12-12 10:00:00" means that
  330. the event will be executed every 5 minutes but this will
  331. end at the date shown above. Expressions are possible :
  332. DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tommorow at
  333. same time.
  334. RETURN VALUE
  335. 0 OK
  336. EVEX_BAD_PARAMS Error (reported)
  337. */
  338. int
  339. Event_parse_data::init_ends(THD *thd)
  340. {
  341. my_bool not_used;
  342. MYSQL_TIME ltime;
  343. my_time_t ltime_utc;
  344. DBUG_ENTER("Event_parse_data::init_ends");
  345. if (!item_ends)
  346. DBUG_RETURN(0);
  347. if (item_ends->fix_fields(thd, &item_ends))
  348. goto error_bad_params;
  349. DBUG_PRINT("info", ("convert to TIME"));
  350. if ((not_used= item_ends->get_date(&ltime, TIME_NO_ZERO_DATE)))
  351. goto error_bad_params;
  352. ltime_utc= TIME_to_timestamp(thd, &ltime, &not_used);
  353. if (!ltime_utc)
  354. goto error_bad_params;
  355. /* Check whether ends is after starts */
  356. DBUG_PRINT("info", ("ENDS after STARTS?"));
  357. if (!starts_null && starts >= ltime_utc)
  358. goto error_bad_params;
  359. check_if_in_the_past(thd, ltime_utc);
  360. ends_null= FALSE;
  361. ends= ltime_utc;
  362. DBUG_RETURN(0);
  363. error_bad_params:
  364. my_error(ER_EVENT_ENDS_BEFORE_STARTS, MYF(0));
  365. DBUG_RETURN(EVEX_BAD_PARAMS);
  366. }
  367. /*
  368. Prints an error message about invalid value. Internally used
  369. during input data verification
  370. SYNOPSIS
  371. Event_parse_data::report_bad_value()
  372. item_name The name of the parameter
  373. bad_item The parameter
  374. */
  375. void
  376. Event_parse_data::report_bad_value(const char *item_name, Item *bad_item)
  377. {
  378. char buff[120];
  379. String str(buff,(uint32) sizeof(buff), system_charset_info);
  380. String *str2= bad_item->fixed? bad_item->val_str(&str):NULL;
  381. my_error(ER_WRONG_VALUE, MYF(0), item_name, str2? str2->c_ptr_safe():"NULL");
  382. }
  383. /*
  384. Checks for validity the data gathered during the parsing phase.
  385. SYNOPSIS
  386. Event_parse_data::check_parse_data()
  387. thd Thread
  388. RETURN VALUE
  389. FALSE OK
  390. TRUE Error (reported)
  391. */
  392. bool
  393. Event_parse_data::check_parse_data(THD *thd)
  394. {
  395. bool ret;
  396. DBUG_ENTER("Event_parse_data::check_parse_data");
  397. DBUG_PRINT("info", ("execute_at: 0x%lx expr=0x%lx starts=0x%lx ends=0x%lx",
  398. (long) item_execute_at, (long) item_expression,
  399. (long) item_starts, (long) item_ends));
  400. init_name(thd, identifier);
  401. init_definer(thd);
  402. ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) ||
  403. init_ends(thd);
  404. check_originator_id(thd);
  405. DBUG_RETURN(ret);
  406. }
  407. /*
  408. Inits definer (definer_user and definer_host) during parsing.
  409. SYNOPSIS
  410. Event_parse_data::init_definer()
  411. thd Thread
  412. */
  413. void
  414. Event_parse_data::init_definer(THD *thd)
  415. {
  416. DBUG_ENTER("Event_parse_data::init_definer");
  417. DBUG_ASSERT(thd->lex->definer);
  418. const char *definer_user= thd->lex->definer->user.str;
  419. const char *definer_host= thd->lex->definer->host.str;
  420. size_t definer_user_len= thd->lex->definer->user.length;
  421. size_t definer_host_len= thd->lex->definer->host.length;
  422. DBUG_PRINT("info",("init definer_user thd->mem_root: 0x%lx "
  423. "definer_user: 0x%lx", (long) thd->mem_root,
  424. (long) definer_user));
  425. /* + 1 for @ */
  426. DBUG_PRINT("info",("init definer as whole"));
  427. definer.length= definer_user_len + definer_host_len + 1;
  428. definer.str= (char*) thd->alloc(definer.length + 1);
  429. DBUG_PRINT("info",("copy the user"));
  430. memcpy(definer.str, definer_user, definer_user_len);
  431. definer.str[definer_user_len]= '@';
  432. DBUG_PRINT("info",("copy the host"));
  433. memcpy(definer.str + definer_user_len + 1, definer_host, definer_host_len);
  434. definer.str[definer.length]= '\0';
  435. DBUG_PRINT("info",("definer [%s] initted", definer.str));
  436. DBUG_VOID_RETURN;
  437. }
  438. /**
  439. Set the originator id of the event to the server_id if executing on
  440. the master or set to the server_id of the master if executing on
  441. the slave. If executing on slave, also set status to SLAVESIDE_DISABLED.
  442. SYNOPSIS
  443. Event_parse_data::check_originator_id()
  444. */
  445. void Event_parse_data::check_originator_id(THD *thd)
  446. {
  447. /* Disable replicated events on slave. */
  448. if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) ||
  449. (thd->system_thread == SYSTEM_THREAD_SLAVE_IO))
  450. {
  451. DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED."));
  452. if ((status == Event_parse_data::ENABLED) ||
  453. (status == Event_parse_data::DISABLED))
  454. status = Event_parse_data::SLAVESIDE_DISABLED;
  455. originator = thd->server_id;
  456. }
  457. else
  458. originator = server_id;
  459. }