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
f2e14517
Commit
f2e14517
authored
Mar 01, 2019
by
Oleksandr Byelkin
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '10.0' into 10.1
parents
e39d6e0c
2d347132
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
239 additions
and
60 deletions
+239
-60
mysql-test/r/loaddata.result
mysql-test/r/loaddata.result
+50
-0
mysql-test/r/sp.result
mysql-test/r/sp.result
+33
-0
mysql-test/t/loaddata.test
mysql-test/t/loaddata.test
+45
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+41
-0
sql/sql_delete.cc
sql/sql_delete.cc
+3
-3
sql/sql_derived.cc
sql/sql_derived.cc
+1
-30
sql/sql_derived.h
sql/sql_derived.h
+0
-1
sql/sql_insert.cc
sql/sql_insert.cc
+1
-2
sql/sql_lex.cc
sql/sql_lex.cc
+5
-11
sql/sql_lex.h
sql/sql_lex.h
+31
-1
sql/sql_load.cc
sql/sql_load.cc
+8
-2
sql/sql_prepare.cc
sql/sql_prepare.cc
+15
-6
sql/sql_union.cc
sql/sql_union.cc
+3
-2
win/packaging/create_msi.cmake.in
win/packaging/create_msi.cmake.in
+3
-2
No files found.
mysql-test/r/loaddata.result
View file @
f2e14517
...
...
@@ -574,3 +574,53 @@ SELECT HEX(a) FROM t1;
HEX(a)
C3A4
DROP TABLE t1;
#
# MDEV-15744: Assertion `derived->table' failed in mysql_derived_merge_for_insert
#
create table t1 (a int, b int);
CREATE OR REPLACE VIEW t2 AS SELECT * FROM t1;
CREATE VIEW v2 AS SELECT * FROM t2;
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
select * from v2;
a b
2 2
3 3
4 4
5 5
6 6
select * from t2;
a b
2 2
3 3
4 4
5 5
6 6
DROP VIEW IF EXISTS v2,t2;
DROP TABLE IF EXISTS t1;
#
# MDEV-15950: LOAD DATA INTO compex_view crashed
#
create table t1 (a int, b int);
create table t0 (x int, y int);
CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1,t0;
CREATE VIEW v2 AS SELECT * FROM v1;
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v1
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
LOAD DATA INFILE '../../std_data/loaddata7.dat' INTO TABLE v2
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
DROP VIEW IF EXISTS v2,v1;
DROP TABLE IF EXISTS t1,t0;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), UNIQUE(b));
INSERT INTO t1 VALUES (1,1);
CREATE TABLE t2 (c INT);
CREATE VIEW v AS SELECT t1.* FROM t1 JOIN t2;
SELECT a, b FROM t1 INTO OUTFILE '15645.data';
LOAD DATA INFILE '15645.data' IGNORE INTO TABLE v (a,b);
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
LOAD DATA INFILE '15645.data' REPLACE INTO TABLE v (a,b);
ERROR HY000: Incorrect usage of Multi-table VIEW and LOAD
drop table t1,t2;
drop view v;
mysql-test/r/sp.result
View file @
f2e14517
...
...
@@ -7918,6 +7918,39 @@ CALL sp;
c a b a b
DROP PROCEDURE sp;
DROP TABLE t1;
#
# MDEV-17055: Server crashes in find_order_in_list upon
# 2nd (3rd) execution of SP with UPDATE
#
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (c INT);
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 ORDER BY a, b LIMIT 1;
LOCK TABLE t2 READ;
CALL sp;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'order clause'
DROP PROCEDURE sp;
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 WHERE a=1 and b=2;
LOCK TABLE t2 READ;
CALL sp;
ERROR HY000: Table 'v1' was not locked with LOCK TABLES
UNLOCK TABLES;
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
CALL sp;
ERROR 42S22: Unknown column 'b' in 'where clause'
DROP PROCEDURE sp;
DROP VIEW v1;
DROP TABLE t1, t2;
# End of 5.5 test
#
# MDEV-7040: Crash in field_conv, memcpy_field_possible, part#2
...
...
mysql-test/t/loaddata.test
View file @
f2e14517
...
...
@@ -676,3 +676,48 @@ CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8);
LOAD
DATA
INFILE
'../../std_data/loaddata/mdev-11631.txt'
INTO
TABLE
t1
CHARACTER
SET
utf8
;
SELECT
HEX
(
a
)
FROM
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# MDEV-15744: Assertion `derived->table' failed in mysql_derived_merge_for_insert
--
echo
#
create
table
t1
(
a
int
,
b
int
);
CREATE
OR
REPLACE
VIEW
t2
AS
SELECT
*
FROM
t1
;
CREATE
VIEW
v2
AS
SELECT
*
FROM
t2
;
LOAD
DATA
INFILE
'../../std_data/loaddata7.dat'
INTO
TABLE
v2
FIELDS
TERMINATED
BY
','
LINES
TERMINATED
BY
'\r\n'
;
select
*
from
v2
;
select
*
from
t2
;
DROP
VIEW
IF
EXISTS
v2
,
t2
;
DROP
TABLE
IF
EXISTS
t1
;
--
echo
#
--
echo
# MDEV-15950: LOAD DATA INTO compex_view crashed
--
echo
#
create
table
t1
(
a
int
,
b
int
);
create
table
t0
(
x
int
,
y
int
);
CREATE
OR
REPLACE
VIEW
v1
AS
SELECT
*
FROM
t1
,
t0
;
CREATE
VIEW
v2
AS
SELECT
*
FROM
v1
;
--
error
ER_WRONG_USAGE
LOAD
DATA
INFILE
'../../std_data/loaddata7.dat'
INTO
TABLE
v1
FIELDS
TERMINATED
BY
','
LINES
TERMINATED
BY
'\r\n'
;
--
error
ER_WRONG_USAGE
LOAD
DATA
INFILE
'../../std_data/loaddata7.dat'
INTO
TABLE
v2
FIELDS
TERMINATED
BY
','
LINES
TERMINATED
BY
'\r\n'
;
DROP
VIEW
IF
EXISTS
v2
,
v1
;
DROP
TABLE
IF
EXISTS
t1
,
t0
;
CREATE
TABLE
t1
(
a
INT
,
b
INT
,
PRIMARY
KEY
(
a
),
UNIQUE
(
b
));
INSERT
INTO
t1
VALUES
(
1
,
1
);
CREATE
TABLE
t2
(
c
INT
);
CREATE
VIEW
v
AS
SELECT
t1
.*
FROM
t1
JOIN
t2
;
SELECT
a
,
b
FROM
t1
INTO
OUTFILE
'15645.data'
;
--
error
ER_WRONG_USAGE
LOAD
DATA
INFILE
'15645.data'
IGNORE
INTO
TABLE
v
(
a
,
b
);
--
error
ER_WRONG_USAGE
LOAD
DATA
INFILE
'15645.data'
REPLACE
INTO
TABLE
v
(
a
,
b
);
drop
table
t1
,
t2
;
drop
view
v
;
mysql-test/t/sp.test
View file @
f2e14517
...
...
@@ -9369,6 +9369,47 @@ CALL sp;
DROP PROCEDURE sp;
DROP TABLE t1;
--echo #
--echo # MDEV-17055: Server crashes in find_order_in_list upon
--echo # 2nd (3rd) execution of SP with UPDATE
--echo #
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS SELECT * FROM t1;
CREATE TABLE t2 (c INT);
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 ORDER BY a, b LIMIT 1;
LOCK TABLE t2 READ;
--error ER_TABLE_NOT_LOCKED
CALL sp;
UNLOCK TABLES;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
# Cleanup
DROP PROCEDURE sp;
CREATE PROCEDURE sp() UPDATE v1 SET a = 1 WHERE a=1 and b=2;
LOCK TABLE t2 READ;
--error ER_TABLE_NOT_LOCKED
CALL sp;
UNLOCK TABLES;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
--error ER_BAD_FIELD_ERROR
CALL sp;
# Cleanup
DROP PROCEDURE sp;
DROP VIEW v1;
DROP TABLE t1, t2;
--echo # End of 5.5 test
...
...
sql/sql_delete.cc
View file @
f2e14517
...
...
@@ -39,7 +39,7 @@
#include "sql_statistics.h"
#include "transaction.h"
#include "records.h" // init_read_record,
#include "sql_derived.h" // mysql_handle_
list_of_
derived
#include "sql_derived.h" // mysql_handle_derived
// end_read_record
#include "sql_partition.h" // make_used_partitions_str
...
...
@@ -248,9 +248,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if
(
open_and_lock_tables
(
thd
,
table_list
,
TRUE
,
0
))
DBUG_RETURN
(
TRUE
);
if
(
mysql_handle_list_of_derived
(
thd
->
lex
,
table_list
,
DT_MERGE_FOR_INSERT
))
if
(
thd
->
lex
->
handle_list_of_derived
(
table_list
,
DT_MERGE_FOR_INSERT
))
DBUG_RETURN
(
TRUE
);
if
(
mysql_handle_list_of_derived
(
thd
->
lex
,
table_list
,
DT_PREPARE
))
if
(
thd
->
lex
->
handle_list_of_derived
(
table_list
,
DT_PREPARE
))
DBUG_RETURN
(
TRUE
);
if
(
!
table_list
->
single_table_updatable
())
...
...
sql/sql_derived.cc
View file @
f2e14517
...
...
@@ -91,6 +91,7 @@ mysql_handle_derived(LEX *lex, uint phases)
sl
=
sl
->
next_select_in_list
())
{
TABLE_LIST
*
cursor
=
sl
->
get_table_list
();
sl
->
changed_elements
|=
TOUCHED_SEL_DERIVED
;
/*
DT_MERGE_FOR_INSERT is not needed for views/derived tables inside
subqueries. Views and derived tables of subqueries should be
...
...
@@ -200,36 +201,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases)
}
/**
Run specified phases for derived tables/views in the given list
@param lex LEX for this thread
@param table_list list of derived tables/view to handle
@param phase_map phases to process tables/views through
@details
This function runs phases specified by the 'phases_map' on derived
tables/views found in the 'dt_list' with help of the
TABLE_LIST::handle_derived function.
'lex' is passed as an argument to the TABLE_LIST::handle_derived.
@return FALSE ok
@return TRUE error
*/
bool
mysql_handle_list_of_derived
(
LEX
*
lex
,
TABLE_LIST
*
table_list
,
uint
phases
)
{
for
(
TABLE_LIST
*
tl
=
table_list
;
tl
;
tl
=
tl
->
next_local
)
{
if
(
tl
->
is_view_or_derived
()
&&
tl
->
handle_derived
(
lex
,
phases
))
return
TRUE
;
}
return
FALSE
;
}
/**
Merge a derived table/view into the embedding select
...
...
sql/sql_derived.h
View file @
f2e14517
...
...
@@ -22,7 +22,6 @@ struct LEX;
bool
mysql_handle_derived
(
LEX
*
lex
,
uint
phases
);
bool
mysql_handle_single_derived
(
LEX
*
lex
,
TABLE_LIST
*
derived
,
uint
phases
);
bool
mysql_handle_list_of_derived
(
LEX
*
lex
,
TABLE_LIST
*
dt_list
,
uint
phases
);
bool
mysql_derived_reinit
(
THD
*
thd
,
LEX
*
lex
,
TABLE_LIST
*
derived
);
/**
...
...
sql/sql_insert.cc
View file @
f2e14517
...
...
@@ -1461,7 +1461,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
TRUE
);
if
(
table_list
->
handle_derived
(
thd
->
lex
,
DT_MERGE_FOR_INSERT
))
DBUG_RETURN
(
TRUE
);
if
(
mysql_handle_list_of_derived
(
thd
->
lex
,
table_list
,
DT_PREPARE
))
if
(
thd
->
lex
->
handle_list_of_derived
(
table_list
,
DT_PREPARE
))
DBUG_RETURN
(
TRUE
);
/*
For subqueries in VALUES() we should not see the table in which we are
...
...
@@ -1557,7 +1557,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN
(
TRUE
);
}
select_lex
->
fix_prepare_information
(
thd
,
&
fake_conds
,
&
fake_conds
);
select_lex
->
first_execution
=
0
;
}
/*
Only call prepare_for_posistion() if we are not performing a DELAYED
...
...
sql/sql_lex.cc
View file @
f2e14517
...
...
@@ -2127,7 +2127,7 @@ void st_select_lex::init_query()
n_child_sum_items
=
0
;
subquery_in_having
=
explicit_limit
=
0
;
is_item_list_lookup
=
0
;
first_execution
=
1
;
changed_elements
=
0
;
first_natural_join_processing
=
1
;
first_cond_optimization
=
1
;
parsing_place
=
NO_MATTER
;
...
...
@@ -3597,9 +3597,10 @@ void st_select_lex::fix_prepare_information(THD *thd, Item **conds,
Item
**
having_conds
)
{
DBUG_ENTER
(
"st_select_lex::fix_prepare_information"
);
if
(
!
thd
->
stmt_arena
->
is_conventional
()
&&
first_execution
)
if
(
!
thd
->
stmt_arena
->
is_conventional
()
&&
!
(
changed_elements
&
TOUCHED_SEL_COND
))
{
first_execution
=
0
;
changed_elements
|=
TOUCHED_SEL_COND
;
if
(
group_list
.
first
)
{
if
(
!
group_list_ptrs
)
...
...
@@ -3850,14 +3851,7 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
bool
st_select_lex
::
handle_derived
(
LEX
*
lex
,
uint
phases
)
{
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
table_list
.
first
;
cursor
;
cursor
=
cursor
->
next_local
)
{
if
(
cursor
->
is_view_or_derived
()
&&
cursor
->
handle_derived
(
lex
,
phases
))
return
TRUE
;
}
return
FALSE
;
return
lex
->
handle_list_of_derived
(
table_list
.
first
,
phases
);
}
...
...
sql/sql_lex.h
View file @
f2e14517
...
...
@@ -714,6 +714,10 @@ class st_select_lex_unit: public st_select_lex_node {
typedef
class
st_select_lex_unit
SELECT_LEX_UNIT
;
#define TOUCHED_SEL_COND 1
/* WHERE/HAVING/ON should be reinited before use */
#define TOUCHED_SEL_DERIVED (1<<1)
/* derived should be reinited before use */
/*
SELECT_LEX - store information of parsed SELECT statment
*/
...
...
@@ -875,7 +879,8 @@ class st_select_lex: public st_select_lex_node
subquery. Prepared statements work OK in that regard, as in
case of an error during prepare the PS is not created.
*/
bool
first_execution
;
uint8
changed_elements
;
// see TOUCHED_SEL_*
/* TODO: add foloowing first_* to bitmap above */
bool
first_natural_join_processing
;
bool
first_cond_optimization
;
/* do not wrap view fields with Item_ref */
...
...
@@ -2998,6 +3003,31 @@ struct LEX: public Query_tables_list
*/
bool
tmp_table
()
const
{
return
create_info
.
tmp_table
();
}
bool
if_exists
()
const
{
return
create_info
.
if_exists
();
}
/*
Run specified phases for derived tables/views in the given list
@param table_list - list of derived tables/view to handle
@param phase - phases to process tables/views through
@details
This method runs phases specified by the 'phases' on derived
tables/views found in the 'table_list' with help of the
TABLE_LIST::handle_derived function.
'this' is passed as an argument to the TABLE_LIST::handle_derived.
@return false - ok
@return true - error
*/
bool
handle_list_of_derived
(
TABLE_LIST
*
table_list
,
uint
phases
)
{
for
(
TABLE_LIST
*
tl
=
table_list
;
tl
;
tl
=
tl
->
next_local
)
{
if
(
tl
->
is_view_or_derived
()
&&
tl
->
handle_derived
(
this
,
phases
))
return
true
;
}
return
false
;
}
};
...
...
sql/sql_load.cc
View file @
f2e14517
...
...
@@ -293,8 +293,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if
(
open_and_lock_tables
(
thd
,
table_list
,
TRUE
,
0
))
DBUG_RETURN
(
TRUE
);
if
(
mysql_handle_single_derived
(
thd
->
lex
,
table_list
,
DT_MERGE_FOR_INSERT
)
||
mysql_handle_single_derived
(
thd
->
lex
,
table_list
,
DT_PREPARE
))
if
(
table_list
->
handle_derived
(
thd
->
lex
,
DT_MERGE_FOR_INSERT
))
DBUG_RETURN
(
TRUE
);
if
(
thd
->
lex
->
handle_list_of_derived
(
table_list
,
DT_PREPARE
))
DBUG_RETURN
(
TRUE
);
if
(
setup_tables_and_check_access
(
thd
,
&
thd
->
lex
->
select_lex
.
context
,
&
thd
->
lex
->
select_lex
.
top_join_list
,
...
...
@@ -310,6 +311,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
my_error
(
ER_NON_UPDATABLE_TABLE
,
MYF
(
0
),
table_list
->
alias
,
"LOAD"
);
DBUG_RETURN
(
TRUE
);
}
if
(
table_list
->
is_multitable
())
{
my_error
(
ER_WRONG_USAGE
,
MYF
(
0
),
"Multi-table VIEW"
,
"LOAD"
);
DBUG_RETURN
(
TRUE
);
}
if
(
table_list
->
prepare_where
(
thd
,
0
,
TRUE
)
||
table_list
->
prepare_check_option
(
thd
))
{
...
...
sql/sql_prepare.cc
View file @
f2e14517
...
...
@@ -2794,7 +2794,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
for
(;
sl
;
sl
=
sl
->
next_select_in_list
())
{
if
(
!
sl
->
first_execution
)
if
(
sl
->
changed_elements
&
TOUCHED_SEL_COND
)
{
/* remove option which was put by mysql_explain_union() */
sl
->
options
&=
~
SELECT_DESCRIBE
;
...
...
@@ -2841,19 +2841,28 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
order
->
next
=
sl
->
group_list_ptrs
->
at
(
ix
+
1
);
}
}
}
{
// no harm to do it (item_ptr set on parsing)
ORDER
*
order
;
for
(
order
=
sl
->
group_list
.
first
;
order
;
order
=
order
->
next
)
{
order
->
item
=
&
order
->
item_ptr
;
}
/* Fix ORDER list */
for
(
order
=
sl
->
order_list
.
first
;
order
;
order
=
order
->
next
)
order
->
item
=
&
order
->
item_ptr
;
{
order
->
item
=
&
order
->
item_ptr
;
}
}
if
(
sl
->
changed_elements
&
TOUCHED_SEL_DERIVED
)
{
#ifndef DBUG_OFF
bool
res
=
bool
res
=
#endif
sl
->
handle_derived
(
lex
,
DT_REINIT
);
DBUG_ASSERT
(
res
==
0
);
}
sl
->
handle_derived
(
lex
,
DT_REINIT
);
DBUG_ASSERT
(
res
==
0
);
}
{
SELECT_LEX_UNIT
*
unit
=
sl
->
master_unit
();
unit
->
unclean
();
...
...
sql/sql_union.cc
View file @
f2e14517
...
...
@@ -313,8 +313,9 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
called at the first execution of the statement, while first_execution
shows whether this is called at the first execution of the union that
may form just a subselect.
*/
if
(
!
fake_select_lex
->
first_execution
&&
first_execution
)
*/
if
((
fake_select_lex
->
changed_elements
&
TOUCHED_SEL_COND
)
&&
first_execution
)
{
for
(
ORDER
*
order
=
global_parameters
()
->
order_list
.
first
;
order
;
...
...
win/packaging/create_msi.cmake.in
View file @
f2e14517
...
...
@@ -398,9 +398,10 @@ IF("$ENV{EXTRA_LIGHT_ARGS}")
ENDIF()
FILE(REMOVE mysql_server.wixobj extra.wixobj)
STRING(REPLACE " " ";" EXTRA_WIX_PREPROCESSOR_FLAGS_LIST ${EXTRA_WIX_PREPROCESSOR_FLAGS})
EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE}
${EXTRA_WIX_PREPROCESSOR_FLAGS
}
${EXTRA_WIX_PREPROCESSOR_FLAGS
_LIST}
${CANDLE_ARCH}
-ext WixUtilExtension
-ext WixFirewallExtension
...
...
@@ -410,7 +411,7 @@ EXECUTE_PROCESS(
EXECUTE_PROCESS(
COMMAND ${CANDLE_EXECUTABLE} ${CANDLE_ARCH}
${EXTRA_WIX_PREPROCESSOR_FLAGS
}
${EXTRA_WIX_PREPROCESSOR_FLAGS
_LIST}
-ext WixUtilExtension
-ext WixFirewallExtension
${CMAKE_CURRENT_BINARY_DIR}/extra.wxs
...
...
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