From: Date: February 14 2006 12:12am Subject: bk commit into 5.1 tree (andrey:1.2097) BUG#16537 List-Archive: http://lists.mysql.com/commits/2554 X-Bug: 16537 Message-Id: <20060213231205.5715A32104@andrey.hristov.com> Below is the list of changes that have just been committed into a local 5.1 repository of andrey. When andrey does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2097 06/02/14 00:11:50 andrey@lmy004. +8 -0 fix for bug#16537 (Events: mysql.event.starts is null) - now when the event is created and STARTS is omitted then STARTS is implicitly CURRENT_TIMESTAMP - This CS also fixed incorrect presentation of STARTS/ENDS in I_S.EVENTS sql/sql_yacc.yy 1.454 06/02/14 00:11:41 andrey@lmy004. +1 -1 - if STARTS is omitted default to current_timestamp sql/sql_show.cc 1.302 06/02/14 00:11:41 andrey@lmy004. +23 -11 - don't show 0000-00-00 in I_S.EVENTS when the value is NULL sql/event_timed.cc 1.25 06/02/14 00:11:41 andrey@lmy004. +60 -28 - introduce xxx_null and change the usage of xxx.year to !xxx_null sql/event_executor.cc 1.23 06/02/14 00:11:41 andrey@lmy004. +9 -8 - check whether xxx_null instead of !xxxx.year sql/event.h 1.18 06/02/14 00:11:41 andrey@lmy004. +3 -0 - add flags whether starts, ends and execute_at are null or not sql/event.cc 1.24 06/02/14 00:11:41 andrey@lmy004. +27 -24 - check whether event_timed::starts_null only in case event_timed::expression is set, so for recurring events only - disable binlogging of CREATE EVENT statement. It should not be replicated but the result of the execution. Still the replication is untouched topic. mysql-test/t/events.test 1.13 06/02/14 00:11:41 andrey@lmy004. +32 -0 new test cases for bug #16537 (Events: mysql.event.starts is null) mysql-test/r/events.result 1.12 06/02/14 00:11:41 andrey@lmy004. +49 -1 results of new test cases # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: andrey # Host: lmy004. # Root: /work/mysql-5.1-bug16537 --- 1.301/sql/sql_show.cc 2006-02-09 09:34:36 +01:00 +++ 1.302/sql/sql_show.cc 2006-02-14 00:11:41 +01:00 @@ -3883,8 +3883,6 @@ { //type sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs); - //execute_at - sch_table->field[6]->set_null(); //interval_value sch_table->field[7]->set_notnull(); sch_table->field[7]->store((longlong) et.expression); @@ -3893,26 +3891,40 @@ sch_table->field[8]->set_notnull(); sch_table->field[8]->store(ival->str, ival->length, scs); //starts & ends - sch_table->field[10]->set_notnull(); - sch_table->field[10]->store_time(&et.starts, MYSQL_TIMESTAMP_DATETIME); - sch_table->field[11]->set_notnull(); - sch_table->field[11]->store_time(&et.ends, MYSQL_TIMESTAMP_DATETIME); } else { //type sch_table->field[5]->store(STRING_WITH_LEN("ONE TIME"), scs); - //execute_at - sch_table->field[6]->set_notnull(); - sch_table->field[6]->store_time(&et.execute_at, MYSQL_TIMESTAMP_DATETIME); //interval sch_table->field[7]->set_null(); //interval_type sch_table->field[8]->set_null(); - //starts & ends + } + + if (!et.execute_at_null) + { + sch_table->field[6]->set_notnull(); + sch_table->field[6]->store_time(&et.execute_at, MYSQL_TIMESTAMP_DATETIME); + } + else + sch_table->field[6]->set_null(); + + if (!et.starts_null) + { + sch_table->field[10]->set_notnull(); + sch_table->field[10]->store_time(&et.starts, MYSQL_TIMESTAMP_DATETIME); + } + else sch_table->field[10]->set_null(); - sch_table->field[11]->set_null(); + + if (!et.ends_null) + { + sch_table->field[11]->set_notnull(); + sch_table->field[11]->store_time(&et.ends, MYSQL_TIMESTAMP_DATETIME); } + else + sch_table->field[11]->set_null(); //status if (et.status == MYSQL_EVENT_ENABLED) --- 1.453/sql/sql_yacc.yy 2006-02-08 11:11:36 +01:00 +++ 1.454/sql/sql_yacc.yy 2006-02-14 00:11:41 +01:00 @@ -1474,7 +1474,7 @@ } ; -ev_starts: /* empty */ +ev_starts: /* empty */{Lex->et->init_starts(YYTHD, new Item_func_now_local());} | STARTS_SYM expr { LEX *lex= Lex; --- 1.11/mysql-test/r/events.result 2006-01-30 17:11:41 +01:00 +++ 1.12/mysql-test/r/events.result 2006-02-14 00:11:41 +01:00 @@ -13,6 +13,54 @@ drop event event2; create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; +CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost RECURRING NULL 10 INTERVAL_SECOND # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +0 1 +ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +1 1 +ALTER EVENT event_starts_test COMMENT "non-empty comment"; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +1 1 non-empty comment +ALTER EVENT event_starts_test COMMENT ""; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost ONE TIME 2020-02-02 17:00:02 NULL NULL # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +1 1 +DROP EVENT event_starts_test; +CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +0 0 +ALTER EVENT event_starts_test COMMENT "non-empty comment"; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +starts IS NULL ends IS NULL comment +0 0 non-empty comment +ALTER EVENT event_starts_test COMMENT ""; +SHOW EVENTS; +Db Name Definer Type Execute at Interval value Interval field Starts Ends Status +events_test event_starts_test root@localhost RECURRING NULL 20 INTERVAL_SECOND # # ENABLED +DROP EVENT event_starts_test; create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; select sleep(2); @@ -64,7 +112,7 @@ Grants for ev_test@localhost GRANT USAGE ON *.* TO 'ev_test'@'localhost' GRANT ALL PRIVILEGES ON `events_test`.* TO 'ev_test'@'localhost' -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `events_test2`.* TO 'ev_test'@'localhost' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `events_test2`.* TO 'ev_test'@'localhost' "Here comes an error:"; SHOW EVENTS; ERROR 42000: Access denied for user 'ev_test'@'localhost' to database 'events_test2' --- 1.12/mysql-test/t/events.test 2006-01-30 17:11:42 +01:00 +++ 1.13/mysql-test/t/events.test 2006-02-14 00:11:41 +01:00 @@ -15,6 +15,38 @@ create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end; drop event event2; +# BUG #16537 (Events: mysql.event.starts is null) +CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02'; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +ALTER EVENT event_starts_test COMMENT "non-empty comment"; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +ALTER EVENT event_starts_test COMMENT ""; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +DROP EVENT event_starts_test; +CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +ALTER EVENT event_starts_test COMMENT "non-empty comment"; +--replace_column 8 # 9 # +SHOW EVENTS; +SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test'; +ALTER EVENT event_starts_test COMMENT ""; +--replace_column 8 # 9 # +SHOW EVENTS; +DROP EVENT event_starts_test; +# +# create event e_43 on schedule every 1 second do set @a = 5; set global event_scheduler = 1; select sleep(2); --- 1.23/sql/event.cc 2006-01-30 13:31:16 +01:00 +++ 1.24/sql/event.cc 2006-02-14 00:11:41 +01:00 @@ -273,20 +273,6 @@ store(et->body.str, et->body.length, system_charset_info)) goto trunc_err; - if (et->starts.year) - { - table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF - table->field[EVEX_FIELD_STARTS]-> - store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); - } - - if (et->ends.year) - { - table->field[EVEX_FIELD_ENDS]->set_notnull(); - table->field[EVEX_FIELD_ENDS]-> - store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); - } - if (et->expression) { table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull(); @@ -300,18 +286,31 @@ table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1); table->field[EVEX_FIELD_EXECUTE_AT]->set_null(); + + if (!et->starts_null) + { + table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF + table->field[EVEX_FIELD_STARTS]-> + store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME); + } + + if (!et->ends_null) + { + table->field[EVEX_FIELD_ENDS]->set_notnull(); + table->field[EVEX_FIELD_ENDS]-> + store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME); + } } else if (et->execute_at.year) { - // fix_fields already called in init_execute_at table->field[EVEX_FIELD_INTERVAL_EXPR]->set_null(); table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); - + table->field[EVEX_FIELD_STARTS]->set_null(); + table->field[EVEX_FIELD_ENDS]->set_null(); + table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull(); table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at, MYSQL_TIMESTAMP_DATETIME); - - table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null(); } else { @@ -322,14 +321,17 @@ ((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time(); - if (et->comment.length) - if (table->field[field_num= EVEX_FIELD_COMMENT]-> - store(et->comment.str, et->comment.length, system_charset_info)) + if (et->comment.str) + { + if (table->field[field_num= EVEX_FIELD_COMMENT]->store(et->comment.str, + et->comment.length, + system_charset_info)) goto trunc_err; + } DBUG_RETURN(0); trunc_err: - my_error(ER_EVENT_DATA_TOO_LONG, MYF(0)); + my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), table->field[field_num]->field_name); DBUG_RETURN(EVEX_GENERAL_ERROR); } @@ -442,14 +444,15 @@ my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret); goto err; } - +/* if (mysql_bin_log.is_open()) { thd->clear_error(); - /* Such a statement can always go directly to binlog, no trans cache */ + // Such a statement can always go directly to binlog, no trans cache thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->query, thd->query_length, FALSE, FALSE); } +*/ *rows_affected= 1; ok: --- 1.17/sql/event.h 2006-01-31 17:22:28 +01:00 +++ 1.18/sql/event.h 2006-02-14 00:11:41 +01:00 @@ -100,6 +100,9 @@ TIME starts; TIME ends; TIME execute_at; + my_bool starts_null; + my_bool ends_null; + my_bool execute_at_null; longlong expression; interval_type interval; --- 1.22/sql/event_executor.cc 2006-01-30 17:54:11 +01:00 +++ 1.23/sql/event_executor.cc 2006-02-14 00:11:41 +01:00 @@ -203,7 +203,7 @@ if (init_event_thread(thd)) goto err; - + // make this thread invisible it has no vio -> show processlist won't see thd->system_thread= 1; @@ -321,8 +321,7 @@ et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*); DBUG_PRINT("evex main thread",("got event from the queue")); - if (et->execute_at.year > 1969 && - my_time_compare(&time_now, &et->execute_at) == -1) + if (!et->execute_at_null && my_time_compare(&time_now,&et->execute_at) == -1) { DBUG_PRINT("evex main thread",("still not the time for execution")); VOID(pthread_mutex_unlock(&LOCK_event_arrays)); @@ -359,8 +358,11 @@ #else event_executor_worker((void *) et); #endif - if ((et->execute_at.year && !et->expression) || - TIME_to_ulonglong_datetime(&et->execute_at) == 0) + /* + 1. For one-time event : year is > 0 and expression is 0 + 2. For recurring, expression is != -=> check execute_at_null in this case + */ + if ((et->execute_at.year && !et->expression) || et->execute_at_null) et->flags |= EVENT_EXEC_NO_MORE; if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED) @@ -481,9 +483,9 @@ #endif // thd->security_ctx->priv_host is char[MAX_HOSTNAME] - + strxnmov(thd->security_ctx->priv_host, sizeof(thd->security_ctx->priv_host), - event->definer_host.str, NullS); + event->definer_host.str, NullS); thd->security_ctx->user= thd->security_ctx->priv_user= my_strdup(event->definer_user.str, MYF(0)); @@ -506,7 +508,6 @@ if (ret == EVEX_COMPILE_ERROR) sql_print_information(" EVEX COMPILE ERROR for event %s.%s", event->dbname.str, event->name.str); - DBUG_PRINT("info", (" EVEX EXECUTED event %s.%s [EXPR:%d]. RetCode=%d", event->dbname.str, event->name.str, (int) event->expression, ret)); --- 1.24/sql/event_timed.cc 2006-01-30 17:54:11 +01:00 +++ 1.25/sql/event_timed.cc 2006-02-14 00:11:41 +01:00 @@ -41,6 +41,7 @@ set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME); set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME); set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME); + starts_null= ends_null= execute_at_null= TRUE; definer_user.str= definer_host.str= 0; definer_user.length= definer_host.length= 0; @@ -148,7 +149,13 @@ if (expr->fix_fields(thd, &expr)) DBUG_RETURN(EVEX_PARSE_ERROR); - + + if (!starts_null || !ends_null) + { + DBUG_PRINT("info", ("starts and/or ends are dissallowed")); + DBUG_RETURN(EVEX_PARSE_ERROR); + } + // let's check whether time is in the past thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t) thd->query_start()); @@ -161,14 +168,13 @@ TIME_to_ulonglong_datetime(&time_tmp)) DBUG_RETURN(EVEX_BAD_PARAMS); - /* This may result in a 1970-01-01 date if ltime is > 2037-xx-xx CONVERT_TZ has similar problem */ my_tz_UTC->gmt_sec_to_TIME(<ime, TIME_to_timestamp(thd,<ime, ¬_used)); - + execute_at_null= FALSE; execute_at= ltime; DBUG_RETURN(0); } @@ -320,6 +326,7 @@ my_tz_UTC->gmt_sec_to_TIME(<ime, TIME_to_timestamp(thd, <ime, ¬_used)); starts= ltime; + starts_null= FALSE; DBUG_RETURN(0); } @@ -367,11 +374,15 @@ CONVERT_TZ has similar problem */ my_tz_UTC->gmt_sec_to_TIME(<ime, TIME_to_timestamp(thd, <ime, ¬_used)); - - if (starts.year && my_time_compare(&starts, <ime) != -1) + /* + If we allow STARTS in the past check whether END is in the future compared + to thd->query_start()!!! + */ + if (!starts_null && my_time_compare(&starts, <ime) != -1) DBUG_RETURN(EVEX_BAD_PARAMS); ends= ltime; + ends_null= FALSE; DBUG_RETURN(0); } @@ -498,28 +509,37 @@ et->definer_host.str= strmake_root(mem_root, ptr + 1, len);//1: because of @ et->definer_host.length= len; - res1= table->field[EVEX_FIELD_STARTS]-> - get_date(&et->starts, TIME_NO_ZERO_DATE); + et->starts_null= table->field[EVEX_FIELD_STARTS]->is_null(); + res1= table->field[EVEX_FIELD_STARTS]->get_date(&et->starts,TIME_NO_ZERO_DATE); - res2= table->field[EVEX_FIELD_ENDS]-> - get_date(&et->ends, TIME_NO_ZERO_DATE); + et->ends_null= table->field[EVEX_FIELD_ENDS]->is_null(); + res2= table->field[EVEX_FIELD_ENDS]->get_date(&et->ends, TIME_NO_ZERO_DATE); - et->expression= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int(); - + if (!table->field[EVEX_FIELD_INTERVAL_EXPR]->is_null()) + et->expression= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int(); + else + et->expression= 0; /* If res1 and res2 are true then both fields are empty. Hence if EVEX_FIELD_EXECUTE_AT is empty there is an error. */ - if (res1 && res2 && !et->expression && table->field[EVEX_FIELD_EXECUTE_AT]-> - get_date(&et->execute_at, TIME_NO_ZERO_DATE)) + et->execute_at_null= table->field[EVEX_FIELD_EXECUTE_AT]->is_null(); + DBUG_ASSERT(!(et->starts_null && et->ends_null && !et->expression && + et->execute_at_null)); + if (!et->expression && + table->field[EVEX_FIELD_EXECUTE_AT]->get_date(&et->execute_at, + TIME_NO_ZERO_DATE)) goto error; /* In DB the values start from 1 but enum interval_type starts from 0 */ - et->interval= (interval_type) + if (!table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->is_null()) + et->interval= (interval_type) ((ulonglong) table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->val_int() - 1); + else + et->interval= (interval_type) 0; et->modified= table->field[EVEX_FIELD_CREATED]->val_int(); et->created= table->field[EVEX_FIELD_MODIFIED]->val_int(); @@ -676,14 +696,11 @@ //let's check whether it was executed if (last_executed.year) { - DBUG_PRINT("compute_next_execution_time", - ("One-time event %s was already executed", name.str)); - if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP) - { - DBUG_PRINT("compute_next_execution_time", - ("One-time event will be dropped.")); - dropped= true; - } + DBUG_PRINT("info",("One-time event %s.%s of was already executed", + dbname.str, name.str, definer.str)); + dropped= (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP); + DBUG_PRINT("info",("One-time event will be dropped=%d.", dropped)); + status= MYSQL_EVENT_DISABLED; status_changed= true; } @@ -710,10 +727,11 @@ #endif //if time_now is after ends don't execute anymore - if (ends.year && (tmp= my_time_compare(&ends, &time_now)) == -1) + if (!ends_null && (tmp= my_time_compare(&ends, &time_now)) == -1) { // time_now is after ends. don't execute anymore set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME); + execute_at_null= TRUE; if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP) dropped= true; status= MYSQL_EVENT_DISABLED; @@ -727,7 +745,7 @@ Let's check whether time_now is before starts. If so schedule for starts */ - if (starts.year && (tmp= my_time_compare(&time_now, &starts)) < 1) + if (!starts_null && (tmp= my_time_compare(&time_now, &starts)) < 1) { if (tmp == 0 && my_time_compare(&starts, &last_executed) == 0) { @@ -743,11 +761,12 @@ time_now before starts. Scheduling for starts */ execute_at= starts; + execute_at_null= FALSE; goto ret; } } - if (starts.year && ends.year) + if (!starts_null && !ends_null) { /* Both starts and m_ends are set and time_now is between them (incl.) @@ -756,7 +775,10 @@ If not set then schedule for now. */ if (!last_executed.year) + { execute_at= time_now; + execute_at_null= FALSE; + } else { TIME next_exec; @@ -769,15 +791,19 @@ { // Next execution after ends. No more executions set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME); + execute_at_null= TRUE; if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP) dropped= true; } else + { execute_at= next_exec; + execute_at_null= FALSE; + } } goto ret; } - else if (!starts.year && !ends.year) + else if (starts_null && ends_null) { // both starts and m_ends are not set, se we schedule for the next // based on last_executed @@ -789,11 +815,12 @@ else //last_executed not set. Schedule the event for now execute_at= time_now; + execute_at_null= FALSE; } else { //either starts or m_ends is set - if (starts.year) + if (!starts_null) { /* - starts is set. @@ -808,6 +835,7 @@ } else execute_at= starts; + execute_at_null= FALSE; } else { @@ -830,11 +858,15 @@ if (my_time_compare(&ends, &next_exec) == -1) { set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME); + execute_at_null= TRUE; if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP) dropped= true; } else + { execute_at= next_exec; + execute_at_null= FALSE; + } } } goto ret; @@ -1025,7 +1057,7 @@ if (!sphead && (ret= compile(thd, mem_root))) goto done; - + ret= sphead->execute_procedure(thd, &empty_item_list); VOID(pthread_mutex_lock(&this->LOCK_running));