Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
8fe55c09
Commit
8fe55c09
authored
Feb 28, 2006
by
andrey@lmy004
Browse files
Options
Browse Files
Download
Plain Diff
manual merge
parents
91d09f46
483a6d06
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
213 additions
and
85 deletions
+213
-85
mysql-test/r/events.result
mysql-test/r/events.result
+48
-0
mysql-test/t/events.test
mysql-test/t/events.test
+32
-0
sql/event.cc
sql/event.cc
+28
-24
sql/event.h
sql/event.h
+3
-0
sql/event_executor.cc
sql/event_executor.cc
+6
-4
sql/event_timed.cc
sql/event_timed.cc
+81
-43
sql/sql_show.cc
sql/sql_show.cc
+12
-14
sql/sql_yacc.yy
sql/sql_yacc.yy
+3
-0
No files found.
mysql-test/r/events.result
View file @
8fe55c09
...
@@ -37,6 +37,54 @@ alter event event3 rename to event2;
...
@@ -37,6 +37,54 @@ alter event event3 rename to event2;
drop event event2;
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;
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;
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;
create event e_43 on schedule every 1 second do set @a = 5;
set global event_scheduler = 1;
set global event_scheduler = 1;
alter event e_43 do alter event e_43 do set @a = 4;
alter event e_43 do alter event e_43 do set @a = 4;
...
...
mysql-test/t/events.test
View file @
8fe55c09
...
@@ -48,6 +48,38 @@ drop event event2;
...
@@ -48,6 +48,38 @@ 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
;
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
;
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
;
create
event
e_43
on
schedule
every
1
second
do
set
@
a
=
5
;
set
global
event_scheduler
=
1
;
set
global
event_scheduler
=
1
;
--
sleep
2
--
sleep
2
...
...
sql/event.cc
View file @
8fe55c09
...
@@ -637,20 +637,6 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
...
@@ -637,20 +637,6 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
goto
trunc_err
;
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
)
if
(
et
->
expression
)
{
{
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
set_notnull
();
...
@@ -664,18 +650,31 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
...
@@ -664,18 +650,31 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
store
((
longlong
)
et
->
interval
+
1
);
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
store
((
longlong
)
et
->
interval
+
1
);
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
set_null
();
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
)
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_INTERVAL_EXPR
]
->
set_null
();
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
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
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
store_time
(
&
et
->
execute_at
,
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
store_time
(
&
et
->
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
MYSQL_TIMESTAMP_DATETIME
);
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
set_null
();
}
}
else
else
{
{
...
@@ -686,14 +685,17 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
...
@@ -686,14 +685,17 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
((
Field_timestamp
*
)
table
->
field
[
EVEX_FIELD_MODIFIED
])
->
set_time
();
((
Field_timestamp
*
)
table
->
field
[
EVEX_FIELD_MODIFIED
])
->
set_time
();
if
(
et
->
comment
.
length
)
if
(
et
->
comment
.
str
)
if
(
table
->
field
[
field_num
=
EVEX_FIELD_COMMENT
]
->
{
store
(
et
->
comment
.
str
,
et
->
comment
.
length
,
system_charset_info
))
if
(
table
->
field
[
field_num
=
EVEX_FIELD_COMMENT
]
->
store
(
et
->
comment
.
str
,
et
->
comment
.
length
,
system_charset_info
))
goto
trunc_err
;
goto
trunc_err
;
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
trunc_err:
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
);
DBUG_RETURN
(
EVEX_GENERAL_ERROR
);
}
}
...
@@ -806,14 +808,16 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not,
...
@@ -806,14 +808,16 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not,
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
name
.
str
,
ret
);
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
name
.
str
,
ret
);
goto
err
;
goto
err
;
}
}
#ifdef USE_THIS_CODE_AS_TEMPLATE_WHEN_EVENT_REPLICATION_IS_AGREED
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
{
{
thd
->
clear_error
();
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
->
binlog_query
(
THD
::
MYSQL_QUERY_TYPE
,
thd
->
query
,
thd
->
query_length
,
FALSE
,
FALSE
);
thd
->
query
,
thd
->
query_length
,
FALSE
,
FALSE
);
}
}
#endif
*
rows_affected
=
1
;
*
rows_affected
=
1
;
ok:
ok:
...
...
sql/event.h
View file @
8fe55c09
...
@@ -103,6 +103,9 @@ public:
...
@@ -103,6 +103,9 @@ public:
TIME
starts
;
TIME
starts
;
TIME
ends
;
TIME
ends
;
TIME
execute_at
;
TIME
execute_at
;
my_bool
starts_null
;
my_bool
ends_null
;
my_bool
execute_at_null
;
longlong
expression
;
longlong
expression
;
interval_type
interval
;
interval_type
interval
;
...
...
sql/event_executor.cc
View file @
8fe55c09
...
@@ -523,8 +523,7 @@ restart_ticking:
...
@@ -523,8 +523,7 @@ restart_ticking:
et
=
evex_queue_first_element
(
&
EVEX_EQ_NAME
,
event_timed
*
);
et
=
evex_queue_first_element
(
&
EVEX_EQ_NAME
,
event_timed
*
);
DBUG_PRINT
(
"evex main thread"
,(
"got event from the queue"
));
DBUG_PRINT
(
"evex main thread"
,(
"got event from the queue"
));
if
(
et
->
execute_at
.
year
>
1969
&&
if
(
!
et
->
execute_at_null
&&
my_time_compare
(
&
time_now
,
&
et
->
execute_at
)
==
-
1
)
my_time_compare
(
&
time_now
,
&
et
->
execute_at
)
==
-
1
)
{
{
DBUG_PRINT
(
"evex main thread"
,(
"still not the time for execution"
));
DBUG_PRINT
(
"evex main thread"
,(
"still not the time for execution"
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_event_arrays
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_event_arrays
));
...
@@ -571,8 +570,11 @@ restart_ticking:
...
@@ -571,8 +570,11 @@ restart_ticking:
#else
#else
event_executor_worker
((
void
*
)
et
);
event_executor_worker
((
void
*
)
et
);
#endif
#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
;
et
->
flags
|=
EVENT_EXEC_NO_MORE
;
if
((
et
->
flags
&
EVENT_EXEC_NO_MORE
)
||
et
->
status
==
MYSQL_EVENT_DISABLED
)
if
((
et
->
flags
&
EVENT_EXEC_NO_MORE
)
||
et
->
status
==
MYSQL_EVENT_DISABLED
)
...
...
sql/event_timed.cc
View file @
8fe55c09
...
@@ -41,6 +41,7 @@ event_timed::init()
...
@@ -41,6 +41,7 @@ event_timed::init()
set_zero_time
(
&
ends
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
ends
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
last_executed
,
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
.
str
=
definer_host
.
str
=
0
;
definer_user
.
length
=
definer_host
.
length
=
0
;
definer_user
.
length
=
definer_host
.
length
=
0
;
...
@@ -157,10 +158,15 @@ event_timed::init_execute_at(THD *thd, Item *expr)
...
@@ -157,10 +158,15 @@ event_timed::init_execute_at(THD *thd, Item *expr)
if
(
expr
->
fix_fields
(
thd
,
&
expr
))
if
(
expr
->
fix_fields
(
thd
,
&
expr
))
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
/* Let's check whether time is in the past */
/* no starts and/or ends in case of execute_at */
thd
->
variables
.
time_zone
->
gmt_sec_to_TIME
(
&
time_tmp
,
DBUG_PRINT
(
"info"
,
(
"starts_null && ends_null should be 1 is %d"
,
(
my_time_t
)
thd
->
query_start
());
(
starts_null
&&
ends_null
)))
DBUG_ASSERT
(
starts_null
&&
ends_null
);
// 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
());
if
((
not_used
=
expr
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
if
((
not_used
=
expr
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
...
@@ -177,7 +183,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
...
@@ -177,7 +183,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
*/
*/
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
execute_at_null
=
FALSE
;
execute_at
=
ltime
;
execute_at
=
ltime
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -332,6 +338,7 @@ event_timed::init_starts(THD *thd, Item *new_starts)
...
@@ -332,6 +338,7 @@ event_timed::init_starts(THD *thd, Item *new_starts)
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
starts
=
ltime
;
starts
=
ltime
;
starts_null
=
FALSE
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -361,8 +368,7 @@ event_timed::init_starts(THD *thd, Item *new_starts)
...
@@ -361,8 +368,7 @@ event_timed::init_starts(THD *thd, Item *new_starts)
int
int
event_timed
::
init_ends
(
THD
*
thd
,
Item
*
new_ends
)
event_timed
::
init_ends
(
THD
*
thd
,
Item
*
new_ends
)
{
{
TIME
ltime
;
TIME
ltime
,
ltime_now
;
my_time_t
my_time_tmp
;
my_bool
not_used
;
my_bool
not_used
;
DBUG_ENTER
(
"event_timed::init_ends"
);
DBUG_ENTER
(
"event_timed::init_ends"
);
...
@@ -370,20 +376,34 @@ event_timed::init_ends(THD *thd, Item *new_ends)
...
@@ -370,20 +376,34 @@ event_timed::init_ends(THD *thd, Item *new_ends)
if
(
new_ends
->
fix_fields
(
thd
,
&
new_ends
))
if
(
new_ends
->
fix_fields
(
thd
,
&
new_ends
))
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
/* The field was already fixed in init_ends */
DBUG_PRINT
(
"info"
,
(
"convert to TIME"
));
if
((
not_used
=
new_ends
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
if
((
not_used
=
new_ends
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
/*
/*
This may result in a 1970-01-01 date if ltime is > 2037-xx-xx
.
This may result in a 1970-01-01 date if ltime is > 2037-xx-xx
?
CONVERT_TZ has similar problem
.
CONVERT_TZ has similar problem
?
*/
*/
DBUG_PRINT
(
"info"
,
(
"get the UTC time"
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
if
(
starts
.
year
&&
my_time_compare
(
&
starts
,
&
ltime
)
!=
-
1
)
/* Check whether ends is after starts */
DBUG_PRINT
(
"info"
,
(
"ENDS after STARTS?"
));
if
(
!
starts_null
&&
my_time_compare
(
&
starts
,
&
ltime
)
!=
-
1
)
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
/*
The parser forces starts to be provided but one day STARTS could be
set before NOW() and in this case the following check should be done.
Check whether ENDS is not in the past.
*/
DBUG_PRINT
(
"info"
,
(
"ENDS after NOW?"
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime_now
,
thd
->
query_start
());
if
(
my_time_compare
(
&
ltime_now
,
&
ltime
)
==
1
)
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
ends
=
ltime
;
ends
=
ltime
;
ends_null
=
FALSE
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -403,7 +423,7 @@ event_timed::init_comment(THD *thd, LEX_STRING *set_comment)
...
@@ -403,7 +423,7 @@ event_timed::init_comment(THD *thd, LEX_STRING *set_comment)
DBUG_ENTER
(
"event_timed::init_comment"
);
DBUG_ENTER
(
"event_timed::init_comment"
);
comment
.
str
=
strmake_root
(
thd
->
mem_root
,
set_comment
->
str
,
comment
.
str
=
strmake_root
(
thd
->
mem_root
,
set_comment
->
str
,
comment
.
length
=
set_comment
->
length
);
comment
.
length
=
set_comment
->
length
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -517,29 +537,38 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
...
@@ -517,29 +537,38 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
len
=
et
->
definer
.
length
-
len
-
1
;
//1 is because of @
len
=
et
->
definer
.
length
-
len
-
1
;
//1 is because of @
et
->
definer_host
.
str
=
strmake_root
(
mem_root
,
ptr
+
1
,
len
);
//1: because of @
et
->
definer_host
.
str
=
strmake_root
(
mem_root
,
ptr
+
1
,
len
);
//1: because of @
et
->
definer_host
.
length
=
len
;
et
->
definer_host
.
length
=
len
;
et
->
starts_null
=
table
->
field
[
EVEX_FIELD_STARTS
]
->
is_null
();
res1
=
table
->
field
[
EVEX_FIELD_STARTS
]
->
get_date
(
&
et
->
starts
,
TIME_NO_ZERO_DATE
);
res1
=
table
->
field
[
EVEX_FIELD_STARTS
]
->
et
->
ends_null
=
table
->
field
[
EVEX_FIELD_ENDS
]
->
is_null
();
get_date
(
&
et
->
starts
,
TIME_NO_ZERO_DATE
);
res2
=
table
->
field
[
EVEX_FIELD_ENDS
]
->
get_date
(
&
et
->
ends
,
TIME_NO_ZERO_DATE
);
res2
=
table
->
field
[
EVEX_FIELD_ENDS
]
->
if
(
!
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
is_null
())
get_date
(
&
et
->
ends
,
TIME_NO_ZERO_DATE
);
et
->
expression
=
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
val_int
();
else
et
->
expression
=
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
val_int
();
et
->
expression
=
0
;
/*
/*
If res1 and res2 are true then both fields are empty.
If res1 and res2 are true then both fields are empty.
Hence if EVEX_FIELD_EXECUTE_AT is empty there is an error.
Hence if EVEX_FIELD_EXECUTE_AT is empty there is an error.
*/
*/
if
(
res1
&&
res2
&&
!
et
->
expression
&&
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
et
->
execute_at_null
=
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
is_null
();
get_date
(
&
et
->
execute_at
,
TIME_NO_ZERO_DATE
))
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
;
goto
error
;
/*
/*
In DB the values start from 1 but enum interval_type starts
In DB the values start from 1 but enum interval_type starts
from 0
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
);
((
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
->
modified
=
table
->
field
[
EVEX_FIELD_CREATED
]
->
val_int
();
et
->
created
=
table
->
field
[
EVEX_FIELD_MODIFIED
]
->
val_int
();
et
->
created
=
table
->
field
[
EVEX_FIELD_MODIFIED
]
->
val_int
();
...
@@ -698,14 +727,11 @@ event_timed::compute_next_execution_time()
...
@@ -698,14 +727,11 @@ event_timed::compute_next_execution_time()
/* Let's check whether it was executed */
/* Let's check whether it was executed */
if
(
last_executed
.
year
)
if
(
last_executed
.
year
)
{
{
DBUG_PRINT
(
"compute_next_execution_time"
,
DBUG_PRINT
(
"info"
,(
"One-time event %s.%s of was already executed"
,
(
"One-time event %s was already executed"
,
name
.
str
));
dbname
.
str
,
name
.
str
,
definer
.
str
));
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
);
{
DBUG_PRINT
(
"info"
,(
"One-time event will be dropped=%d."
,
dropped
));
DBUG_PRINT
(
"compute_next_execution_time"
,
(
"One-time event will be dropped."
));
dropped
=
true
;
}
status
=
MYSQL_EVENT_DISABLED
;
status
=
MYSQL_EVENT_DISABLED
;
status_changed
=
true
;
status_changed
=
true
;
}
}
...
@@ -731,11 +757,12 @@ event_timed::compute_next_execution_time()
...
@@ -731,11 +757,12 @@ event_timed::compute_next_execution_time()
last_executed
.
second
);
last_executed
.
second
);
#endif
#endif
/*
I
f time_now is after ends don't execute anymore */
/*
i
f 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 */
/* time_now is after ends. don't execute anymore */
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
execute_at_null
=
TRUE
;
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
dropped
=
true
;
status
=
MYSQL_EVENT_DISABLED
;
status
=
MYSQL_EVENT_DISABLED
;
...
@@ -749,7 +776,7 @@ event_timed::compute_next_execution_time()
...
@@ -749,7 +776,7 @@ event_timed::compute_next_execution_time()
Let's check whether time_now is before starts.
Let's check whether time_now is before starts.
If so schedule for 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
)
if
(
tmp
==
0
&&
my_time_compare
(
&
starts
,
&
last_executed
)
==
0
)
{
{
...
@@ -765,11 +792,12 @@ event_timed::compute_next_execution_time()
...
@@ -765,11 +792,12 @@ event_timed::compute_next_execution_time()
time_now before starts. Scheduling for starts
time_now before starts. Scheduling for starts
*/
*/
execute_at
=
starts
;
execute_at
=
starts
;
execute_at_null
=
FALSE
;
goto
ret
;
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.)
Both starts and m_ends are set and time_now is between them (incl.)
...
@@ -778,7 +806,10 @@ event_timed::compute_next_execution_time()
...
@@ -778,7 +806,10 @@ event_timed::compute_next_execution_time()
If not set then schedule for now.
If not set then schedule for now.
*/
*/
if
(
!
last_executed
.
year
)
if
(
!
last_executed
.
year
)
{
execute_at
=
time_now
;
execute_at
=
time_now
;
execute_at_null
=
FALSE
;
}
else
else
{
{
TIME
next_exec
;
TIME
next_exec
;
...
@@ -791,15 +822,19 @@ event_timed::compute_next_execution_time()
...
@@ -791,15 +822,19 @@ event_timed::compute_next_execution_time()
{
{
/* Next execution after ends. No more executions */
/* Next execution after ends. No more executions */
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
execute_at_null
=
TRUE
;
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
dropped
=
true
;
}
}
else
else
{
execute_at
=
next_exec
;
execute_at
=
next_exec
;
execute_at_null
=
FALSE
;
}
}
}
goto
ret
;
goto
ret
;
}
}
else
if
(
!
starts
.
year
&&
!
ends
.
year
)
else
if
(
starts_null
&&
ends_null
)
{
{
/*
/*
Both starts and m_ends are not set, so we schedule for the next
Both starts and m_ends are not set, so we schedule for the next
...
@@ -815,11 +850,12 @@ event_timed::compute_next_execution_time()
...
@@ -815,11 +850,12 @@ event_timed::compute_next_execution_time()
/* last_executed not set. Schedule the event for now */
/* last_executed not set. Schedule the event for now */
execute_at
=
time_now
;
execute_at
=
time_now
;
}
}
execute_at_null
=
FALSE
;
}
}
else
else
{
{
/*
E
ither starts or m_ends is set */
/*
e
ither starts or m_ends is set */
if
(
starts
.
year
)
if
(
!
starts_null
)
{
{
/*
/*
- starts is set.
- starts is set.
...
@@ -834,6 +870,7 @@ event_timed::compute_next_execution_time()
...
@@ -834,6 +870,7 @@ event_timed::compute_next_execution_time()
}
}
else
else
execute_at
=
starts
;
execute_at
=
starts
;
execute_at_null
=
FALSE
;
}
}
else
else
{
{
...
@@ -856,11 +893,15 @@ event_timed::compute_next_execution_time()
...
@@ -856,11 +893,15 @@ event_timed::compute_next_execution_time()
if
(
my_time_compare
(
&
ends
,
&
next_exec
)
==
-
1
)
if
(
my_time_compare
(
&
ends
,
&
next_exec
)
==
-
1
)
{
{
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
execute_at_null
=
TRUE
;
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
dropped
=
true
;
}
}
else
else
{
execute_at
=
next_exec
;
execute_at
=
next_exec
;
execute_at_null
=
FALSE
;
}
}
}
}
}
goto
ret
;
goto
ret
;
...
@@ -1324,10 +1365,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1324,10 +1365,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
sphead
=
lex
.
et
->
sphead
;
sphead
=
lex
.
et
->
sphead
;
sphead
->
m_db
=
dbname
;
sphead
->
m_db
=
dbname
;
/*
Ccopy also chistics since they will vanish otherwise we get 0x0 pointer
TODO: Handle sql_mode!!
*/
sphead
->
set_definer
(
definer
.
str
,
definer
.
length
);
sphead
->
set_definer
(
definer
.
str
,
definer
.
length
);
sphead
->
set_info
(
0
,
0
,
&
lex
.
sp_chistics
,
sql_mode
);
sphead
->
set_info
(
0
,
0
,
&
lex
.
sp_chistics
,
sql_mode
);
sphead
->
optimize
();
sphead
->
optimize
();
...
...
sql/sql_show.cc
View file @
8fe55c09
...
@@ -3957,7 +3957,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
...
@@ -3957,7 +3957,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table
->
field
[
3
]
->
store
(
et
.
definer
.
str
,
et
.
definer
.
length
,
scs
);
sch_table
->
field
[
3
]
->
store
(
et
.
definer
.
str
,
et
.
definer
.
length
,
scs
);
sch_table
->
field
[
4
]
->
store
(
et
.
body
.
str
,
et
.
body
.
length
,
scs
);
sch_table
->
field
[
4
]
->
store
(
et
.
body
.
str
,
et
.
body
.
length
,
scs
);
/
/ [9] is SQL_MODE
/
* [9] is SQL_MODE */
{
{
byte
*
sql_mode_str
;
byte
*
sql_mode_str
;
ulong
sql_mode_len
=
0
;
ulong
sql_mode_len
=
0
;
...
@@ -3972,9 +3972,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
...
@@ -3972,9 +3972,9 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
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
/
* execute_at */
sch_table
->
field
[
6
]
->
set_null
();
sch_table
->
field
[
6
]
->
set_null
();
/
/interval_value
/
* interval_value */
//interval_type
//interval_type
if
(
event_reconstruct_interval_expression
(
&
show_str
,
et
.
interval
,
if
(
event_reconstruct_interval_expression
(
&
show_str
,
et
.
interval
,
et
.
expression
))
et
.
expression
))
...
@@ -3986,26 +3986,24 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
...
@@ -3986,26 +3986,24 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
LEX_STRING
*
ival
=
&
interval_type_to_name
[
et
.
interval
];
LEX_STRING
*
ival
=
&
interval_type_to_name
[
et
.
interval
];
sch_table
->
field
[
8
]
->
set_notnull
();
sch_table
->
field
[
8
]
->
set_notnull
();
sch_table
->
field
[
8
]
->
store
(
ival
->
str
,
ival
->
length
,
scs
);
sch_table
->
field
[
8
]
->
store
(
ival
->
str
,
ival
->
length
,
scs
);
//starts & ends
//starts & ends
sch_table
->
field
[
10
]
->
set_notnull
();
sch_table
->
field
[
10
]
->
set_notnull
();
sch_table
->
field
[
10
]
->
store_time
(
&
et
.
starts
,
MYSQL_TIMESTAMP_DATETIME
);
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
);
if
(
!
et
.
ends_null
)
{
sch_table
->
field
[
11
]
->
set_notnull
();
sch_table
->
field
[
11
]
->
store_time
(
&
et
.
ends
,
MYSQL_TIMESTAMP_DATETIME
);
}
}
}
else
else
{
{
//type
//type
sch_table
->
field
[
5
]
->
store
(
STRING_WITH_LEN
(
"ONE TIME"
),
scs
);
sch_table
->
field
[
5
]
->
store
(
STRING_WITH_LEN
(
"ONE TIME"
),
scs
);
//execute_at
sch_table
->
field
[
6
]
->
set_notnull
();
sch_table
->
field
[
6
]
->
set_notnull
();
sch_table
->
field
[
6
]
->
store_time
(
&
et
.
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
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
sch_table
->
field
[
10
]
->
set_null
();
sch_table
->
field
[
11
]
->
set_null
();
}
}
//status
//status
...
...
sql/sql_yacc.yy
View file @
8fe55c09
...
@@ -1476,6 +1476,9 @@ opt_ev_status: /* empty */ { $$= 0; }
...
@@ -1476,6 +1476,9 @@ opt_ev_status: /* empty */ { $$= 0; }
;
;
ev_starts: /* empty */
ev_starts: /* empty */
{
Lex->et->init_starts(YYTHD, new Item_func_now_local());
}
| STARTS_SYM expr
| STARTS_SYM expr
{
{
LEX *lex= Lex;
LEX *lex= Lex;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment