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
d5d11a9c
Commit
d5d11a9c
authored
Feb 14, 2006
by
andrey@lmy004
Browse files
Options
Browse Files
Download
Plain Diff
manual merge
parents
0262bb9a
815927e5
Changes
13
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1415 additions
and
132 deletions
+1415
-132
mysql-test/r/events.result
mysql-test/r/events.result
+186
-21
mysql-test/t/events.test
mysql-test/t/events.test
+132
-0
sql/event.cc
sql/event.cc
+459
-32
sql/event.h
sql/event.h
+14
-4
sql/event_executor.cc
sql/event_executor.cc
+185
-4
sql/event_timed.cc
sql/event_timed.cc
+122
-37
sql/sql_acl.cc
sql/sql_acl.cc
+119
-3
sql/sql_acl.h
sql/sql_acl.h
+30
-0
sql/sql_parse.cc
sql/sql_parse.cc
+9
-2
sql/sql_show.cc
sql/sql_show.cc
+5
-26
sql/sql_yacc.yy
sql/sql_yacc.yy
+4
-0
sql/table.cc
sql/table.cc
+139
-3
sql/table.h
sql/table.h
+11
-0
No files found.
mysql-test/r/events.result
View file @
d5d11a9c
This diff is collapsed.
Click to expand it.
mysql-test/t/events.test
View file @
d5d11a9c
...
@@ -33,6 +33,138 @@ select count(*) from t_event3;
...
@@ -33,6 +33,138 @@ select count(*) from t_event3;
drop
event
event3
;
drop
event
event3
;
drop
table
t_event3
;
drop
table
t_event3
;
set
names
utf8
;
#
# SHOW CREATE EVENT test begin
#
CREATE
EVENT
root6
ON
SCHEDULE
EVERY
'10:20'
MINUTE_SECOND
ON
COMPLETION
PRESERVE
ENABLE
COMMENT
'some comment'
DO
select
1
;
SHOW
CREATE
EVENT
root6
;
create
event
root7
on
schedule
every
2
year
do
select
1
;
SHOW
CREATE
EVENT
root7
;
create
event
root8
on
schedule
every
'2:5'
year_month
do
select
1
;
SHOW
CREATE
EVENT
root8
;
create
event
root8_1
on
schedule
every
'2:15'
year_month
do
select
1
;
SHOW
CREATE
EVENT
root8_1
;
create
event
root9
on
schedule
every
2
week
ON
COMPLETION
PRESERVE
DISABLE
COMMENT
'коментар на кирилица'
do
select
1
;
SHOW
CREATE
EVENT
root9
;
create
event
root10
on
schedule
every
'20:5'
day_hour
do
select
1
;
SHOW
CREATE
EVENT
root10
;
create
event
root11
on
schedule
every
'20:25'
day_hour
do
select
1
;
SHOW
CREATE
EVENT
root11
;
create
event
root12
on
schedule
every
'20:25'
hour_minute
do
select
1
;
SHOW
CREATE
EVENT
root12
;
create
event
root13
on
schedule
every
'25:25'
hour_minute
do
select
1
;
SHOW
CREATE
EVENT
root13
;
create
event
root13_1
on
schedule
every
'11:65'
hour_minute
do
select
1
;
SHOW
CREATE
EVENT
root13_1
;
create
event
root14
on
schedule
every
'35:35'
minute_second
do
select
1
;
SHOW
CREATE
EVENT
root14
;
create
event
root15
on
schedule
every
'35:66'
minute_second
do
select
1
;
SHOW
CREATE
EVENT
root15
;
create
event
root16
on
schedule
every
'35:56'
day_minute
do
select
1
;
SHOW
CREATE
EVENT
root16
;
create
event
root17
on
schedule
every
'35:12:45'
day_minute
do
select
1
;
SHOW
CREATE
EVENT
root17
;
create
event
root17_1
on
schedule
every
'35:25:65'
day_minute
do
select
1
;
SHOW
CREATE
EVENT
root17_1
;
create
event
root18
on
schedule
every
'35:12:45'
hour_second
do
select
1
;
SHOW
CREATE
EVENT
root18
;
create
event
root19
on
schedule
every
'15:59:85'
hour_second
do
select
1
;
SHOW
CREATE
EVENT
root19
;
create
event
root20
on
schedule
every
'50:20:12:45'
day_second
do
select
1
;
SHOW
CREATE
EVENT
root20
;
set
names
cp1251
;
create
event
ðóóò21
on
schedule
every
'50:23:59:95'
day_second
COMMENT
'òîâà å 1251 êîìåíòàð'
do
select
1
;
SHOW
CREATE
EVENT
ðóóò21
;
insert
into
mysql
.
event
(
db
,
name
,
body
,
definer
,
interval_value
,
interval_field
)
values
(
database
(),
"root22"
,
"select 1"
,
user
(),
100
,
"SECOND_MICROSECOND"
);
--
error
1535
show
create
event
root22
;
--
error
1535
SHOW
EVENTS
;
drop
event
root22
;
drop
event
root6
;
drop
event
root7
;
drop
event
root8
;
drop
event
root8_1
;
drop
event
root9
;
drop
event
root10
;
drop
event
root11
;
drop
event
root12
;
drop
event
root13
;
drop
event
root13_1
;
drop
event
root14
;
drop
event
root15
;
drop
event
root16
;
drop
event
root17
;
drop
event
root17_1
;
drop
event
root18
;
drop
event
root19
;
drop
event
root20
;
drop
event
ðóóò21
;
set
names
latin1
;
#
# SHOW CREATE EVENT test end
#
#
# mysql.event intact checking start
#
# There should be at least 1 second between the ALTERs or we can't catch the change of create_time!!
#
CREATE
EVENT
intact_check
ON
SCHEDULE
EVERY
10
HOUR
DO
SELECT
"nothing"
;
--
replace_column
8
# 9 #
SHOW
EVENTS
;
ALTER
TABLE
mysql
.
event
ADD
dummy
INT
FIRST
;
--
error
1525
SHOW
EVENTS
;
ALTER
TABLE
mysql
.
event
DROP
dummy
,
ADD
dummy2
VARCHAR
(
64
)
FIRST
;
--
error
1525
SHOW
EVENTS
;
ALTER
TABLE
mysql
.
event
DROP
dummy2
;
--
replace_column
8
# 9 #
SHOW
EVENTS
;
CREATE
TABLE
event_like
LIKE
mysql
.
event
;
INSERT
INTO
event_like
SELECT
*
FROM
mysql
.
event
;
#sleep a bit or we won't catch the change of time
--
sleep
1
ALTER
TABLE
mysql
.
event
MODIFY
db
char
(
20
)
character
set
utf8
collate
utf8_bin
default
''
;
#wait a bit or we won't see the difference because of seconds resolution
--
sleep
1
SHOW
CREATE
TABLE
mysql
.
event
;
--
error
1526
SELECT
event_name
FROM
INFORMATION_SCHEMA
.
EVENTS
;
--
sleep
1
ALTER
TABLE
mysql
.
event
MODIFY
db
char
(
64
)
character
set
utf8
collate
utf8_bin
default
''
;
--
sleep
1
--
echo
"This should work"
--
replace_column
8
# 9 #
SHOW
EVENTS
;
--
sleep
1
ALTER
TABLE
mysql
.
event
MODIFY
db
char
(
64
)
character
set
cp1251
default
''
;
--
error
1526
SELECT
event_name
FROM
INFORMATION_SCHEMA
.
EVENTS
;
--
sleep
1
ALTER
TABLE
mysql
.
event
MODIFY
db
varchar
(
64
)
character
set
utf8
collate
utf8_bin
default
''
;
--
error
1526
SELECT
event_name
FROM
INFORMATION_SCHEMA
.
EVENTS
;
--
sleep
1
ALTER
TABLE
mysql
.
event
DROP
comment
,
DROP
starts
;
--
sleep
1
--
error
1525
SELECT
event_name
FROM
INFORMATION_SCHEMA
.
EVENTS
;
DROP
TABLE
mysql
.
event
;
CREATE
TABLE
mysql
.
event
like
event_like
;
INSERT
INTO
mysql
.
event
SELECT
*
FROM
event_like
;
DROP
TABLE
event_like
;
--
replace_column
8
# 9 #
SHOW
EVENTS
;
DROP
EVENT
intact_check
;
#
# mysql.event intact checking end
#
#
#
#INFORMATION_SCHEMA.EVENTS test begin
#INFORMATION_SCHEMA.EVENTS test begin
#
#
...
...
sql/event.cc
View file @
d5d11a9c
This diff is collapsed.
Click to expand it.
sql/event.h
View file @
d5d11a9c
...
@@ -109,6 +109,7 @@ public:
...
@@ -109,6 +109,7 @@ public:
enum
enum_event_on_completion
on_completion
;
enum
enum_event_on_completion
on_completion
;
enum
enum_event_status
status
;
enum
enum_event_status
status
;
sp_head
*
sphead
;
sp_head
*
sphead
;
ulong
sql_mode
;
const
uchar
*
body_begin
;
const
uchar
*
body_begin
;
...
@@ -119,8 +120,9 @@ public:
...
@@ -119,8 +120,9 @@ public:
event_timed
()
:
running
(
0
),
status_changed
(
false
),
last_executed_changed
(
false
),
event_timed
()
:
running
(
0
),
status_changed
(
false
),
last_executed_changed
(
false
),
expression
(
0
),
created
(
0
),
modified
(
0
),
expression
(
0
),
created
(
0
),
modified
(
0
),
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
on_completion
(
MYSQL_EVENT_ON_COMPLETION_DROP
),
status
(
MYSQL_EVENT_ENABLED
),
sphead
(
0
),
dropped
(
false
),
status
(
MYSQL_EVENT_ENABLED
),
sphead
(
0
),
sql_mode
(
0
),
free_sphead_on_delete
(
true
),
flags
(
0
)
body_begin
(
0
),
dropped
(
false
),
free_sphead_on_delete
(
true
),
flags
(
0
)
{
{
pthread_mutex_init
(
&
this
->
LOCK_running
,
MY_MUTEX_INIT_FAST
);
pthread_mutex_init
(
&
this
->
LOCK_running
,
MY_MUTEX_INIT_FAST
);
...
@@ -177,8 +179,8 @@ public:
...
@@ -177,8 +179,8 @@ public:
bool
bool
update_fields
(
THD
*
thd
);
update_fields
(
THD
*
thd
);
char
*
int
get_
show_create_event
(
THD
*
thd
,
uint32
*
length
);
get_
create_event
(
THD
*
thd
,
String
*
buf
);
int
int
execute
(
THD
*
thd
,
MEM_ROOT
*
mem_root
=
NULL
);
execute
(
THD
*
thd
,
MEM_ROOT
*
mem_root
=
NULL
);
...
@@ -221,8 +223,16 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
...
@@ -221,8 +223,16 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists,
int
int
evex_open_event_table
(
THD
*
thd
,
enum
thr_lock_type
lock_type
,
TABLE
**
table
);
evex_open_event_table
(
THD
*
thd
,
enum
thr_lock_type
lock_type
,
TABLE
**
table
);
int
evex_show_create_event
(
THD
*
thd
,
sp_name
*
spn
,
LEX_STRING
definer
);
int
sortcmp_lex_string
(
LEX_STRING
s
,
LEX_STRING
t
,
CHARSET_INFO
*
cs
);
int
sortcmp_lex_string
(
LEX_STRING
s
,
LEX_STRING
t
,
CHARSET_INFO
*
cs
);
int
event_reconstruct_interval_expression
(
String
*
buf
,
interval_type
interval
,
longlong
expression
);
int
int
init_events
();
init_events
();
...
...
sql/event_executor.cc
View file @
d5d11a9c
...
@@ -33,9 +33,9 @@ extern ulong thread_created;
...
@@ -33,9 +33,9 @@ extern ulong thread_created;
extern
const
char
*
my_localhost
;
extern
const
char
*
my_localhost
;
extern
pthread_attr_t
connection_attrib
;
extern
pthread_attr_t
connection_attrib
;
pthread_mutex_t
LOCK_event_arrays
,
pthread_mutex_t
LOCK_event_arrays
,
// mutex for when working with the queue
LOCK_workers_count
,
LOCK_workers_count
,
// mutex for when inc/dec uint workers_count
LOCK_evex_running
;
LOCK_evex_running
;
// mutes for managing bool evex_is_running
bool
evex_is_running
=
false
;
bool
evex_is_running
=
false
;
...
@@ -62,6 +62,19 @@ event_executor_worker(void *arg);
...
@@ -62,6 +62,19 @@ event_executor_worker(void *arg);
pthread_handler_t
pthread_handler_t
event_executor_main
(
void
*
arg
);
event_executor_main
(
void
*
arg
);
/*
Returns the seconds difference of 2 TIME structs
SYNOPSIS
evex_time_diff()
a - TIME struct 1
b - TIME struct 2
Returns:
the seconds difference
*/
static
int
static
int
evex_time_diff
(
TIME
*
a
,
TIME
*
b
)
evex_time_diff
(
TIME
*
a
,
TIME
*
b
)
{
{
...
@@ -69,6 +82,19 @@ evex_time_diff(TIME *a, TIME *b)
...
@@ -69,6 +82,19 @@ evex_time_diff(TIME *a, TIME *b)
}
}
/*
Inits the mutexes used by the scheduler module
SYNOPSIS
evex_init_mutexes()
NOTES
The mutexes are :
LOCK_event_arrays
LOCK_workers_count
LOCK_evex_running
*/
static
void
static
void
evex_init_mutexes
()
evex_init_mutexes
()
{
{
...
@@ -84,6 +110,75 @@ evex_init_mutexes()
...
@@ -84,6 +110,75 @@ evex_init_mutexes()
}
}
/*
Opens mysql.db and mysql.user and checks whether
1. mysql.db has column Event_priv at column 20 (0 based);
2. mysql.user has column Event_priv at column 29 (0 based);
Synopsis
evex_check_system_tables()
*/
void
evex_check_system_tables
()
{
THD
*
thd
=
current_thd
;
TABLE_LIST
tables
;
bool
not_used
;
Open_tables_state
backup
;
// thd is 0x0 during boot of the server. Later it's !=0x0
if
(
!
thd
)
return
;
thd
->
reset_n_backup_open_tables_state
(
&
backup
);
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
db
=
(
char
*
)
"mysql"
;
tables
.
table_name
=
tables
.
alias
=
(
char
*
)
"db"
;
tables
.
lock_type
=
TL_READ
;
if
(
simple_open_n_lock_tables
(
thd
,
&
tables
))
sql_print_error
(
"Cannot open mysql.db"
);
else
{
table_check_intact
(
tables
.
table
,
MYSQL_DB_FIELD_COUNT
,
mysql_db_table_fields
,
&
mysql_db_table_last_check
,
ER_EVENT_CANNOT_LOAD_FROM_TABLE
);
close_thread_tables
(
thd
);
}
bzero
((
char
*
)
&
tables
,
sizeof
(
tables
));
tables
.
db
=
(
char
*
)
"mysql"
;
tables
.
table_name
=
tables
.
alias
=
(
char
*
)
"user"
;
tables
.
lock_type
=
TL_READ
;
if
(
simple_open_n_lock_tables
(
thd
,
&
tables
))
sql_print_error
(
"Cannot open mysql.db"
);
else
{
if
(
tables
.
table
->
s
->
fields
<
29
||
strncmp
(
tables
.
table
->
field
[
29
]
->
field_name
,
STRING_WITH_LEN
(
"Event_priv"
)))
sql_print_error
(
"mysql.user has no `Event_priv` column at position 29"
);
close_thread_tables
(
thd
);
}
thd
->
restore_backup_open_tables_state
(
&
backup
);
}
/*
Inits the scheduler. Called on server start and every time the scheduler
is started with switching the event_scheduler global variable to TRUE
SYNOPSIS
init_events()
NOTES
Inits the mutexes used by the scheduler. Done at server start.
*/
int
int
init_events
()
init_events
()
{
{
...
@@ -93,6 +188,8 @@ init_events()
...
@@ -93,6 +188,8 @@ init_events()
DBUG_PRINT
(
"info"
,(
"Starting events main thread"
));
DBUG_PRINT
(
"info"
,(
"Starting events main thread"
));
evex_check_system_tables
();
evex_init_mutexes
();
evex_init_mutexes
();
VOID
(
pthread_mutex_lock
(
&
LOCK_evex_running
));
VOID
(
pthread_mutex_lock
(
&
LOCK_evex_running
));
...
@@ -114,6 +211,16 @@ init_events()
...
@@ -114,6 +211,16 @@ init_events()
}
}
/*
Cleans up scheduler memory. Called on server shutdown.
SYNOPSIS
shutdown_events()
NOTES
Destroys the mutexes.
*/
void
void
shutdown_events
()
shutdown_events
()
{
{
...
@@ -130,6 +237,22 @@ shutdown_events()
...
@@ -130,6 +237,22 @@ shutdown_events()
}
}
/*
Inits an scheduler thread handler, both the main and a worker
SYNOPSIS
init_event_thread()
thd - the THD of the thread. Has to be allocated by the caller.
NOTES
1. The host of the thead is my_localhost
2. thd->net is initted with NULL - no communication.
Returns
0 - OK
-1 - Error
*/
static
int
static
int
init_event_thread
(
THD
*
thd
)
init_event_thread
(
THD
*
thd
)
{
{
...
@@ -166,6 +289,22 @@ init_event_thread(THD* thd)
...
@@ -166,6 +289,22 @@ init_event_thread(THD* thd)
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
/*
The main scheduler thread. Inits the priority queue on start and
destroys it on thread shutdown. Forks child threads for every event
execution. Sleeps between thread forking and does not do a busy wait.
SYNOPSIS
event_executor_main()
arg - unused
NOTES
1. The host of the thead is my_localhost
2. thd->net is initted with NULL - no communication.
*/
pthread_handler_t
pthread_handler_t
event_executor_main
(
void
*
arg
)
event_executor_main
(
void
*
arg
)
{
{
...
@@ -437,6 +576,15 @@ err_no_thd:
...
@@ -437,6 +576,15 @@ err_no_thd:
}
}
/*
Function that executes an event in a child thread. Setups the
environment for the event execution and cleans after that.
SYNOPSIS
event_executor_worker()
arg - the event_timed object to be processed
*/
pthread_handler_t
pthread_handler_t
event_executor_worker
(
void
*
event_void
)
event_executor_worker
(
void
*
event_void
)
{
{
...
@@ -562,6 +710,24 @@ err_no_thd:
...
@@ -562,6 +710,24 @@ err_no_thd:
}
}
/*
Loads all ENABLED events from mysql.event into the prioritized
queue. Called during scheduler main thread initialization. Compiles
the events. Creates event_timed instances for every ENABLED event
from mysql.event.
SYNOPSIS
evex_load_events_from_db()
thd - Thread context. Used for memory allocation in some cases.
RETURNS
0 - OK
-1 - Error
NOTES
Reports the error to the console
*/
static
int
static
int
evex_load_events_from_db
(
THD
*
thd
)
evex_load_events_from_db
(
THD
*
thd
)
{
{
...
@@ -648,7 +814,22 @@ end:
...
@@ -648,7 +814,22 @@ end:
}
}
bool
sys_var_event_executor
::
update
(
THD
*
thd
,
set_var
*
var
)
/*
The update method of the global variable event_scheduler.
If event_scheduler is switched from 0 to 1 then the scheduler main
thread is started.
SYNOPSIS
event_executor_worker()
thd - Thread context (unused)
car - the new value
Returns
0 - OK (always)
*/
bool
sys_var_event_executor
::
update
(
THD
*
thd
,
set_var
*
var
)
{
{
// here start the thread if not running.
// here start the thread if not running.
DBUG_ENTER
(
"sys_var_event_executor::update"
);
DBUG_ENTER
(
"sys_var_event_executor::update"
);
...
...
sql/event_timed.cc
View file @
d5d11a9c
...
@@ -116,7 +116,10 @@ event_timed::init_body(THD *thd)
...
@@ -116,7 +116,10 @@ event_timed::init_body(THD *thd)
while
(
body
.
length
&&
body_begin
[
body
.
length
-
1
]
==
'\0'
)
while
(
body
.
length
&&
body_begin
[
body
.
length
-
1
]
==
'\0'
)
body
.
length
--
;
body
.
length
--
;
body
.
str
=
strmake_root
(
root
,
(
char
*
)
body_begin
,
body
.
length
);
//the first is always space which I cannot skip in the parser
DBUG_ASSERT
(
*
body_begin
==
' '
);
body
.
length
--
;
body
.
str
=
strmake_root
(
root
,
(
char
*
)
body_begin
+
1
,
body
.
length
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -847,6 +850,15 @@ err:
...
@@ -847,6 +850,15 @@ err:
}
}
/*
Set the internal last_executed TIME struct to now. NOW is the
time according to thd->query_start(), so the THD's clock.
Synopsis
event_timed::drop()
thd - thread context
*/
void
void
event_timed
::
mark_last_executed
(
THD
*
thd
)
event_timed
::
mark_last_executed
(
THD
*
thd
)
{
{
...
@@ -864,7 +876,13 @@ event_timed::mark_last_executed(THD *thd)
...
@@ -864,7 +876,13 @@ event_timed::mark_last_executed(THD *thd)
/*
/*
Returns :
Drops the event
Synopsis
event_timed::drop()
thd - thread context
RETURNS :
0 - OK
0 - OK
-1 - Cannot open mysql.event
-1 - Cannot open mysql.event
-2 - Cannot find the event in mysql.event (already deleted?)
-2 - Cannot find the event in mysql.event (already deleted?)
...
@@ -884,6 +902,22 @@ event_timed::drop(THD *thd)
...
@@ -884,6 +902,22 @@ event_timed::drop(THD *thd)
}
}
/*
Saves status and last_executed_at to the disk if changed.
Synopsis
event_timed::drop()
thd - thread context
Returns :
0 - OK
SP_OPEN_TABLE_FAILED - Error while opening mysql.event for writing
EVEX_WRITE_ROW_FAILED - On error to write to disk
others - return code from SE in case deletion of the event row
failed.
*/
bool
bool
event_timed
::
update_fields
(
THD
*
thd
)
event_timed
::
update_fields
(
THD
*
thd
)
{
{
...
@@ -941,40 +975,75 @@ done:
...
@@ -941,40 +975,75 @@ done:
}
}
char
*
/*
event_timed
::
get_show_create_event
(
THD
*
thd
,
uint32
*
length
)
Get SHOW CREATE EVENT as string
thd - Thread
buf - String*, should be already allocated. CREATE EVENT goes inside.
Returns:
0 - OK
1 - Error (for now if mysql.event has been tampered and MICROSECONDS
interval or derivative has been put there.
*/
int
event_timed
::
get_create_event
(
THD
*
thd
,
String
*
buf
)
{
{
char
*
dst
,
*
ret
;
int
multipl
=
0
;
uint
len
,
tmp_len
;
char
tmp_buff
[
128
];
DBUG_ENTER
(
"get_show_create_event"
);
String
expr_buf
(
tmp_buff
,
sizeof
(
tmp_buff
),
system_charset_info
);
expr_buf
.
length
(
0
);
DBUG_ENTER
(
"get_create_event"
);
DBUG_PRINT
(
"ret_info"
,(
"body_len=[%d]body=[%s]"
,
body
.
length
,
body
.
str
));
DBUG_PRINT
(
"ret_info"
,(
"body_len=[%d]body=[%s]"
,
body
.
length
,
body
.
str
));
len
=
strlen
(
"CREATE EVENT `"
)
+
dbname
.
length
+
strlen
(
"`.`"
)
+
name
.
length
+
if
(
expression
&&
strlen
(
"` ON SCHEDULE EVERY 5 MINUTE DO "
)
+
body
.
length
;
// + strlen(";");
event_reconstruct_interval_expression
(
&
expr_buf
,
interval
,
expression
))
DBUG_RETURN
(
1
);
ret
=
dst
=
(
char
*
)
alloc_root
(
thd
->
mem_root
,
len
+
1
);
memcpy
(
dst
,
"CREATE EVENT `"
,
tmp_len
=
strlen
(
"CREATE EVENT `"
));
buf
->
append
(
STRING_WITH_LEN
(
"CREATE EVENT "
));
dst
+=
tmp_len
;
append_identifier
(
thd
,
buf
,
dbname
.
str
,
dbname
.
length
);
memcpy
(
dst
,
dbname
.
str
,
tmp_len
=
dbname
.
length
);
buf
->
append
(
STRING_WITH_LEN
(
"."
));
dst
+=
tmp_len
;
append_identifier
(
thd
,
buf
,
name
.
str
,
name
.
length
);
memcpy
(
dst
,
"`.`"
,
tmp_len
=
strlen
(
"`.`"
));
dst
+=
tmp_len
;
buf
->
append
(
STRING_WITH_LEN
(
" ON SCHEDULE "
));
memcpy
(
dst
,
name
.
str
,
tmp_len
=
name
.
length
);
if
(
expression
)
dst
+=
tmp_len
;
{
memcpy
(
dst
,
"` ON SCHEDULE EVERY 5 MINUTE DO "
,
buf
->
append
(
STRING_WITH_LEN
(
"EVERY "
));
tmp_len
=
strlen
(
"` ON SCHEDULE EVERY 5 MINUTE DO "
));
buf
->
append
(
expr_buf
);
dst
+=
tmp_len
;
}
else
memcpy
(
dst
,
body
.
str
,
tmp_len
=
body
.
length
);
{
dst
+=
tmp_len
;
char
dtime_buff
[
20
*
2
+
32
];
// +32 to make my_snprintf_{8bit|ucs2} happy
// memcpy(dst, ";", 1);
buf
->
append
(
STRING_WITH_LEN
(
"AT '"
));
// ++dst;
/*
*
dst
=
'\0'
;
pass the buffer and the second param tells fills the buffer and returns
the number of chars to copy
*
length
=
len
;
*/
buf
->
append
(
dtime_buff
,
my_datetime_to_str
(
&
execute_at
,
dtime_buff
));
DBUG_PRINT
(
"ret_info"
,(
"len=%d"
,
*
length
));
buf
->
append
(
STRING_WITH_LEN
(
"'"
));
DBUG_RETURN
(
ret
);
}
if
(
on_completion
==
MYSQL_EVENT_ON_COMPLETION_DROP
)
buf
->
append
(
STRING_WITH_LEN
(
" ON COMPLETION NOT PRESERVE "
));
else
buf
->
append
(
STRING_WITH_LEN
(
" ON COMPLETION PRESERVE "
));
if
(
status
==
MYSQL_EVENT_ENABLED
)
buf
->
append
(
STRING_WITH_LEN
(
"ENABLE"
));
else
buf
->
append
(
STRING_WITH_LEN
(
"DISABLE"
));
if
(
comment
.
length
)
{
buf
->
append
(
STRING_WITH_LEN
(
" COMMENT "
));
append_unescaped
(
buf
,
comment
.
str
,
comment
.
length
);
}
buf
->
append
(
STRING_WITH_LEN
(
" DO "
));
buf
->
append
(
body
.
str
,
body
.
length
);
DBUG_RETURN
(
0
);
}
}
...
@@ -1035,13 +1104,21 @@ done:
...
@@ -1035,13 +1104,21 @@ done:
/*
/*
Compiles an event before it's execution. Compiles the anonymous
sp_head object held by the event
Synopsis
event_timed::compile()
thd - thread context, used for memory allocation mostly
mem_root - if != NULL then this memory root is used for allocs
instead of thd->mem_root
Returns
Returns
0 - Success
0 - Success
EVEX_COMPILE_ERROR - Error during compilation
EVEX_COMPILE_ERROR - Error during compilation
*/
*/
int
int
event_timed
::
compile
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
event_timed
::
compile
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
{
...
@@ -1054,9 +1131,13 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1054,9 +1131,13 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
char
*
old_query
;
char
*
old_query
;
uint
old_query_len
;
uint
old_query_len
;
st_sp_chistics
*
p
;
st_sp_chistics
*
p
;
CHARSET_INFO
*
old_character_set_client
,
*
old_collation_connection
,
char
create_buf
[
2048
];
String
show_create
(
create_buf
,
sizeof
(
create_buf
),
system_charset_info
);
CHARSET_INFO
*
old_character_set_client
,
*
old_collation_connection
,
*
old_character_set_results
;
*
old_character_set_results
;
show_create
.
length
(
0
);
old_character_set_client
=
thd
->
variables
.
character_set_client
;
old_character_set_client
=
thd
->
variables
.
character_set_client
;
old_character_set_results
=
thd
->
variables
.
character_set_results
;
old_character_set_results
=
thd
->
variables
.
character_set_results
;
old_collation_connection
=
thd
->
variables
.
collation_connection
;
old_collation_connection
=
thd
->
variables
.
collation_connection
;
...
@@ -1079,7 +1160,11 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
...
@@ -1079,7 +1160,11 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
old_query
=
thd
->
query
;
old_query
=
thd
->
query
;
old_db
=
thd
->
db
;
old_db
=
thd
->
db
;
thd
->
db
=
dbname
.
str
;
thd
->
db
=
dbname
.
str
;
thd
->
query
=
get_show_create_event
(
thd
,
&
thd
->
query_length
);
get_create_event
(
thd
,
&
show_create
);
thd
->
query
=
show_create
.
c_ptr
();
thd
->
query_length
=
show_create
.
length
();
DBUG_PRINT
(
"event_timed::compile"
,
(
"query:%s"
,
thd
->
query
));
DBUG_PRINT
(
"event_timed::compile"
,
(
"query:%s"
,
thd
->
query
));
thd
->
lex
=
&
lex
;
thd
->
lex
=
&
lex
;
...
...
sql/sql_acl.cc
View file @
d5d11a9c
...
@@ -36,6 +36,122 @@
...
@@ -36,6 +36,122 @@
#define FIRST_NON_YN_FIELD 26
#define FIRST_NON_YN_FIELD 26
time_t
mysql_db_table_last_check
=
0L
;
TABLE_FIELD_W_TYPE
mysql_db_table_fields
[
MYSQL_DB_FIELD_COUNT
]
=
{
{
{(
char
*
)
STRING_WITH_LEN
(
"Host"
)},
{(
char
*
)
STRING_WITH_LEN
(
"char(60)"
)},
{
NULL
,
0
}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Db"
)},
{(
char
*
)
STRING_WITH_LEN
(
"char(64)"
)},
{
NULL
,
0
}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"User"
)},
{(
char
*
)
STRING_WITH_LEN
(
"char(16)"
)},
{
NULL
,
0
}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Select_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Insert_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Update_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Delete_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Create_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Drop_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Grant_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"References_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Index_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Alter_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Create_tmp_table_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Lock_tables_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Create_view_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Show_view_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Create_routine_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Alter_routine_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Execute_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Event_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
},
{
{(
char
*
)
STRING_WITH_LEN
(
"Trigger_priv"
)},
{(
char
*
)
STRING_WITH_LEN
(
"enum('N','Y')"
)},
{(
char
*
)
STRING_WITH_LEN
(
"utf8"
)}
}
};
class
acl_entry
:
public
hash_filo_element
class
acl_entry
:
public
hash_filo_element
{
{
public:
public:
...
@@ -441,14 +557,14 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
...
@@ -441,14 +557,14 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
while
(
!
(
read_record_info
.
read_record
(
&
read_record_info
)))
while
(
!
(
read_record_info
.
read_record
(
&
read_record_info
)))
{
{
ACL_DB
db
;
ACL_DB
db
;
update_hostname
(
&
db
.
host
,
get_field
(
&
mem
,
table
->
field
[
0
]));
update_hostname
(
&
db
.
host
,
get_field
(
&
mem
,
table
->
field
[
MYSQL_DB_FIELD_HOST
]));
db
.
db
=
get_field
(
&
mem
,
table
->
field
[
1
]);
db
.
db
=
get_field
(
&
mem
,
table
->
field
[
MYSQL_DB_FIELD_DB
]);
if
(
!
db
.
db
)
if
(
!
db
.
db
)
{
{
sql_print_warning
(
"Found an entry in the 'db' table with empty database name; Skipped"
);
sql_print_warning
(
"Found an entry in the 'db' table with empty database name; Skipped"
);
continue
;
continue
;
}
}
db
.
user
=
get_field
(
&
mem
,
table
->
field
[
2
]);
db
.
user
=
get_field
(
&
mem
,
table
->
field
[
MYSQL_DB_FIELD_USER
]);
if
(
check_no_resolve
&&
hostname_requires_resolving
(
db
.
host
.
hostname
))
if
(
check_no_resolve
&&
hostname_requires_resolving
(
db
.
host
.
hostname
))
{
{
sql_print_warning
(
"'db' entry '%s %s@%s' "
sql_print_warning
(
"'db' entry '%s %s@%s' "
...
...
sql/sql_acl.h
View file @
d5d11a9c
...
@@ -134,6 +134,36 @@
...
@@ -134,6 +134,36 @@
(((A) & ALTER_PROC_ACL) >> 23) | \
(((A) & ALTER_PROC_ACL) >> 23) | \
(((A) & GRANT_ACL) >> 8))
(((A) & GRANT_ACL) >> 8))
enum
mysql_db_table_field
{
MYSQL_DB_FIELD_HOST
=
0
,
MYSQL_DB_FIELD_DB
,
MYSQL_DB_FIELD_USER
,
MYSQL_DB_FIELD_SELECT_PRIV
,
MYSQL_DB_FIELD_INSERT_PRIV
,
MYSQL_DB_FIELD_UPDATE_PRIV
,
MYSQL_DB_FIELD_DELETE_PRIV
,
MYSQL_DB_FIELD_CREATE_PRIV
,
MYSQL_DB_FIELD_DROP_PRIV
,
MYSQL_DB_FIELD_GRANT_PRIV
,
MYSQL_DB_FIELD_REFERENCES_PRIV
,
MYSQL_DB_FIELD_INDEX_PRIV
,
MYSQL_DB_FIELD_ALTER_PRIV
,
MYSQL_DB_FIELD_CREATE_TMP_TABLE_PRIV
,
MYSQL_DB_FIELD_LOCK_TABLES_PRIV
,
MYSQL_DB_FIELD_CREATE_VIEW_PRIV
,
MYSQL_DB_FIELD_SHOW_VIEW_PRIV
,
MYSQL_DB_FIELD_CREATE_ROUTINE_PRIV
,
MYSQL_DB_FIELD_ALTER_ROUTINE_PRIV
,
MYSQL_DB_FIELD_EXECUTE_PRIV
,
MYSQL_DB_FIELD_EVENT_PRIV
,
MYSQL_DB_FIELD_TRIGGER_PRIV
,
MYSQL_DB_FIELD_COUNT
};
extern
TABLE_FIELD_W_TYPE
mysql_db_table_fields
[];
extern
time_t
mysql_db_table_last_check
;
/* Classes */
/* Classes */
struct
acl_host_and_ip
struct
acl_host_and_ip
...
...
sql/sql_parse.cc
View file @
d5d11a9c
...
@@ -3799,6 +3799,14 @@ end_with_restore_list:
...
@@ -3799,6 +3799,14 @@ end_with_restore_list:
}
}
case
SQLCOM_SHOW_CREATE_EVENT
:
case
SQLCOM_SHOW_CREATE_EVENT
:
{
{
DBUG_ASSERT
(
lex
->
spname
);
DBUG_ASSERT
(
lex
->
et
);
if
(
!
lex
->
spname
->
m_db
.
str
)
{
my_message
(
ER_NO_DB_ERROR
,
ER
(
ER_NO_DB_ERROR
),
MYF
(
0
));
res
=
true
;
break
;
}
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
spname
->
m_db
.
str
,
0
,
0
,
0
,
if
(
check_access
(
thd
,
EVENT_ACL
,
lex
->
spname
->
m_db
.
str
,
0
,
0
,
0
,
is_schema_db
(
lex
->
spname
->
m_db
.
str
)))
is_schema_db
(
lex
->
spname
->
m_db
.
str
)))
break
;
break
;
...
@@ -3808,8 +3816,7 @@ end_with_restore_list:
...
@@ -3808,8 +3816,7 @@ end_with_restore_list:
my_error
(
ER_TOO_LONG_IDENT
,
MYF
(
0
),
lex
->
spname
->
m_name
.
str
);
my_error
(
ER_TOO_LONG_IDENT
,
MYF
(
0
),
lex
->
spname
->
m_name
.
str
);
goto
error
;
goto
error
;
}
}
/* TODO : Implement it */
res
=
evex_show_create_event
(
thd
,
lex
->
spname
,
lex
->
et
->
definer
);
send_ok
(
thd
,
1
);
break
;
break
;
}
}
case
SQLCOM_CREATE_FUNCTION
:
// UDF function
case
SQLCOM_CREATE_FUNCTION
:
// UDF function
...
...
sql/sql_show.cc
View file @
d5d11a9c
...
@@ -3766,30 +3766,6 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
...
@@ -3766,30 +3766,6 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
}
}
static
LEX_STRING
interval_type_to_name
[]
=
{
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_YEAR"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_QUARTER"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_MONTH"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_DAY"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_HOUR"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_MINUTE"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_WEEK"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_SECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_MICROSECOND "
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_YEAR_MONTH"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_DAY_HOUR"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_DAY_MINUTE"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_DAY_SECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_HOUR_MINUTE"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_HOUR_SECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_MINUTE_SECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_DAY_MICROSECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_HOUR_MICROSECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_MINUTE_MICROSECOND"
)},
{(
char
*
)
STRING_WITH_LEN
(
"INTERVAL_SECOND_MICROSECOND"
)}
};
static
interval_type
get_real_interval_type
(
interval_type
i_type
)
static
interval_type
get_real_interval_type
(
interval_type
i_type
)
{
{
switch
(
i_type
)
{
switch
(
i_type
)
{
...
@@ -3863,6 +3839,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
...
@@ -3863,6 +3839,7 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table
->
field
[
9
]
->
set_null
();
sch_table
->
field
[
9
]
->
set_null
();
if
(
et
.
expression
)
if
(
et
.
expression
)
{
{
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
...
@@ -3871,9 +3848,11 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
...
@@ -3871,9 +3848,11 @@ fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
sch_table
->
field
[
7
]
->
set_notnull
();
sch_table
->
field
[
7
]
->
set_notnull
();
sch_table
->
field
[
7
]
->
store
((
longlong
)
et
.
expression
);
sch_table
->
field
[
7
]
->
store
((
longlong
)
et
.
expression
);
//interval_type
//interval_type
LEX_STRING
*
ival
=&
interval_type_to_name
[
get_real_interval_type
(
et
.
interval
)];
if
(
event_reconstruct_interval_expression
(
&
show_str
,
et
.
interval
,
et
.
expression
))
DBUG_RETURN
(
1
);
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
(
show_str
.
c_ptr
(),
show_str
.
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
);
...
...
sql/sql_yacc.yy
View file @
d5d11a9c
...
@@ -8431,6 +8431,10 @@ show_param:
...
@@ -8431,6 +8431,10 @@ show_param:
{
{
Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
Lex->spname= $3;
Lex->spname= $3;
Lex->et= new event_timed();
if (!Lex->et)
YYABORT;
Lex->et->init_definer(YYTHD);
}
}
;
;
...
...
sql/table.cc
View file @
d5d11a9c
...
@@ -343,9 +343,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
...
@@ -343,9 +343,7 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
allow to lock such tables for writing with any other tables (even with
allow to lock such tables for writing with any other tables (even with
other system tables) and some privilege tables need this.
other system tables) and some privilege tables need this.
*/
*/
if
(
!
my_strcasecmp
(
system_charset_info
,
share
->
table_name
.
str
,
"proc"
)
if
(
!
my_strcasecmp
(
system_charset_info
,
share
->
table_name
.
str
,
"proc"
))
||
!
my_strcasecmp
(
system_charset_info
,
share
->
table_name
.
str
,
"event"
))
share
->
system_table
=
1
;
share
->
system_table
=
1
;
else
else
{
{
...
@@ -2291,6 +2289,144 @@ bool check_column_name(const char *name)
...
@@ -2291,6 +2289,144 @@ bool check_column_name(const char *name)
return
last_char_is_space
||
(
uint
)
(
name
-
start
)
>
NAME_LEN
;
return
last_char_is_space
||
(
uint
)
(
name
-
start
)
>
NAME_LEN
;
}
}
/*
Checks whether a table is intact. Should be done *just* after the table has
been opened.
Synopsis
table_check_intact()
table - the table to check
table_f_count - expected number of columns in the table
table_def - expected structure of the table (column name and type)
last_create_time- the table->file->create_time of the table in memory
we have checked last time
error_num - ER_XXXX from the error messages file. When 0 no error
is sent to the client in case types does not match.
If different col number either
ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE or
ER_COL_COUNT_DOESNT_MATCH_CORRUPTED is used
RETURNS
0 - OK
1 - There was an error
*/
my_bool
table_check_intact
(
TABLE
*
table
,
uint
table_f_count
,
TABLE_FIELD_W_TYPE
*
table_def
,
time_t
*
last_create_time
,
int
error_num
)
{
uint
i
;
my_bool
error
=
FALSE
;
my_bool
fields_diff_count
;
DBUG_ENTER
(
"table_check_intact"
);
DBUG_PRINT
(
"info"
,(
"table=%s expected_count=%d"
,
table
->
alias
,
table_f_count
));
DBUG_PRINT
(
"info"
,(
"last_create_time=%d"
,
*
last_create_time
));
if
((
fields_diff_count
=
(
table
->
s
->
fields
!=
table_f_count
))
||
(
*
last_create_time
!=
table
->
file
->
create_time
))
{
DBUG_PRINT
(
"info"
,
(
"I am suspecting, checking table"
));
if
(
fields_diff_count
)
{
// previous MySQL version
error
=
TRUE
;
if
(
MYSQL_VERSION_ID
>
table
->
s
->
mysql_version
)
my_error
(
ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE
,
MYF
(
0
),
table
->
alias
,
table_f_count
,
table
->
s
->
fields
,
table
->
s
->
mysql_version
,
MYSQL_VERSION_ID
);
else
if
(
MYSQL_VERSION_ID
==
table
->
s
->
mysql_version
)
my_error
(
ER_COL_COUNT_DOESNT_MATCH_CORRUPTED
,
MYF
(
0
),
table
->
alias
,
table_f_count
,
table
->
s
->
fields
);
else
/*
moving from newer mysql to older one -> let's say not an error but
will check the definition afterwards. If a column was added at the end
then we don't care much since it's not in the middle.
*/
error
=
FALSE
;
}
//definitely something has changed
char
buffer
[
255
];
for
(
i
=
0
;
i
<
table_f_count
;
++
i
,
++
table_def
)
{
Field
*
field
=
table
->
field
[
i
];
String
sql_type
(
buffer
,
sizeof
(
buffer
),
system_charset_info
);
sql_type
.
length
(
0
);
/*
name changes are not fatal, we use sequence numbers => no prob for us
but this can show tampered table or broken table.
*/
if
(
!
fields_diff_count
||
i
<
table
->
s
->
fields
)
{
if
(
strncmp
(
field
->
field_name
,
table_def
->
name
.
str
,
table_def
->
name
.
length
))
{
sql_print_error
(
"(%s) Expected field %s at position %d, found %s"
,
table
->
alias
,
table_def
->
name
.
str
,
i
,
field
->
field_name
);
}
/*
IF the type does not match than something is really wrong
Check up to length - 1. Why?
1. datetime -> datetim -> the same
2. int(11) -> int(11 -> the same
3. set('one','two') -> set('one','two'
so for sets if the same prefix is there it's ok if more are
added as part of the set. The same is valid for enum. So a new
table running on a old server will be valid.
*/
field
->
sql_type
(
sql_type
);
if
(
strncmp
(
sql_type
.
c_ptr
(),
table_def
->
type
.
str
,
table_def
->
type
.
length
-
1
))
{
sql_print_error
(
"(%s) Expected field %s at position %d to have type "
"%s, found %s"
,
table
->
alias
,
table_def
->
name
.
str
,
i
,
table_def
->
type
.
str
,
sql_type
.
c_ptr
());
error
=
TRUE
;
}
else
if
(
table_def
->
cset
.
str
&&
!
field
->
has_charset
())
{
sql_print_error
(
"(%s) Expected field %s at position %d to have "
"character set '%s' but found no such"
,
table
->
alias
,
table_def
->
name
.
str
,
i
,
table_def
->
cset
.
str
);
error
=
TRUE
;
}
else
if
(
table_def
->
cset
.
str
&&
strcmp
(
field
->
charset
()
->
csname
,
table_def
->
cset
.
str
))
{
sql_print_error
(
"(%s) Expected field %s at position %d to have "
"character set '%s' but found '%s'"
,
table
->
alias
,
table_def
->
name
.
str
,
i
,
table_def
->
cset
.
str
,
field
->
charset
()
->
csname
);
error
=
TRUE
;
}
}
else
{
sql_print_error
(
"(%s) Expected field %s at position %d to have type %s "
" but no field found."
,
table_def
->
name
.
str
,
table_def
->
name
.
str
,
i
,
table_def
->
type
.
str
);
error
=
TRUE
;
}
}
if
(
!
error
)
*
last_create_time
=
table
->
file
->
create_time
;
else
if
(
!
fields_diff_count
&&
error_num
)
my_error
(
error_num
,
MYF
(
0
),
table
->
alias
,
table_f_count
,
table
->
s
->
fields
);
}
else
{
DBUG_PRINT
(
"info"
,
(
"Table seems ok without through checking."
));
*
last_create_time
=
table
->
file
->
create_time
;
}
DBUG_RETURN
(
error
);
}
/*
/*
Create Item_field for each column in the table.
Create Item_field for each column in the table.
...
...
sql/table.h
View file @
d5d11a9c
...
@@ -866,4 +866,15 @@ typedef struct st_open_table_list{
...
@@ -866,4 +866,15 @@ typedef struct st_open_table_list{
uint32
in_use
,
locked
;
uint32
in_use
,
locked
;
}
OPEN_TABLE_LIST
;
}
OPEN_TABLE_LIST
;
typedef
struct
st_table_field_w_type
{
LEX_STRING
name
;
LEX_STRING
type
;
LEX_STRING
cset
;
}
TABLE_FIELD_W_TYPE
;
my_bool
table_check_intact
(
TABLE
*
table
,
uint
table_f_count
,
TABLE_FIELD_W_TYPE
*
table_def
,
time_t
*
last_create_time
,
int
error_num
);
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