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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
3d854641
Commit
3d854641
authored
Dec 08, 2005
by
andrey@lmy004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL #1034 updates after review
(strip m_ as prefix from member variables' names)
parent
b7578df0
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
392 additions
and
387 deletions
+392
-387
sql/event.cc
sql/event.cc
+77
-76
sql/event.h
sql/event.h
+45
-44
sql/event_executor.cc
sql/event_executor.cc
+29
-29
sql/event_priv.h
sql/event_priv.h
+1
-1
sql/event_timed.cc
sql/event_timed.cc
+213
-206
sql/sql_parse.cc
sql/sql_parse.cc
+22
-26
sql/sql_yacc.yy
sql/sql_yacc.yy
+5
-5
No files found.
sql/event.cc
View file @
3d854641
/* Copyright (C) 200
0-2003
MySQL AB
/* Copyright (C) 200
4-2005
MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -143,7 +143,7 @@ my_time_compare(TIME *a, TIME *b)
inline
int
event_timed_compare
(
event_timed
**
a
,
event_timed
**
b
)
{
return
my_time_compare
(
&
(
*
a
)
->
m_execute_at
,
&
(
*
b
)
->
m_
execute_at
);
return
my_time_compare
(
&
(
*
a
)
->
execute_at
,
&
(
*
b
)
->
execute_at
);
}
...
...
@@ -258,55 +258,55 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
DBUG_RETURN
(
EVEX_GET_FIELD_FAILED
);
}
DBUG_PRINT
(
"info"
,
(
"
m_db.len=%d"
,
et
->
m_db
.
length
));
DBUG_PRINT
(
"info"
,
(
"
m_name.len=%d"
,
et
->
m_
name
.
length
));
DBUG_PRINT
(
"info"
,
(
"
dbname.len=%d"
,
et
->
dbname
.
length
));
DBUG_PRINT
(
"info"
,
(
"
name.len=%d"
,
et
->
name
.
length
));
table
->
field
[
EVEX_FIELD_DB
]
->
store
(
et
->
m_db
.
str
,
et
->
m_db
.
length
,
system_charset_info
);
store
(
et
->
dbname
.
str
,
et
->
dbname
.
length
,
system_charset_info
);
table
->
field
[
EVEX_FIELD_NAME
]
->
store
(
et
->
m_name
.
str
,
et
->
m_
name
.
length
,
system_charset_info
);
store
(
et
->
name
.
str
,
et
->
name
.
length
,
system_charset_info
);
table
->
field
[
EVEX_FIELD_ON_COMPLETION
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_ON_COMPLETION
]
->
store
((
longlong
)
et
->
m_
on_completion
);
table
->
field
[
EVEX_FIELD_ON_COMPLETION
]
->
store
((
longlong
)
et
->
on_completion
);
table
->
field
[
EVEX_FIELD_STATUS
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_STATUS
]
->
store
((
longlong
)
et
->
m_
status
);
et
->
m_
status_changed
=
false
;
table
->
field
[
EVEX_FIELD_STATUS
]
->
store
((
longlong
)
et
->
status
);
// et->
status_changed= false;
// ToDo: Andrey. How to use users current charset?
if
(
et
->
m_
body
.
str
)
if
(
et
->
body
.
str
)
table
->
field
[
EVEX_FIELD_BODY
]
->
store
(
et
->
m_body
.
str
,
et
->
m_
body
.
length
,
system_charset_info
);
store
(
et
->
body
.
str
,
et
->
body
.
length
,
system_charset_info
);
if
(
et
->
m_
starts
.
year
)
if
(
et
->
starts
.
year
)
{
table
->
field
[
EVEX_FIELD_STARTS
]
->
set_notnull
();
// set NULL flag to OFF
table
->
field
[
EVEX_FIELD_STARTS
]
->
store_time
(
&
et
->
m_starts
,
MYSQL_TIMESTAMP_DATETIME
);
table
->
field
[
EVEX_FIELD_STARTS
]
->
store_time
(
&
et
->
starts
,
MYSQL_TIMESTAMP_DATETIME
);
}
if
(
et
->
m_
ends
.
year
)
if
(
et
->
ends
.
year
)
{
table
->
field
[
EVEX_FIELD_ENDS
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_ENDS
]
->
store_time
(
&
et
->
m_
ends
,
MYSQL_TIMESTAMP_DATETIME
);
table
->
field
[
EVEX_FIELD_ENDS
]
->
store_time
(
&
et
->
ends
,
MYSQL_TIMESTAMP_DATETIME
);
}
if
(
et
->
m_expr
)
if
(
et
->
expression
)
{
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
store
((
longlong
)
et
->
m_expr
);
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
store
((
longlong
)
et
->
expression
);
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
set_notnull
();
/*
In the enum (C) intervals start from 0 but in mysql enum valid values start
from 1. Thus +1 offset is needed!
*/
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
store
((
longlong
)
et
->
m_
interval
+
1
);
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
store
((
longlong
)
et
->
interval
+
1
);
}
else
if
(
et
->
m_
execute_at
.
year
)
else
if
(
et
->
execute_at
.
year
)
{
// fix_fields already called in init_execute_at
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
store_time
(
&
et
->
m_
execute_at
,
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
store_time
(
&
et
->
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
//this will make it NULL because we don't call set_notnull
...
...
@@ -321,9 +321,9 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
((
Field_timestamp
*
)
table
->
field
[
EVEX_FIELD_MODIFIED
])
->
set_time
();
if
(
(
et
->
m_comment
)
.
length
)
if
(
et
->
comment
.
length
)
table
->
field
[
EVEX_FIELD_COMMENT
]
->
store
(
(
et
->
m_comment
).
str
,
(
et
->
m_comment
)
.
length
,
system_charset_info
);
store
(
et
->
comment
.
str
,
et
->
comment
.
length
,
system_charset_info
);
DBUG_RETURN
(
0
);
}
...
...
@@ -351,7 +351,7 @@ db_create_event(THD *thd, event_timed *et)
char
olddb
[
128
];
bool
dbchanged
=
false
;
DBUG_ENTER
(
"db_create_event"
);
DBUG_PRINT
(
"enter"
,
(
"name: %.*s"
,
et
->
m_name
.
length
,
et
->
m_
name
.
str
));
DBUG_PRINT
(
"enter"
,
(
"name: %.*s"
,
et
->
name
.
length
,
et
->
name
.
str
));
DBUG_PRINT
(
"info"
,
(
"open mysql.event for update"
));
...
...
@@ -362,14 +362,14 @@ db_create_event(THD *thd, event_timed *et)
}
DBUG_PRINT
(
"info"
,
(
"check existance of an event with the same name"
));
if
(
!
evex_db_find_routine_aux
(
thd
,
et
->
m_db
,
et
->
m_
name
,
table
))
if
(
!
evex_db_find_routine_aux
(
thd
,
et
->
dbname
,
et
->
name
,
table
))
{
my_error
(
ER_EVENT_ALREADY_EXISTS
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_ALREADY_EXISTS
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
DBUG_PRINT
(
"info"
,
(
"non-existant, go forward"
));
if
((
ret
=
sp_use_new_db
(
thd
,
et
->
m_db
.
str
,
olddb
,
sizeof
(
olddb
),
0
,
&
dbchanged
)))
if
((
ret
=
sp_use_new_db
(
thd
,
et
->
dbname
.
str
,
olddb
,
sizeof
(
olddb
),
0
,
&
dbchanged
)))
{
my_error
(
ER_BAD_DB_ERROR
,
MYF
(
0
));
goto
err
;
...
...
@@ -378,31 +378,31 @@ db_create_event(THD *thd, event_timed *et)
restore_record
(
table
,
s
->
default_values
);
// Get default values for fields
if
(
et
->
m_
name
.
length
>
table
->
field
[
EVEX_FIELD_NAME
]
->
field_length
)
if
(
et
->
name
.
length
>
table
->
field
[
EVEX_FIELD_NAME
]
->
field_length
)
{
my_error
(
ER_TOO_LONG_IDENT
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_TOO_LONG_IDENT
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
if
(
et
->
m_
body
.
length
>
table
->
field
[
EVEX_FIELD_BODY
]
->
field_length
)
if
(
et
->
body
.
length
>
table
->
field
[
EVEX_FIELD_BODY
]
->
field_length
)
{
my_error
(
ER_TOO_LONG_BODY
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_TOO_LONG_BODY
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
if
(
!
(
et
->
m_expr
)
&&
!
(
et
->
m_
execute_at
.
year
))
if
(
!
(
et
->
expression
)
&&
!
(
et
->
execute_at
.
year
))
{
DBUG_PRINT
(
"error"
,
(
"neither
m_expr nor m_execute_as
are set!"
));
DBUG_PRINT
(
"error"
,
(
"neither
expression nor execute_at
are set!"
));
my_error
(
ER_EVENT_NEITHER_M_EXPR_NOR_M_AT
,
MYF
(
0
));
goto
err
;
}
strxmov
(
definer
,
et
->
m_definer_user
.
str
,
"@"
,
et
->
m_
definer_host
.
str
,
NullS
);
strxmov
(
definer
,
et
->
definer_user
.
str
,
"@"
,
et
->
definer_host
.
str
,
NullS
);
if
(
table
->
field
[
EVEX_FIELD_DEFINER
]
->
store
(
definer
,
et
->
m_definer_user
.
length
+
1
+
et
->
m_
definer_host
.
length
,
store
(
definer
,
et
->
definer_user
.
length
+
1
+
et
->
definer_host
.
length
,
system_charset_info
))
{
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
...
...
@@ -413,7 +413,7 @@ db_create_event(THD *thd, event_timed *et)
ret
=
EVEX_OK
;
if
(
table
->
file
->
write_row
(
table
->
record
[
0
]))
{
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
...
...
@@ -452,14 +452,15 @@ db_create_event(THD *thd, event_timed *et)
*/
static
int
db_update_event
(
THD
*
thd
,
sp_name
*
name
,
event_timed
*
et
)
db_update_event
(
THD
*
thd
,
sp_name
*
n
ew_n
ame
,
event_timed
*
et
)
{
TABLE
*
table
;
int
ret
=
EVEX_OPEN_TABLE_FAILED
;
DBUG_ENTER
(
"db_update_event"
);
DBUG_PRINT
(
"enter"
,
(
"name: %.*s"
,
et
->
m_name
.
length
,
et
->
m_name
.
str
));
if
(
name
)
DBUG_PRINT
(
"enter"
,
(
"rename to: %.*s"
,
name
->
m_name
.
length
,
name
->
m_name
.
str
));
DBUG_PRINT
(
"enter"
,
(
"name: %.*s"
,
et
->
name
.
length
,
et
->
name
.
str
));
if
(
new_name
)
DBUG_PRINT
(
"enter"
,
(
"rename to: %.*s"
,
new_name
->
m_name
.
length
,
new_name
->
m_name
.
str
));
if
(
!
(
table
=
evex_open_event_table
(
thd
,
TL_WRITE
)))
{
...
...
@@ -467,10 +468,10 @@ db_update_event(THD *thd, sp_name *name, event_timed *et)
goto
err
;
}
if
(
EVEX_KEY_NOT_FOUND
==
evex_db_find_routine_aux
(
thd
,
et
->
m_db
,
et
->
m_
name
,
if
(
EVEX_KEY_NOT_FOUND
==
evex_db_find_routine_aux
(
thd
,
et
->
dbname
,
et
->
name
,
table
))
{
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
...
...
@@ -483,17 +484,17 @@ db_update_event(THD *thd, sp_name *name, event_timed *et)
if
((
ret
=
evex_fill_row
(
thd
,
table
,
et
,
true
)))
goto
err
;
if
(
name
)
if
(
n
ew_n
ame
)
{
table
->
field
[
EVEX_FIELD_DB
]
->
store
(
n
ame
->
m_db
.
str
,
name
->
m_db
.
length
,
system_charset_info
);
store
(
n
ew_name
->
m_db
.
str
,
new_
name
->
m_db
.
length
,
system_charset_info
);
table
->
field
[
EVEX_FIELD_NAME
]
->
store
(
n
ame
->
m_name
.
str
,
name
->
m_name
.
length
,
system_charset_info
);
store
(
n
ew_name
->
m_name
.
str
,
new_
name
->
m_name
.
length
,
system_charset_info
);
}
if
((
ret
=
table
->
file
->
update_row
(
table
->
record
[
1
],
table
->
record
[
0
])))
{
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_STORE_FAILED
,
MYF
(
0
),
et
->
name
.
str
);
goto
err
;
}
...
...
@@ -546,7 +547,7 @@ db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl)
if
((
ret
=
evex_db_find_routine_aux
(
thd
,
name
->
m_db
,
name
->
m_name
,
table
)))
{
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
et
->
m_name
.
str
);
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
name
->
m_name
.
str
);
goto
done
;
}
et
=
new
event_timed
;
...
...
@@ -612,7 +613,7 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
/*
allocate on evex_mem_root. if you call without evex_mem_root
then
m_
sphead will not be cleared!
then sphead will not be cleared!
*/
if
((
ret
=
ett
->
compile
(
thd
,
&
evex_mem_root
)))
goto
done
;
...
...
@@ -627,10 +628,10 @@ evex_load_and_compile_event(THD * thd, sp_name *spn, bool use_lock)
VOID
(
push_dynamic
(
&
evex_executing_queue
,
(
gptr
)
&
ett_copy
));
/*
There is a copy in the array which we don't need.
m_
sphead won't be
There is a copy in the array which we don't need. sphead won't be
destroyed.
*/
ett
->
m_
free_sphead_on_delete
=
false
;
ett
->
free_sphead_on_delete
=
false
;
delete
ett
;
/*
...
...
@@ -674,11 +675,11 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
event_timed
**
p_et
=
dynamic_element
(
&
evex_executing_queue
,
i
,
event_timed
**
);
event_timed
*
ett
=
*
p_et
;
DBUG_PRINT
(
"info"
,
(
"[%s.%s]==[%s.%s]?"
,
db
->
str
,
name
->
str
,
ett
->
m_db
.
str
,
ett
->
m_
name
.
str
));
if
(
name
->
length
==
ett
->
m_
name
.
length
&&
db
->
length
==
ett
->
m_db
.
length
&&
0
==
strncmp
(
db
->
str
,
ett
->
m_db
.
str
,
db
->
length
)
&&
0
==
strncmp
(
name
->
str
,
ett
->
m_
name
.
str
,
name
->
length
)
ett
->
dbname
.
str
,
ett
->
name
.
str
));
if
(
name
->
length
==
ett
->
name
.
length
&&
db
->
length
==
ett
->
dbname
.
length
&&
0
==
strncmp
(
db
->
str
,
ett
->
dbname
.
str
,
db
->
length
)
&&
0
==
strncmp
(
name
->
str
,
ett
->
name
.
str
,
name
->
length
)
)
{
int
idx
;
...
...
@@ -722,10 +723,10 @@ evex_remove_from_cache(LEX_STRING *db, LEX_STRING *name, bool use_lock)
{
event_timed
*
ett
=
dynamic_element
(
&
events_array
,
i
,
event_timed
*
);
if
(
name
->
length
==
ett
->
m_
name
.
length
&&
db
->
length
==
ett
->
m_db
.
length
&&
0
==
strncmp
(
db
->
str
,
ett
->
m_db
.
str
,
db
->
length
)
&&
0
==
strncmp
(
name
->
str
,
ett
->
m_
name
.
str
,
name
->
length
)
if
(
name
->
length
==
ett
->
name
.
length
&&
db
->
length
==
ett
->
dbname
.
length
&&
0
==
strncmp
(
db
->
str
,
ett
->
dbname
.
str
,
db
->
length
)
&&
0
==
strncmp
(
name
->
str
,
ett
->
name
.
str
,
name
->
length
)
)
delete_dynamic_element
(
&
events_array
,
i
);
}
...
...
@@ -763,15 +764,15 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
int
ret
=
0
;
DBUG_ENTER
(
"evex_create_event"
);
DBUG_PRINT
(
"enter"
,
(
"name: %*s options:%d"
,
et
->
m_
name
.
length
,
et
->
m_
name
.
str
,
create_options
));
DBUG_PRINT
(
"enter"
,
(
"name: %*s options:%d"
,
et
->
name
.
length
,
et
->
name
.
str
,
create_options
));
if
((
ret
=
db_create_event
(
thd
,
et
))
==
EVEX_WRITE_ROW_FAILED
&&
(
create_options
&
HA_LEX_CREATE_IF_NOT_EXISTS
))
{
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_DB_CREATE_EXISTS
,
ER
(
ER_DB_CREATE_EXISTS
),
"EVENT"
,
thd
->
lex
->
et
->
m_
name
.
str
);
"EVENT"
,
et
->
name
.
str
);
ret
=
0
;
goto
done
;
}
...
...
@@ -785,9 +786,9 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
goto
done
;
VOID
(
pthread_mutex_lock
(
&
LOCK_evex_running
));
if
(
evex_is_running
&&
et
->
m_
status
==
MYSQL_EVENT_ENABLED
)
if
(
evex_is_running
&&
et
->
status
==
MYSQL_EVENT_ENABLED
)
{
sp_name
spn
(
et
->
m_db
,
et
->
m_
name
);
sp_name
spn
(
et
->
dbname
,
et
->
name
);
ret
=
evex_load_and_compile_event
(
thd
,
&
spn
,
true
);
}
VOID
(
pthread_mutex_unlock
(
&
LOCK_evex_running
));
...
...
@@ -805,8 +806,8 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
SYNOPSIS
evex_update_event()
thd THD
name the real name of the event.
et event's data
new_name set in case of RENAME TO.
NOTES
et contains data about dbname and event name.
...
...
@@ -815,14 +816,14 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
*/
int
evex_update_event
(
THD
*
thd
,
sp_name
*
name
,
event_timed
*
et
)
evex_update_event
(
THD
*
thd
,
event_timed
*
et
,
sp_name
*
name
)
{
int
ret
,
i
;
bool
need_second_pass
=
true
;
sp_name
*
spn
=
0
;
DBUG_ENTER
(
"evex_update_event"
);
DBUG_PRINT
(
"enter"
,
(
"name: %*s"
,
et
->
m_name
.
length
,
et
->
m_
name
.
str
));
DBUG_PRINT
(
"enter"
,
(
"name: %*s"
,
et
->
name
.
length
,
et
->
name
.
str
));
/*
db_update_event() opens & closes the table to prevent
...
...
@@ -836,13 +837,13 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et)
UNLOCK_MUTEX_AND_BAIL_OUT
(
LOCK_evex_running
,
done
);
VOID
(
pthread_mutex_lock
(
&
LOCK_event_arrays
));
evex_remove_from_cache
(
&
et
->
m_db
,
&
et
->
m_
name
,
false
);
if
(
et
->
m_
status
==
MYSQL_EVENT_ENABLED
)
evex_remove_from_cache
(
&
et
->
dbname
,
&
et
->
name
,
false
);
if
(
et
->
status
==
MYSQL_EVENT_ENABLED
)
if
(
name
)
ret
=
evex_load_and_compile_event
(
thd
,
name
,
false
);
else
{
spn
=
new
sp_name
(
et
->
m_db
,
et
->
m_
name
);
spn
=
new
sp_name
(
et
->
dbname
,
et
->
name
);
ret
=
evex_load_and_compile_event
(
thd
,
spn
,
false
);
delete
spn
;
}
...
...
@@ -884,9 +885,9 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
goto
done
;
}
if
(
!
(
ret
=
evex_db_find_routine_aux
(
thd
,
et
->
m_db
,
et
->
m_
name
,
table
)))
if
(
!
(
ret
=
evex_db_find_routine_aux
(
thd
,
et
->
dbname
,
et
->
name
,
table
)))
{
if
(
ret
=
table
->
file
->
delete_row
(
table
->
record
[
0
]
))
if
(
(
ret
=
table
->
file
->
delete_row
(
table
->
record
[
0
])
))
{
my_error
(
ER_EVENT_CANNOT_DELETE
,
MYF
(
0
));
goto
done
;
...
...
@@ -896,7 +897,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
{
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_SP_DOES_NOT_EXIST
,
ER
(
ER_SP_DOES_NOT_EXIST
),
"EVENT"
,
thd
->
lex
->
et
->
m_
name
.
str
);
"EVENT"
,
et
->
name
.
str
);
ret
=
0
;
goto
done
;
}
else
...
...
@@ -904,7 +905,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
VOID
(
pthread_mutex_lock
(
&
LOCK_evex_running
));
if
(
evex_is_running
)
ret
=
evex_remove_from_cache
(
&
et
->
m_db
,
&
et
->
m_
name
,
true
);
ret
=
evex_remove_from_cache
(
&
et
->
dbname
,
&
et
->
name
,
true
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_evex_running
));
done:
...
...
sql/event.h
View file @
3d854641
/* Copyright (C) 200
0-2003
MySQL AB
/* Copyright (C) 200
4-2005
MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -63,41 +63,45 @@ class event_timed
my_bool
running
;
pthread_mutex_t
LOCK_running
;
bool
status_changed
;
bool
last_executed_changed
;
TIME
last_executed
;
public:
LEX_STRING
m_db
;
LEX_STRING
m_
name
;
LEX_STRING
m_
body
;
LEX_STRING
m_
definer_user
;
LEX_STRING
m_
definer_host
;
LEX_STRING
m_
definer
;
// combination of user and host
LEX_STRING
m_
comment
;
TIME
m_
starts
;
TIME
m_
ends
;
TIME
m_
execute_at
;
longlong
m_expr
;
interval_type
m_interval
;
longlong
m_created
;
longlong
m_modified
;
TIME
m_last_execu
ted
;
enum
enum_event_on_completion
m_on_completion
;
enum
enum_event_
status
m_status
;
sp_head
*
m_sphead
;
const
uchar
*
m_body_begin
;
bool
m_dropped
;
bool
m_free_sphead_on_delete
;
uint
m_flags
;
//all kind of purposes
bool
m_last_executed_changed
;
bool
m_status_changed
;
event_timed
()
:
running
(
0
),
m_expr
(
0
),
m_created
(
0
),
m_
modified
(
0
),
m_
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
m_status
(
MYSQL_EVENT_ENABLED
),
m_sphead
(
0
),
m_
dropped
(
false
),
m_free_sphead_on_delete
(
true
),
m_flags
(
0
),
m_last_executed_changed
(
false
),
m_status_changed
(
false
)
LEX_STRING
dbname
;
LEX_STRING
name
;
LEX_STRING
body
;
LEX_STRING
definer_user
;
LEX_STRING
definer_host
;
LEX_STRING
definer
;
// combination of user and host
LEX_STRING
comment
;
TIME
starts
;
TIME
ends
;
TIME
execute_at
;
longlong
expression
;
interval_type
interval
;
longlong
crea
ted
;
longlong
modified
;
enum
enum_event_
on_completion
on_completion
;
enum
enum_event_status
status
;
sp_head
*
sphead
;
const
uchar
*
body_begin
;
bool
dropped
;
bool
free_sphead_on_delete
;
uint
flags
;
//all kind of purposes
event_timed
()
:
running
(
0
),
status_changed
(
false
),
last_executed_changed
(
false
),
expression
(
0
),
created
(
0
),
modified
(
0
),
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
status
(
MYSQL_EVENT_ENABLED
),
sphead
(
0
),
dropped
(
false
),
free_sphead_on_delete
(
true
),
flags
(
0
)
{
pthread_mutex_init
(
&
LOCK_running
,
MY_MUTEX_INIT_FAST
);
init
();
...
...
@@ -106,7 +110,7 @@ class event_timed
~
event_timed
()
{
pthread_mutex_destroy
(
&
LOCK_running
);
if
(
m_
free_sphead_on_delete
)
if
(
free_sphead_on_delete
)
free_sp
();
}
...
...
@@ -120,10 +124,10 @@ class event_timed
init_execute_at
(
THD
*
thd
,
Item
*
expr
);
int
init_interval
(
THD
*
thd
,
Item
*
expr
,
interval_type
interval
);
init_interval
(
THD
*
thd
,
Item
*
expr
,
interval_type
new_
interval
);
void
init_name
(
THD
*
thd
,
sp_name
*
name
);
init_name
(
THD
*
thd
,
sp_name
*
spn
);
int
init_starts
(
THD
*
thd
,
Item
*
starts
);
...
...
@@ -135,7 +139,7 @@ class event_timed
event_timed
::
init_body
(
THD
*
thd
);
void
init_comment
(
THD
*
thd
,
LEX_STRING
*
comment
);
init_comment
(
THD
*
thd
,
LEX_STRING
*
set_
comment
);
int
load_from_row
(
MEM_ROOT
*
mem_root
,
TABLE
*
table
);
...
...
@@ -163,11 +167,8 @@ class event_timed
void
free_sp
()
{
if
(
m_sphead
)
{
delete
m_sphead
;
m_sphead
=
0
;
}
delete
sphead
;
sphead
=
0
;
}
};
...
...
@@ -176,7 +177,7 @@ int
evex_create_event
(
THD
*
thd
,
event_timed
*
et
,
uint
create_options
);
int
evex_update_event
(
THD
*
thd
,
sp_name
*
name
,
event_timed
*
et
);
evex_update_event
(
THD
*
thd
,
event_timed
*
et
,
sp_name
*
new_name
);
int
evex_drop_event
(
THD
*
thd
,
event_timed
*
et
,
bool
drop_if_exists
);
...
...
sql/event_executor.cc
View file @
3d854641
/* Copyright (C) 200
0-2003
MySQL AB
/* Copyright (C) 200
4-2005
MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -226,7 +226,7 @@ event_executor_main(void *arg)
for
(
i
=
0
;
(
i
<
evex_executing_queue
.
elements
)
&&
!
thd
->
killed
;
++
i
)
{
event_timed
*
et
=
*
dynamic_element
(
&
evex_executing_queue
,
i
,
event_timed
**
);
// printf("%llu\n", TIME_to_ulonglong_datetime(&et->
m_
execute_at));
// printf("%llu\n", TIME_to_ulonglong_datetime(&et->execute_at));
if
(
!
event_executor_running_global_var
)
break
;
...
...
@@ -236,13 +236,13 @@ event_executor_main(void *arg)
if this is the first event which is after time_now then no
more need to iterate over more elements since the array is sorted.
*/
if
(
et
->
m_
execute_at
.
year
>
1969
&&
my_time_compare
(
&
time_now
,
&
et
->
m_
execute_at
)
==
-
1
)
if
(
et
->
execute_at
.
year
>
1969
&&
my_time_compare
(
&
time_now
,
&
et
->
execute_at
)
==
-
1
)
break
;
if
(
et
->
m_
status
==
MYSQL_EVENT_ENABLED
&&
!
check_access
(
thd
,
EVENT_ACL
,
et
->
m_db
.
str
,
0
,
0
,
0
,
is_schema_db
(
et
->
m_db
.
str
)))
if
(
et
->
status
==
MYSQL_EVENT_ENABLED
&&
!
check_access
(
thd
,
EVENT_ACL
,
et
->
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
et
->
dbname
.
str
)))
{
pthread_t
th
;
...
...
@@ -262,9 +262,9 @@ event_executor_main(void *arg)
thd
->
proc_info
=
"Computing next time"
;
et
->
compute_next_execution_time
();
et
->
update_fields
(
thd
);
if
((
et
->
m_execute_at
.
year
&&
!
et
->
m_expr
)
||
TIME_to_ulonglong_datetime
(
&
et
->
m_
execute_at
)
==
0L
)
et
->
m_
flags
|=
EVENT_EXEC_NO_MORE
;
if
((
et
->
execute_at
.
year
&&
!
et
->
expression
)
||
TIME_to_ulonglong_datetime
(
&
et
->
execute_at
)
==
0L
)
et
->
flags
|=
EVENT_EXEC_NO_MORE
;
}
}
/*
...
...
@@ -275,13 +275,13 @@ event_executor_main(void *arg)
while
(
j
<
i
&&
j
<
evex_executing_queue
.
elements
)
{
event_timed
*
et
=
*
dynamic_element
(
&
evex_executing_queue
,
j
,
event_timed
**
);
if
(
et
->
m_flags
&
EVENT_EXEC_NO_MORE
||
et
->
m_
status
==
MYSQL_EVENT_DISABLED
)
if
(
(
et
->
flags
&
EVENT_EXEC_NO_MORE
)
||
et
->
status
==
MYSQL_EVENT_DISABLED
)
{
delete_dynamic_element
(
&
evex_executing_queue
,
j
);
DBUG_PRINT
(
"EVEX main thread"
,
(
"DELETING FROM EXECUTION QUEUE [%s.%s]"
,
et
->
m_db
.
str
,
et
->
m_
name
.
str
));
et
->
dbname
.
str
,
et
->
name
.
str
));
// nulling the position, will delete later
if
(
et
->
m_
dropped
)
if
(
et
->
dropped
)
{
// we have to drop the event
int
idx
;
...
...
@@ -311,7 +311,7 @@ event_executor_main(void *arg)
evex_is_running
=
false
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_evex_running
));
sql_print_information
(
"Event
executo
r stopping"
);
sql_print_information
(
"Event
schedule
r stopping"
);
/*
TODO: A better will be with a conditional variable
...
...
@@ -334,7 +334,7 @@ event_executor_main(void *arg)
// No need to use lock here if EVEX is not running but anyway
delete_dynamic
(
&
evex_executing_queue
);
delete_dynamic
(
&
events_array
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_eve
x_running
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_eve
nt_arrays
));
thd
->
proc_info
=
"Clearing"
;
DBUG_ASSERT
(
thd
->
net
.
buff
!=
0
);
...
...
@@ -355,7 +355,7 @@ event_executor_main(void *arg)
VOID
(
pthread_mutex_unlock
(
&
LOCK_evex_running
));
free_root
(
&
evex_mem_root
,
MYF
(
0
));
sql_print_information
(
"Event
executo
r stopped"
);
sql_print_information
(
"Event
schedule
r stopped"
);
my_thread_end
();
pthread_exit
(
0
);
...
...
@@ -381,7 +381,7 @@ event_executor_worker(void *event_void)
if
(
!
(
thd
=
new
THD
))
// note that contructor of THD uses DBUG_ !
{
sql_print_error
(
"Cannot create a THD structure in worker thread"
);
sql_print_error
(
"Cannot create a THD structure in
a scheduler
worker thread"
);
goto
err_no_thd
;
}
thd
->
thread_stack
=
(
char
*
)
&
thd
;
// remember where our stack is
...
...
@@ -406,20 +406,20 @@ event_executor_worker(void *event_void)
// thd->security_ctx->priv_host is char[MAX_HOSTNAME]
strxnmov
(
thd
->
security_ctx
->
priv_host
,
sizeof
(
thd
->
security_ctx
->
priv_host
),
event
->
m_
definer_host
.
str
,
NullS
);
event
->
definer_host
.
str
,
NullS
);
thd
->
security_ctx
->
priv_user
=
event
->
m_
definer_user
.
str
;
thd
->
security_ctx
->
priv_user
=
event
->
definer_user
.
str
;
thd
->
db
=
event
->
m_db
.
str
;
thd
->
db
=
event
->
dbname
.
str
;
{
char
exec_time
[
200
];
int
ret
;
my_TIME_to_str
(
&
event
->
m_
execute_at
,
exec_time
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
m_db
.
str
,
event
->
m_name
.
str
,(
int
)
event
->
m_expr
,
exec_time
));
sql_print_information
(
" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
m_db
.
str
,
event
->
m_name
.
str
,(
int
)
event
->
m_expr
,
exec_time
);
my_TIME_to_str
(
&
event
->
execute_at
,
exec_time
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
,
exec_time
));
sql_print_information
(
" EVEX EXECUTING event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
,
exec_time
);
ret
=
event
->
execute
(
thd
,
&
worker_mem_root
);
sql_print_information
(
" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]. RetCode=%d"
,
event
->
m_db
.
str
,
event
->
m_name
.
str
,(
int
)
event
->
m_expr
,
exec_time
,
ret
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
m_db
.
str
,
event
->
m_name
.
str
,(
int
)
event
->
m_expr
,
exec_time
));
sql_print_information
(
" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]. RetCode=%d"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
,
exec_time
,
ret
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTED event for event %s.%s [EXPR:%d][EXECUTE_AT:%s]"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
,
exec_time
));
}
thd
->
db
=
0
;
...
...
@@ -495,19 +495,19 @@ evex_load_events_from_db(THD *thd)
}
DBUG_PRINT
(
"evex_load_events_from_db"
,
(
"Event %s loaded from row. Time to compile"
,
et
->
m_
name
.
str
));
(
"Event %s loaded from row. Time to compile"
,
et
->
name
.
str
));
if
((
ret
=
et
->
compile
(
thd
,
&
evex_mem_root
)))
{
sql_print_error
(
"Error while compiling %s.%s. Aborting load."
,
et
->
m_db
.
str
,
et
->
m_
name
.
str
);
et
->
dbname
.
str
,
et
->
name
.
str
);
goto
end
;
}
// let's find when to be executed
et
->
compute_next_execution_time
();
DBUG_PRINT
(
"evex_load_events_from_db"
,
(
"Adding %s to the executor list."
,
et
->
m_
name
.
str
));
(
"Adding %s to the executor list."
,
et
->
name
.
str
));
VOID
(
push_dynamic
(
&
events_array
,(
gptr
)
et
));
/*
We always add at the end so the number of elements - 1 is the place
...
...
@@ -518,7 +518,7 @@ evex_load_events_from_db(THD *thd)
et_copy
=
dynamic_element
(
&
events_array
,
events_array
.
elements
-
1
,
event_timed
*
);
VOID
(
push_dynamic
(
&
evex_executing_queue
,(
gptr
)
&
et_copy
));
et
->
m_
free_sphead_on_delete
=
false
;
et
->
free_sphead_on_delete
=
false
;
delete
et
;
}
end_read_record
(
&
read_record_info
);
...
...
sql/event_priv.h
View file @
3d854641
/* Copyright (C) 200
0-2003
MySQL AB
/* Copyright (C) 200
4-2005
MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
sql/event_timed.cc
View file @
3d854641
/* Copyright (C) 200
0-2003
MySQL AB
/* Copyright (C) 200
4-2005
MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
...
...
@@ -35,16 +35,16 @@ event_timed::init()
{
DBUG_ENTER
(
"event_timed::init"
);
m_db
.
str
=
m_name
.
str
=
m_body
.
str
=
m_
comment
.
str
=
0
;
m_db
.
length
=
m_name
.
length
=
m_body
.
length
=
m_
comment
.
length
=
0
;
dbname
.
str
=
name
.
str
=
body
.
str
=
comment
.
str
=
0
;
dbname
.
length
=
name
.
length
=
body
.
length
=
comment
.
length
=
0
;
set_zero_time
(
&
m_
starts
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
m_
ends
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
m_
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
m_
last_executed
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
starts
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
ends
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
last_executed
,
MYSQL_TIMESTAMP_DATETIME
);
m_definer_user
.
str
=
m_
definer_host
.
str
=
0
;
m_definer_user
.
length
=
m_
definer_host
.
length
=
0
;
definer_user
.
str
=
definer_host
.
str
=
0
;
definer_user
.
length
=
definer_host
.
length
=
0
;
DBUG_VOID_RETURN
;
}
...
...
@@ -56,11 +56,11 @@ event_timed::init()
SYNOPSIS
event_timed::init_name()
thd THD
name
the name extracted in the parser
spn
the name extracted in the parser
*/
void
event_timed
::
init_name
(
THD
*
thd
,
sp_name
*
name
)
event_timed
::
init_name
(
THD
*
thd
,
sp_name
*
spn
)
{
DBUG_ENTER
(
"event_timed::init_name"
);
uint
n
;
/* Counter for nul trimming */
...
...
@@ -68,27 +68,27 @@ event_timed::init_name(THD *thd, sp_name *name)
MEM_ROOT
*
root
=
thd
->
mem_root
;
/* We have to copy strings to get them into the right memroot */
if
(
name
)
if
(
spn
)
{
m_db
.
length
=
name
->
m_db
.
length
;
if
(
name
->
m_db
.
length
==
0
)
m_db
.
str
=
NULL
;
dbname
.
length
=
spn
->
m_db
.
length
;
if
(
spn
->
m_db
.
length
==
0
)
dbname
.
str
=
NULL
;
else
m_db
.
str
=
strmake_root
(
root
,
name
->
m_db
.
str
,
name
->
m_db
.
length
);
m_name
.
length
=
name
->
m_name
.
length
;
m_name
.
str
=
strmake_root
(
root
,
name
->
m_name
.
str
,
name
->
m_name
.
length
);
dbname
.
str
=
strmake_root
(
root
,
spn
->
m_db
.
str
,
spn
->
m_db
.
length
);
name
.
length
=
spn
->
m_name
.
length
;
name
.
str
=
strmake_root
(
root
,
spn
->
m_name
.
str
,
spn
->
m_name
.
length
);
if
(
name
->
m_qname
.
length
==
0
)
name
->
init_qname
(
thd
);
if
(
spn
->
m_qname
.
length
==
0
)
spn
->
init_qname
(
thd
);
}
else
if
(
thd
->
db
)
{
m_db
.
length
=
thd
->
db_length
;
m_db
.
str
=
strmake_root
(
root
,
thd
->
db
,
m_db
.
length
);
dbname
.
length
=
thd
->
db_length
;
dbname
.
str
=
strmake_root
(
root
,
thd
->
db
,
dbname
.
length
);
}
DBUG_PRINT
(
"
m_db"
,
(
"len=%d db=%s"
,
m_db
.
length
,
m_db
.
str
));
DBUG_PRINT
(
"
m_name"
,
(
"len=%d name=%s"
,
m_name
.
length
,
m_
name
.
str
));
DBUG_PRINT
(
"
dbname"
,
(
"len=%d db=%s"
,
dbname
.
length
,
dbname
.
str
));
DBUG_PRINT
(
"
name"
,
(
"len=%d name=%s"
,
name
.
length
,
name
.
str
));
DBUG_VOID_RETURN
;
}
...
...
@@ -112,12 +112,12 @@ event_timed::init_body(THD *thd)
DBUG_ENTER
(
"event_timed::init_body"
);
MEM_ROOT
*
root
=
thd
->
mem_root
;
m_body
.
length
=
thd
->
lex
->
ptr
-
m_
body_begin
;
body
.
length
=
thd
->
lex
->
ptr
-
body_begin
;
// Trim nuls at the end
while
(
m_body
.
length
&&
m_body_begin
[
m_
body
.
length
-
1
]
==
'\0'
)
m_
body
.
length
--
;
while
(
body
.
length
&&
body_begin
[
body
.
length
-
1
]
==
'\0'
)
body
.
length
--
;
m_body
.
str
=
strmake_root
(
root
,
(
char
*
)
m_body_begin
,
m_
body
.
length
);
body
.
str
=
strmake_root
(
root
,
(
char
*
)
body_begin
,
body
.
length
);
DBUG_VOID_RETURN
;
}
...
...
@@ -169,7 +169,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
));
m_
execute_at
=
ltime
;
execute_at
=
ltime
;
DBUG_RETURN
(
0
);
}
...
...
@@ -180,7 +180,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
SYNOPSIS
event_timed::init_interval()
expr how much?
interval what is the interval
new_
interval what is the interval
RETURNS
0 - OK
...
...
@@ -189,7 +189,7 @@ event_timed::init_execute_at(THD *thd, Item *expr)
*/
int
event_timed
::
init_interval
(
THD
*
thd
,
Item
*
expr
,
interval_type
interval
)
event_timed
::
init_interval
(
THD
*
thd
,
Item
*
expr
,
interval_type
new_
interval
)
{
longlong
tmp
;
DBUG_ENTER
(
"event_timed::init_interval"
);
...
...
@@ -200,8 +200,8 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type interval)
if
((
tmp
=
expr
->
val_int
())
<=
0
)
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
m_expr
=
tmp
;
m_interval
=
interval
;
expression
=
tmp
;
interval
=
new_
interval
;
DBUG_RETURN
(
0
);
}
...
...
@@ -228,7 +228,7 @@ event_timed::init_interval(THD *thd, Item *expr, interval_type interval)
*/
int
event_timed
::
init_starts
(
THD
*
thd
,
Item
*
starts
)
event_timed
::
init_starts
(
THD
*
thd
,
Item
*
new_
starts
)
{
my_bool
not_used
;
TIME
ltime
;
...
...
@@ -236,22 +236,22 @@ event_timed::init_starts(THD *thd, Item *starts)
DBUG_ENTER
(
"event_timed::init_starts"
);
if
(
starts
->
fix_fields
(
thd
,
&
starts
))
if
(
new_starts
->
fix_fields
(
thd
,
&
new_
starts
))
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
if
(
starts
->
val_int
()
==
MYSQL_TIMESTAMP_ERROR
)
if
(
new_
starts
->
val_int
()
==
MYSQL_TIMESTAMP_ERROR
)
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
if
((
not_used
=
starts
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
if
((
not_used
=
new_
starts
->
get_date
(
&
ltime
,
TIME_NO_ZERO_DATE
)))
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
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
m_
starts
=
ltime
;
starts
=
ltime
;
DBUG_RETURN
(
0
);
}
...
...
@@ -262,7 +262,7 @@ event_timed::init_starts(THD *thd, Item *starts)
SYNOPSIS
event_timed::init_ends()
thd THD
ends when?
new_
ends when?
NOTES
Note that activation time is not execution time.
...
...
@@ -279,7 +279,7 @@ event_timed::init_starts(THD *thd, Item *starts)
*/
int
event_timed
::
init_ends
(
THD
*
thd
,
Item
*
ends
)
event_timed
::
init_ends
(
THD
*
thd
,
Item
*
new_
ends
)
{
TIME
ltime
;
my_time_t
my_time_tmp
;
...
...
@@ -287,11 +287,11 @@ event_timed::init_ends(THD *thd, Item *ends)
DBUG_ENTER
(
"event_timed::init_ends"
);
if
(
ends
->
fix_fields
(
thd
,
&
ends
))
if
(
new_ends
->
fix_fields
(
thd
,
&
new_
ends
))
DBUG_RETURN
(
EVEX_PARSE_ERROR
);
// the field was already fixed in init_ends
if
((
not_used
=
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
);
/*
...
...
@@ -300,10 +300,10 @@ event_timed::init_ends(THD *thd, Item *ends)
*/
my_tz_UTC
->
gmt_sec_to_TIME
(
&
ltime
,
TIME_to_timestamp
(
thd
,
&
ltime
,
&
not_used
));
if
(
m_starts
.
year
&&
my_time_compare
(
&
m_
starts
,
&
ltime
)
!=
-
1
)
if
(
starts
.
year
&&
my_time_compare
(
&
starts
,
&
ltime
)
!=
-
1
)
DBUG_RETURN
(
EVEX_BAD_PARAMS
);
m_
ends
=
ltime
;
ends
=
ltime
;
DBUG_RETURN
(
0
);
}
...
...
@@ -318,19 +318,19 @@ event_timed::init_ends(THD *thd, Item *ends)
*/
void
event_timed
::
init_comment
(
THD
*
thd
,
LEX_STRING
*
comment
)
event_timed
::
init_comment
(
THD
*
thd
,
LEX_STRING
*
set_
comment
)
{
DBUG_ENTER
(
"event_timed::init_comment"
);
m_comment
.
str
=
strmake_root
(
thd
->
mem_root
,
comment
->
str
,
m_comment
.
length
=
comment
->
length
);
comment
.
str
=
strmake_root
(
thd
->
mem_root
,
set_
comment
->
str
,
comment
.
length
=
set_
comment
->
length
);
DBUG_VOID_RETURN
;
}
/*
Inits definer (
m_definer_user and m_
definer_host) during
Inits definer (
definer_user and
definer_host) during
parsing.
SYNOPSIS
...
...
@@ -342,11 +342,11 @@ event_timed::init_definer(THD *thd)
{
DBUG_ENTER
(
"event_timed::init_definer"
);
m_
definer_user
.
str
=
strdup_root
(
thd
->
mem_root
,
thd
->
security_ctx
->
priv_user
);
m_
definer_user
.
length
=
strlen
(
thd
->
security_ctx
->
priv_user
);
definer_user
.
str
=
strdup_root
(
thd
->
mem_root
,
thd
->
security_ctx
->
priv_user
);
definer_user
.
length
=
strlen
(
thd
->
security_ctx
->
priv_user
);
m_
definer_host
.
str
=
strdup_root
(
thd
->
mem_root
,
thd
->
security_ctx
->
priv_host
);
m_
definer_host
.
length
=
strlen
(
thd
->
security_ctx
->
priv_host
);
definer_host
.
str
=
strdup_root
(
thd
->
mem_root
,
thd
->
security_ctx
->
priv_host
);
definer_host
.
length
=
strlen
(
thd
->
security_ctx
->
priv_host
);
DBUG_RETURN
(
0
);
}
...
...
@@ -384,68 +384,68 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
if
(
table
->
s
->
fields
!=
EVEX_FIELD_COUNT
)
goto
error
;
if
((
et
->
m_db
.
str
=
get_field
(
mem_root
,
if
((
et
->
dbname
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_DB
]))
==
NULL
)
goto
error
;
et
->
m_db
.
length
=
strlen
(
et
->
m_db
.
str
);
et
->
dbname
.
length
=
strlen
(
et
->
dbname
.
str
);
if
((
et
->
m_
name
.
str
=
get_field
(
mem_root
,
if
((
et
->
name
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_NAME
]))
==
NULL
)
goto
error
;
et
->
m_name
.
length
=
strlen
(
et
->
m_
name
.
str
);
et
->
name
.
length
=
strlen
(
et
->
name
.
str
);
if
((
et
->
m_
body
.
str
=
get_field
(
mem_root
,
if
((
et
->
body
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_BODY
]))
==
NULL
)
goto
error
;
et
->
m_body
.
length
=
strlen
(
et
->
m_
body
.
str
);
et
->
body
.
length
=
strlen
(
et
->
body
.
str
);
if
((
et
->
m_
definer
.
str
=
get_field
(
mem_root
,
if
((
et
->
definer
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_DEFINER
]))
==
NullS
)
goto
error
;
et
->
m_definer
.
length
=
strlen
(
et
->
m_
definer
.
str
);
et
->
definer
.
length
=
strlen
(
et
->
definer
.
str
);
ptr
=
strchr
(
et
->
m_
definer
.
str
,
'@'
);
ptr
=
strchr
(
et
->
definer
.
str
,
'@'
);
if
(
!
ptr
)
ptr
=
et
->
m_definer
.
str
;
// Weird, isn't it?
ptr
=
et
->
definer
.
str
;
len
=
ptr
-
et
->
m_
definer
.
str
;
len
=
ptr
-
et
->
definer
.
str
;
et
->
m_definer_user
.
str
=
strmake_root
(
mem_root
,
et
->
m_
definer
.
str
,
len
);
et
->
m_
definer_user
.
length
=
len
;
len
=
et
->
m_
definer
.
length
-
len
-
1
;
//1 is because of @
et
->
m_
definer_host
.
str
=
strmake_root
(
mem_root
,
ptr
+
1
,
len
);
//1: because of @
et
->
m_
definer_host
.
length
=
len
;
et
->
definer_user
.
str
=
strmake_root
(
mem_root
,
et
->
definer
.
str
,
len
);
et
->
definer_user
.
length
=
len
;
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
.
length
=
len
;
res1
=
table
->
field
[
EVEX_FIELD_STARTS
]
->
get_date
(
&
et
->
m_
starts
,
TIME_NO_ZERO_DATE
);
get_date
(
&
et
->
starts
,
TIME_NO_ZERO_DATE
);
res2
=
table
->
field
[
EVEX_FIELD_ENDS
]
->
get_date
(
&
et
->
m_
ends
,
TIME_NO_ZERO_DATE
);
get_date
(
&
et
->
ends
,
TIME_NO_ZERO_DATE
);
et
->
m_expr
=
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
val_int
();
et
->
expression
=
table
->
field
[
EVEX_FIELD_INTERVAL_EXPR
]
->
val_int
();
/*
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
->
m_expr
&&
table
->
field
[
EVEX_FIELD_EXECUTE_AT
]
->
get_date
(
&
et
->
m_
execute_at
,
TIME_NO_ZERO_DATE
))
if
(
res1
&&
res2
&&
!
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
->
m_
interval
=
(
interval_type
)
et
->
interval
=
(
interval_type
)
((
ulonglong
)
table
->
field
[
EVEX_FIELD_TRANSIENT_INTERVAL
]
->
val_int
()
-
1
);
et
->
m
_m
odified
=
table
->
field
[
EVEX_FIELD_CREATED
]
->
val_int
();
et
->
m_
created
=
table
->
field
[
EVEX_FIELD_MODIFIED
]
->
val_int
();
et
->
modified
=
table
->
field
[
EVEX_FIELD_CREATED
]
->
val_int
();
et
->
created
=
table
->
field
[
EVEX_FIELD_MODIFIED
]
->
val_int
();
/*
ToDo Andrey : Ask PeterG & Serg what to do in this case.
...
...
@@ -458,25 +458,25 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
is loaded from DB, execution at L_E_AT+15min
will be scheduled. However this time is in the past.
Hence immediate execution. Due to patch of
::mark_last_executed()
m_
last_executed gets time_now
and not
m_
execute_at. If not like this a big
::mark_last_executed() last_executed gets time_now
and not execute_at. If not like this a big
queue can be scheduled for times which are still in
the past (2, 3 and more executions which will be
consequent).
*/
set_zero_time
(
&
m_
last_executed
,
MYSQL_TIMESTAMP_DATETIME
);
set_zero_time
(
&
last_executed
,
MYSQL_TIMESTAMP_DATETIME
);
#ifdef ANDREY_0
table
->
field
[
EVEX_FIELD_LAST_EXECUTED
]
->
get_date
(
&
et
->
m_
last_executed
,
TIME_NO_ZERO_DATE
);
get_date
(
&
et
->
last_executed
,
TIME_NO_ZERO_DATE
);
#endif
m_
last_executed_changed
=
false
;
last_executed_changed
=
false
;
// ToDo : Andrey . Find a way not to allocate ptr on event_mem_root
if
((
ptr
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_STATUS
]))
==
NullS
)
goto
error
;
DBUG_PRINT
(
"load_from_row"
,
(
"Event [%s] is [%s]"
,
et
->
m_
name
.
str
,
ptr
));
et
->
m_
status
=
(
ptr
[
0
]
==
'E'
?
MYSQL_EVENT_ENABLED
:
DBUG_PRINT
(
"load_from_row"
,
(
"Event [%s] is [%s]"
,
et
->
name
.
str
,
ptr
));
et
->
status
=
(
ptr
[
0
]
==
'E'
?
MYSQL_EVENT_ENABLED
:
MYSQL_EVENT_DISABLED
);
// ToDo : Andrey . Find a way not to allocate ptr on event_mem_root
...
...
@@ -484,14 +484,14 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
table
->
field
[
EVEX_FIELD_ON_COMPLETION
]))
==
NullS
)
goto
error
;
et
->
m_
on_completion
=
(
ptr
[
0
]
==
'D'
?
MYSQL_EVENT_ON_COMPLETION_DROP
:
et
->
on_completion
=
(
ptr
[
0
]
==
'D'
?
MYSQL_EVENT_ON_COMPLETION_DROP
:
MYSQL_EVENT_ON_COMPLETION_PRESERVE
);
et
->
m_
comment
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_COMMENT
]);
if
(
et
->
m_
comment
.
str
!=
NullS
)
et
->
m_comment
.
length
=
strlen
(
et
->
m_
comment
.
str
);
et
->
comment
.
str
=
get_field
(
mem_root
,
table
->
field
[
EVEX_FIELD_COMMENT
]);
if
(
et
->
comment
.
str
!=
NullS
)
et
->
comment
.
length
=
strlen
(
et
->
comment
.
str
);
else
et
->
m_
comment
.
length
=
0
;
et
->
comment
.
length
=
0
;
DBUG_RETURN
(
0
);
error:
...
...
@@ -499,6 +499,11 @@ event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
}
/*
Note: In the comments this->ends is referenced as m_ends
*/
bool
event_timed
::
compute_next_execution_time
()
{
...
...
@@ -508,179 +513,181 @@ event_timed::compute_next_execution_time()
DBUG_ENTER
(
"event_timed::compute_next_execution_time"
);
if
(
m_
status
==
MYSQL_EVENT_DISABLED
)
if
(
status
==
MYSQL_EVENT_DISABLED
)
{
DBUG_PRINT
(
"compute_next_execution_time"
,
(
"Event %s is DISABLED"
,
m_
name
.
str
));
(
"Event %s is DISABLED"
,
name
.
str
));
goto
ret
;
}
//if one-time no need to do computation
if
(
!
m_expr
)
if
(
!
expression
)
{
//let's check whether it was executed
if
(
m_
last_executed
.
year
)
if
(
last_executed
.
year
)
{
DBUG_PRINT
(
"compute_next_execution_time"
,
(
"One-time event %s was already executed"
,
m_
name
.
str
));
if
(
m_
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
(
"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."
));
m_
dropped
=
true
;
dropped
=
true
;
}
m_
status
=
MYSQL_EVENT_DISABLED
;
m_
status_changed
=
true
;
status
=
MYSQL_EVENT_DISABLED
;
status_changed
=
true
;
}
goto
ret
;
}
time
(
&
now
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
time_now
,
now
);
/*
sql_print_information("[%s.%s]",
m_db.str, m_
name.str);
sql_print_information("[%s.%s]",
dbname.str,
name.str);
sql_print_information("time_now : [%d-%d-%d %d:%d:%d ]",
time_now.year, time_now.month, time_now.day,
time_now.hour, time_now.minute, time_now.second);
sql_print_information("
m_starts : [%d-%d-%d %d:%d:%d ]", m_
starts.year,
m_starts.month, m_starts.day, m_
starts.hour,
m_starts.minute, m_
starts.second);
sql_print_information("
m_ends : [%d-%d-%d %d:%d:%d ]", m_
ends.year,
m_ends.month, m_ends.day, m_
ends.hour,
m_ends.minute, m_
ends.second);
sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]",
m_
last_executed.year,
m_last_executed.month, m_
last_executed.day,
m_last_executed.hour, m_
last_executed.minute,
m_
last_executed.second);
sql_print_information("
starts : [%d-%d-%d %d:%d:%d ]",
starts.year,
starts.month, starts.day,
starts.hour,
starts.minute,
starts.second);
sql_print_information("
ends : [%d-%d-%d %d:%d:%d ]",
ends.year,
ends.month, ends.day,
ends.hour,
ends.minute,
ends.second);
sql_print_information("m_last_ex: [%d-%d-%d %d:%d:%d ]", last_executed.year,
last_executed.month,
last_executed.day,
last_executed.hour,
last_executed.minute,
last_executed.second);
*/
//if time_now is after
m_
ends don't execute anymore
if
(
m_ends
.
year
&&
(
tmp
=
my_time_compare
(
&
m_
ends
,
&
time_now
))
==
-
1
)
//if time_now is after ends don't execute anymore
if
(
ends
.
year
&&
(
tmp
=
my_time_compare
(
&
ends
,
&
time_now
))
==
-
1
)
{
// time_now is after
m_
ends. don't execute anymore
set_zero_time
(
&
m_
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
m_
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
m_
dropped
=
true
;
m_
status
=
MYSQL_EVENT_DISABLED
;
m_
status_changed
=
true
;
// time_now is after ends. don't execute anymore
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
status
=
MYSQL_EVENT_DISABLED
;
status_changed
=
true
;
goto
ret
;
}
/*
Here time_now is before or equals
m_
ends if the latter is set.
Let's check whether time_now is before
m_
starts.
If so schedule for
m_
starts
Here time_now is before or equals ends if the latter is set.
Let's check whether time_now is before starts.
If so schedule for starts
*/
if
(
m_starts
.
year
&&
(
tmp
=
my_time_compare
(
&
time_now
,
&
m_
starts
))
<
1
)
if
(
starts
.
year
&&
(
tmp
=
my_time_compare
(
&
time_now
,
&
starts
))
<
1
)
{
if
(
tmp
==
0
&&
my_time_compare
(
&
m_starts
,
&
m_
last_executed
)
==
0
)
if
(
tmp
==
0
&&
my_time_compare
(
&
starts
,
&
last_executed
)
==
0
)
{
/*
time_now =
m_starts = m_
last_executed
do nothing or we will schedule for second time execution at
m_
starts.
time_now =
starts =
last_executed
do nothing or we will schedule for second time execution at starts.
*/
}
else
{
//m_starts is in the future
//time_now before m_starts. Scheduling for m_starts
m_execute_at
=
m_starts
;
/*
starts is in the future
time_now before starts. Scheduling for starts
*/
execute_at
=
starts
;
goto
ret
;
}
}
if
(
m_starts
.
year
&&
m_
ends
.
year
)
if
(
starts
.
year
&&
ends
.
year
)
{
/*
Both
m_
starts and m_ends are set and time_now is between them (incl.)
If
m_last_executed is set then increase with m_expr
. The new TIME is
after m_ends set
m_execute_at to 0. And check for m_
on_completion
Both starts and m_ends are set and time_now is between them (incl.)
If
last_executed is set then increase with m_expression
. The new TIME is
after m_ends set
execute_at to 0. And check for
on_completion
If not set then schedule for now.
*/
if
(
!
m_
last_executed
.
year
)
m_
execute_at
=
time_now
;
if
(
!
last_executed
.
year
)
execute_at
=
time_now
;
else
{
my_time_t
last
,
ll_ends
;
// There was previous execution
last
=
sec_since_epoch_TIME
(
&
m_last_executed
)
+
m_expr
;
ll_ends
=
sec_since_epoch_TIME
(
&
m_
ends
);
last
=
sec_since_epoch_TIME
(
&
last_executed
)
+
expression
;
ll_ends
=
sec_since_epoch_TIME
(
&
ends
);
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
if
(
ll_ends
<
last
)
{
// Next execution after ends. No more executions
set_zero_time
(
&
m_
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
m_
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
m_
dropped
=
true
;
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
}
else
my_tz_UTC
->
gmt_sec_to_TIME
(
&
m_
execute_at
,
last
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
execute_at
,
last
);
}
goto
ret
;
}
else
if
(
!
m_starts
.
year
&&
!
m_
ends
.
year
)
else
if
(
!
starts
.
year
&&
!
ends
.
year
)
{
// both
m_
starts and m_ends are not set, se we schedule for the next
// based on
m_
last_executed
if
(
!
m_
last_executed
.
year
)
//
m_
last_executed not set. Schedule the event for now
m_
execute_at
=
time_now
;
// both starts and m_ends are not set, se we schedule for the next
// based on last_executed
if
(
!
last_executed
.
year
)
//last_executed not set. Schedule the event for now
execute_at
=
time_now
;
else
//ToDo Andrey: maybe check for error here?
my_tz_UTC
->
gmt_sec_to_TIME
(
&
m_
execute_at
,
sec_since_epoch_TIME
(
&
m_last_executed
)
+
m_expr
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
execute_at
,
sec_since_epoch_TIME
(
&
last_executed
)
+
expression
);
goto
ret
;
}
else
{
//either
m_
starts or m_ends is set
if
(
m_
starts
.
year
)
//either starts or m_ends is set
if
(
starts
.
year
)
{
/*
-
m_
starts is set.
-
m_
starts is not in the future according to check made before
Hence schedule for
m_starts + m_expr in case m_
last_executed
is not set, otherwise to
m_last_executed + m_expr
- starts is set.
- starts is not in the future according to check made before
Hence schedule for
starts + m_expression in case
last_executed
is not set, otherwise to
last_executed + m_expression
*/
my_time_t
last
;
//convert either
m_last_executed or m_
starts to seconds
if
(
m_
last_executed
.
year
)
last
=
sec_since_epoch_TIME
(
&
m_last_executed
)
+
m_expr
;
//convert either
last_executed or
starts to seconds
if
(
last_executed
.
year
)
last
=
sec_since_epoch_TIME
(
&
last_executed
)
+
expression
;
else
last
=
sec_since_epoch_TIME
(
&
m_
starts
);
last
=
sec_since_epoch_TIME
(
&
starts
);
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
my_tz_UTC
->
gmt_sec_to_TIME
(
&
m_
execute_at
,
last
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
execute_at
,
last
);
}
else
{
/*
- m_ends is set
- m_ends is after time_now or is equal
Hence check for m_last_execute and increment with m_expr.
If
m_
last_executed is not set then schedule for now
Hence check for m_last_execute and increment with m_expr
ession
.
If last_executed is not set then schedule for now
*/
my_time_t
last
,
ll_ends
;
if
(
!
m_
last_executed
.
year
)
m_
execute_at
=
time_now
;
if
(
!
last_executed
.
year
)
execute_at
=
time_now
;
else
{
last
=
sec_since_epoch_TIME
(
&
m_
last_executed
);
ll_ends
=
sec_since_epoch_TIME
(
&
m_
ends
);
last
+=
m_expr
;
last
=
sec_since_epoch_TIME
(
&
last_executed
);
ll_ends
=
sec_since_epoch_TIME
(
&
ends
);
last
+=
expression
;
//now convert back to TIME
//ToDo Andrey: maybe check for error here?
if
(
ll_ends
<
last
)
{
set_zero_time
(
&
m_
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
m_
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
m_
dropped
=
true
;
set_zero_time
(
&
execute_at
,
MYSQL_TIMESTAMP_DATETIME
);
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
dropped
=
true
;
}
else
my_tz_UTC
->
gmt_sec_to_TIME
(
&
m_
execute_at
,
last
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
execute_at
,
last
);
}
}
goto
ret
;
...
...
@@ -700,11 +707,11 @@ event_timed::mark_last_executed()
time
(
&
now
);
my_tz_UTC
->
gmt_sec_to_TIME
(
&
time_now
,
now
);
m_last_executed
=
time_now
;
// was m_
execute_at
last_executed
=
time_now
;
// was
execute_at
#ifdef ANDREY_0
m_last_executed
=
m_
execute_at
;
last_executed
=
execute_at
;
#endif
m_
last_executed_changed
=
true
;
last_executed_changed
=
true
;
}
...
...
@@ -724,33 +731,33 @@ event_timed::update_fields(THD *thd)
DBUG_ENTER
(
"event_timed::update_time_fields"
);
DBUG_PRINT
(
"enter"
,
(
"name: %*s"
,
m_name
.
length
,
m_
name
.
str
));
DBUG_PRINT
(
"enter"
,
(
"name: %*s"
,
name
.
length
,
name
.
str
));
//no need to update if nothing has changed
if
(
!
(
m_status_changed
||
m_
last_executed_changed
))
if
(
!
(
status_changed
||
last_executed_changed
))
goto
done
;
if
(
!
(
table
=
evex_open_event_table
(
thd
,
TL_WRITE
)))
DBUG_RETURN
(
SP_OPEN_TABLE_FAILED
);
if
((
ret
=
evex_db_find_routine_aux
(
thd
,
m_db
,
m_
name
,
table
)))
if
((
ret
=
evex_db_find_routine_aux
(
thd
,
dbname
,
name
,
table
)))
goto
done
;
store_record
(
table
,
record
[
1
]);
table
->
timestamp_field_type
=
TIMESTAMP_NO_AUTO_SET
;
// Don't update create on row update.
if
(
m_
last_executed_changed
)
if
(
last_executed_changed
)
{
table
->
field
[
EVEX_FIELD_LAST_EXECUTED
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_LAST_EXECUTED
]
->
store_time
(
&
m_
last_executed
,
table
->
field
[
EVEX_FIELD_LAST_EXECUTED
]
->
store_time
(
&
last_executed
,
MYSQL_TIMESTAMP_DATETIME
);
m_
last_executed_changed
=
false
;
last_executed_changed
=
false
;
}
if
(
m_
status_changed
)
if
(
status_changed
)
{
table
->
field
[
EVEX_FIELD_STATUS
]
->
set_notnull
();
table
->
field
[
EVEX_FIELD_STATUS
]
->
store
((
longlong
)
m_
status
);
m_
status_changed
=
false
;
table
->
field
[
EVEX_FIELD_STATUS
]
->
store
((
longlong
)
status
);
status_changed
=
false
;
}
if
((
table
->
file
->
update_row
(
table
->
record
[
1
],
table
->
record
[
0
])))
...
...
@@ -769,27 +776,27 @@ event_timed::get_show_create_event(THD *thd, uint *length)
char
*
dst
,
*
ret
;
uint
len
,
tmp_len
;
len
=
strlen
(
"CREATE EVENT "
)
+
m_db
.
length
+
strlen
(
"."
)
+
m_
name
.
length
+
len
=
strlen
(
"CREATE EVENT "
)
+
dbname
.
length
+
strlen
(
"."
)
+
name
.
length
+
strlen
(
" ON SCHEDULE "
)
+
strlen
(
"EVERY 5 MINUTE "
)
/*
+ strlen("ON COMPLETION ")
+ (
m_
on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
+ (on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
strlen("NOT PRESERVE "):strlen("PRESERVE "))
+ (
m_
status==MYSQL_EVENT_ENABLED?
+ (status==MYSQL_EVENT_ENABLED?
strlen("ENABLE "):strlen("DISABLE "))
+ strlen("COMMENT \"") +
m_
comment.length + strlen("\" ")
+ strlen("COMMENT \"") + comment.length + strlen("\" ")
*/
+
strlen
(
"DO "
)
+
+
m_
body
.
length
+
strlen
(
";"
);
+
body
.
length
+
strlen
(
";"
);
ret
=
dst
=
(
char
*
)
alloc_root
(
thd
->
mem_root
,
len
);
memcpy
(
dst
,
"CREATE EVENT "
,
tmp_len
=
strlen
(
"CREATE EVENT "
));
dst
+=
tmp_len
;
memcpy
(
dst
,
m_db
.
str
,
tmp_len
=
m_db
.
length
);
memcpy
(
dst
,
dbname
.
str
,
tmp_len
=
dbname
.
length
);
dst
+=
tmp_len
;
memcpy
(
dst
,
"."
,
tmp_len
=
strlen
(
"."
));
dst
+=
tmp_len
;
memcpy
(
dst
,
m_name
.
str
,
tmp_len
=
m_
name
.
length
);
memcpy
(
dst
,
name
.
str
,
tmp_len
=
name
.
length
);
dst
+=
tmp_len
;
memcpy
(
dst
,
" ON SCHEDULE "
,
tmp_len
=
strlen
(
" ON SCHEDULE "
));
dst
+=
tmp_len
;
...
...
@@ -798,19 +805,19 @@ event_timed::get_show_create_event(THD *thd, uint *length)
/*
memcpy(dst, "ON COMPLETION ", tmp_len =strlen("ON COMPLETION "));
dst+= tmp_len;
memcpy(dst, (
m_
on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
memcpy(dst, (on_completion==MYSQL_EVENT_ON_COMPLETION_DROP?
"NOT PRESERVE ":"PRESERVE "),
tmp_len =(
m_
on_completion==MYSQL_EVENT_ON_COMPLETION_DROP? 13:9));
tmp_len =(on_completion==MYSQL_EVENT_ON_COMPLETION_DROP? 13:9));
dst+= tmp_len;
memcpy(dst, (
m_
status==MYSQL_EVENT_ENABLED?
memcpy(dst, (status==MYSQL_EVENT_ENABLED?
"ENABLE ":"DISABLE "),
tmp_len= (
m_
status==MYSQL_EVENT_ENABLED? 8:9));
tmp_len= (status==MYSQL_EVENT_ENABLED? 8:9));
dst+=tmp_len;
memcpy(dst, "COMMENT \"", tmp_len= strlen("COMMENT \""));
dst+= tmp_len;
memcpy(dst,
m_comment.str, tmp_len= m_
comment.length);
memcpy(dst,
comment.str, tmp_len=
comment.length);
dst+= tmp_len;
memcpy(dst, "\" ", tmp_len=2);
dst+= tmp_len;
...
...
@@ -818,7 +825,7 @@ event_timed::get_show_create_event(THD *thd, uint *length)
memcpy
(
dst
,
"DO "
,
tmp_len
=
3
);
dst
+=
tmp_len
;
memcpy
(
dst
,
m_body
.
str
,
tmp_len
=
m_
body
.
length
);
memcpy
(
dst
,
body
.
str
,
tmp_len
=
body
.
length
);
dst
+=
tmp_len
;
memcpy
(
dst
,
";"
,
1
);
++
dst
;
...
...
@@ -865,21 +872,21 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
// TODO Andrey : make this as member variable and delete in destructor
empty_item_list
.
empty
();
if
(
!
m_
sphead
&&
(
ret
=
compile
(
thd
,
mem_root
)))
if
(
!
sphead
&&
(
ret
=
compile
(
thd
,
mem_root
)))
goto
done
;
ret
=
m_
sphead
->
execute_procedure
(
thd
,
&
empty_item_list
);
ret
=
sphead
->
execute_procedure
(
thd
,
&
empty_item_list
);
VOID
(
pthread_mutex_lock
(
&
LOCK_running
));
running
=
false
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_running
));
done:
// Don't cache
m_
sphead if allocated on another mem_root
if
(
mem_root
&&
m_
sphead
)
// Don't cache sphead if allocated on another mem_root
if
(
mem_root
&&
sphead
)
{
delete
m_
sphead
;
m_
sphead
=
0
;
delete
sphead
;
sphead
=
0
;
}
DBUG_RETURN
(
ret
);
...
...
@@ -908,7 +915,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
old_query_len
=
thd
->
query_length
;
old_query
=
thd
->
query
;
old_db
=
thd
->
db
;
thd
->
db
=
m_db
.
str
;
thd
->
db
=
dbname
.
str
;
thd
->
query
=
get_show_create_event
(
thd
,
&
thd
->
query_length
);
DBUG_PRINT
(
"event_timed::compile"
,
(
"query:%s"
,
thd
->
query
));
...
...
@@ -932,13 +939,13 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
DBUG_RETURN
(
-
1
);
}
m_
sphead
=
lex
.
sphead
;
m_sphead
->
m_db
=
m_db
;
sphead
=
lex
.
sphead
;
sphead
->
m_db
=
dbname
;
//copy also chistics since they will vanish otherwise we get 0x0 pointer
// Todo : Handle sql_mode !!
m_sphead
->
set_definer
(
m_definer
.
str
,
m_
definer
.
length
);
m_
sphead
->
set_info
(
0
,
0
,
&
lex
.
sp_chistics
,
0
/*sql_mode*/
);
m_
sphead
->
optimize
();
sphead
->
set_definer
(
definer
.
str
,
definer
.
length
);
sphead
->
set_info
(
0
,
0
,
&
lex
.
sp_chistics
,
0
/*sql_mode*/
);
sphead
->
optimize
();
lex_end
(
&
lex
);
thd
->
lex
=
old_lex
;
thd
->
query
=
old_query
;
...
...
sql/sql_parse.cc
View file @
3d854641
...
...
@@ -3676,26 +3676,25 @@ mysql_execute_command(THD *thd)
case
SQLCOM_CREATE_EVENT
:
{
DBUG_ASSERT
(
lex
->
et
);
if
(
!
lex
->
et
->
m_db
.
str
)
if
(
!
lex
->
et
->
dbname
.
str
)
{
my_message
(
ER_NO_DB_ERROR
,
ER
(
ER_NO_DB_ERROR
),
MYF
(
0
));
delete
lex
->
et
;
lex
->
et
=
0
;
goto
error
;
}
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
m_db
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
m_db
.
str
)))
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
dbname
.
str
)))
break
;
int
result
;
uint
create_options
=
lex
->
create_info
.
options
;
res
=
(
result
=
evex_create_event
(
thd
,
lex
->
et
,
create_options
));
if
(
result
==
EVEX_OK
)
if
(
!
(
res
=
evex_create_event
(
thd
,
lex
->
et
,
(
uint
)
lex
->
create_info
.
options
)))
send_ok
(
thd
,
1
);
/* lex->unit.cleanup() is called outside, no need to call it here */
delete
lex
->
et
;
lex
->
et
=
0
;
delete
lex
->
sphead
;
lex
->
et
=
0
;
lex
->
sphead
=
0
;
break
;
...
...
@@ -3703,53 +3702,50 @@ mysql_execute_command(THD *thd)
case
SQLCOM_ALTER_EVENT
:
{
DBUG_ASSERT
(
lex
->
et
);
if
(
!
lex
->
et
->
m_db
.
str
)
if
(
!
lex
->
et
->
dbname
.
str
)
{
my_message
(
ER_NO_DB_ERROR
,
ER
(
ER_NO_DB_ERROR
),
MYF
(
0
));
delete
lex
->
et
;
lex
->
et
=
0
;
goto
error
;
}
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
m_db
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
m_db
.
str
)))
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
dbname
.
str
)))
break
;
int
result
;
res
=
(
result
=
evex_update_event
(
thd
,
lex
->
spname
,
lex
->
et
));
res
=
(
result
=
evex_update_event
(
thd
,
lex
->
et
,
lex
->
spname
));
switch
(
result
)
{
case
EVEX_OK
:
send_ok
(
thd
,
1
);
break
;
case
EVEX_KEY_NOT_FOUND
:
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
lex
->
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
lex
->
et
->
name
.
str
);
break
;
default:
my_error
(
ER_EVENT_CANT_ALTER
,
MYF
(
0
),
lex
->
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_CANT_ALTER
,
MYF
(
0
),
lex
->
et
->
name
.
str
);
break
;
}
/* lex->unit.cleanup() is called outside, no need to call it here */
delete
lex
->
et
;
lex
->
et
=
0
;
if
(
lex
->
sphead
)
{
delete
lex
->
sphead
;
lex
->
et
=
0
;
lex
->
sphead
=
0
;
}
break
;
}
case
SQLCOM_DROP_EVENT
:
{
DBUG_ASSERT
(
lex
->
et
);
if
(
!
lex
->
et
->
m_db
.
str
)
if
(
!
lex
->
et
->
dbname
.
str
)
{
my_message
(
ER_NO_DB_ERROR
,
ER
(
ER_NO_DB_ERROR
),
MYF
(
0
));
delete
lex
->
et
;
lex
->
et
=
0
;
goto
error
;
}
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
m_db
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
m_db
.
str
)))
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
et
->
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
et
->
dbname
.
str
)))
break
;
int
result
;
...
...
@@ -3759,10 +3755,10 @@ mysql_execute_command(THD *thd)
send_ok
(
thd
,
1
);
break
;
case
EVEX_KEY_NOT_FOUND
:
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
lex
->
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_DOES_NOT_EXIST
,
MYF
(
0
),
lex
->
et
->
name
.
str
);
break
;
default:
my_error
(
ER_EVENT_DROP_FAILED
,
MYF
(
0
),
lex
->
et
->
m_
name
.
str
);
my_error
(
ER_EVENT_DROP_FAILED
,
MYF
(
0
),
lex
->
et
->
name
.
str
);
break
;
}
delete
lex
->
et
;
...
...
sql/sql_yacc.yy
View file @
3d854641
...
...
@@ -1415,14 +1415,14 @@ ev_status: /* empty */
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->
m_
status= MYSQL_EVENT_ENABLED;
lex->et->status= MYSQL_EVENT_ENABLED;
}
| DISABLE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->
m_
status= MYSQL_EVENT_DISABLED;
lex->et->status= MYSQL_EVENT_DISABLED;
}
;
ev_starts: /* empty */
...
...
@@ -1457,13 +1457,13 @@ ev_on_completion: /* empty */
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->
m_
on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_PRESERVE;
}
| ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
{
LEX *lex=Lex;
if (!lex->et_compile_phase)
lex->et->
m_
on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
lex->et->on_completion= MYSQL_EVENT_ON_COMPLETION_DROP;
}
;
ev_comment: /* empty */
...
...
@@ -1497,7 +1497,7 @@ ev_sql_stmt:
lex->sphead->m_body_begin= lex->ptr;
if (!lex->et_compile_phase)
lex->et->
m_
body_begin= lex->ptr;
lex->et->body_begin= lex->ptr;
}
ev_sql_stmt_inner
{
...
...
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