17 #include "my_global.h"
20 #include "sql_parse.h"
50 static bool load_from_db(THD *thd,
53 const char *event_name,
89 Event_creation_ctx::load_from_db(THD *thd,
92 const char *event_name,
102 bool invalid_creation_ctx= FALSE;
104 if (load_charset(event_mem_root,
105 event_tbl->field[ET_FIELD_CHARACTER_SET_CLIENT],
106 thd->variables.character_set_client,
109 sql_print_warning(
"Event '%s'.'%s': invalid value "
110 "in column mysql.event.character_set_client.",
111 (
const char *) db_name,
112 (
const char *) event_name);
114 invalid_creation_ctx= TRUE;
117 if (load_collation(event_mem_root,
118 event_tbl->field[ET_FIELD_COLLATION_CONNECTION],
119 thd->variables.collation_connection,
122 sql_print_warning(
"Event '%s'.'%s': invalid value "
123 "in column mysql.event.collation_connection.",
124 (
const char *) db_name,
125 (
const char *) event_name);
127 invalid_creation_ctx= TRUE;
130 if (load_collation(event_mem_root,
131 event_tbl->field[ET_FIELD_DB_COLLATION],
135 sql_print_warning(
"Event '%s'.'%s': invalid value "
136 "in column mysql.event.db_collation.",
137 (
const char *) db_name,
138 (
const char *) event_name);
140 invalid_creation_ctx= TRUE;
149 db_cl= get_default_db_collation(thd, db_name);
155 return invalid_creation_ctx;
175 if (!(dbname.str= my_strndup(db.str, dbname.length= db.length, MYF(MY_WME))))
177 if (!(name.str= my_strndup(n.str, name.length= n.length, MYF(MY_WME))))
193 Event_queue_element_for_exec::~Event_queue_element_for_exec()
207 Event_basic::Event_basic()
209 DBUG_ENTER(
"Event_basic::Event_basic");
211 init_sql_alloc(&mem_root, 256, 512);
212 dbname.str= name.str= NULL;
213 dbname.length= name.length= 0;
226 Event_basic::~Event_basic()
228 DBUG_ENTER(
"Event_basic::~Event_basic");
229 free_root(&mem_root, MYF(0));
246 Event_basic::load_string_fields(
Field **fields, ...)
250 enum enum_events_table_field field_name;
253 DBUG_ENTER(
"Event_basic::load_string_fields");
255 va_start(args, fields);
256 field_name= (
enum enum_events_table_field) va_arg(args,
int);
257 while (field_name < ET_FIELD_COUNT)
260 if ((field_value->str= get_field(&mem_root, fields[field_name])) == NullS)
265 field_value->length= strlen(field_value->str);
267 field_name= (
enum enum_events_table_field) va_arg(args,
int);
276 Event_basic::load_time_zone(THD *thd,
const LEX_STRING tz_name)
278 String str(tz_name.str, &my_charset_latin1);
279 time_zone= my_tz_find(thd, &str);
281 return (time_zone == NULL);
292 Event_queue_element::Event_queue_element():
297 DBUG_ENTER(
"Event_queue_element::Event_queue_element");
299 starts= ends= execute_at= last_executed= 0;
300 starts_null= ends_null= execute_at_null= TRUE;
312 Event_queue_element::~Event_queue_element()
324 Event_timed::Event_timed():
325 created(0), modified(0), sql_mode(0)
327 DBUG_ENTER(
"Event_timed::Event_timed");
340 Event_timed::~Event_timed()
352 Event_job_data::Event_job_data()
367 DBUG_ENTER(
"Event_timed::init");
369 definer_user.str= definer_host.str= body.str= comment.str= NULL;
370 definer_user.length= definer_host.length= body.length= comment.length= 0;
397 DBUG_ENTER(
"Event_job_data::load_from_row");
402 if (table->s->fields < ET_FIELD_COUNT)
405 if (load_string_fields(table->field,
406 ET_FIELD_DB, &dbname,
407 ET_FIELD_NAME, &name,
408 ET_FIELD_BODY, &body,
409 ET_FIELD_DEFINER, &definer,
410 ET_FIELD_TIME_ZONE, &tz_name,
414 if (load_time_zone(thd, tz_name))
417 Event_creation_ctx::load_from_db(thd, &mem_root, dbname.str, name.str, table,
420 ptr= strchr(definer.str,
'@');
425 len= ptr - definer.str;
426 definer_user.str= strmake_root(&mem_root, definer.str, len);
427 definer_user.length= len;
428 len= definer.length - len - 1;
430 definer_host.str= strmake_root(&mem_root, ptr + 1, len);
431 definer_host.length= len;
433 sql_mode= (sql_mode_t) table->field[ET_FIELD_SQL_MODE]->val_int();
458 DBUG_ENTER(
"Event_queue_element::load_from_row");
463 if (table->s->fields < ET_FIELD_COUNT)
466 if (load_string_fields(table->field,
467 ET_FIELD_DB, &dbname,
468 ET_FIELD_NAME, &name,
469 ET_FIELD_DEFINER, &definer,
470 ET_FIELD_TIME_ZONE, &tz_name,
474 if (load_time_zone(thd, tz_name))
477 starts_null= table->field[ET_FIELD_STARTS]->is_null();
478 my_bool not_used= FALSE;
481 table->field[ET_FIELD_STARTS]->get_date(&time, TIME_NO_ZERO_DATE);
485 ends_null= table->field[ET_FIELD_ENDS]->is_null();
488 table->field[ET_FIELD_ENDS]->get_date(&time, TIME_NO_ZERO_DATE);
492 if (!table->field[ET_FIELD_INTERVAL_EXPR]->is_null())
493 expression= table->field[ET_FIELD_INTERVAL_EXPR]->val_int();
500 execute_at_null= table->field[ET_FIELD_EXECUTE_AT]->is_null();
501 DBUG_ASSERT(!(starts_null && ends_null && !expression && execute_at_null));
502 if (!expression && !execute_at_null)
504 if (table->field[ET_FIELD_EXECUTE_AT]->get_date(&time,
516 if (!table->field[ET_FIELD_TRANSIENT_INTERVAL]->is_null())
519 char buff[MAX_FIELD_WIDTH];
520 String str(buff,
sizeof(buff), &my_charset_bin);
523 table->field[ET_FIELD_TRANSIENT_INTERVAL]->val_str(&str);
524 if (!(tmp.length= str.length()))
527 tmp.str= str.c_ptr_safe();
529 i= find_string_in_array(interval_type_to_name, &tmp, system_charset_info);
532 interval= (interval_type) i;
535 if (!table->field[ET_FIELD_LAST_EXECUTED]->is_null())
537 table->field[ET_FIELD_LAST_EXECUTED]->get_date(&time,
542 if ((ptr= get_field(&mem_root, table->field[ET_FIELD_STATUS])) == NullS)
545 DBUG_PRINT(
"load_from_row", (
"Event [%s] is [%s]", name.str, ptr));
551 status = Event_parse_data::ENABLED;
554 status = Event_parse_data::SLAVESIDE_DISABLED;
558 status = Event_parse_data::DISABLED;
561 if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS)
563 originator = table->field[ET_FIELD_ORIGINATOR]->val_int();
566 if ((ptr= get_field(&mem_root,
567 table->field[ET_FIELD_ON_COMPLETION])) == NullS)
570 on_completion= (ptr[0]==
'D'? Event_parse_data::ON_COMPLETION_DROP:
571 Event_parse_data::ON_COMPLETION_PRESERVE);
595 DBUG_ENTER(
"Event_timed::load_from_row");
600 if (load_string_fields(table->field,
601 ET_FIELD_BODY, &body,
602 ET_FIELD_BODY_UTF8, &body_utf8,
606 if (Event_creation_ctx::load_from_db(thd, &mem_root, dbname.str, name.str,
607 table, &creation_ctx))
609 push_warning_printf(thd,
610 Sql_condition::WARN_LEVEL_WARN,
611 ER_EVENT_INVALID_CREATION_CTX,
612 ER(ER_EVENT_INVALID_CREATION_CTX),
613 (
const char *) dbname.str,
614 (
const char *) name.str);
617 ptr= strchr(definer.str,
'@');
622 len= ptr - definer.str;
623 definer_user.str= strmake_root(&mem_root, definer.str, len);
624 definer_user.length= len;
625 len= definer.length - len - 1;
627 definer_host.str= strmake_root(&mem_root, ptr + 1, len);
628 definer_host.length= len;
630 created= table->field[ET_FIELD_CREATED]->val_int();
631 modified= table->field[ET_FIELD_MODIFIED]->val_int();
633 comment.str= get_field(&mem_root, table->field[ET_FIELD_COMMENT]);
634 if (comment.str != NullS)
635 comment.length= strlen(comment.str);
639 sql_mode= (sql_mode_t) table->field[ET_FIELD_SQL_MODE]->val_int();
654 interval_type scale,
INTERVAL interval)
656 if (date_add_interval(ltime, scale, interval))
689 bool get_next_time(
const Time_zone *time_zone, my_time_t *next,
690 my_time_t start, my_time_t time_now,
691 int i_value, interval_type i_type)
693 DBUG_ENTER(
"get_next_time");
694 DBUG_PRINT(
"enter", (
"start: %lu now: %lu", (
long) start, (
long) time_now));
696 DBUG_ASSERT(start <= time_now);
698 longlong months=0, seconds=0;
704 case INTERVAL_QUARTER:
706 case INTERVAL_YEAR_MONTH:
713 seconds= i_value*24*3600;
715 case INTERVAL_DAY_HOUR:
717 seconds= i_value*3600;
719 case INTERVAL_DAY_MINUTE:
720 case INTERVAL_HOUR_MINUTE:
721 case INTERVAL_MINUTE:
724 case INTERVAL_DAY_SECOND:
725 case INTERVAL_HOUR_SECOND:
726 case INTERVAL_MINUTE_SECOND:
727 case INTERVAL_SECOND:
730 case INTERVAL_DAY_MICROSECOND:
731 case INTERVAL_HOUR_MICROSECOND:
732 case INTERVAL_MINUTE_MICROSECOND:
733 case INTERVAL_SECOND_MICROSECOND:
734 case INTERVAL_MICROSECOND:
744 DBUG_PRINT(
"info", (
"seconds: %ld months: %ld", (
long) seconds, (
long) months));
756 memset(&interval, 0,
sizeof(interval));
757 my_time_t next_time= 0;
761 longlong seconds_diff;
763 bool negative= calc_time_diff(&local_now, &local_start, 1,
764 &seconds_diff, µsec_diff);
771 interval.second= seconds_diff - seconds_diff % seconds + seconds;
772 next_time= add_interval(&local_start, time_zone,
773 INTERVAL_SECOND, interval);
778 if (next_time <= time_now)
786 DBUG_ASSERT(negative || next_time > 0);
834 interval.second= seconds;
837 next_time= add_interval(&local_start, time_zone,
838 INTERVAL_SECOND, interval);
842 while (next_time <= time_now);
847 long diff_months= ((long) local_now.year - (
long) local_start.year)*12 +
848 ((
long) local_now.month - (long) local_start.month);
868 interval.month= (ulong) (diff_months - diff_months % months);
869 next_time= add_interval(&local_start, time_zone,
870 INTERVAL_MONTH, interval);
874 if (next_time <= time_now)
876 interval.month= (ulong) months;
877 next_time= add_interval(&local_start, time_zone,
878 INTERVAL_MONTH, interval);
884 DBUG_ASSERT(time_now < next_time);
889 DBUG_PRINT(
"info", (
"next_time: %ld", (
long) next_time));
890 DBUG_RETURN(next_time == 0);
910 Event_queue_element::compute_next_execution_time()
913 DBUG_ENTER(
"Event_queue_element::compute_next_execution_time");
914 DBUG_PRINT(
"enter", (
"starts: %lu ends: %lu last_executed: %lu this: 0x%lx",
915 (
long) starts, (
long) ends, (
long) last_executed,
918 if (status != Event_parse_data::ENABLED)
920 DBUG_PRINT(
"compute_next_execution_time",
921 (
"Event %s is DISABLED", name.str));
930 DBUG_PRINT(
"info",(
"One-time event %s.%s of was already executed",
931 dbname.str, name.str));
932 dropped= (on_completion == Event_parse_data::ON_COMPLETION_DROP);
933 DBUG_PRINT(
"info",(
"One-time event will be dropped: %d.", dropped));
935 status= Event_parse_data::DISABLED;
940 time_now= (my_time_t) current_thd->query_start();
942 DBUG_PRINT(
"info",(
"NOW: [%lu]", (ulong) time_now));
945 if (!ends_null && ends < time_now)
947 DBUG_PRINT(
"info", (
"NOW after ENDS, don't execute anymore"));
950 execute_at_null= TRUE;
951 if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
953 DBUG_PRINT(
"info", (
"Dropped: %d", dropped));
954 status= Event_parse_data::DISABLED;
964 if (!starts_null && time_now <= starts)
966 if (time_now == starts && starts == last_executed)
974 DBUG_PRINT(
"info", (
"STARTS is future, NOW <= STARTS,sched for STARTS"));
980 execute_at_null= FALSE;
985 if (!starts_null && !ends_null)
993 DBUG_PRINT(
"info", (
"Both STARTS & ENDS are set"));
996 DBUG_PRINT(
"info", (
"Not executed so far."));
1000 my_time_t next_exec;
1002 if (get_next_time(time_zone, &next_exec, starts, time_now,
1003 (
int) expression, interval))
1007 if (ends < next_exec)
1009 DBUG_PRINT(
"info", (
"Next execution of %s after ENDS. Stop executing.",
1013 execute_at_null= TRUE;
1014 if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
1016 status= Event_parse_data::DISABLED;
1020 DBUG_PRINT(
"info",(
"Next[%lu]", (ulong) next_exec));
1021 execute_at= next_exec;
1022 execute_at_null= FALSE;
1027 else if (starts_null && ends_null)
1030 DBUG_PRINT(
"info", (
"Neither STARTS nor ENDS are set"));
1037 my_time_t next_exec;
1038 if (get_next_time(time_zone, &next_exec, starts, time_now,
1039 (
int) expression, interval))
1041 execute_at= next_exec;
1042 DBUG_PRINT(
"info",(
"Next[%lu]", (ulong) next_exec));
1047 DBUG_PRINT(
"info", (
"Execute NOW"));
1048 execute_at= time_now;
1050 execute_at_null= FALSE;
1057 DBUG_PRINT(
"info", (
"STARTS is set"));
1066 DBUG_PRINT(
"info", (
"Not executed so far."));
1070 my_time_t next_exec;
1071 if (get_next_time(time_zone, &next_exec, starts, time_now,
1072 (
int) expression, interval))
1074 execute_at= next_exec;
1075 DBUG_PRINT(
"info",(
"Next[%lu]", (ulong) next_exec));
1077 execute_at_null= FALSE;
1082 DBUG_PRINT(
"info", (
"STARTS is not set. ENDS is set"));
1091 execute_at= time_now;
1094 my_time_t next_exec;
1096 if (get_next_time(time_zone, &next_exec, starts, time_now,
1097 (
int) expression, interval))
1100 if (ends < next_exec)
1102 DBUG_PRINT(
"info", (
"Next execution after ENDS. Stop executing."));
1104 execute_at_null= TRUE;
1105 status= Event_parse_data::DISABLED;
1106 if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
1111 DBUG_PRINT(
"info", (
"Next[%lu]", (ulong) next_exec));
1112 execute_at= next_exec;
1113 execute_at_null= FALSE;
1120 DBUG_PRINT(
"info", (
"ret: 0 execute_at: %lu", (
long) execute_at));
1123 DBUG_PRINT(
"info", (
"ret=1"));
1138 Event_queue_element::mark_last_executed(THD *thd)
1140 last_executed= (my_time_t) thd->query_start();
1149 const char *
name, uint len)
1151 char dtime_buff[20*2+32];
1152 buf->append(STRING_WITH_LEN(
" "));
1153 buf->append(name, len);
1154 buf->append(STRING_WITH_LEN(
" '"));
1161 buf->append(dtime_buff, my_datetime_to_str(&time, dtime_buff, 0));
1162 buf->append(STRING_WITH_LEN(
"'"));
1182 Event_timed::get_create_event(THD *thd,
String *buf)
1184 char tmp_buf[2 * STRING_BUFFER_USUAL_SIZE];
1185 String expr_buf(tmp_buf,
sizeof(tmp_buf), system_charset_info);
1188 DBUG_ENTER(
"get_create_event");
1189 DBUG_PRINT(
"ret_info",(
"body_len=[%d]body=[%s]",
1190 (
int) body.length, body.str));
1194 DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
1196 buf->append(STRING_WITH_LEN(
"CREATE "));
1197 append_definer(thd, buf, &definer_user, &definer_host);
1198 buf->append(STRING_WITH_LEN(
"EVENT "));
1199 append_identifier(thd, buf, name.str, name.length);
1203 buf->append(STRING_WITH_LEN(
" ON SCHEDULE EVERY "));
1204 buf->append(expr_buf);
1206 LEX_STRING *ival= &interval_type_to_name[interval];
1207 buf->append(ival->str, ival->length);
1210 append_datetime(buf, time_zone, starts, STRING_WITH_LEN(
"STARTS"));
1213 append_datetime(buf, time_zone, ends, STRING_WITH_LEN(
"ENDS"));
1217 append_datetime(buf, time_zone, execute_at,
1218 STRING_WITH_LEN(
"ON SCHEDULE AT"));
1221 if (on_completion == Event_parse_data::ON_COMPLETION_DROP)
1222 buf->append(STRING_WITH_LEN(
" ON COMPLETION NOT PRESERVE "));
1224 buf->append(STRING_WITH_LEN(
" ON COMPLETION PRESERVE "));
1226 if (status == Event_parse_data::ENABLED)
1227 buf->append(STRING_WITH_LEN(
"ENABLE"));
1228 else if (status == Event_parse_data::SLAVESIDE_DISABLED)
1229 buf->append(STRING_WITH_LEN(
"DISABLE ON SLAVE"));
1231 buf->append(STRING_WITH_LEN(
"DISABLE"));
1235 buf->append(STRING_WITH_LEN(
" COMMENT "));
1236 append_unescaped(buf, comment.str, comment.length);
1238 buf->append(STRING_WITH_LEN(
" DO "));
1239 buf->append(body.str, body.length);
1250 Event_job_data::construct_sp_sql(THD *thd,
String *sp_sql)
1253 const uint STATIC_SQL_LENGTH= 44;
1255 DBUG_ENTER(
"Event_job_data::construct_sp_sql");
1261 buffer.length= STATIC_SQL_LENGTH + name.length + body.length;
1262 if (! (buffer.str= (
char*) thd->alloc(buffer.length)))
1265 sp_sql->set(buffer.str, buffer.length, system_charset_info);
1269 sp_sql->append(C_STRING_WITH_LEN(
"CREATE "));
1270 sp_sql->append(C_STRING_WITH_LEN(
"PROCEDURE "));
1277 append_identifier(thd, sp_sql, name.str, name.length);
1285 sp_sql->append(C_STRING_WITH_LEN(
"() SQL SECURITY INVOKER "));
1287 sp_sql->append(body.str, body.length);
1289 DBUG_RETURN(thd->is_fatal_error);
1299 Event_job_data::construct_drop_event_sql(THD *thd,
String *sp_sql)
1302 const uint STATIC_SQL_LENGTH= 14;
1304 DBUG_ENTER(
"Event_job_data::construct_drop_event_sql");
1306 buffer.length= STATIC_SQL_LENGTH + name.length*2 + dbname.length*2;
1307 if (! (buffer.str= (
char*) thd->alloc(buffer.length)))
1310 sp_sql->set(buffer.str, buffer.length, system_charset_info);
1313 sp_sql->append(C_STRING_WITH_LEN(
"DROP EVENT "));
1314 append_identifier(thd, sp_sql, dbname.str, dbname.length);
1315 sp_sql->append(
'.');
1316 append_identifier(thd, sp_sql, name.str, name.length);
1318 DBUG_RETURN(thd->is_fatal_error);
1332 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1333 Security_context event_sctx, *save_sctx= NULL;
1337 PSI_statement_locker *parent_locker= thd->m_statement_psi;
1339 DBUG_ENTER(
"Event_job_data::execute");
1359 thd->set_db(dbname.str, dbname.length);
1363 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1364 if (event_sctx.change_security_context(thd,
1365 &definer_user, &definer_host,
1366 &dbname, &save_sctx))
1368 sql_print_error(
"Event Scheduler: "
1369 "[%s].[%s.%s] execution failed, "
1370 "failed to authenticate the user.",
1371 definer.str, dbname.str, name.str);
1376 if (
check_access(thd, EVENT_ACL, dbname.str, NULL, NULL, 0, 0))
1384 sql_print_error(
"Event Scheduler: "
1385 "[%s].[%s.%s] execution failed, "
1386 "user no longer has EVENT privilege.",
1387 definer.str, dbname.str, name.str);
1391 if (construct_sp_sql(thd, &sp_sql))
1402 thd->variables.sql_mode= sql_mode;
1403 thd->variables.time_zone= time_zone;
1405 thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
1408 Parser_state parser_state;
1409 if (parser_state.init(thd, thd->query(), thd->query_length()))
1412 thd->m_statement_psi= NULL;
1413 if (
parse_sql(thd, & parser_state, creation_ctx))
1415 sql_print_error(
"Event Scheduler: "
1416 "%serror during compilation of %s.%s",
1417 thd->is_fatal_error ?
"fatal " :
"",
1418 (
const char *) dbname.str, (
const char *) name.str);
1419 thd->m_statement_psi= parent_locker;
1422 thd->m_statement_psi= parent_locker;
1426 sp_head *sphead= thd->lex->sphead;
1428 DBUG_ASSERT(sphead);
1430 if (thd->enable_slow_log)
1431 sphead->
m_flags|= sp_head::LOG_SLOW_STATEMENTS;
1432 sphead->
m_flags|= sp_head::LOG_GENERAL_LOG;
1434 sphead->set_info(0, 0, &thd->lex->sp_chistics, sql_mode);
1435 sphead->set_creation_ctx(creation_ctx);
1446 if (drop && !thd->is_fatal_error)
1452 sql_print_information(
"Event Scheduler: Dropping %s.%s",
1453 (
const char *) dbname.str, (
const char *) name.str);
1458 if (construct_drop_event_sql(thd, &sp_sql))
1462 ulong saved_master_access;
1464 thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
1475 saved_master_access= thd->security_ctx->master_access;
1476 thd->security_ctx->master_access |= SUPER_ACL;
1477 bool save_tx_read_only= thd->tx_read_only;
1478 thd->tx_read_only=
false;
1482 thd->tx_read_only= save_tx_read_only;
1483 thd->security_ctx->master_access= saved_master_access;
1486 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1488 event_sctx.restore_security_context(thd, save_sctx);
1490 thd->lex->unit.cleanup();
1491 thd->end_statement();
1492 thd->cleanup_after_query();
1496 DBUG_PRINT(
"info", (
"EXECUTED %s.%s ret: %d", dbname.str, name.str, ret));
1518 return !sortcmp_lex_string(et->dbname, db, system_charset_info);
1539 return !sortcmp_lex_string(name, b->name, system_charset_info) &&
1540 !sortcmp_lex_string(db, b->dbname, system_charset_info);