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
17e6c8f2
Commit
17e6c8f2
authored
Apr 29, 2005
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/usr/local/home/marty/MySQL/mysql-5.0
parents
b84dc099
027f9390
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
122 additions
and
24 deletions
+122
-24
mysql-test/r/ndb_multi.result
mysql-test/r/ndb_multi.result
+21
-1
mysql-test/t/ndb_multi.test
mysql-test/t/ndb_multi.test
+24
-0
ndb/include/ndbapi/NdbDictionary.hpp
ndb/include/ndbapi/NdbDictionary.hpp
+4
-1
ndb/src/ndbapi/NdbDictionaryImpl.cpp
ndb/src/ndbapi/NdbDictionaryImpl.cpp
+7
-4
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.cc
+64
-16
sql/ha_ndbcluster.h
sql/ha_ndbcluster.h
+2
-2
No files found.
mysql-test/r/ndb_multi.result
View file @
17e6c8f2
...
@@ -13,6 +13,26 @@ a
...
@@ -13,6 +13,26 @@ a
show status like 'handler_discover%';
show status like 'handler_discover%';
Variable_name Value
Variable_name Value
Handler_discover 0
Handler_discover 0
select * from t1;
a
2
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
a
2
show status like 'handler_discover%';
Variable_name Value
Handler_discover 0
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster
select * from t1;
a
2
flush status;
flush status;
select * from t1;
select * from t1;
a
a
...
@@ -20,7 +40,7 @@ a
...
@@ -20,7 +40,7 @@ a
update t1 set a=3 where a=2;
update t1 set a=3 where a=2;
show status like 'handler_discover%';
show status like 'handler_discover%';
Variable_name Value
Variable_name Value
Handler_discover
1
Handler_discover
0
create table t3 (a int not null primary key, b varchar(22),
create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb;
c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column');
insert into t3 values(1, 'Hi!', 89, 'Longtext column');
...
...
mysql-test/t/ndb_multi.test
View file @
17e6c8f2
...
@@ -18,6 +18,30 @@ select * from t1;
...
@@ -18,6 +18,30 @@ select * from t1;
select
*
from
t2
;
select
*
from
t2
;
show
status
like
'handler_discover%'
;
show
status
like
'handler_discover%'
;
# Check dropping and recreating table on same server
connect
(
con1
,
localhost
,,,
test
);
connect
(
con2
,
localhost
,,,
test
);
connection
con1
;
select
*
from
t1
;
connection
con2
;
drop
table
t1
;
create
table
t1
(
a
int
)
engine
=
ndbcluster
;
insert
into
t1
value
(
2
);
connection
con1
;
select
*
from
t1
;
# Check dropping and recreating table on different server
connection
server2
;
show
status
like
'handler_discover%'
;
drop
table
t1
;
create
table
t1
(
a
int
)
engine
=
ndbcluster
;
insert
into
t1
value
(
2
);
connection
server1
;
# Currently a retry is required remotely
--
error
1296
select
*
from
t1
;
select
*
from
t1
;
# Connect to server2 and use the tables from there
# Connect to server2 and use the tables from there
connection
server2
;
connection
server2
;
flush
status
;
flush
status
;
...
...
ndb/include/ndbapi/NdbDictionary.hpp
View file @
17e6c8f2
...
@@ -76,8 +76,11 @@ public:
...
@@ -76,8 +76,11 @@ public:
Changed
,
///< The object has been modified in memory
Changed
,
///< The object has been modified in memory
///< and has to be commited in NDB Kernel for
///< and has to be commited in NDB Kernel for
///< changes to take effect
///< changes to take effect
Retrieved
///< The object exist and has been read
Retrieved
,
///< The object exist and has been read
///< into main memory from NDB Kernel
///< into main memory from NDB Kernel
Invalid
///< The object has been invalidated
///< and should not be used
};
};
/**
/**
...
...
ndb/src/ndbapi/NdbDictionaryImpl.cpp
View file @
17e6c8f2
...
@@ -1526,6 +1526,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
...
@@ -1526,6 +1526,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
// If in local cache it must be in global
// If in local cache it must be in global
if
(
!
cachedImpl
)
if
(
!
cachedImpl
)
abort
();
abort
();
cachedImpl
->
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
cachedImpl
);
m_globalHash
->
drop
(
cachedImpl
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
}
}
...
@@ -1830,8 +1831,8 @@ NdbDictionaryImpl::dropTable(const char * name)
...
@@ -1830,8 +1831,8 @@ NdbDictionaryImpl::dropTable(const char * name)
DBUG_PRINT
(
"info"
,(
"INCOMPATIBLE_VERSION internal_name: %s"
,
internalTableName
));
DBUG_PRINT
(
"info"
,(
"INCOMPATIBLE_VERSION internal_name: %s"
,
internalTableName
));
m_localHash
.
drop
(
internalTableName
);
m_localHash
.
drop
(
internalTableName
);
m_globalHash
->
lock
();
m_globalHash
->
lock
();
tab
->
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
tab
);
m_globalHash
->
drop
(
tab
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
DBUG_RETURN
(
dropTable
(
name
));
DBUG_RETURN
(
dropTable
(
name
));
...
@@ -1875,10 +1876,11 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
...
@@ -1875,10 +1876,11 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
int
ret
=
m_receiver
.
dropTable
(
impl
);
int
ret
=
m_receiver
.
dropTable
(
impl
);
if
(
ret
==
0
||
m_error
.
code
==
709
){
if
(
ret
==
0
||
m_error
.
code
==
709
){
const
char
*
internalTableName
=
impl
.
m_internalName
.
c_str
();
const
char
*
internalTableName
=
impl
.
m_internalName
.
c_str
();
m_localHash
.
drop
(
internalTableName
);
m_localHash
.
drop
(
internalTableName
);
m_globalHash
->
lock
();
m_globalHash
->
lock
();
impl
.
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
&
impl
);
m_globalHash
->
drop
(
&
impl
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
...
@@ -1976,6 +1978,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
...
@@ -1976,6 +1978,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
m_localHash
.
drop
(
internalTableName
);
m_localHash
.
drop
(
internalTableName
);
m_globalHash
->
lock
();
m_globalHash
->
lock
();
impl
.
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
&
impl
);
m_globalHash
->
drop
(
&
impl
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
return
0
;
return
0
;
...
@@ -2242,8 +2245,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
...
@@ -2242,8 +2245,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
m_ndb
.
internalizeTableName
(
indexName
);
// Index is also a table
m_ndb
.
internalizeTableName
(
indexName
);
// Index is also a table
m_localHash
.
drop
(
internalIndexName
);
m_localHash
.
drop
(
internalIndexName
);
m_globalHash
->
lock
();
m_globalHash
->
lock
();
idx
->
m_table
->
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
idx
->
m_table
);
m_globalHash
->
drop
(
idx
->
m_table
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
return
dropIndex
(
indexName
,
tableName
);
return
dropIndex
(
indexName
,
tableName
);
...
@@ -2277,8 +2280,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
...
@@ -2277,8 +2280,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
int
ret
=
m_receiver
.
dropIndex
(
impl
,
*
timpl
);
int
ret
=
m_receiver
.
dropIndex
(
impl
,
*
timpl
);
if
(
ret
==
0
){
if
(
ret
==
0
){
m_localHash
.
drop
(
internalIndexName
);
m_localHash
.
drop
(
internalIndexName
);
m_globalHash
->
lock
();
m_globalHash
->
lock
();
impl
.
m_table
->
m_status
=
NdbDictionary
::
Object
::
Invalid
;
m_globalHash
->
drop
(
impl
.
m_table
);
m_globalHash
->
drop
(
impl
.
m_table
);
m_globalHash
->
unlock
();
m_globalHash
->
unlock
();
}
}
...
...
sql/ha_ndbcluster.cc
View file @
17e6c8f2
...
@@ -418,11 +418,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
...
@@ -418,11 +418,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
# The mapped error code
# The mapped error code
*/
*/
void
ha_ndbcluster
::
invalidate
DictionaryCache
(
)
void
ha_ndbcluster
::
invalidate
_dictionary_cache
(
bool
global
)
{
{
NDBDICT
*
dict
=
get_ndb
()
->
getDictionary
();
NDBDICT
*
dict
=
get_ndb
()
->
getDictionary
();
DBUG_ENTER
(
"invalidate_dictionary_cache"
);
DBUG_PRINT
(
"info"
,
(
"invalidating %s"
,
m_tabname
));
DBUG_PRINT
(
"info"
,
(
"invalidating %s"
,
m_tabname
));
dict
->
invalidateTable
(
m_tabname
);
if
(
global
)
{
const
NDBTAB
*
tab
=
dict
->
getTable
(
m_tabname
);
if
(
!
tab
)
DBUG_VOID_RETURN
;
if
(
tab
->
getObjectStatus
()
==
NdbDictionary
::
Object
::
Invalid
)
{
// Global cache has already been invalidated
dict
->
removeCachedTable
(
m_tabname
);
global
=
FALSE
;
}
else
dict
->
invalidateTable
(
m_tabname
);
}
else
dict
->
removeCachedTable
(
m_tabname
);
table
->
s
->
version
=
0L
;
/* Free when thread is ready */
table
->
s
->
version
=
0L
;
/* Free when thread is ready */
/* Invalidate indexes */
/* Invalidate indexes */
for
(
uint
i
=
0
;
i
<
table
->
s
->
keys
;
i
++
)
for
(
uint
i
=
0
;
i
<
table
->
s
->
keys
;
i
++
)
...
@@ -434,18 +451,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
...
@@ -434,18 +451,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
switch
(
idx_type
)
{
switch
(
idx_type
)
{
case
(
PRIMARY_KEY_ORDERED_INDEX
):
case
(
PRIMARY_KEY_ORDERED_INDEX
):
case
(
ORDERED_INDEX
):
case
(
ORDERED_INDEX
):
dict
->
invalidateIndex
(
index
->
getName
(),
m_tabname
);
if
(
global
)
dict
->
invalidateIndex
(
index
->
getName
(),
m_tabname
);
else
dict
->
removeCachedIndex
(
index
->
getName
(),
m_tabname
);
break
;
break
;
case
(
UNIQUE_ORDERED_INDEX
):
case
(
UNIQUE_ORDERED_INDEX
):
dict
->
invalidateIndex
(
index
->
getName
(),
m_tabname
);
if
(
global
)
dict
->
invalidateIndex
(
index
->
getName
(),
m_tabname
);
else
dict
->
removeCachedIndex
(
index
->
getName
(),
m_tabname
);
case
(
UNIQUE_INDEX
):
case
(
UNIQUE_INDEX
):
dict
->
invalidateIndex
(
unique_index
->
getName
(),
m_tabname
);
if
(
global
)
dict
->
invalidateIndex
(
unique_index
->
getName
(),
m_tabname
);
else
dict
->
removeCachedIndex
(
unique_index
->
getName
(),
m_tabname
);
break
;
break
;
case
(
PRIMARY_KEY_INDEX
):
case
(
PRIMARY_KEY_INDEX
):
case
(
UNDEFINED_INDEX
):
case
(
UNDEFINED_INDEX
):
break
;
break
;
}
}
}
}
DBUG_VOID_RETURN
;
}
}
int
ha_ndbcluster
::
ndb_err
(
NdbTransaction
*
trans
)
int
ha_ndbcluster
::
ndb_err
(
NdbTransaction
*
trans
)
...
@@ -457,7 +484,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
...
@@ -457,7 +484,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
ERR_PRINT
(
err
);
ERR_PRINT
(
err
);
switch
(
err
.
classification
)
{
switch
(
err
.
classification
)
{
case
NdbError
:
:
SchemaError
:
case
NdbError
:
:
SchemaError
:
invalidate
DictionaryCache
(
);
invalidate
_dictionary_cache
(
TRUE
);
if
(
err
.
code
==
284
)
if
(
err
.
code
==
284
)
{
{
...
@@ -882,7 +909,14 @@ int ha_ndbcluster::get_metadata(const char *path)
...
@@ -882,7 +909,14 @@ int ha_ndbcluster::get_metadata(const char *path)
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
)))
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
)))
ERR_RETURN
(
dict
->
getNdbError
());
ERR_RETURN
(
dict
->
getNdbError
());
DBUG_PRINT
(
"info"
,
(
"Table schema version: %d"
,
tab
->
getObjectVersion
()));
// Check if thread has stale local cache
if
(
tab
->
getObjectStatus
()
==
NdbDictionary
::
Object
::
Invalid
)
{
invalidate_dictionary_cache
(
FALSE
);
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
)))
ERR_RETURN
(
dict
->
getNdbError
());
DBUG_PRINT
(
"info"
,
(
"Table schema version: %d"
,
tab
->
getObjectVersion
()));
}
/*
/*
Compare FrmData in NDB with frm file from disk.
Compare FrmData in NDB with frm file from disk.
*/
*/
...
@@ -901,7 +935,7 @@ int ha_ndbcluster::get_metadata(const char *path)
...
@@ -901,7 +935,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if
(
!
invalidating_ndb_table
)
if
(
!
invalidating_ndb_table
)
{
{
DBUG_PRINT
(
"info"
,
(
"Invalidating table"
));
DBUG_PRINT
(
"info"
,
(
"Invalidating table"
));
invalidate
DictionaryCache
(
);
invalidate
_dictionary_cache
(
TRUE
);
invalidating_ndb_table
=
TRUE
;
invalidating_ndb_table
=
TRUE
;
}
}
else
else
...
@@ -927,7 +961,7 @@ int ha_ndbcluster::get_metadata(const char *path)
...
@@ -927,7 +961,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if
(
error
)
if
(
error
)
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
m_table
V
ersion
=
tab
->
getObjectVersion
();
m_table
_v
ersion
=
tab
->
getObjectVersion
();
m_table
=
(
void
*
)
tab
;
m_table
=
(
void
*
)
tab
;
m_table_info
=
NULL
;
// Set in external lock
m_table_info
=
NULL
;
// Set in external lock
...
@@ -3269,15 +3303,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
...
@@ -3269,15 +3303,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
void
*
tab_info
;
void
*
tab_info
;
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
,
&
tab_info
)))
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
,
&
tab_info
)))
ERR_RETURN
(
dict
->
getNdbError
());
ERR_RETURN
(
dict
->
getNdbError
());
DBUG_PRINT
(
"info"
,
(
"Table schema version: %d"
,
tab
->
getObjectVersion
()));
DBUG_PRINT
(
"info"
,
(
"Table schema version: %d"
,
if
(
m_table
!=
(
void
*
)
tab
||
m_tableVersion
!=
tab
->
getObjectVersion
())
tab
->
getObjectVersion
()));
// Check if thread has stale local cache
if
(
tab
->
getObjectStatus
()
==
NdbDictionary
::
Object
::
Invalid
)
{
invalidate_dictionary_cache
(
FALSE
);
if
(
!
(
tab
=
dict
->
getTable
(
m_tabname
,
&
tab_info
)))
ERR_RETURN
(
dict
->
getNdbError
());
DBUG_PRINT
(
"info"
,
(
"Table schema version: %d"
,
tab
->
getObjectVersion
()));
}
if
(
m_table
!=
(
void
*
)
tab
||
m_table_version
<
tab
->
getObjectVersion
())
{
{
/*
/*
The table has been altered, refresh the index list
The table has been altered, refresh the index list
*/
*/
build_index_list
(
ndb
,
table
,
ILBP_OPEN
);
build_index_list
(
ndb
,
table
,
ILBP_OPEN
);
m_table
=
(
void
*
)
tab
;
m_table
=
(
void
*
)
tab
;
m_table
V
ersion
=
tab
->
getObjectVersion
();
m_table
_v
ersion
=
tab
->
getObjectVersion
();
}
}
m_table_info
=
tab_info
;
m_table_info
=
tab_info
;
}
}
...
@@ -3321,7 +3365,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
...
@@ -3321,7 +3365,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd_ndb
->
stmt
=
NULL
;
thd_ndb
->
stmt
=
NULL
;
}
}
}
}
m_table
=
NULL
;
m_table_info
=
NULL
;
m_table_info
=
NULL
;
/*
/*
...
@@ -4036,7 +4079,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
...
@@ -4036,7 +4079,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
dict
=
ndb
->
getDictionary
();
dict
=
ndb
->
getDictionary
();
if
(
!
(
orig_tab
=
dict
->
getTable
(
m_tabname
)))
if
(
!
(
orig_tab
=
dict
->
getTable
(
m_tabname
)))
ERR_RETURN
(
dict
->
getNdbError
());
ERR_RETURN
(
dict
->
getNdbError
());
// Check if thread has stale local cache
if
(
orig_tab
->
getObjectStatus
()
==
NdbDictionary
::
Object
::
Invalid
)
{
dict
->
removeCachedTable
(
m_tabname
);
if
(
!
(
orig_tab
=
dict
->
getTable
(
m_tabname
)))
ERR_RETURN
(
dict
->
getNdbError
());
}
m_table
=
(
void
*
)
orig_tab
;
m_table
=
(
void
*
)
orig_tab
;
// Change current database to that of target table
// Change current database to that of target table
set_dbname
(
to
);
set_dbname
(
to
);
...
@@ -4159,7 +4208,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
...
@@ -4159,7 +4208,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_active_trans
(
NULL
),
m_active_trans
(
NULL
),
m_active_cursor
(
NULL
),
m_active_cursor
(
NULL
),
m_table
(
NULL
),
m_table
(
NULL
),
m_table
V
ersion
(
-
1
),
m_table
_v
ersion
(
-
1
),
m_table_info
(
NULL
),
m_table_info
(
NULL
),
m_table_flags
(
HA_REC_NOT_IN_SEQ
|
m_table_flags
(
HA_REC_NOT_IN_SEQ
|
HA_NULL_IN_KEY
|
HA_NULL_IN_KEY
|
...
@@ -4409,7 +4458,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
...
@@ -4409,7 +4458,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
ERR_RETURN
(
err
);
ERR_RETURN
(
err
);
}
}
DBUG_PRINT
(
"info"
,
(
"Found table %s"
,
tab
->
getName
()));
DBUG_PRINT
(
"info"
,
(
"Found table %s"
,
tab
->
getName
()));
len
=
tab
->
getFrmLength
();
len
=
tab
->
getFrmLength
();
...
...
sql/ha_ndbcluster.h
View file @
17e6c8f2
...
@@ -558,7 +558,7 @@ static void set_tabname(const char *pathname, char *tabname);
...
@@ -558,7 +558,7 @@ static void set_tabname(const char *pathname, char *tabname);
void
print_results
();
void
print_results
();
ulonglong
get_auto_increment
();
ulonglong
get_auto_increment
();
void
invalidate
DictionaryCache
(
);
void
invalidate
_dictionary_cache
(
bool
global
);
int
ndb_err
(
NdbTransaction
*
);
int
ndb_err
(
NdbTransaction
*
);
bool
uses_blob_value
(
bool
all_fields
);
bool
uses_blob_value
(
bool
all_fields
);
...
@@ -596,7 +596,7 @@ static void set_tabname(const char *pathname, char *tabname);
...
@@ -596,7 +596,7 @@ static void set_tabname(const char *pathname, char *tabname);
NdbTransaction
*
m_active_trans
;
NdbTransaction
*
m_active_trans
;
NdbScanOperation
*
m_active_cursor
;
NdbScanOperation
*
m_active_cursor
;
void
*
m_table
;
void
*
m_table
;
int
m_table
V
ersion
;
int
m_table
_v
ersion
;
void
*
m_table_info
;
void
*
m_table_info
;
char
m_dbname
[
FN_HEADLEN
];
char
m_dbname
[
FN_HEADLEN
];
//char m_schemaname[FN_HEADLEN];
//char m_schemaname[FN_HEADLEN];
...
...
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