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
4ef964e3
Commit
4ef964e3
authored
Jun 17, 2005
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1
into rurik.mysql.com:/home/igor/mysql-4.1
parents
8ed67aa6
f21a807d
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
101 additions
and
48 deletions
+101
-48
mysql-test/r/ps_grant.result
mysql-test/r/ps_grant.result
+1
-1
sql/mysql_priv.h
sql/mysql_priv.h
+4
-2
sql/mysqld.cc
sql/mysqld.cc
+23
-3
sql/sql_class.h
sql/sql_class.h
+1
-1
sql/sql_parse.cc
sql/sql_parse.cc
+23
-19
sql/sql_prepare.cc
sql/sql_prepare.cc
+49
-22
No files found.
mysql-test/r/ps_grant.result
View file @
4ef964e3
...
@@ -78,4 +78,4 @@ drop database mysqltest;
...
@@ -78,4 +78,4 @@ drop database mysqltest;
prepare stmt4 from ' show full processlist ';
prepare stmt4 from ' show full processlist ';
execute stmt4;
execute stmt4;
Id User Host db Command Time State Info
Id User Host db Command Time State Info
number root localhost test
Query
time NULL show full processlist
number root localhost test
Execute
time NULL show full processlist
sql/mysql_priv.h
View file @
4ef964e3
...
@@ -424,8 +424,6 @@ struct Query_cache_query_flags
...
@@ -424,8 +424,6 @@ struct Query_cache_query_flags
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
#endif
/*HAVE_QUERY_CACHE*/
#endif
/*HAVE_QUERY_CACHE*/
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
int
mysql_create_db
(
THD
*
thd
,
char
*
db
,
HA_CREATE_INFO
*
create
,
bool
silent
);
int
mysql_create_db
(
THD
*
thd
,
char
*
db
,
HA_CREATE_INFO
*
create
,
bool
silent
);
int
mysql_alter_db
(
THD
*
thd
,
const
char
*
db
,
HA_CREATE_INFO
*
create
);
int
mysql_alter_db
(
THD
*
thd
,
const
char
*
db
,
HA_CREATE_INFO
*
create
);
int
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
,
bool
silent
);
int
mysql_rm_db
(
THD
*
thd
,
char
*
db
,
bool
if_exists
,
bool
silent
);
...
@@ -462,6 +460,7 @@ void mysql_execute_command(THD *thd);
...
@@ -462,6 +460,7 @@ void mysql_execute_command(THD *thd);
bool
do_command
(
THD
*
thd
);
bool
do_command
(
THD
*
thd
);
bool
dispatch_command
(
enum
enum_server_command
command
,
THD
*
thd
,
bool
dispatch_command
(
enum
enum_server_command
command
,
THD
*
thd
,
char
*
packet
,
uint
packet_length
);
char
*
packet
,
uint
packet_length
);
void
log_slow_statement
(
THD
*
thd
);
bool
check_dup
(
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
bool
check_dup
(
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
bool
table_cache_init
(
void
);
bool
table_cache_init
(
void
);
...
@@ -899,6 +898,8 @@ extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
...
@@ -899,6 +898,8 @@ extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern
ulong
max_binlog_size
,
max_relay_log_size
;
extern
ulong
max_binlog_size
,
max_relay_log_size
;
extern
ulong
rpl_recovery_rank
,
thread_cache_size
;
extern
ulong
rpl_recovery_rank
,
thread_cache_size
;
extern
ulong
com_stat
[(
uint
)
SQLCOM_END
],
com_other
,
back_log
;
extern
ulong
com_stat
[(
uint
)
SQLCOM_END
],
com_other
,
back_log
;
extern
ulong
com_stmt_prepare
,
com_stmt_execute
,
com_stmt_send_long_data
;
extern
ulong
com_stmt_reset
,
com_stmt_close
;
extern
ulong
specialflag
,
current_pid
;
extern
ulong
specialflag
,
current_pid
;
extern
ulong
expire_logs_days
,
sync_binlog_period
,
sync_binlog_counter
;
extern
ulong
expire_logs_days
,
sync_binlog_period
,
sync_binlog_counter
;
extern
my_bool
relay_log_purge
,
opt_innodb_safe_binlog
;
extern
my_bool
relay_log_purge
,
opt_innodb_safe_binlog
;
...
@@ -918,6 +919,7 @@ extern my_bool opt_slave_compressed_protocol, use_temp_pool;
...
@@ -918,6 +919,7 @@ extern my_bool opt_slave_compressed_protocol, use_temp_pool;
extern
my_bool
opt_readonly
,
lower_case_file_system
;
extern
my_bool
opt_readonly
,
lower_case_file_system
;
extern
my_bool
opt_enable_named_pipe
,
opt_sync_frm
,
opt_allow_suspicious_udfs
;
extern
my_bool
opt_enable_named_pipe
,
opt_sync_frm
,
opt_allow_suspicious_udfs
;
extern
my_bool
opt_secure_auth
;
extern
my_bool
opt_secure_auth
;
extern
my_bool
opt_log_slow_admin_statements
;
extern
uint
opt_crash_binlog_innodb
;
extern
uint
opt_crash_binlog_innodb
;
extern
char
*
shared_memory_base_name
,
*
mysqld_unix_port
;
extern
char
*
shared_memory_base_name
,
*
mysqld_unix_port
;
extern
bool
opt_enable_shared_memory
;
extern
bool
opt_enable_shared_memory
;
...
...
sql/mysqld.cc
View file @
4ef964e3
...
@@ -294,6 +294,7 @@ my_bool opt_sync_bdb_logs, opt_sync_frm, opt_allow_suspicious_udfs;
...
@@ -294,6 +294,7 @@ my_bool opt_sync_bdb_logs, opt_sync_frm, opt_allow_suspicious_udfs;
my_bool
opt_secure_auth
=
0
;
my_bool
opt_secure_auth
=
0
;
my_bool
opt_short_log_format
=
0
;
my_bool
opt_short_log_format
=
0
;
my_bool
opt_log_queries_not_using_indexes
=
0
;
my_bool
opt_log_queries_not_using_indexes
=
0
;
my_bool
opt_log_slow_admin_statements
=
0
;
my_bool
lower_case_file_system
=
0
;
my_bool
lower_case_file_system
=
0
;
my_bool
opt_innodb_safe_binlog
=
0
;
my_bool
opt_innodb_safe_binlog
=
0
;
volatile
bool
mqh_used
=
0
;
volatile
bool
mqh_used
=
0
;
...
@@ -315,6 +316,8 @@ ulong slave_net_timeout, slave_trans_retries;
...
@@ -315,6 +316,8 @@ ulong slave_net_timeout, slave_trans_retries;
ulong
thread_cache_size
=
0
,
binlog_cache_size
=
0
,
max_binlog_cache_size
=
0
;
ulong
thread_cache_size
=
0
,
binlog_cache_size
=
0
,
max_binlog_cache_size
=
0
;
ulong
query_cache_size
=
0
;
ulong
query_cache_size
=
0
;
ulong
com_stat
[(
uint
)
SQLCOM_END
],
com_other
;
ulong
com_stat
[(
uint
)
SQLCOM_END
],
com_other
;
ulong
com_stmt_prepare
,
com_stmt_execute
,
com_stmt_send_long_data
;
ulong
com_stmt_close
,
com_stmt_reset
;
ulong
bytes_sent
,
bytes_received
,
net_big_packet_count
;
ulong
bytes_sent
,
bytes_received
,
net_big_packet_count
;
ulong
refresh_version
,
flush_version
;
/* Increments on each reload */
ulong
refresh_version
,
flush_version
;
/* Increments on each reload */
ulong
query_id
,
long_query_count
;
ulong
query_id
,
long_query_count
;
...
@@ -4196,7 +4199,8 @@ enum options_mysqld
...
@@ -4196,7 +4199,8 @@ enum options_mysqld
OPT_TIME_FORMAT
,
OPT_TIME_FORMAT
,
OPT_DATETIME_FORMAT
,
OPT_DATETIME_FORMAT
,
OPT_LOG_QUERIES_NOT_USING_INDEXES
,
OPT_LOG_QUERIES_NOT_USING_INDEXES
,
OPT_DEFAULT_TIME_ZONE
OPT_DEFAULT_TIME_ZONE
,
OPT_LOG_SLOW_ADMIN_STATEMENTS
};
};
...
@@ -4456,7 +4460,7 @@ Disable with --skip-isam.",
...
@@ -4456,7 +4460,7 @@ Disable with --skip-isam.",
"Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option."
,
"Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option."
,
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"log-queries-not-using-indexes"
,
OPT_LOG_QUERIES_NOT_USING_INDEXES
,
{
"log-queries-not-using-indexes"
,
OPT_LOG_QUERIES_NOT_USING_INDEXES
,
"Log queries that are executed without benefit of any index."
,
"Log queries that are executed without benefit of any index
to the slow log if it is open
."
,
(
gptr
*
)
&
opt_log_queries_not_using_indexes
,
(
gptr
*
)
&
opt_log_queries_not_using_indexes
,
(
gptr
*
)
&
opt_log_queries_not_using_indexes
,
(
gptr
*
)
&
opt_log_queries_not_using_indexes
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"log-short-format"
,
OPT_SHORT_LOG_FORMAT
,
{
"log-short-format"
,
OPT_SHORT_LOG_FORMAT
,
...
@@ -4467,8 +4471,13 @@ Disable with --skip-isam.",
...
@@ -4467,8 +4471,13 @@ Disable with --skip-isam.",
"Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves."
,
"Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves."
,
(
gptr
*
)
&
opt_log_slave_updates
,
(
gptr
*
)
&
opt_log_slave_updates
,
0
,
GET_BOOL
,
(
gptr
*
)
&
opt_log_slave_updates
,
(
gptr
*
)
&
opt_log_slave_updates
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"log-slow-admin-statements"
,
OPT_LOG_SLOW_ADMIN_STATEMENTS
,
"Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open."
,
(
gptr
*
)
&
opt_log_slow_admin_statements
,
(
gptr
*
)
&
opt_log_slow_admin_statements
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"log-slow-queries"
,
OPT_SLOW_QUERY_LOG
,
{
"log-slow-queries"
,
OPT_SLOW_QUERY_LOG
,
"Log slow queries to this log file. Defaults logging to hostname-slow.log file
."
,
"Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options
."
,
(
gptr
*
)
&
opt_slow_logname
,
(
gptr
*
)
&
opt_slow_logname
,
0
,
GET_STR
,
OPT_ARG
,
(
gptr
*
)
&
opt_slow_logname
,
(
gptr
*
)
&
opt_slow_logname
,
0
,
GET_STR
,
OPT_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
0
,
0
,
0
,
0
,
0
,
0
},
{
"log-update"
,
OPT_UPDATE_LOG
,
{
"log-update"
,
OPT_UPDATE_LOG
,
...
@@ -5467,6 +5476,11 @@ struct show_var_st status_vars[]= {
...
@@ -5467,6 +5476,11 @@ struct show_var_st status_vars[]= {
{
"Com_show_warnings"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SHOW_WARNS
),
SHOW_LONG
},
{
"Com_show_warnings"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SHOW_WARNS
),
SHOW_LONG
},
{
"Com_slave_start"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SLAVE_START
),
SHOW_LONG
},
{
"Com_slave_start"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SLAVE_START
),
SHOW_LONG
},
{
"Com_slave_stop"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SLAVE_STOP
),
SHOW_LONG
},
{
"Com_slave_stop"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_SLAVE_STOP
),
SHOW_LONG
},
{
"Com_stmt_prepare"
,
(
char
*
)
&
com_stmt_prepare
,
SHOW_LONG
},
{
"Com_stmt_execute"
,
(
char
*
)
&
com_stmt_execute
,
SHOW_LONG
},
{
"Com_stmt_send_long_data"
,
(
char
*
)
&
com_stmt_send_long_data
,
SHOW_LONG
},
{
"Com_stmt_reset"
,
(
char
*
)
&
com_stmt_reset
,
SHOW_LONG
},
{
"Com_stmt_close"
,
(
char
*
)
&
com_stmt_close
,
SHOW_LONG
},
{
"Com_truncate"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_TRUNCATE
),
SHOW_LONG
},
{
"Com_truncate"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_TRUNCATE
),
SHOW_LONG
},
{
"Com_unlock_tables"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_UNLOCK_TABLES
),
SHOW_LONG
},
{
"Com_unlock_tables"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_UNLOCK_TABLES
),
SHOW_LONG
},
{
"Com_update"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_UPDATE
),
SHOW_LONG
},
{
"Com_update"
,
(
char
*
)
(
com_stat
+
(
uint
)
SQLCOM_UPDATE
),
SHOW_LONG
},
...
@@ -6084,6 +6098,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
...
@@ -6084,6 +6098,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case
(
int
)
OPT_SLOW_QUERY_LOG
:
case
(
int
)
OPT_SLOW_QUERY_LOG
:
opt_slow_log
=
1
;
opt_slow_log
=
1
;
break
;
break
;
case
(
int
)
OPT_LOG_SLOW_ADMIN_STATEMENTS
:
opt_log_slow_admin_statements
=
1
;
break
;
case
(
int
)
OPT_SKIP_NEW
:
case
(
int
)
OPT_SKIP_NEW
:
opt_specialflag
|=
SPECIAL_NO_NEW_FUNC
;
opt_specialflag
|=
SPECIAL_NO_NEW_FUNC
;
delay_key_write_options
=
(
uint
)
DELAY_KEY_WRITE_NONE
;
delay_key_write_options
=
(
uint
)
DELAY_KEY_WRITE_NONE
;
...
@@ -6443,6 +6460,9 @@ static void get_options(int argc,char **argv)
...
@@ -6443,6 +6460,9 @@ static void get_options(int argc,char **argv)
if
(
opt_bdb
)
if
(
opt_bdb
)
sql_print_warning
(
"this binary does not contain BDB storage engine"
);
sql_print_warning
(
"this binary does not contain BDB storage engine"
);
#endif
#endif
if
((
opt_log_slow_admin_statements
||
opt_log_queries_not_using_indexes
)
&&
!
opt_slow_log
)
sql_print_warning
(
"options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set"
);
/*
/*
Check that the default storage engine is actually available.
Check that the default storage engine is actually available.
...
...
sql/sql_class.h
View file @
4ef964e3
...
@@ -916,7 +916,7 @@ class THD :public ilink,
...
@@ -916,7 +916,7 @@ class THD :public ilink,
bool
query_error
,
bootstrap
,
cleanup_done
;
bool
query_error
,
bootstrap
,
cleanup_done
;
bool
tmp_table_used
;
bool
tmp_table_used
;
bool
charset_is_system_charset
,
charset_is_collation_connection
;
bool
charset_is_system_charset
,
charset_is_collation_connection
;
bool
slow_command
;
bool
enable_slow_log
;
/* enable slow log for current statement */
my_bool
volatile
killed
;
my_bool
volatile
killed
;
/*
/*
...
...
sql/sql_parse.cc
View file @
4ef964e3
...
@@ -59,7 +59,6 @@ static void remove_escape(char *name);
...
@@ -59,7 +59,6 @@ static void remove_escape(char *name);
static
void
refresh_status
(
void
);
static
void
refresh_status
(
void
);
static
bool
append_file_to_dir
(
THD
*
thd
,
const
char
**
filename_ptr
,
static
bool
append_file_to_dir
(
THD
*
thd
,
const
char
**
filename_ptr
,
const
char
*
table_name
);
const
char
*
table_name
);
static
void
log_slow_query
(
THD
*
thd
);
const
char
*
any_db
=
"*any*"
;
// Special symbol for check_access
const
char
*
any_db
=
"*any*"
;
// Special symbol for check_access
...
@@ -1342,10 +1341,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1342,10 +1341,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd
->
command
=
command
;
thd
->
command
=
command
;
/*
/*
Commands which
will always take a long time should be marked with
Commands which
always take a long time are logged into
th
is so that they will not get logged to the slow query log
th
e slow log only if opt_log_slow_admin_statements is set.
*/
*/
thd
->
slow_command
=
FALS
E
;
thd
->
enable_slow_log
=
TRU
E
;
thd
->
set_time
();
thd
->
set_time
();
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
thd
->
query_id
=
query_id
;
thd
->
query_id
=
query_id
;
...
@@ -1383,7 +1382,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1383,7 +1382,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint
tbl_len
=
*
(
uchar
*
)
(
packet
+
db_len
+
1
);
uint
tbl_len
=
*
(
uchar
*
)
(
packet
+
db_len
+
1
);
statistic_increment
(
com_other
,
&
LOCK_status
);
statistic_increment
(
com_other
,
&
LOCK_status
);
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
db
=
thd
->
alloc
(
db_len
+
tbl_len
+
2
);
db
=
thd
->
alloc
(
db_len
+
tbl_len
+
2
);
tbl_name
=
strmake
(
db
,
packet
+
1
,
db_len
)
+
1
;
tbl_name
=
strmake
(
db
,
packet
+
1
,
db_len
)
+
1
;
strmake
(
tbl_name
,
packet
+
db_len
+
2
,
tbl_len
);
strmake
(
tbl_name
,
packet
+
db_len
+
2
,
tbl_len
);
...
@@ -1515,7 +1514,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1515,7 +1514,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
#endif
ulong
length
=
(
ulong
)(
packet_end
-
packet
);
ulong
length
=
(
ulong
)(
packet_end
-
packet
);
log_slow_
query
(
thd
);
log_slow_
statement
(
thd
);
/* Remove garbage at start of query */
/* Remove garbage at start of query */
while
(
my_isspace
(
thd
->
charset
(),
*
packet
)
&&
length
>
0
)
while
(
my_isspace
(
thd
->
charset
(),
*
packet
)
&&
length
>
0
)
...
@@ -1658,7 +1657,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1658,7 +1657,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint32
slave_server_id
;
uint32
slave_server_id
;
statistic_increment
(
com_other
,
&
LOCK_status
);
statistic_increment
(
com_other
,
&
LOCK_status
);
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
if
(
check_global_access
(
thd
,
REPL_SLAVE_ACL
))
if
(
check_global_access
(
thd
,
REPL_SLAVE_ACL
))
break
;
break
;
...
@@ -1827,7 +1826,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1827,7 +1826,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if
(
thd
->
is_fatal_error
)
if
(
thd
->
is_fatal_error
)
send_error
(
thd
,
0
);
// End of memory ?
send_error
(
thd
,
0
);
// End of memory ?
log_slow_
query
(
thd
);
log_slow_
statement
(
thd
);
thd
->
proc_info
=
"cleaning up"
;
thd
->
proc_info
=
"cleaning up"
;
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
// For process list
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
// For process list
...
@@ -1843,13 +1842,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
...
@@ -1843,13 +1842,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
}
static
void
log_slow_query
(
THD
*
thd
)
void
log_slow_statement
(
THD
*
thd
)
{
{
time_t
start_of_query
=
thd
->
start_time
;
time_t
start_of_query
=
thd
->
start_time
;
thd
->
end_time
();
// Set start time
thd
->
end_time
();
// Set start time
/* If not reading from backup and if the query took too long */
/*
if
(
!
thd
->
slow_command
&&
!
thd
->
user_time
)
// do not log 'slow_command' queries
Do not log administrative statements unless the appropriate option is
set; do not log into slow log if reading from backup.
*/
if
(
thd
->
enable_slow_log
&&
!
thd
->
user_time
)
{
{
thd
->
proc_info
=
"logging slow query"
;
thd
->
proc_info
=
"logging slow query"
;
...
@@ -2190,6 +2192,8 @@ mysql_execute_command(THD *thd)
...
@@ -2190,6 +2192,8 @@ mysql_execute_command(THD *thd)
DBUG_PRINT
(
"info"
,
(
"DEALLOCATE PREPARE: %.*s
\n
"
,
DBUG_PRINT
(
"info"
,
(
"DEALLOCATE PREPARE: %.*s
\n
"
,
lex
->
prepared_stmt_name
.
length
,
lex
->
prepared_stmt_name
.
length
,
lex
->
prepared_stmt_name
.
str
));
lex
->
prepared_stmt_name
.
str
));
/* We account deallocate in the same manner as mysql_stmt_close */
statistic_increment
(
com_stmt_close
,
&
LOCK_status
);
if
((
stmt
=
thd
->
stmt_map
.
find_by_name
(
&
lex
->
prepared_stmt_name
)))
if
((
stmt
=
thd
->
stmt_map
.
find_by_name
(
&
lex
->
prepared_stmt_name
)))
{
{
thd
->
stmt_map
.
erase
(
stmt
);
thd
->
stmt_map
.
erase
(
stmt
);
...
@@ -2292,7 +2296,7 @@ mysql_execute_command(THD *thd)
...
@@ -2292,7 +2296,7 @@ mysql_execute_command(THD *thd)
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)
||
check_table_access
(
thd
,
SELECT_ACL
,
tables
,
0
)
||
check_global_access
(
thd
,
FILE_ACL
))
check_global_access
(
thd
,
FILE_ACL
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_backup_table
(
thd
,
tables
);
res
=
mysql_backup_table
(
thd
,
tables
);
break
;
break
;
...
@@ -2303,7 +2307,7 @@ mysql_execute_command(THD *thd)
...
@@ -2303,7 +2307,7 @@ mysql_execute_command(THD *thd)
check_table_access
(
thd
,
INSERT_ACL
,
tables
,
0
)
||
check_table_access
(
thd
,
INSERT_ACL
,
tables
,
0
)
||
check_global_access
(
thd
,
FILE_ACL
))
check_global_access
(
thd
,
FILE_ACL
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_restore_table
(
thd
,
tables
);
res
=
mysql_restore_table
(
thd
,
tables
);
break
;
break
;
}
}
...
@@ -2538,7 +2542,7 @@ mysql_execute_command(THD *thd)
...
@@ -2538,7 +2542,7 @@ mysql_execute_command(THD *thd)
case
SQLCOM_CREATE_INDEX
:
case
SQLCOM_CREATE_INDEX
:
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
))
if
(
check_one_table_access
(
thd
,
INDEX_ACL
,
tables
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
if
(
end_active_trans
(
thd
))
if
(
end_active_trans
(
thd
))
res
=
-
1
;
res
=
-
1
;
else
else
...
@@ -2624,7 +2628,7 @@ mysql_execute_command(THD *thd)
...
@@ -2624,7 +2628,7 @@ mysql_execute_command(THD *thd)
res
=
-
1
;
res
=
-
1
;
else
else
{
{
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_alter_table
(
thd
,
select_lex
->
db
,
lex
->
name
,
res
=
mysql_alter_table
(
thd
,
select_lex
->
db
,
lex
->
name
,
&
lex
->
create_info
,
&
lex
->
create_info
,
tables
,
lex
->
create_list
,
tables
,
lex
->
create_list
,
...
@@ -2716,7 +2720,7 @@ mysql_execute_command(THD *thd)
...
@@ -2716,7 +2720,7 @@ mysql_execute_command(THD *thd)
if
(
check_db_used
(
thd
,
tables
)
||
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_repair_table
(
thd
,
tables
,
&
lex
->
check_opt
);
res
=
mysql_repair_table
(
thd
,
tables
,
&
lex
->
check_opt
);
/* ! we write after unlocking the table */
/* ! we write after unlocking the table */
if
(
!
res
&&
!
lex
->
no_write_to_binlog
)
if
(
!
res
&&
!
lex
->
no_write_to_binlog
)
...
@@ -2736,7 +2740,7 @@ mysql_execute_command(THD *thd)
...
@@ -2736,7 +2740,7 @@ mysql_execute_command(THD *thd)
if
(
check_db_used
(
thd
,
tables
)
||
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
tables
,
0
))
check_table_access
(
thd
,
SELECT_ACL
|
EXTRA_ACL
,
tables
,
0
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_check_table
(
thd
,
tables
,
&
lex
->
check_opt
);
res
=
mysql_check_table
(
thd
,
tables
,
&
lex
->
check_opt
);
break
;
break
;
}
}
...
@@ -2745,7 +2749,7 @@ mysql_execute_command(THD *thd)
...
@@ -2745,7 +2749,7 @@ mysql_execute_command(THD *thd)
if
(
check_db_used
(
thd
,
tables
)
||
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
mysql_analyze_table
(
thd
,
tables
,
&
lex
->
check_opt
);
res
=
mysql_analyze_table
(
thd
,
tables
,
&
lex
->
check_opt
);
/* ! we write after unlocking the table */
/* ! we write after unlocking the table */
if
(
!
res
&&
!
lex
->
no_write_to_binlog
)
if
(
!
res
&&
!
lex
->
no_write_to_binlog
)
...
@@ -2766,7 +2770,7 @@ mysql_execute_command(THD *thd)
...
@@ -2766,7 +2770,7 @@ mysql_execute_command(THD *thd)
if
(
check_db_used
(
thd
,
tables
)
||
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
check_table_access
(
thd
,
SELECT_ACL
|
INSERT_ACL
,
tables
,
0
))
goto
error
;
/* purecov: inspected */
goto
error
;
/* purecov: inspected */
thd
->
slow_command
=
TRUE
;
thd
->
enable_slow_log
=
opt_log_slow_admin_statements
;
res
=
(
specialflag
&
(
SPECIAL_SAFE_MODE
|
SPECIAL_NO_NEW_FUNC
))
?
res
=
(
specialflag
&
(
SPECIAL_SAFE_MODE
|
SPECIAL_NO_NEW_FUNC
))
?
mysql_recreate_table
(
thd
,
tables
,
1
)
:
mysql_recreate_table
(
thd
,
tables
,
1
)
:
mysql_optimize_table
(
thd
,
tables
,
&
lex
->
check_opt
);
mysql_optimize_table
(
thd
,
tables
,
&
lex
->
check_opt
);
...
...
sql/sql_prepare.cc
View file @
4ef964e3
...
@@ -820,7 +820,8 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
...
@@ -820,7 +820,8 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
DBUG_ENTER
(
"insert_params_from_vars"
);
DBUG_ENTER
(
"insert_params_from_vars"
);
List_iterator
<
LEX_STRING
>
var_it
(
varnames
);
List_iterator
<
LEX_STRING
>
var_it
(
varnames
);
String
str
;
String
buf
;
const
String
*
val
;
uint32
length
=
0
;
uint32
length
=
0
;
if
(
query
->
copy
(
stmt
->
query
,
stmt
->
query_length
,
default_charset_info
))
if
(
query
->
copy
(
stmt
->
query
,
stmt
->
query_length
,
default_charset_info
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -831,32 +832,35 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
...
@@ -831,32 +832,35 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
varname
=
var_it
++
;
varname
=
var_it
++
;
if
(
get_var_with_binlog
(
stmt
->
thd
,
*
varname
,
&
entry
))
if
(
get_var_with_binlog
(
stmt
->
thd
,
*
varname
,
&
entry
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
DBUG_ASSERT
(
entry
);
if
(
param
->
set_from_user_var
(
stmt
->
thd
,
entry
))
if
(
param
->
set_from_user_var
(
stmt
->
thd
,
entry
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
/* Insert @'escaped-varname' instead of parameter in the query */
/* Insert @'escaped-varname' instead of parameter in the query */
char
*
buf
,
*
ptr
;
if
(
entry
)
str
.
length
(
0
);
{
if
(
str
.
reserve
(
entry
->
name
.
length
*
2
+
3
))
char
*
begin
,
*
ptr
;
buf
.
length
(
0
);
if
(
buf
.
reserve
(
entry
->
name
.
length
*
2
+
3
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
buf
=
str
.
c_ptr_quick
();
begin
=
ptr
=
buf
.
c_ptr_quick
();
ptr
=
buf
;
*
ptr
++=
'@'
;
*
ptr
++=
'@'
;
*
ptr
++=
'\''
;
*
ptr
++=
'\''
;
ptr
+=
ptr
+=
escape_string_for_mysql
(
&
my_charset_utf8_general_ci
,
escape_string_for_mysql
(
&
my_charset_utf8_general_ci
,
ptr
,
entry
->
name
.
str
,
entry
->
name
.
length
);
ptr
,
entry
->
name
.
str
,
entry
->
name
.
length
);
*
ptr
++=
'\''
;
*
ptr
++=
'\''
;
str
.
length
(
ptr
-
buf
);
buf
.
length
(
ptr
-
begin
);
val
=
&
buf
;
}
else
val
=
&
my_null_string
;
if
(
param
->
convert_str_value
(
stmt
->
thd
))
if
(
param
->
convert_str_value
(
stmt
->
thd
))
DBUG_RETURN
(
1
);
/* out of memory */
DBUG_RETURN
(
1
);
/* out of memory */
if
(
query
->
replace
(
param
->
pos_in_query
+
length
,
1
,
str
))
if
(
query
->
replace
(
param
->
pos_in_query
+
length
,
1
,
*
val
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
length
+=
str
.
length
()
-
1
;
length
+=
val
->
length
()
-
1
;
}
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -1558,6 +1562,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
...
@@ -1558,6 +1562,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_PRINT
(
"prep_query"
,
(
"%s"
,
packet
));
DBUG_PRINT
(
"prep_query"
,
(
"%s"
,
packet
));
/*
If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
However, it seems handy if com_stmt_prepare is increased always,
no matter what kind of prepare is processed.
*/
statistic_increment
(
com_stmt_prepare
,
&
LOCK_status
);
if
(
stmt
==
0
)
if
(
stmt
==
0
)
{
{
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
send_error
(
thd
,
ER_OUT_OF_RESOURCES
);
...
@@ -1596,7 +1607,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
...
@@ -1596,7 +1607,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
mysql_log
.
write
(
thd
,
COM_PREPARE
,
"[%lu] %s"
,
stmt
->
id
,
packet
);
mysql_log
.
write
(
thd
,
thd
->
command
,
"[%lu] %s"
,
stmt
->
id
,
packet
);
thd
->
current_arena
=
stmt
;
thd
->
current_arena
=
stmt
;
mysql_init_query
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
mysql_init_query
(
thd
,
(
uchar
*
)
thd
->
query
,
thd
->
query_length
);
...
@@ -1763,6 +1774,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1763,6 +1774,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
packet
+=
9
;
/* stmt_id + 5 bytes of flags */
packet
+=
9
;
/* stmt_id + 5 bytes of flags */
statistic_increment
(
com_stmt_execute
,
&
LOCK_status
);
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_execute"
,
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_execute"
,
SEND_ERROR
)))
SEND_ERROR
)))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
@@ -1796,9 +1808,6 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
...
@@ -1796,9 +1808,6 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
if
(
stmt
->
param_count
&&
stmt
->
set_params_data
(
stmt
,
&
expanded_query
))
if
(
stmt
->
param_count
&&
stmt
->
set_params_data
(
stmt
,
&
expanded_query
))
goto
set_params_data_err
;
goto
set_params_data_err
;
#endif
#endif
mysql_log
.
write
(
thd
,
COM_EXECUTE
,
"[%lu] %s"
,
stmt
->
id
,
expanded_query
.
length
()
?
expanded_query
.
c_ptr
()
:
stmt
->
query
);
thd
->
protocol
=
&
thd
->
protocol_prep
;
// Switch to binary protocol
thd
->
protocol
=
&
thd
->
protocol_prep
;
// Switch to binary protocol
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
TRUE
);
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
TRUE
);
thd
->
protocol
=
&
thd
->
protocol_simple
;
// Use normal protocol
thd
->
protocol
=
&
thd
->
protocol_simple
;
// Use normal protocol
...
@@ -1827,6 +1836,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
...
@@ -1827,6 +1836,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
String
expanded_query
;
String
expanded_query
;
DBUG_ENTER
(
"mysql_sql_stmt_execute"
);
DBUG_ENTER
(
"mysql_sql_stmt_execute"
);
/* See comment for statistics_increment in mysql_stmt_prepare */
statistic_increment
(
com_stmt_execute
,
&
LOCK_status
);
if
(
!
(
stmt
=
(
Prepared_statement
*
)
thd
->
stmt_map
.
find_by_name
(
stmt_name
)))
if
(
!
(
stmt
=
(
Prepared_statement
*
)
thd
->
stmt_map
.
find_by_name
(
stmt_name
)))
{
{
my_error
(
ER_UNKNOWN_STMT_HANDLER
,
MYF
(
0
),
stmt_name
->
length
,
my_error
(
ER_UNKNOWN_STMT_HANDLER
,
MYF
(
0
),
stmt_name
->
length
,
...
@@ -1853,6 +1864,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
...
@@ -1853,6 +1864,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"EXECUTE"
);
my_error
(
ER_WRONG_ARGUMENTS
,
MYF
(
0
),
"EXECUTE"
);
send_error
(
thd
);
send_error
(
thd
);
}
}
thd
->
command
=
COM_EXECUTE
;
/* For nice messages in general log */
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
FALSE
);
execute_stmt
(
thd
,
stmt
,
&
expanded_query
,
FALSE
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1887,6 +1899,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
...
@@ -1887,6 +1899,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
my_error
(
ER_OUTOFMEMORY
,
0
,
expanded_query
->
length
());
my_error
(
ER_OUTOFMEMORY
,
0
,
expanded_query
->
length
());
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
mysql_log
.
write
(
thd
,
thd
->
command
,
"[%lu] %s"
,
stmt
->
id
,
thd
->
query
);
/*
/*
At first execution of prepared statement we will perform logical
At first execution of prepared statement we will perform logical
transformations of the query tree (i.e. negations elimination).
transformations of the query tree (i.e. negations elimination).
...
@@ -1900,6 +1913,14 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
...
@@ -1900,6 +1913,14 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
thd
->
lex
->
unit
.
cleanup
();
thd
->
lex
->
unit
.
cleanup
();
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
if
(
!
(
specialflag
&
SPECIAL_NO_PRIOR
))
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
my_pthread_setprio
(
pthread_self
(),
WAIT_PRIOR
);
/*
'start_time' is set in dispatch_command, but THD::query will
be freed when we return from this function. So let's log the slow
query here.
*/
log_slow_statement
(
thd
);
/* Prevent from second logging in the end of dispatch_command */
thd
->
enable_slow_log
=
FALSE
;
/* Free Items that were created during this execution of the PS. */
/* Free Items that were created during this execution of the PS. */
free_items
(
thd
->
free_list
);
free_items
(
thd
->
free_list
);
...
@@ -1941,6 +1962,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
...
@@ -1941,6 +1962,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
DBUG_ENTER
(
"mysql_stmt_reset"
);
DBUG_ENTER
(
"mysql_stmt_reset"
);
statistic_increment
(
com_stmt_reset
,
&
LOCK_status
);
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_reset"
,
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_reset"
,
SEND_ERROR
)))
SEND_ERROR
)))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
@@ -1973,6 +1995,7 @@ void mysql_stmt_free(THD *thd, char *packet)
...
@@ -1973,6 +1995,7 @@ void mysql_stmt_free(THD *thd, char *packet)
DBUG_ENTER
(
"mysql_stmt_free"
);
DBUG_ENTER
(
"mysql_stmt_free"
);
statistic_increment
(
com_stmt_close
,
&
LOCK_status
);
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_close"
,
if
(
!
(
stmt
=
find_prepared_statement
(
thd
,
stmt_id
,
"mysql_stmt_close"
,
DONT_SEND_ERROR
)))
DONT_SEND_ERROR
)))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
@@ -2012,6 +2035,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
...
@@ -2012,6 +2035,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
DBUG_ENTER
(
"mysql_stmt_get_longdata"
);
DBUG_ENTER
(
"mysql_stmt_get_longdata"
);
statistic_increment
(
com_stmt_send_long_data
,
&
LOCK_status
);
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
/* Minimal size of long data packet is 6 bytes */
if
((
ulong
)
(
packet_end
-
packet
)
<
MYSQL_LONG_DATA_HEADER
)
if
((
ulong
)
(
packet_end
-
packet
)
<
MYSQL_LONG_DATA_HEADER
)
...
@@ -2068,10 +2092,12 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
...
@@ -2068,10 +2092,12 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
*
last_error
=
'\0'
;
*
last_error
=
'\0'
;
}
}
void
Prepared_statement
::
setup_set_params
()
void
Prepared_statement
::
setup_set_params
()
{
{
/* Setup binary logging */
/* Setup binary logging */
if
(
mysql_bin_log
.
is_open
()
&&
is_update_query
(
lex
->
sql_command
))
if
(
mysql_bin_log
.
is_open
()
&&
is_update_query
(
lex
->
sql_command
)
||
mysql_log
.
is_open
()
||
mysql_slow_log
.
is_open
())
{
{
set_params_from_vars
=
insert_params_from_vars_with_log
;
set_params_from_vars
=
insert_params_from_vars_with_log
;
#ifndef EMBEDDED_LIBRARY
#ifndef EMBEDDED_LIBRARY
...
@@ -2091,6 +2117,7 @@ void Prepared_statement::setup_set_params()
...
@@ -2091,6 +2117,7 @@ void Prepared_statement::setup_set_params()
}
}
}
}
Prepared_statement
::~
Prepared_statement
()
Prepared_statement
::~
Prepared_statement
()
{
{
free_items
(
free_list
);
free_items
(
free_list
);
...
...
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