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
9baf84e9
Commit
9baf84e9
authored
May 04, 2011
by
Tor Didriksen
Browse files
Options
Browse Files
Download
Plain Diff
merge 5.0 => 5.1 : Bug#12329653
parents
c00c350f
a32df762
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
128 additions
and
57 deletions
+128
-57
mysql-test/r/explain.result
mysql-test/r/explain.result
+6
-5
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+26
-0
mysql-test/t/explain.test
mysql-test/t/explain.test
+5
-4
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+33
-0
sql/item.cc
sql/item.cc
+2
-2
sql/item_subselect.cc
sql/item_subselect.cc
+8
-0
sql/item_sum.cc
sql/item_sum.cc
+3
-3
sql/mysql_priv.h
sql/mysql_priv.h
+0
-7
sql/sql_lex.cc
sql/sql_lex.cc
+4
-1
sql/sql_lex.h
sql/sql_lex.h
+17
-11
sql/sql_partition.cc
sql/sql_partition.cc
+18
-18
sql/sql_select.cc
sql/sql_select.cc
+6
-6
No files found.
mysql-test/r/explain.result
View file @
9baf84e9
...
@@ -176,11 +176,12 @@ SELECT @@session.sql_mode INTO @old_sql_mode;
...
@@ -176,11 +176,12 @@ SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
EXPLAIN EXTENDED SELECT 1 FROM t1
EXPLAIN EXTENDED SELECT 1 FROM t1
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
WHERE f1 > ALL( SELECT t.f1 FROM t1,t1 AS t );
ERROR 42000: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
id select_type table type possible_keys key key_len ref rows filtered Extra
SHOW WARNINGS;
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Level Code Message
2 SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
Error 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause
2 SUBQUERY t system NULL NULL NULL NULL 0 0.00 const row not found
Note 1003 select 1 AS `1` from `test`.`t1` where <not>(<exists>(...))
Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where 0
SET SESSION sql_mode=@old_sql_mode;
SET SESSION sql_mode=@old_sql_mode;
DROP TABLE t1;
DROP TABLE t1;
End of 5.0 tests.
End of 5.0 tests.
...
...
mysql-test/r/subselect.result
View file @
9baf84e9
...
@@ -4435,6 +4435,32 @@ pk int_key
...
@@ -4435,6 +4435,32 @@ pk int_key
3 3
3 3
7 3
7 3
DROP TABLE t1,t2;
DROP TABLE t1,t2;
#
# Bug#12329653
# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
#
CREATE TABLE t1(a1 int);
INSERT INTO t1 VALUES (1),(2);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
1
1
1
PREPARE stmt FROM
'SELECT 1 UNION ALL
SELECT 1 FROM t1
ORDER BY
(SELECT 1 FROM t1 AS t1_0
WHERE 1 < SOME (SELECT a1 FROM t1)
)' ;
EXECUTE stmt ;
ERROR 21000: Subquery returns more than 1 row
EXECUTE stmt ;
ERROR 21000: Subquery returns more than 1 row
SET SESSION sql_mode=@old_sql_mode;
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.0 tests.
End of 5.0 tests.
CREATE TABLE t1 (a INT, b INT);
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
...
...
mysql-test/t/explain.test
View file @
9baf84e9
#
#
# Test of different EXPLAIN
'
s
# Test of different EXPLAINs
--
disable_warnings
--
disable_warnings
drop
table
if
exists
t1
;
drop
table
if
exists
t1
;
...
@@ -157,11 +157,12 @@ CREATE TABLE t1 (f1 INT);
...
@@ -157,11 +157,12 @@ CREATE TABLE t1 (f1 INT);
SELECT
@@
session
.
sql_mode
INTO
@
old_sql_mode
;
SELECT
@@
session
.
sql_mode
INTO
@
old_sql_mode
;
SET
SESSION
sql_mode
=
'ONLY_FULL_GROUP_BY'
;
SET
SESSION
sql_mode
=
'ONLY_FULL_GROUP_BY'
;
# EXPLAIN EXTENDED (with subselect). used to crash. should give NOTICE.
# EXPLAIN EXTENDED (with subselect). used to crash.
--
error
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
# This is actually a valid query for this sql_mode,
# but it was transformed in such a way that it failed, see
# Bug#12329653 - EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
EXPLAIN
EXTENDED
SELECT
1
FROM
t1
EXPLAIN
EXTENDED
SELECT
1
FROM
t1
WHERE
f1
>
ALL
(
SELECT
t
.
f1
FROM
t1
,
t1
AS
t
);
WHERE
f1
>
ALL
(
SELECT
t
.
f1
FROM
t1
,
t1
AS
t
);
SHOW
WARNINGS
;
SET
SESSION
sql_mode
=@
old_sql_mode
;
SET
SESSION
sql_mode
=@
old_sql_mode
;
...
...
mysql-test/t/subselect.test
View file @
9baf84e9
...
@@ -3393,6 +3393,39 @@ ORDER BY outr.pk;
...
@@ -3393,6 +3393,39 @@ ORDER BY outr.pk;
DROP
TABLE
t1
,
t2
;
DROP
TABLE
t1
,
t2
;
--
echo
#
--
echo
# Bug#12329653
--
echo
# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
--
echo
#
CREATE
TABLE
t1
(
a1
int
);
INSERT
INTO
t1
VALUES
(
1
),(
2
);
SELECT
@@
session
.
sql_mode
INTO
@
old_sql_mode
;
SET
SESSION
sql_mode
=
'ONLY_FULL_GROUP_BY'
;
## First a simpler query, illustrating the transformation
## '1 < some (...)' => '1 < max(...)'
SELECT
1
FROM
t1
WHERE
1
<
SOME
(
SELECT
a1
FROM
t1
);
## The query which made the server crash.
PREPARE
stmt
FROM
'SELECT 1 UNION ALL
SELECT 1 FROM t1
ORDER BY
(SELECT 1 FROM t1 AS t1_0
WHERE 1 < SOME (SELECT a1 FROM t1)
)'
;
--
error
ER_SUBQUERY_NO_1_ROW
EXECUTE
stmt
;
--
error
ER_SUBQUERY_NO_1_ROW
EXECUTE
stmt
;
SET
SESSION
sql_mode
=@
old_sql_mode
;
DEALLOCATE
PREPARE
stmt
;
DROP
TABLE
t1
;
--
echo
End
of
5.0
tests
.
--
echo
End
of
5.0
tests
.
...
...
sql/item.cc
View file @
9baf84e9
...
@@ -4464,14 +4464,14 @@ mark_non_agg_field:
...
@@ -4464,14 +4464,14 @@ mark_non_agg_field:
SELECT_LEX
*
select_lex
=
cached_table
?
SELECT_LEX
*
select_lex
=
cached_table
?
cached_table
->
select_lex
:
context
->
select_lex
;
cached_table
->
select_lex
:
context
->
select_lex
;
if
(
!
thd
->
lex
->
in_sum_func
)
if
(
!
thd
->
lex
->
in_sum_func
)
select_lex
->
full_group_by_flag
|=
NON_AGG_FIELD_USED
;
select_lex
->
set_non_agg_field_used
(
true
)
;
else
else
{
{
if
(
outer_fixed
)
if
(
outer_fixed
)
thd
->
lex
->
in_sum_func
->
outer_fields
.
push_back
(
this
);
thd
->
lex
->
in_sum_func
->
outer_fields
.
push_back
(
this
);
else
if
(
thd
->
lex
->
in_sum_func
->
nest_level
!=
else
if
(
thd
->
lex
->
in_sum_func
->
nest_level
!=
thd
->
lex
->
current_select
->
nest_level
)
thd
->
lex
->
current_select
->
nest_level
)
select_lex
->
full_group_by_flag
|=
NON_AGG_FIELD_USED
;
select_lex
->
set_non_agg_field_used
(
true
)
;
}
}
}
}
return
FALSE
;
return
FALSE
;
...
...
sql/item_subselect.cc
View file @
9baf84e9
...
@@ -1016,6 +1016,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -1016,6 +1016,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
it
.
replace
(
item
);
it
.
replace
(
item
);
}
}
DBUG_EXECUTE
(
"where"
,
print_where
(
item
,
"rewrite with MIN/MAX"
,
QT_ORDINARY
););
if
(
thd
->
variables
.
sql_mode
&
MODE_ONLY_FULL_GROUP_BY
)
{
DBUG_ASSERT
(
select_lex
->
non_agg_field_used
());
select_lex
->
set_non_agg_field_used
(
false
);
}
save_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
save_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
thd
->
lex
->
allow_sum_func
|=
1
<<
thd
->
lex
->
current_select
->
nest_level
;
thd
->
lex
->
allow_sum_func
|=
1
<<
thd
->
lex
->
current_select
->
nest_level
;
/*
/*
...
...
sql/item_sum.cc
View file @
9baf84e9
...
@@ -247,10 +247,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
...
@@ -247,10 +247,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
in_sum_func
->
outer_fields
.
push_back
(
field
);
in_sum_func
->
outer_fields
.
push_back
(
field
);
}
}
else
else
sel
->
full_group_by_flag
|=
NON_AGG_FIELD_USED
;
sel
->
set_non_agg_field_used
(
true
)
;
}
}
if
(
sel
->
nest_level
>
aggr_level
&&
if
(
sel
->
nest_level
>
aggr_level
&&
(
sel
->
full_group_by_flag
&
SUM_FUNC_USED
)
&&
(
sel
->
agg_func_used
()
)
&&
!
sel
->
group_list
.
elements
)
!
sel
->
group_list
.
elements
)
{
{
my_message
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
,
my_message
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
,
...
@@ -259,7 +259,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
...
@@ -259,7 +259,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
}
}
}
}
}
}
aggr_sel
->
full_group_by_flag
|=
SUM_FUNC_USED
;
aggr_sel
->
set_agg_func_used
(
true
)
;
update_used_tables
();
update_used_tables
();
thd
->
lex
->
in_sum_func
=
in_sum_func
;
thd
->
lex
->
in_sum_func
=
in_sum_func
;
return
FALSE
;
return
FALSE
;
...
...
sql/mysql_priv.h
View file @
9baf84e9
...
@@ -1469,13 +1469,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
...
@@ -1469,13 +1469,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
bool
allow_null_cond
,
int
*
error
);
bool
allow_null_cond
,
int
*
error
);
extern
Item
**
not_found_item
;
extern
Item
**
not_found_item
;
/*
A set of constants used for checking non aggregated fields and sum
functions mixture in the ONLY_FULL_GROUP_BY_MODE.
*/
#define NON_AGG_FIELD_USED 1
#define SUM_FUNC_USED 2
/*
/*
This enumeration type is used only by the function find_item_in_list
This enumeration type is used only by the function find_item_in_list
to return the info on how an item has been resolved against a list
to return the info on how an item has been resolved against a list
...
...
sql/sql_lex.cc
View file @
9baf84e9
...
@@ -1621,6 +1621,8 @@ void st_select_lex::init_query()
...
@@ -1621,6 +1621,8 @@ void st_select_lex::init_query()
nest_level
=
0
;
nest_level
=
0
;
link_next
=
0
;
link_next
=
0
;
lock_option
=
TL_READ_DEFAULT
;
lock_option
=
TL_READ_DEFAULT
;
m_non_agg_field_used
=
false
;
m_agg_func_used
=
false
;
}
}
void
st_select_lex
::
init_select
()
void
st_select_lex
::
init_select
()
...
@@ -1651,7 +1653,8 @@ void st_select_lex::init_select()
...
@@ -1651,7 +1653,8 @@ void st_select_lex::init_select()
non_agg_fields
.
empty
();
non_agg_fields
.
empty
();
cond_value
=
having_value
=
Item
::
COND_UNDEF
;
cond_value
=
having_value
=
Item
::
COND_UNDEF
;
inner_refs_list
.
empty
();
inner_refs_list
.
empty
();
full_group_by_flag
=
0
;
m_non_agg_field_used
=
false
;
m_agg_func_used
=
false
;
}
}
/*
/*
...
...
sql/sql_lex.h
View file @
9baf84e9
...
@@ -713,16 +713,7 @@ public:
...
@@ -713,16 +713,7 @@ public:
joins on the right.
joins on the right.
*/
*/
List
<
String
>
*
prev_join_using
;
List
<
String
>
*
prev_join_using
;
/*
Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate
functions and non aggregated fields when GROUP BY list is absent.
Bits:
0 - non aggregated fields are used in this select,
defined as NON_AGG_FIELD_USED.
1 - aggregate functions are used in this select,
defined as SUM_FUNC_USED.
*/
uint8
full_group_by_flag
;
void
init_query
();
void
init_query
();
void
init_select
();
void
init_select
();
st_select_lex_unit
*
master_unit
();
st_select_lex_unit
*
master_unit
();
...
@@ -830,7 +821,22 @@ public:
...
@@ -830,7 +821,22 @@ public:
void
clear_index_hints
(
void
)
{
index_hints
=
NULL
;
}
void
clear_index_hints
(
void
)
{
index_hints
=
NULL
;
}
/*
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
- Non-aggregated fields are used in this select.
- Aggregate functions are used in this select.
In MODE_ONLY_FULL_GROUP_BY only one of these may be true.
*/
bool
non_agg_field_used
()
const
{
return
m_non_agg_field_used
;
}
bool
agg_func_used
()
const
{
return
m_agg_func_used
;
}
void
set_non_agg_field_used
(
bool
val
)
{
m_non_agg_field_used
=
val
;
}
void
set_agg_func_used
(
bool
val
)
{
m_agg_func_used
=
val
;
}
private:
private:
bool
m_non_agg_field_used
;
bool
m_agg_func_used
;
/* current index hint kind. used in filling up index_hints */
/* current index hint kind. used in filling up index_hints */
enum
index_hint_type
current_index_hint_type
;
enum
index_hint_type
current_index_hint_type
;
index_clause_map
current_index_hint_clause
;
index_clause_map
current_index_hint_clause
;
...
...
sql/sql_partition.cc
View file @
9baf84e9
...
@@ -930,9 +930,6 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
...
@@ -930,9 +930,6 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
const
char
*
save_where
;
const
char
*
save_where
;
char
*
db_name
;
char
*
db_name
;
char
db_name_string
[
FN_REFLEN
];
char
db_name_string
[
FN_REFLEN
];
bool
save_use_only_table_context
;
uint8
saved_full_group_by_flag
;
nesting_map
saved_allow_sum_func
;
DBUG_ENTER
(
"fix_fields_part_func"
);
DBUG_ENTER
(
"fix_fields_part_func"
);
if
(
part_info
->
fixed
)
if
(
part_info
->
fixed
)
...
@@ -999,23 +996,26 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
...
@@ -999,23 +996,26 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
of interesting side effects, both desirable and undesirable.
of interesting side effects, both desirable and undesirable.
*/
*/
save_use_only_table_context
=
thd
->
lex
->
use_only_table_context
;
{
const
bool
save_use_only_table_context
=
thd
->
lex
->
use_only_table_context
;
thd
->
lex
->
use_only_table_context
=
TRUE
;
thd
->
lex
->
use_only_table_context
=
TRUE
;
thd
->
lex
->
current_select
->
cur_pos_in_select_list
=
UNDEF_POS
;
thd
->
lex
->
current_select
->
cur_pos_in_select_list
=
UNDEF_POS
;
saved_full_group_by_flag
=
thd
->
lex
->
current_select
->
full_group_by_flag
;
const
bool
save_agg_field
=
thd
->
lex
->
current_select
->
non_agg_field_used
();
saved_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
const
bool
save_agg_func
=
thd
->
lex
->
current_select
->
agg_func_used
();
const
nesting_map
saved_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
thd
->
lex
->
allow_sum_func
=
0
;
thd
->
lex
->
allow_sum_func
=
0
;
error
=
func_expr
->
fix_fields
(
thd
,
(
Item
**
)
&
func_expr
);
error
=
func_expr
->
fix_fields
(
thd
,
(
Item
**
)
&
func_expr
);
/*
/*
Restore full_group_by_flag
and allow_sum_func,
Restore agg_field/agg_func
and allow_sum_func,
fix_fields should not affect mysql_select later, see Bug#46923.
fix_fields should not affect mysql_select later, see Bug#46923.
*/
*/
thd
->
lex
->
current_select
->
full_group_by_flag
=
saved_full_group_by_flag
;
thd
->
lex
->
current_select
->
set_non_agg_field_used
(
save_agg_field
);
thd
->
lex
->
current_select
->
set_agg_func_used
(
save_agg_func
);
thd
->
lex
->
allow_sum_func
=
saved_allow_sum_func
;
thd
->
lex
->
allow_sum_func
=
saved_allow_sum_func
;
thd
->
lex
->
use_only_table_context
=
save_use_only_table_context
;
thd
->
lex
->
use_only_table_context
=
save_use_only_table_context
;
}
context
->
table_list
=
save_table_list
;
context
->
table_list
=
save_table_list
;
context
->
first_name_resolution_table
=
save_first_table
;
context
->
first_name_resolution_table
=
save_first_table
;
...
...
sql/sql_select.cc
View file @
9baf84e9
...
@@ -426,19 +426,18 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
...
@@ -426,19 +426,18 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
int
res
;
int
res
;
nesting_map
save_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
nesting_map
save_allow_sum_func
=
thd
->
lex
->
allow_sum_func
;
/*
/*
Need to save the value, so we can turn off only
the new NON_AGG_FIELD
Need to save the value, so we can turn off only
any new non_agg_field_used
additions coming from the WHERE
additions coming from the WHERE
*/
*/
uint8
saved_flag
=
thd
->
lex
->
current_select
->
full_group_by_flag
;
const
bool
saved_non_agg_field_used
=
thd
->
lex
->
current_select
->
non_agg_field_used
();
DBUG_ENTER
(
"setup_without_group"
);
DBUG_ENTER
(
"setup_without_group"
);
thd
->
lex
->
allow_sum_func
&=
~
(
1
<<
thd
->
lex
->
current_select
->
nest_level
);
thd
->
lex
->
allow_sum_func
&=
~
(
1
<<
thd
->
lex
->
current_select
->
nest_level
);
res
=
setup_conds
(
thd
,
tables
,
leaves
,
conds
);
res
=
setup_conds
(
thd
,
tables
,
leaves
,
conds
);
/* it's not wrong to have non-aggregated columns in a WHERE */
/* it's not wrong to have non-aggregated columns in a WHERE */
if
(
thd
->
variables
.
sql_mode
&
MODE_ONLY_FULL_GROUP_BY
)
thd
->
lex
->
current_select
->
set_non_agg_field_used
(
saved_non_agg_field_used
);
thd
->
lex
->
current_select
->
full_group_by_flag
=
saved_flag
|
(
thd
->
lex
->
current_select
->
full_group_by_flag
&
~
NON_AGG_FIELD_USED
);
thd
->
lex
->
allow_sum_func
|=
1
<<
thd
->
lex
->
current_select
->
nest_level
;
thd
->
lex
->
allow_sum_func
|=
1
<<
thd
->
lex
->
current_select
->
nest_level
;
res
=
res
||
setup_order
(
thd
,
ref_pointer_array
,
tables
,
fields
,
all_fields
,
res
=
res
||
setup_order
(
thd
,
ref_pointer_array
,
tables
,
fields
,
all_fields
,
...
@@ -644,7 +643,8 @@ JOIN::prepare(Item ***rref_pointer_array,
...
@@ -644,7 +643,8 @@ JOIN::prepare(Item ***rref_pointer_array,
aggregate functions with implicit grouping (there is no GROUP BY).
aggregate functions with implicit grouping (there is no GROUP BY).
*/
*/
if
(
thd
->
variables
.
sql_mode
&
MODE_ONLY_FULL_GROUP_BY
&&
!
group_list
&&
if
(
thd
->
variables
.
sql_mode
&
MODE_ONLY_FULL_GROUP_BY
&&
!
group_list
&&
select_lex
->
full_group_by_flag
==
(
NON_AGG_FIELD_USED
|
SUM_FUNC_USED
))
select_lex
->
non_agg_field_used
()
&&
select_lex
->
agg_func_used
())
{
{
my_message
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
,
my_message
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
,
ER
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
),
MYF
(
0
));
ER
(
ER_MIX_OF_GROUP_FUNC_AND_FIELDS
),
MYF
(
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