Commit 7bd09ac2 authored by andrey@lmy004's avatar andrey@lmy004

manual merge

parents af294b28 36cfa4df
...@@ -106,7 +106,6 @@ drop event if exists event3; ...@@ -106,7 +106,6 @@ drop event if exists event3;
Warnings: Warnings:
Note 1305 Event event3 does not exist Note 1305 Event event3 does not exist
create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
set max_allowed_packet=128000000;
select count(*) from t_event3; select count(*) from t_event3;
count(*) count(*)
0 0
...@@ -232,6 +231,9 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status ...@@ -232,6 +231,9 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
CREATE TABLE event_like LIKE mysql.event; CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event; INSERT INTO event_like SELECT * FROM mysql.event;
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
SHOW CREATE TABLE mysql.event; SHOW CREATE TABLE mysql.event;
Table Create Table Table Create Table
...@@ -261,10 +263,9 @@ ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin d ...@@ -261,10 +263,9 @@ ALTER TABLE mysql.event MODIFY db char(64) character set utf8 collate utf8_bin d
SHOW EVENTS; SHOW EVENTS;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED events_test intact_check root@localhost RECURRING NULL 10 HOUR # # ENABLED
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default '';
Warnings:
Warning 1265 Data truncated for column 'db' at row 1
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log. ERROR HY000: Cannot load from mysql.event. Table probably corrupted. See error log.
ALTER TABLE mysql.event DROP comment, DROP starts; ALTER TABLE mysql.event DROP comment, DROP starts;
......
CREATE DATABASE IF NOT EXISTS events_test;
USE events_test;
CREATE TABLE table_1(a int);
CREATE TABLE table_2(a int);
CREATE TABLE table_3(a int);
CREATE TABLE table_4(a int);
SET GLOBAL event_scheduler=1;
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
CREATE EVENT start_n_end
ON SCHEDULE EVERY 1 SECOND
ENDS NOW() + INTERVAL 6 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO table_2 VALUES(1);
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
IF(SUM(a) >= 4, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
IF(SUM(a) >= 5, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
IF(SUM(a) > 0, 'OK', 'ERROR')
OK
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
IF(SUM(a) > 0, 'OK', 'ERROR')
OK
DROP EVENT two_sec;
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR')
OK
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR')
OK
DROP EVENT start_n_end;
"Already dropped because ended. Therefore an error."
DROP EVENT only_one_time;
ERROR HY000: Unknown event 'only_one_time'
"Already dropped because ended. Therefore an error."
DROP EVENT two_time;
ERROR HY000: Unknown event 'two_time'
DROP TABLE table_1;
DROP TABLE table_2;
DROP TABLE table_3;
DROP TABLE table_4;
DROP DATABASE events_test;
...@@ -101,7 +101,6 @@ set global event_scheduler = 0; ...@@ -101,7 +101,6 @@ set global event_scheduler = 0;
create table t_event3 (a int, b float); create table t_event3 (a int, b float);
drop event if exists event3; drop event if exists event3;
create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand()); create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
set max_allowed_packet=128000000;
select count(*) from t_event3; select count(*) from t_event3;
drop event event3; drop event event3;
drop table t_event3; drop table t_event3;
...@@ -148,8 +147,8 @@ SHOW CREATE EVENT root19; ...@@ -148,8 +147,8 @@ SHOW CREATE EVENT root19;
create event root20 on schedule every '50:20:12:45' day_second do select 1; create event root20 on schedule every '50:20:12:45' day_second do select 1;
SHOW CREATE EVENT root20; SHOW CREATE EVENT root20;
set names cp1251; set names cp1251;
create event ðóóò21 on schedule every '50:23:59:95' day_second COMMENT 'òîâà å 1251 êîìåíòàð' do select 1; create event ðóóò21 on schedule every '50:23:59:95' day_second COMMENT 'òîâà å 1251 êîìåíòàð' do select 1;
SHOW CREATE EVENT ðóóò21; SHOW CREATE EVENT ðóóò21;
insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND"); insert into mysql.event (db, name, body, definer, interval_value, interval_field) values (database(), "root22", "select 1", user(), 100, "SECOND_MICROSECOND");
--error 1235 --error 1235
show create event root22; show create event root22;
...@@ -174,7 +173,7 @@ drop event root17_1; ...@@ -174,7 +173,7 @@ drop event root17_1;
drop event root18; drop event root18;
drop event root19; drop event root19;
drop event root20; drop event root20;
drop event ðóóò21; drop event ðóóò21;
set names latin1; set names latin1;
# #
...@@ -202,6 +201,9 @@ CREATE TABLE event_like LIKE mysql.event; ...@@ -202,6 +201,9 @@ CREATE TABLE event_like LIKE mysql.event;
INSERT INTO event_like SELECT * FROM mysql.event; INSERT INTO event_like SELECT * FROM mysql.event;
#sleep a bit or we won't catch the change of time #sleep a bit or we won't catch the change of time
--sleep 1 --sleep 1
ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
--error 1526
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db char(20) character set utf8 collate utf8_bin default '';
#wait a bit or we won't see the difference because of seconds resolution #wait a bit or we won't see the difference because of seconds resolution
--sleep 1 --sleep 1
...@@ -220,6 +222,7 @@ ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default ''; ...@@ -220,6 +222,7 @@ ALTER TABLE mysql.event MODIFY db char(64) character set cp1251 default '';
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1 --sleep 1
ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default ''; ALTER TABLE mysql.event MODIFY db varchar(64) character set utf8 collate utf8_bin default '';
--sleep 1
--error ER_CANNOT_LOAD_FROM_TABLE --error ER_CANNOT_LOAD_FROM_TABLE
SELECT event_name FROM INFORMATION_SCHEMA.EVENTS; SELECT event_name FROM INFORMATION_SCHEMA.EVENTS;
--sleep 1 --sleep 1
...@@ -412,7 +415,8 @@ select 1; ...@@ -412,7 +415,8 @@ select 1;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space'; select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
drop event white_space; drop event white_space;
create event white_space on schedule every 10 hour disable do create event white_space on schedule every 10 hour disable do
select 2;
select 2;
select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space'; select event_schema, event_name, definer, event_body from information_schema.events where event_name='white_space';
drop event white_space; drop event white_space;
create event white_space on schedule every 10 hour disable do select 3; create event white_space on schedule every 10 hour disable do select 3;
...@@ -422,7 +426,7 @@ drop event white_space; ...@@ -422,7 +426,7 @@ drop event white_space;
# END: BUG #17453: Creating Event crash the server # END: BUG #17453: Creating Event crash the server
# #
# ##set global event_scheduler=1;
# Bug#17403 "Events: packets out of order with show create event" # Bug#17403 "Events: packets out of order with show create event"
# #
create event e1 on schedule every 1 year do set @a = 5; create event e1 on schedule every 1 year do set @a = 5;
...@@ -436,7 +440,7 @@ drop event e1; ...@@ -436,7 +440,7 @@ drop event e1;
##select get_lock("test_lock3", 20); ##select get_lock("test_lock3", 20);
##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20); ##create event закачка on schedule every 10 hour do select get_lock("test_lock3", 20);
##select sleep(2); ##select sleep(2);
##select /*7*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##show processlist;
##drop event закачка; ##drop event закачка;
##select release_lock("test_lock3"); ##select release_lock("test_lock3");
...@@ -446,13 +450,14 @@ drop event e1; ...@@ -446,13 +450,14 @@ drop event e1;
##select get_lock("test_lock4", 20); ##select get_lock("test_lock4", 20);
##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20); ##create event закачка4 on schedule every 1 second do select get_lock("test_lock4", 20);
##select sleep(3); ##select sleep(3);
##select /*8*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##--replace_column 1 # 6 #
##drop event закачка4; ##drop event закачка4;
##select release_lock("test_lock4"); ##select release_lock("test_lock4");
##set global event_scheduler=0; ##set global event_scheduler=0;
##select sleep(2); ##select sleep(2);
##select /*9*/ user, host, db, command, state, info from information_schema.processlist where info is null or info not like '%processlist%' order by info; ##--replace_column 1 # 6 #
##select count(*) from mysql.event; ##select count(*) from mysql.event;
drop database events_test; drop database events_test;
CREATE DATABASE IF NOT EXISTS events_test;
USE events_test;
CREATE TABLE table_1(a int);
CREATE TABLE table_2(a int);
CREATE TABLE table_3(a int);
CREATE TABLE table_4(a int);
SET GLOBAL event_scheduler=1;
CREATE EVENT two_sec ON SCHEDULE EVERY 2 SECOND DO INSERT INTO table_1 VALUES(1);
CREATE EVENT start_n_end
ON SCHEDULE EVERY 1 SECOND
ENDS NOW() + INTERVAL 6 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO table_2 VALUES(1);
--sleep 5
CREATE EVENT only_one_time ON SCHEDULE EVERY 2 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_3 VALUES(1);
CREATE EVENT two_time ON SCHEDULE EVERY 1 SECOND ENDS NOW() + INTERVAL 1 SECOND DO INSERT INTO table_4 VALUES(1);
--sleep 5
SELECT IF(SUM(a) >= 4, 'OK', 'ERROR') FROM table_1;
SELECT IF(SUM(a) >= 5, 'OK', 'ERROR') FROM table_2;
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_3;
SELECT IF(SUM(a) > 0, 'OK', 'ERROR') FROM table_4;
DROP EVENT two_sec;
SELECT IF(TIME_TO_SEC(TIMEDIFF(ENDS,STARTS))=6, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
SELECT IF(LAST_EXECUTED-ENDS < 2, 'OK', 'ERROR') FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=DATABASE() AND EVENT_NAME='start_n_end' AND ENDS IS NOT NULL;
DROP EVENT start_n_end;
--echo "Already dropped because ended. Therefore an error."
--error 1517
DROP EVENT only_one_time;
--echo "Already dropped because ended. Therefore an error."
--error 1517
DROP EVENT two_time;
DROP TABLE table_1;
DROP TABLE table_2;
DROP TABLE table_3;
DROP TABLE table_4;
DROP DATABASE events_test;
...@@ -1052,13 +1052,6 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, LEX_STRING definer, ...@@ -1052,13 +1052,6 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, LEX_STRING definer,
if (ret) if (ret)
goto done; goto done;
/*
allocate on evex_mem_root. if you call without evex_mem_root
then sphead will not be cleared!
*/
if ((ret= ett->compile(thd, &evex_mem_root)))
goto done;
ett->compute_next_execution_time(); ett->compute_next_execution_time();
if (use_lock) if (use_lock)
VOID(pthread_mutex_lock(&LOCK_event_arrays)); VOID(pthread_mutex_lock(&LOCK_event_arrays));
......
...@@ -42,6 +42,8 @@ pthread_mutex_t LOCK_event_arrays, // mutex for when working with t ...@@ -42,6 +42,8 @@ pthread_mutex_t LOCK_event_arrays, // mutex for when working with t
LOCK_workers_count, // mutex for when inc/dec uint workers_count LOCK_workers_count, // mutex for when inc/dec uint workers_count
LOCK_evex_running; // mutes for managing bool evex_is_running LOCK_evex_running; // mutes for managing bool evex_is_running
static pthread_mutex_t LOCK_evex_main_thread; // mutex for when working with the queue
bool scheduler_main_thread_running= false;
bool evex_is_running= false; bool evex_is_running= false;
...@@ -111,6 +113,7 @@ evex_init_mutexes() ...@@ -111,6 +113,7 @@ evex_init_mutexes()
pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&LOCK_evex_main_thread, MY_MUTEX_INIT_FAST);
event_executor_running_global_var= opt_event_executor; event_executor_running_global_var= opt_event_executor;
} }
...@@ -241,6 +244,7 @@ shutdown_events() ...@@ -241,6 +244,7 @@ shutdown_events()
pthread_mutex_destroy(&LOCK_event_arrays); pthread_mutex_destroy(&LOCK_event_arrays);
pthread_mutex_destroy(&LOCK_workers_count); pthread_mutex_destroy(&LOCK_workers_count);
pthread_mutex_destroy(&LOCK_evex_running); pthread_mutex_destroy(&LOCK_evex_running);
pthread_mutex_destroy(&LOCK_evex_main_thread);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -351,6 +355,7 @@ executor_wait_till_next_event_exec(THD *thd) ...@@ -351,6 +355,7 @@ executor_wait_till_next_event_exec(THD *thd)
t2sleep= evex_time_diff(&et->execute_at, &time_now); t2sleep= evex_time_diff(&et->execute_at, &time_now);
VOID(pthread_mutex_unlock(&LOCK_event_arrays)); VOID(pthread_mutex_unlock(&LOCK_event_arrays));
t2sleep*=20;
DBUG_PRINT("evex main thread",("unlocked LOCK_event_arrays")); DBUG_PRINT("evex main thread",("unlocked LOCK_event_arrays"));
if (t2sleep > 0) if (t2sleep > 0)
{ {
...@@ -366,7 +371,7 @@ executor_wait_till_next_event_exec(THD *thd) ...@@ -366,7 +371,7 @@ executor_wait_till_next_event_exec(THD *thd)
modified)) modified))
{ {
DBUG_PRINT("evex main thread",("will sleep a bit more.")); DBUG_PRINT("evex main thread",("will sleep a bit more."));
my_sleep(1000000); my_sleep(50000);
} }
DBUG_PRINT("info",("saved_modified=%llu current=%llu", modified, DBUG_PRINT("info",("saved_modified=%llu current=%llu", modified,
evex_queue_num_elements(EVEX_EQ_NAME)? evex_queue_num_elements(EVEX_EQ_NAME)?
...@@ -411,6 +416,19 @@ event_executor_main(void *arg) ...@@ -411,6 +416,19 @@ event_executor_main(void *arg)
DBUG_ENTER("event_executor_main"); DBUG_ENTER("event_executor_main");
DBUG_PRINT("event_executor_main", ("EVEX thread started")); DBUG_PRINT("event_executor_main", ("EVEX thread started"));
pthread_mutex_lock(&LOCK_evex_main_thread);
if (!scheduler_main_thread_running)
scheduler_main_thread_running= true;
else
{
DBUG_PRINT("event_executor_main", ("already running. thd_id=%d",
evex_main_thread_id));
pthread_mutex_unlock(&LOCK_evex_main_thread);
my_thread_end();
pthread_exit(0);
DBUG_RETURN(0); // Can't return anything here
}
pthread_mutex_unlock(&LOCK_evex_main_thread);
/* init memory root */ /* init memory root */
init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_alloc_root(&evex_mem_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
...@@ -489,7 +507,7 @@ event_executor_main(void *arg) ...@@ -489,7 +507,7 @@ event_executor_main(void *arg)
if (!evex_queue_num_elements(EVEX_EQ_NAME)) if (!evex_queue_num_elements(EVEX_EQ_NAME))
{ {
my_sleep(1000000);// sleep 1s my_sleep(100000);// sleep 0.1s
continue; continue;
} }
...@@ -652,12 +670,17 @@ finish: ...@@ -652,12 +670,17 @@ finish:
err_no_thd: err_no_thd:
VOID(pthread_mutex_lock(&LOCK_evex_running)); VOID(pthread_mutex_lock(&LOCK_evex_running));
evex_is_running= false; evex_is_running= false;
event_executor_running_global_var= false;
VOID(pthread_mutex_unlock(&LOCK_evex_running)); VOID(pthread_mutex_unlock(&LOCK_evex_running));
free_root(&evex_mem_root, MYF(0)); free_root(&evex_mem_root, MYF(0));
sql_print_information("SCHEDULER: Stopped."); sql_print_information("SCHEDULER: Stopped.");
#ifndef DBUG_FAULTY_THR #ifndef DBUG_FAULTY_THR
pthread_mutex_lock(&LOCK_evex_main_thread);
scheduler_main_thread_running= false;
pthread_mutex_unlock(&LOCK_evex_main_thread);
my_thread_end(); my_thread_end();
pthread_exit(0); pthread_exit(0);
#endif #endif
......
This diff is collapsed.
...@@ -772,81 +772,6 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs, ...@@ -772,81 +772,6 @@ static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
} }
/*
Calculate difference between two datetime values as seconds + microseconds.
SYNOPSIS
calc_time_diff()
l_time1 - TIME/DATE/DATETIME value
l_time2 - TIME/DATE/DATETIME value
l_sign - 1 absolute values are substracted,
-1 absolute values are added.
seconds_out - Out parameter where difference between
l_time1 and l_time2 in seconds is stored.
microseconds_out- Out parameter where microsecond part of difference
between l_time1 and l_time2 is stored.
NOTE
This function calculates difference between l_time1 and l_time2 absolute
values. So one should set l_sign and correct result if he want to take
signs into account (i.e. for TIME values).
RETURN VALUES
Returns sign of difference.
1 means negative result
0 means positive result
*/
static bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out)
{
long days;
bool neg;
longlong microseconds;
/*
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
the second argument should be TIMESTAMP_TIME also.
We should check it before calc_time_diff call.
*/
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
days= (long)l_time1->day - l_sign * (long)l_time2->day;
else
{
days= calc_daynr((uint) l_time1->year,
(uint) l_time1->month,
(uint) l_time1->day);
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
days-= l_sign * (long)l_time2->day;
else
days-= l_sign*calc_daynr((uint) l_time2->year,
(uint) l_time2->month,
(uint) l_time2->day);
}
microseconds= ((longlong)days*LL(86400) +
(longlong)(l_time1->hour*3600L +
l_time1->minute*60L +
l_time1->second) -
l_sign*(longlong)(l_time2->hour*3600L +
l_time2->minute*60L +
l_time2->second)) * LL(1000000) +
(longlong)l_time1->second_part -
l_sign*(longlong)l_time2->second_part;
neg= 0;
if (microseconds < 0)
{
microseconds= -microseconds;
neg= 1;
}
*seconds_out= microseconds/1000000L;
*microseconds_out= (long) (microseconds%1000000L);
return neg;
}
longlong Item_func_period_add::val_int() longlong Item_func_period_add::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -2031,16 +1956,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) ...@@ -2031,16 +1956,13 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
INTERVAL interval; INTERVAL interval;
if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) || if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) ||
get_interval_value(args[1],int_type,&value,&interval)) get_interval_value(args[1], int_type, &value, &interval))
goto null_date; return (null_value=1);
if (date_sub_interval) if (date_sub_interval)
interval.neg = !interval.neg; interval.neg = !interval.neg;
return (null_value= date_add_interval(ltime, int_type, interval)); return (null_value= date_add_interval(ltime, int_type, interval));
null_date:
return (null_value=1);
} }
......
...@@ -1549,6 +1549,8 @@ void make_truncated_value_warning(THD *thd, const char *str_val, ...@@ -1549,6 +1549,8 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
const char *field_name); const char *field_name);
bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval); bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval);
bool calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign,
longlong *seconds_out, long *microseconds_out);
extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type,
const char *format_str, const char *format_str,
......
...@@ -3980,7 +3980,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -3980,7 +3980,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0))) if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
DBUG_RETURN(0); DBUG_RETURN(0);
//->field[0] is EVENT_CATALOG and is by default NULL /* ->field[0] is EVENT_CATALOG and is by default NULL */
sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs); sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs);
sch_table->field[2]->store(et.name.str, et.name.length, scs); sch_table->field[2]->store(et.name.str, et.name.length, scs);
...@@ -4000,12 +4000,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -4000,12 +4000,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
if (et.expression) if (et.expression)
{ {
String show_str; String show_str;
//type /* type */
sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs); sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs);
/* execute_at */
sch_table->field[6]->set_null();
/* interval_value */
//interval_type
if (event_reconstruct_interval_expression(&show_str, et.interval, if (event_reconstruct_interval_expression(&show_str, et.interval,
et.expression)) et.expression))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -4058,9 +4055,10 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) ...@@ -4058,9 +4055,10 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
if (et.last_executed.year) if (et.last_executed.year)
{
sch_table->field[16]->set_notnull();
sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME); sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME);
else }
sch_table->field[16]->set_null();
sch_table->field[17]->store(et.comment.str, et.comment.length, scs); sch_table->field[17]->store(et.comment.str, et.comment.length, scs);
......
...@@ -833,4 +833,80 @@ invalid_date: ...@@ -833,4 +833,80 @@ invalid_date:
} }
/*
Calculate difference between two datetime values as seconds + microseconds.
SYNOPSIS
calc_time_diff()
l_time1 - TIME/DATE/DATETIME value
l_time2 - TIME/DATE/DATETIME value
l_sign - 1 absolute values are substracted,
-1 absolute values are added.
seconds_out - Out parameter where difference between
l_time1 and l_time2 in seconds is stored.
microseconds_out- Out parameter where microsecond part of difference
between l_time1 and l_time2 is stored.
NOTE
This function calculates difference between l_time1 and l_time2 absolute
values. So one should set l_sign and correct result if he want to take
signs into account (i.e. for TIME values).
RETURN VALUES
Returns sign of difference.
1 means negative result
0 means positive result
*/
bool
calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, longlong *seconds_out,
long *microseconds_out)
{
long days;
bool neg;
longlong microseconds;
/*
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
the second argument should be TIMESTAMP_TIME also.
We should check it before calc_time_diff call.
*/
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
days= (long)l_time1->day - l_sign * (long)l_time2->day;
else
{
days= calc_daynr((uint) l_time1->year,
(uint) l_time1->month,
(uint) l_time1->day);
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
days-= l_sign * (long)l_time2->day;
else
days-= l_sign*calc_daynr((uint) l_time2->year,
(uint) l_time2->month,
(uint) l_time2->day);
}
microseconds= ((longlong)days*LL(86400) +
(longlong)(l_time1->hour*3600L +
l_time1->minute*60L +
l_time1->second) -
l_sign*(longlong)(l_time2->hour*3600L +
l_time2->minute*60L +
l_time2->second)) * LL(1000000) +
(longlong)l_time1->second_part -
l_sign*(longlong)l_time2->second_part;
neg= 0;
if (microseconds < 0)
{
microseconds= -microseconds;
neg= 1;
}
*seconds_out= microseconds/1000000L;
*microseconds_out= (long) (microseconds%1000000L);
return neg;
}
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment