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
3f4ef592
Commit
3f4ef592
authored
May 18, 2012
by
Michael Widenius
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge
parents
32498ead
960f6600
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
185 additions
and
79 deletions
+185
-79
dbug/tests.c
dbug/tests.c
+2
-1
mysql-test/r/handlersocket.result
mysql-test/r/handlersocket.result
+6
-5
mysql-test/suite/innodb/t/innodb_bug60196.test
mysql-test/suite/innodb/t/innodb_bug60196.test
+2
-1
mysql-test/suite/maria/maria.result
mysql-test/suite/maria/maria.result
+5
-1
mysql-test/suite/maria/maria.test
mysql-test/suite/maria/maria.test
+4
-0
mysql-test/suite/maria/truncate.result
mysql-test/suite/maria/truncate.result
+37
-0
mysql-test/suite/maria/truncate.test
mysql-test/suite/maria/truncate.test
+47
-0
mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
+1
-1
mysql-test/t/handlersocket.test
mysql-test/t/handlersocket.test
+1
-1
plugin/handler_socket/handlersocket/handlersocket.cpp
plugin/handler_socket/handlersocket/handlersocket.cpp
+5
-5
plugin/handler_socket/handlersocket/mysql_incl.hpp
plugin/handler_socket/handlersocket/mysql_incl.hpp
+3
-0
plugin/handler_socket/libhsclient/auto_addrinfo.hpp
plugin/handler_socket/libhsclient/auto_addrinfo.hpp
+3
-2
sql/handler.h
sql/handler.h
+1
-1
sql/sql_plugin.cc
sql/sql_plugin.cc
+2
-3
storage/maria/ha_maria.cc
storage/maria/ha_maria.cc
+59
-55
storage/maria/ma_checkpoint.c
storage/maria/ma_checkpoint.c
+2
-0
storage/maria/ma_loghandler.c
storage/maria/ma_loghandler.c
+2
-0
unittest/mysys/base64-t.c
unittest/mysys/base64-t.c
+1
-1
unittest/mysys/bitmap-t.c
unittest/mysys/bitmap-t.c
+1
-1
unittest/mysys/my_malloc-t.c
unittest/mysys/my_malloc-t.c
+1
-1
No files found.
dbug/tests.c
View file @
3f4ef592
...
...
@@ -36,7 +36,8 @@ int func1()
DBUG_RETURN
(
10
);
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
__attribute__
((
unused
)),
char
*
argv
[]
__attribute__
((
unused
)))
{
#ifdef DBUG_OFF
return
1
;
...
...
mysql-test/r/handlersocket.result
View file @
3f4ef592
install plugin handlersocket soname 'handlersocket.so';
select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket';
select plugin_name, plugin_version, plugin_status, plugin_type, plugin_library, plugin_library_version, plugin_author, plugin_description
,
plugin_license, plugin_maturity, plugin_auth_version from information_schema.plugins where plugin_name = 'handlersocket';
plugin_name handlersocket
plugin_version 1.0
plugin_status ACTIVE
plugin_type DAEMON
plugin_library handlersocket.so
plugin_library_version
0.0
plugin_library_version
1.3
plugin_author higuchi dot akira at dena dot jp
plugin_license
plugin_maturity Unknown
plugin_auth_version Unknown
plugin_description Direct access into InnoDB
plugin_license BSD
plugin_maturity Beta
plugin_auth_version 1.0
uninstall plugin handlersocket;
mysql-test/suite/innodb/t/innodb_bug60196.test
View file @
3f4ef592
...
...
@@ -78,7 +78,8 @@ SELECT * FROM Bug_60196;
INSERT
INTO
Bug_60196
VALUES
(
2
,
1
);
INSERT
INTO
Bug_60196
VALUES
(
2
,
2
);
INSERT
INTO
Bug_60196
VALUES
(
2
,
3
);
SELECT
*
FROM
Bug_60196
ORDER
BY
FK1_Key
,
FK2_Key
;
--
sorted_result
SELECT
*
FROM
Bug_60196
;
--
echo
--
echo
# Clean up.
...
...
mysql-test/suite/maria/maria.result
View file @
3f4ef592
...
...
@@ -2542,8 +2542,12 @@ drop table t1;
create table t1 (a int) engine=aria transactional=1;
insert into t1 values (1);
lock table t1 write concurrent;
delete from t1;
delete from t1
where a>0
;
ERROR 42000: The storage engine for the table doesn't support DELETE in WRITE CONCURRENT
delete from t1;
ERROR 42000: The storage engine for the table doesn't support TRUNCATE in WRITE CONCURRENT
truncate t1;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
unlock tables;
drop table t1;
create table t1 (p int primary key, i int, a char(10), key k1(i), key k2(a))
...
...
mysql-test/suite/maria/maria.test
View file @
3f4ef592
...
...
@@ -1805,7 +1805,11 @@ insert into t1 values (1);
lock
table
t1
write
concurrent
;
# should be fixed with fully implemented versioning
--
error
ER_CHECK_NOT_IMPLEMENTED
delete
from
t1
where
a
>
0
;
--
error
ER_CHECK_NOT_IMPLEMENTED
delete
from
t1
;
--
error
ER_TABLE_NOT_LOCKED_FOR_WRITE
truncate
t1
;
unlock
tables
;
drop
table
t1
;
...
...
mysql-test/suite/maria/truncate.result
0 → 100644
View file @
3f4ef592
CREATE TABLE t1 ( i INT ) ENGINE=Aria PARTITION BY HASH(i) PARTITIONS 2;
SET AUTOCOMMIT = 0;
TRUNCATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1 ( i INT ) ENGINE=Aria;
CREATE TABLE t2 ( i INT ) ENGINE=Aria;
insert into t1 values(1);
lock table t1 write;
truncate table t1;
select count(*) from t1;
count(*)
0
insert into t1 values(2);
select count(*) from t1;
count(*)
1
truncate table t1;
select count(*) from t1;
count(*)
0
insert into t1 values(3);
select count(*) from t1;
count(*)
1
select * from t2;
ERROR HY000: Table 't2' was not locked with LOCK TABLES
unlock tables;
insert into t1 values(4);
select * from t1;
i
3
4
truncate t1;
select count(*) from t1;
count(*)
0
drop table t1,t2;
mysql-test/suite/maria/truncate.test
0 → 100644
View file @
3f4ef592
#
# Testing of potential problems in Aria
#
--
source
include
/
have_maria
.
inc
--
source
include
/
have_partition
.
inc
--
disable_warnings
--
disable_query_log
drop
table
if
exists
t1
,
t2
;
--
enable_query_log
--
enable_warnings
#
# LP:997460 truncate table on partitioned Aria table fails with ER_ILLEGAL_HA
#
CREATE
TABLE
t1
(
i
INT
)
ENGINE
=
Aria
PARTITION
BY
HASH
(
i
)
PARTITIONS
2
;
SET
AUTOCOMMIT
=
0
;
TRUNCATE
TABLE
t1
;
DROP
TABLE
t1
;
#
# Other truncate tests
#
CREATE
TABLE
t1
(
i
INT
)
ENGINE
=
Aria
;
CREATE
TABLE
t2
(
i
INT
)
ENGINE
=
Aria
;
insert
into
t1
values
(
1
);
lock
table
t1
write
;
truncate
table
t1
;
select
count
(
*
)
from
t1
;
insert
into
t1
values
(
2
);
select
count
(
*
)
from
t1
;
truncate
table
t1
;
select
count
(
*
)
from
t1
;
insert
into
t1
values
(
3
);
select
count
(
*
)
from
t1
;
# Check that locking is still working
--
error
1100
select
*
from
t2
;
unlock
tables
;
insert
into
t1
values
(
4
);
select
*
from
t1
;
truncate
t1
;
select
count
(
*
)
from
t1
;
drop
table
t1
,
t2
;
mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
View file @
3f4ef592
...
...
@@ -324,7 +324,7 @@ call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received w
let
$slave_errno
=
ER_DUP_ENTRY
--
source
include
/
wait_for_slave_sql_error
.
inc
let
$rcvd_heartbeats_before
=
query_get_value
(
SHOW
STATUS
LIKE
'slave_received_heartbeats'
,
Value
,
1
);
sleep
2
;
sleep
4
;
let
$rcvd_heartbeats_after
=
query_get_value
(
SHOW
STATUS
LIKE
'slave_received_heartbeats'
,
Value
,
1
);
let
$result
=
query_get_value
(
SELECT
(
$rcvd_heartbeats_after
-
$rcvd_heartbeats_before
)
>
0
AS
Result
,
Result
,
1
);
--
echo
Heartbeat
events
are
received
while
sql
thread
stopped
(
1
means
'yes'
)
:
$result
...
...
mysql-test/t/handlersocket.test
View file @
3f4ef592
...
...
@@ -5,6 +5,6 @@ if (`select length('$HANDLERSOCKET_SO') = 0`) {
}
install
plugin
handlersocket
soname
'handlersocket.so'
;
--
query_vertical
select
plugin_name
,
plugin_version
,
plugin_status
,
plugin_type
,
plugin_library
,
plugin_library_version
,
plugin_author
,
plugin_description
plugin_license
,
plugin_maturity
,
plugin_auth_version
from
information_schema
.
plugins
where
plugin_name
=
'handlersocket'
--
query_vertical
select
plugin_name
,
plugin_version
,
plugin_status
,
plugin_type
,
plugin_library
,
plugin_library_version
,
plugin_author
,
plugin_description
,
plugin_license
,
plugin_maturity
,
plugin_auth_version
from
information_schema
.
plugins
where
plugin_name
=
'handlersocket'
uninstall
plugin
handlersocket
;
plugin/handler_socket/handlersocket/handlersocket.cpp
View file @
3f4ef592
...
...
@@ -197,20 +197,20 @@ static SHOW_VAR daemon_handlersocket_status_variables[] = {
};
m
ysql
_declare_plugin
(
handlersocket
)
m
aria
_declare_plugin
(
handlersocket
)
{
MYSQL_DAEMON_PLUGIN
,
&
daemon_handlersocket_plugin
,
"handlersocket"
,
"higuchi dot akira at dena dot jp"
,
""
,
"
Direct access into InnoDB
"
,
PLUGIN_LICENSE_BSD
,
daemon_handlersocket_init
,
daemon_handlersocket_deinit
,
0x0100
/* 1.0 */
,
daemon_handlersocket_status_variables
,
daemon_handlersocket_system_variables
,
0
"1.0"
,
MariaDB_PLUGIN_MATURITY_BETA
}
mysql_declare_plugin_end
;
maria_declare_plugin_end
;
plugin/handler_socket/handlersocket/mysql_incl.hpp
View file @
3f4ef592
...
...
@@ -36,6 +36,9 @@
#include <sql_base.h>
// FIXME FIXME FIXME
#define safeFree(X) my_free(X)
#undef pthread_cond_timedwait
#undef pthread_mutex_lock
#undef pthread_mutex_unlock
#define pthread_cond_timedwait mysql_cond_timedwait
#define pthread_mutex_lock mysql_mutex_lock
#define pthread_mutex_unlock mysql_mutex_unlock
...
...
plugin/handler_socket/libhsclient/auto_addrinfo.hpp
View file @
3f4ef592
...
...
@@ -13,7 +13,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include "util.hpp"
typedef
SOCKET_SIZE_TYPE
size_socket
;
...
...
@@ -34,8 +34,9 @@ struct auto_addrinfo : private noncopyable {
const
addrinfo
*
get
()
const
{
return
addr
;
}
int
resolve
(
const
char
*
node
,
const
char
*
service
,
int
flags
=
0
,
int
family
=
AF_UNSPEC
,
int
socktype
=
SOCK_STREAM
,
int
protocol
=
0
)
{
addrinfo
hints
;
reset
();
addrinfo
hints
=
{
}
;
memset
(
&
hints
,
0
,
sizeof
(
hints
))
;
hints
.
ai_flags
=
flags
;
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
socktype
;
...
...
sql/handler.h
View file @
3f4ef592
...
...
@@ -1063,7 +1063,7 @@ inline LEX_STRING *hton_name(const handlerton *hton)
#define HTON_NO_FLAGS 0
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
#define HTON_CAN_RECREATE (1 << 2) //Delete all is used f
ro
truncate
#define HTON_CAN_RECREATE (1 << 2) //Delete all is used f
or
truncate
#define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
#define HTON_NOT_USER_SELECTABLE (1 << 5)
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
...
...
sql/sql_plugin.cc
View file @
3f4ef592
...
...
@@ -739,15 +739,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report)
}
bzero
(
&
plugin_dl
,
sizeof
(
plugin_dl
));
/* Compile dll path */
dlpathlen
=
strxnmov
(
dlpath
,
sizeof
(
dlpath
)
-
1
,
opt_plugin_dir
,
"/"
,
dl
->
str
,
NullS
)
-
dlpath
;
strxnmov
(
dlpath
,
sizeof
(
dlpath
)
-
1
,
opt_plugin_dir
,
"/"
,
dl
->
str
,
NullS
);
(
void
)
unpack_filename
(
dlpath
,
dlpath
);
plugin_dl
.
ref_count
=
1
;
/* Open new dll handle */
if
(
!
(
plugin_dl
.
handle
=
dlopen
(
dlpath
,
RTLD_NOW
)))
{
const
char
*
errmsg
=
dlerror
();
dlpathlen
=
strlen
(
dlpath
);
if
(
!
strncmp
(
dlpath
,
errmsg
,
dlpathlen
))
{
// if errmsg starts from dlpath, trim this prefix.
errmsg
+=
dlpathlen
;
...
...
storage/maria/ha_maria.cc
View file @
3f4ef592
...
...
@@ -2537,9 +2537,10 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
int
ha_maria
::
delete_all_rows
()
{
#ifdef EXTRA_DEBUG
THD
*
thd
=
table
->
in_use
;
TRN
*
trn
=
file
->
trn
;
CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING
(
"TRUNCATE in WRITE CONCURRENT"
);
#ifdef EXTRA_DEBUG
if
(
trn
&&
!
(
trnman_get_flags
(
trn
)
&
TRN_STATE_INFO_LOGGED
))
{
trnman_set_flags
(
trn
,
trnman_get_flags
(
trn
)
|
TRN_STATE_INFO_LOGGED
|
...
...
@@ -2548,16 +2549,19 @@ int ha_maria::delete_all_rows()
(
uchar
*
)
thd
->
query
(),
thd
->
query_length
());
}
#endif
if
(
file
->
s
->
now_transactional
&&
((
table
->
in_use
->
variables
.
option_bits
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
))
||
table
->
in_use
->
locked_tables_mode
))
/*
If we are under LOCK TABLES, we have to do a commit as
delete_all_rows() can't be rolled back
*/
if
(
table
->
in_use
->
locked_tables_mode
&&
trn
&&
trnman_has_locked_tables
(
trn
))
{
/*
We are not in autocommit mode or user have done LOCK TABLES.
We must do the delete row by row to be able to rollback the command
*/
return
HA_ERR_WRONG_COMMAND
;
int
error
;
if
((
error
=
implicit_commit
(
thd
,
1
)))
return
error
;
}
/* Note that this can't be rolled back */
return
maria_delete_all_rows
(
file
);
}
...
...
@@ -2775,10 +2779,11 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
#error this method should be removed
#endif
TRN
*
trn
;
int
error
=
0
;
int
error
;
uint
locked_tables
;
TABLE
*
table
;
DBUG_ENTER
(
"ha_maria::implicit_commit"
);
if
(
!
maria_hton
)
if
(
!
maria_hton
||
!
(
trn
=
THD_TRN
)
)
DBUG_RETURN
(
0
);
if
(
!
new_trn
&&
(
thd
->
locked_tables_mode
==
LTM_LOCK_TABLES
||
thd
->
locked_tables_mode
==
LTM_PRELOCKED_UNDER_LOCK_TABLES
))
...
...
@@ -2792,60 +2797,59 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn)
DBUG_PRINT
(
"info"
,
(
"locked_tables, skipping"
));
DBUG_RETURN
(
0
);
}
if
((
trn
=
THD_TRN
)
!=
NULL
)
locked_tables
=
trnman_has_locked_tables
(
trn
);
error
=
0
;
if
(
unlikely
(
ma_commit
(
trn
)))
error
=
1
;
if
(
!
new_trn
)
{
uint
locked_tables
=
trnman_has_locked_tables
(
trn
);
if
(
unlikely
(
ma_commit
(
trn
)))
error
=
1
;
if
(
!
new_trn
)
{
/*
To be extra safe, we should also reset file->trn for all open
tables as some calls, like extra() may access it. We take care
of this in extra() by resetting file->trn if THD_TRN is 0.
*/
THD_TRN
=
NULL
;
goto
end
;
}
/*
We need to create a new transaction and put it in THD_TRN. Indeed,
tables
may be under LOCK TABLES, and so they will start the next
statement assuming they have a trn (see ha_maria::start_stmt())
.
To be extra safe, we should also reset file->trn for all open
tables
as some calls, like extra() may access it. We take care
of this in extra() by resetting file->trn if THD_TRN is 0
.
*/
trn
=
trnman_new_trn
(
&
thd
->
transaction
.
wt
);
THD_TRN
=
trn
;
if
(
unlikely
(
trn
==
NULL
))
{
error
=
HA_ERR_OUT_OF_MEM
;
goto
end
;
}
/*
Move all locked tables to the new transaction
We must do it here as otherwise file->thd and file->state may be
stale pointers. We can't do this in start_stmt() as we don't know
when we should call _ma_setup_live_state() and in some cases, like
in check table, we use the table without calling start_stmt().
*/
for
(
table
=
thd
->
open_tables
;
table
;
table
=
table
->
next
)
THD_TRN
=
NULL
;
goto
end
;
}
/*
We need to create a new transaction and put it in THD_TRN. Indeed,
tables may be under LOCK TABLES, and so they will start the next
statement assuming they have a trn (see ha_maria::start_stmt()).
*/
trn
=
trnman_new_trn
(
&
thd
->
transaction
.
wt
);
THD_TRN
=
trn
;
if
(
unlikely
(
trn
==
NULL
))
{
error
=
HA_ERR_OUT_OF_MEM
;
goto
end
;
}
/*
Move all locked tables to the new transaction
We must do it here as otherwise file->thd and file->state may be
stale pointers. We can't do this in start_stmt() as we don't know
when we should call _ma_setup_live_state() and in some cases, like
in check table, we use the table without calling start_stmt().
*/
for
(
table
=
thd
->
open_tables
;
table
;
table
=
table
->
next
)
{
if
(
table
->
db_stat
&&
table
->
file
->
ht
==
maria_hton
)
{
if
(
table
->
db_stat
&&
table
->
file
->
ht
==
maria_hton
)
MARIA_HA
*
handler
=
((
ha_maria
*
)
table
->
file
)
->
file
;
if
(
handler
->
s
->
base
.
born_transactional
)
{
MARIA_HA
*
handler
=
((
ha_maria
*
)
table
->
file
)
->
file
;
if
(
handler
->
s
->
base
.
born_transactional
)
_ma_set_trn_for_table
(
handler
,
trn
);
/* If handler uses versioning */
if
(
handler
->
s
->
lock_key_trees
)
{
_ma_set_trn_for_table
(
handler
,
trn
);
/* If handler uses versioning */
if
(
handler
->
s
->
lock_key_trees
)
{
if
(
_ma_setup_live_state
(
handler
))
error
=
HA_ERR_OUT_OF_MEM
;
}
if
(
_ma_setup_live_state
(
handler
))
error
=
HA_ERR_OUT_OF_MEM
;
}
}
}
/* This is just a commit, tables stay locked if they were: */
trnman_reset_locked_tables
(
trn
,
locked_tables
);
}
/* This is just a commit, tables stay locked if they were: */
trnman_reset_locked_tables
(
trn
,
locked_tables
);
end:
DBUG_RETURN
(
error
);
}
...
...
storage/maria/ma_checkpoint.c
View file @
3f4ef592
...
...
@@ -763,6 +763,8 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
PAGECACHE_FLUSH_FILTER
filter
;
DBUG_ENTER
(
"collect_tables"
);
LINT_INIT
(
state_copies_horizon
);
/* let's make a list of distinct shares */
mysql_mutex_lock
(
&
THR_LOCK_maria
);
for
(
nb
=
0
,
pos
=
maria_open_list
;
pos
;
pos
=
pos
->
next
)
...
...
storage/maria/ma_loghandler.c
View file @
3f4ef592
...
...
@@ -7474,6 +7474,8 @@ static void translog_force_current_buffer_to_finish()
uint16
left
=
TRANSLOG_PAGE_SIZE
-
log_descriptor
.
bc
.
current_page_fill
;
uint16
current_page_fill
,
write_counter
,
previous_offset
;
DBUG_ENTER
(
"translog_force_current_buffer_to_finish"
);
LINT_INIT
(
current_page_fill
);
DBUG_PRINT
(
"enter"
,
(
"Buffer #%u 0x%lx "
"Buffer addr: (%lu,0x%lx) "
"Page addr: (%lu,0x%lx) "
...
...
unittest/mysys/base64-t.c
View file @
3f4ef592
...
...
@@ -24,7 +24,7 @@
#define BASE64_ROWS 4
/* Number of ok(..) */
int
main
(
int
argc
,
char
*
argv
[])
main
(
int
argc
__attribute__
((
unused
))
,
char
*
argv
[])
{
int
i
,
cmp
;
size_t
j
,
k
,
l
,
dst_len
,
needed_length
;
...
...
unittest/mysys/bitmap-t.c
View file @
3f4ef592
...
...
@@ -520,7 +520,7 @@ error:
return
TRUE
;
}
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
__attribute__
((
unused
))
,
char
*
argv
[])
{
int
i
;
int
const
min_size
=
1
;
...
...
unittest/mysys/my_malloc-t.c
View file @
3f4ef592
...
...
@@ -17,7 +17,7 @@
#include <my_sys.h>
#include "tap.h"
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
__attribute__
((
unused
))
,
char
*
argv
[])
{
void
*
p
;
MY_INIT
(
argv
[
0
]);
...
...
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