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
bb3ac3e3
Commit
bb3ac3e3
authored
Feb 14, 2006
by
andrey@lmy004
Browse files
Options
Browse Files
Download
Plain Diff
Merge ahristov@bk-internal.mysql.com:/home/bk/mysql-5.1-new
into lmy004.:/work/mysql-5.1-bug17289
parents
cea8c9af
446c791e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
233 additions
and
31 deletions
+233
-31
mysql-test/r/events.result
mysql-test/r/events.result
+26
-1
mysql-test/t/events.test
mysql-test/t/events.test
+33
-0
sql/event.h
sql/event.h
+6
-0
sql/event_executor.cc
sql/event_executor.cc
+79
-22
sql/event_timed.cc
sql/event_timed.cc
+80
-4
sql/sql_error.cc
sql/sql_error.cc
+9
-4
No files found.
mysql-test/r/events.result
View file @
bb3ac3e3
create database if not exists events_test;
use events_test;
CREATE USER pauline@localhost;
CREATE DATABASE db_x;
GRANT EVENT ON db_x.* TO pauline@localhost;
USE db_x;
CREATE TABLE x_table(a int);
CREATE EVENT e_x1 ON SCHEDULE EVERY 1 SECOND DO DROP DATABASE db_x;
CREATE EVENT e_x2 ON SCHEDULE EVERY 1 SECOND DO DROP TABLE x_table;
SHOW DATABASES LIKE 'db_x';
Database (db_x)
db_x
SET GLOBAL event_scheduler=1;
SHOW DATABASES LIKE 'db_x';
Database (db_x)
db_x
SHOW TABLES FROM db_x;
Tables_in_db_x
x_table
SET GLOBAL event_scheduler=0;
DROP EVENT e_x1;
DROP EVENT e_x2;
DROP DATABASE db_x;
DROP USER pauline@localhost;
USE events_test;
drop event if exists event1;
Warnings:
Note 1305 Event event1 does not exist
...
...
@@ -166,7 +189,7 @@ show processlist;
Id User Host db Command Time State Info
# root localhost events_test Query # NULL show processlist
# event_scheduler NULL Connect # Sleeping NULL
# root events_test Connect # User lock select get_lock("test_lock2", 20)
# root
localhost
events_test Connect # User lock select get_lock("test_lock2", 20)
"Release the mutex, the event worker should finish."
select release_lock("test_lock2");
release_lock("test_lock2")
...
...
@@ -184,6 +207,8 @@ set global event_scheduler=0;
show processlist;
Id User Host db Command Time State Info
# root localhost events_test Query # NULL show processlist
# event_scheduler NULL Connect # Sleeping NULL
# root localhost events_test Connect # User lock select get_lock("test_lock2_1", 20)
"Release the lock so the child process should finish. Hence the scheduler also"
select release_lock("test_lock2_1");
release_lock("test_lock2_1")
...
...
mysql-test/t/events.test
View file @
bb3ac3e3
create
database
if
not
exists
events_test
;
use
events_test
;
#
# START: BUG #17289 Events: missing privilege check for drop database
#
CREATE
USER
pauline
@
localhost
;
CREATE
DATABASE
db_x
;
GRANT
EVENT
ON
db_x
.*
TO
pauline
@
localhost
;
USE
db_x
;
CREATE
TABLE
x_table
(
a
int
);
connect
(
priv_conn
,
localhost
,
pauline
,,
db_x
);
CREATE
EVENT
e_x1
ON
SCHEDULE
EVERY
1
SECOND
DO
DROP
DATABASE
db_x
;
CREATE
EVENT
e_x2
ON
SCHEDULE
EVERY
1
SECOND
DO
DROP
TABLE
x_table
;
connection
default
;
SHOW
DATABASES
LIKE
'db_x'
;
SET
GLOBAL
event_scheduler
=
1
;
--
sleep
2
SHOW
DATABASES
LIKE
'db_x'
;
SHOW
TABLES
FROM
db_x
;
SET
GLOBAL
event_scheduler
=
0
;
--
sleep
1
connection
priv_conn
;
DROP
EVENT
e_x1
;
DROP
EVENT
e_x2
;
disconnect
priv_conn
;
connection
default
;
DROP
DATABASE
db_x
;
DROP
USER
pauline
@
localhost
;
USE
events_test
;
--
sleep
1
#
# END: BUG #17289 Events: missing privilege check for drop database
#
drop
event
if
exists
event1
;
create
event
event1
on
schedule
every
15
minute
starts
now
()
ends
date_add
(
now
(),
interval
5
hour
)
DO
begin
end
;
alter
event
event1
rename
to
event2
enable
;
...
...
sql/event.h
View file @
bb3ac3e3
...
...
@@ -203,6 +203,12 @@ public:
delete
sphead
;
sphead
=
0
;
}
protected:
bool
change_security_context
(
THD
*
thd
,
Security_context
**
backup
);
void
restore_security_context
(
THD
*
thd
,
Security_context
*
backup
);
};
...
...
sql/event_executor.cc
View file @
bb3ac3e3
...
...
@@ -49,7 +49,8 @@ static uint workers_count;
static
int
evex_load_events_from_db
(
THD
*
thd
);
bool
evex_print_warnings
(
THD
*
thd
,
event_timed
*
et
);
/*
TODO Andrey: Check for command line option whether to start
...
...
@@ -135,7 +136,8 @@ init_event_thread(THD* thd)
{
DBUG_ENTER
(
"init_event_thread"
);
thd
->
client_capabilities
=
0
;
thd
->
security_ctx
->
skip_grants
();
thd
->
security_ctx
->
master_access
=
0
;
thd
->
security_ctx
->
db_access
=
0
;
thd
->
security_ctx
->
host
=
(
char
*
)
my_localhost
;
my_net_init
(
&
thd
->
net
,
0
);
thd
->
net
.
read_timeout
=
slave_net_timeout
;
...
...
@@ -204,8 +206,11 @@ event_executor_main(void *arg)
if
(
init_event_thread
(
thd
))
goto
err
;
// make this thread invisible it has no vio -> show processlist won't see
/*
make this thread visible it has no vio -> show processlist won't see it
unless it's marked as system thread
*/
thd
->
system_thread
=
1
;
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
...
...
@@ -481,21 +486,8 @@ event_executor_worker(void *event_void)
thd
=
current_thd
;
#endif
// thd->security_ctx->priv_host is char[MAX_HOSTNAME]
strxnmov
(
thd
->
security_ctx
->
priv_host
,
sizeof
(
thd
->
security_ctx
->
priv_host
),
event
->
definer_host
.
str
,
NullS
);
thd
->
security_ctx
->
user
=
thd
->
security_ctx
->
priv_user
=
my_strdup
(
event
->
definer_user
.
str
,
MYF
(
0
));
thd
->
db
=
event
->
dbname
.
str
;
if
(
!
check_access
(
thd
,
EVENT_ACL
,
event
->
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
event
->
dbname
.
str
)))
{
int
ret
;
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTING event %s.%s [EXPR:%d]"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
));
sql_print_information
(
" EVEX EXECUTING event %s.%s [EXPR:%d]"
,
event
->
dbname
.
str
,
event
->
name
.
str
,(
int
)
event
->
expression
);
...
...
@@ -507,10 +499,7 @@ event_executor_worker(void *event_void)
if
(
ret
==
EVEX_COMPILE_ERROR
)
sql_print_information
(
" EVEX COMPILE ERROR for event %s.%s"
,
event
->
dbname
.
str
,
event
->
name
.
str
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTED event %s.%s [EXPR:%d]. RetCode=%d"
,
event
->
dbname
.
str
,
event
->
name
.
str
,
(
int
)
event
->
expression
,
ret
));
evex_print_warnings
(
thd
,
event
);
}
if
((
event
->
flags
&
EVENT_EXEC_NO_MORE
)
||
event
->
status
==
MYSQL_EVENT_DISABLED
)
{
...
...
@@ -521,7 +510,6 @@ event_executor_worker(void *event_void)
delete
event
;
}
thd
->
db
=
0
;
err:
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
...
...
@@ -666,3 +654,72 @@ bool sys_var_event_executor::update(THD *thd, set_var *var)
DBUG_RETURN
(
0
);
}
extern
LEX_STRING
warning_level_names
[];
typedef
void
(
*
sql_print_xxx_func
)(
const
char
*
format
,
...);
static
sql_print_xxx_func
sql_print_xxx_handlers
[
3
]
=
{
sql_print_information
,
sql_print_warning
,
sql_print_error
};
/*
Prints the stack of infos, warnings, errors from thd to
the console so it can be fetched by the logs-into-tables and
checked later.
Synopsis
evex_print_warnings
thd - thread used during the execution of the event
et - the event itself
Returns
0 - OK (always)
*/
bool
evex_print_warnings
(
THD
*
thd
,
event_timed
*
et
)
{
MYSQL_ERROR
*
err
;
DBUG_ENTER
(
"evex_show_warnings"
);
char
msg_buf
[
1024
];
char
prefix_buf
[
512
];
String
prefix
(
prefix_buf
,
sizeof
(
prefix_buf
),
system_charset_info
);
prefix
.
length
(
0
);
List_iterator_fast
<
MYSQL_ERROR
>
it
(
thd
->
warn_list
);
while
((
err
=
it
++
))
{
String
err_msg
(
msg_buf
,
sizeof
(
msg_buf
),
system_charset_info
);
err_msg
.
length
(
0
);
// set it to 0 or we start adding at the end
if
(
!
prefix
.
length
())
{
prefix
.
append
(
"SCHEDULER: ["
);
append_identifier
(
thd
,
&
prefix
,
et
->
definer_user
.
str
,
et
->
definer_user
.
length
);
prefix
.
append
(
'@'
);
append_identifier
(
thd
,
&
prefix
,
et
->
definer_host
.
str
,
et
->
definer_host
.
length
);
prefix
.
append
(
"]["
,
2
);
append_identifier
(
thd
,
&
prefix
,
et
->
dbname
.
str
,
et
->
dbname
.
length
);
prefix
.
append
(
'.'
);
append_identifier
(
thd
,
&
prefix
,
et
->
name
.
str
,
et
->
name
.
length
);
prefix
.
append
(
"] "
,
2
);
}
err_msg
.
append
(
prefix
);
err_msg
.
append
(
'['
);
err_msg
.
append
(
warning_level_names
[
err
->
level
].
str
,
warning_level_names
[
err
->
level
].
length
,
system_charset_info
);
err_msg
.
append
(
"] ["
);
err_msg
.
append
(
err
->
msg
,
strlen
(
err
->
msg
),
system_charset_info
);
err_msg
.
append
(
"]"
);
DBUG_ASSERT
(
err
->
level
<
3
);
(
sql_print_xxx_handlers
[
err
->
level
])(
"%*s"
,
err_msg
.
length
(),
err_msg
.
c_ptr
());
// sql_print_information("%*s", err_msg.length(), err_msg.c_ptr());
}
DBUG_RETURN
(
FALSE
);
}
sql/event_timed.cc
View file @
bb3ac3e3
...
...
@@ -982,12 +982,13 @@ event_timed::get_show_create_event(THD *thd, uint32 *length)
Executes the event (the underlying sp_head object);
SYNOPSIS
eve
x_fill_row
()
eve
nt_timed::execute
()
thd THD
mem_root If != NULL use it to compile the event on it
Returns
0 - success
-99 - No access to the database.
-100 - event in execution (parallel execution is impossible)
others - retcodes of sp_head::execute_procedure()
...
...
@@ -996,10 +997,12 @@ event_timed::get_show_create_event(THD *thd, uint32 *length)
int
event_timed
::
execute
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
List
<
Item
>
empty_item_list
;
Security_context
*
save_ctx
;
int
ret
=
0
;
DBUG_ENTER
(
"event_timed::execute"
);
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTING event %s.%s [EXPR:%d]"
,
dbname
.
str
,
name
.
str
,
(
int
)
expression
));
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
if
(
running
)
...
...
@@ -1011,12 +1014,35 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
VOID
(
pthread_mutex_unlock
(
&
this
->
LOCK_running
));
// TODO Andrey : make this as member variable and delete in destructor
empty_item_list
.
empty
();
if
(
!
sphead
&&
(
ret
=
compile
(
thd
,
mem_root
)))
goto
done
;
ret
=
sphead
->
execute_procedure
(
thd
,
&
empty_item_list
);
thd
->
db
=
dbname
.
str
;
thd
->
db_length
=
dbname
.
length
;
DBUG_PRINT
(
"info"
,
(
"master_access=%d db_access=%d"
,
thd
->
security_ctx
->
master_access
,
thd
->
security_ctx
->
db_access
));
change_security_context
(
thd
,
&
save_ctx
);
DBUG_PRINT
(
"info"
,
(
"master_access=%d db_access=%d"
,
thd
->
security_ctx
->
master_access
,
thd
->
security_ctx
->
db_access
));
// if (mysql_change_db(thd, dbname.str, 0))
if
(
!
check_access
(
thd
,
EVENT_ACL
,
dbname
.
str
,
0
,
0
,
0
,
is_schema_db
(
dbname
.
str
)))
{
List
<
Item
>
empty_item_list
;
empty_item_list
.
empty
();
ret
=
sphead
->
execute_procedure
(
thd
,
&
empty_item_list
);
}
else
{
DBUG_PRINT
(
"error"
,
(
"%s@%s has no rights on %s"
,
definer_user
.
str
,
definer_host
.
str
,
dbname
.
str
));
ret
=
-
99
;
}
restore_security_context
(
thd
,
save_ctx
);
DBUG_PRINT
(
"info"
,
(
"master_access=%d db_access=%d"
,
thd
->
security_ctx
->
master_access
,
thd
->
security_ctx
->
db_access
));
thd
->
db
=
0
;
VOID
(
pthread_mutex_lock
(
&
this
->
LOCK_running
));
running
=
false
;
...
...
@@ -1029,11 +1055,61 @@ done:
delete
sphead
;
sphead
=
0
;
}
DBUG_PRINT
(
"info"
,
(
" EVEX EXECUTED event %s.%s [EXPR:%d]. RetCode=%d"
,
dbname
.
str
,
name
.
str
,
(
int
)
expression
,
ret
));
DBUG_RETURN
(
ret
);
}
/*
Switches the security context
Synopsis
event_timed::change_security_context()
thd - thread
backup - where to store the old context
RETURN
0 - OK
1 - Error (generates error too)
*/
bool
event_timed
::
change_security_context
(
THD
*
thd
,
Security_context
**
backup
)
{
DBUG_ENTER
(
"event_timed::change_security_context"
);
DBUG_PRINT
(
"info"
,(
"%s@%s@%s"
,
definer_user
.
str
,
definer_host
.
str
,
dbname
.
str
));
*
backup
=
0
;
if
(
acl_getroot_no_password
(
&
sphead
->
m_security_ctx
,
definer_user
.
str
,
definer_host
.
str
,
definer_host
.
str
,
dbname
.
str
))
{
my_error
(
ER_NO_SUCH_USER
,
MYF
(
0
),
definer_user
.
str
,
definer_host
.
str
);
DBUG_RETURN
(
TRUE
);
}
*
backup
=
thd
->
security_ctx
;
thd
->
security_ctx
=
&
sphead
->
m_security_ctx
;
DBUG_RETURN
(
FALSE
);
}
/*
Restores the security context
Synopsis
event_timed::restore_security_context()
thd - thread
backup - switch to this context
*/
void
event_timed
::
restore_security_context
(
THD
*
thd
,
Security_context
*
backup
)
{
DBUG_ENTER
(
"event_timed::change_security_context"
);
if
(
backup
)
thd
->
security_ctx
=
backup
;
DBUG_VOID_RETURN
;
}
/*
Returns
0 - Success
...
...
sql/sql_error.cc
View file @
bb3ac3e3
...
...
@@ -211,8 +211,13 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
TRUE Error sending data to client
*/
static
const
char
*
warning_level_names
[]
=
{
"Note"
,
"Warning"
,
"Error"
,
"?"
};
static
int
warning_level_length
[]
=
{
4
,
7
,
5
,
1
};
LEX_STRING
warning_level_names
[]
=
{
{(
char
*
)
STRING_WITH_LEN
(
"Note"
)},
{(
char
*
)
STRING_WITH_LEN
(
"Warning"
)},
{(
char
*
)
STRING_WITH_LEN
(
"Error"
)},
{(
char
*
)
STRING_WITH_LEN
(
"?"
)}
};
bool
mysqld_show_warnings
(
THD
*
thd
,
ulong
levels_to_show
)
{
...
...
@@ -246,8 +251,8 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
if
(
idx
>
unit
->
select_limit_cnt
)
break
;
protocol
->
prepare_for_resend
();
protocol
->
store
(
warning_level_names
[
err
->
level
],
warning_level_
length
[
err
->
level
]
,
system_charset_info
);
protocol
->
store
(
warning_level_names
[
err
->
level
]
.
str
,
warning_level_
names
[
err
->
level
].
length
,
system_charset_info
);
protocol
->
store
((
uint32
)
err
->
code
);
protocol
->
store
(
err
->
msg
,
strlen
(
err
->
msg
),
system_charset_info
);
if
(
protocol
->
write
())
...
...
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