Commit 4ece8ae4 authored by joreland@mysql.com's avatar joreland@mysql.com

Merge joreland@bk-internal.mysql.com:/home/bk/mysql-4.1

into mysql.com:/home/jonas/src/mysql-4.1
parents f06452fb 7213ca46
...@@ -214,7 +214,7 @@ if (-d $target_dir) ...@@ -214,7 +214,7 @@ if (-d $target_dir)
@stat= stat("$target_dir/configure.in"); @stat= stat("$target_dir/configure.in");
my $mtime= $stat[9]; my $mtime= $stat[9];
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime); my ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
my $mtime= sprintf("%04d%-02d-%02d-%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min); my $mtime= sprintf("%04d-%02d-%02d-%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min);
&logger("Renaming $target_dir to $target_dir-$mtime"); &logger("Renaming $target_dir to $target_dir-$mtime");
$command= "mv "; $command= "mv ";
......
...@@ -7,7 +7,7 @@ use Sys::Hostname; ...@@ -7,7 +7,7 @@ use Sys::Hostname;
@config_options= (); @config_options= ();
@make_options= (); @make_options= ();
$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env=""; $opt_comment=$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix=""; $opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix=""; $opt_tmp=$opt_version_suffix="";
$opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0; $opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0;
...@@ -17,6 +17,7 @@ GetOptions( ...@@ -17,6 +17,7 @@ GetOptions(
"bdb", "bdb",
"build-thread=i", "build-thread=i",
"bundled-zlib", "bundled-zlib",
"comment=s",
"config-env=s" => \@config_env, "config-env=s" => \@config_env,
"config-extra-env=s" => \@config_extra_env, "config-extra-env=s" => \@config_extra_env,
"config-options=s" => \@config_options, "config-options=s" => \@config_options,
...@@ -110,6 +111,7 @@ $log="$pwd/Logs/$host-$major.$minor$opt_version_suffix.log"; ...@@ -110,6 +111,7 @@ $log="$pwd/Logs/$host-$major.$minor$opt_version_suffix.log";
$opt_distribution =~ /(mysql[^\/]*)\.tar/; $opt_distribution =~ /(mysql[^\/]*)\.tar/;
$ver=$1; $ver=$1;
$gcc_version=which("gcc"); $gcc_version=which("gcc");
$opt_comment= "Official MySQL$opt_version_suffix binary" unless $opt_comment;
if (defined($gcc_version) && ! $opt_config_env) if (defined($gcc_version) && ! $opt_config_env)
{ {
$tmp=`$gcc_version -v 2>&1`; $tmp=`$gcc_version -v 2>&1`;
...@@ -303,7 +305,7 @@ if ($opt_stage <= 1) ...@@ -303,7 +305,7 @@ if ($opt_stage <= 1)
} }
$prefix="/usr/local/mysql"; $prefix="/usr/local/mysql";
check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL"); check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"$opt_comment\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL");
if (-d "$pwd/$host/include-mysql") if (-d "$pwd/$host/include-mysql")
{ {
safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include"); safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include");
...@@ -530,6 +532,10 @@ When running several Do-compile runs in parallel, each build ...@@ -530,6 +532,10 @@ When running several Do-compile runs in parallel, each build
should have its own thread ID, so running the test suites should have its own thread ID, so running the test suites
does not cause conflicts with duplicate TCP port numbers. does not cause conflicts with duplicate TCP port numbers.
--comment=<comment>
Replace the default compilation comment that is embedded into
the mysqld binary.
--config-env=<environment for configure> --config-env=<environment for configure>
To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3' To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3'
...@@ -684,16 +690,20 @@ sub abort ...@@ -684,16 +690,20 @@ sub abort
if ($opt_user) if ($opt_user)
{ {
$mail_header_file="$opt_tmp/do-command.$$"; # Take the last 40 lines of the build log
open(TMP,">$mail_header_file"); open(LOG, "$log") or die $!;
my @log= <LOG>;
close LOG;
splice @log => 0, -40;
my $mail_file="$opt_tmp/do-command.$$";
open(TMP,">$mail_file") or die $!;
print TMP "From: mysqldev\@$full_host_name\n"; print TMP "From: mysqldev\@$full_host_name\n";
print TMP "To: $email\n"; print TMP "To: $email\n";
print TMP "Subject: $host($uname): $ver$opt_version_suffix compilation failed\n\n"; print TMP "Subject: $host($uname): $ver$opt_version_suffix compilation failed\n\n";
print TMP @log;
close TMP; close TMP;
system("tail -n 40 $log > $log.mail"); system("$sendmail -t -f $email < $mail_file");
system("cat $mail_header_file $log.mail | $sendmail -t -f $email"); unlink($mail_file);
unlink($mail_header_file);
unlink("$log.mail");
} }
exit 1; exit 1;
} }
......
...@@ -1008,6 +1008,7 @@ static void usage(void) ...@@ -1008,6 +1008,7 @@ static void usage(void)
print_defaults("my",load_default_groups); print_defaults("my",load_default_groups);
puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ puts("\nWhere command is a one or more of: (Commands may be shortened)\n\
create databasename Create a new database\n\ create databasename Create a new database\n\
debug Instruct server to write debug information to log\n\
drop databasename Delete a database and all its tables\n\ drop databasename Delete a database and all its tables\n\
extended-status Gives an extended status message from the server\n\ extended-status Gives an extended status message from the server\n\
flush-hosts Flush all cached hosts\n\ flush-hosts Flush all cached hosts\n\
......
...@@ -1677,8 +1677,8 @@ then ...@@ -1677,8 +1677,8 @@ then
elif test "$with_debug" = "full" elif test "$with_debug" = "full"
then then
# Full debug. Very slow in some cases # Full debug. Very slow in some cases
CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC -DUNIV_DEBUG $CFLAGS" CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS"
CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC -DUNIV_DEBUG $CXXFLAGS" CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
else else
# Optimized version. No debug # Optimized version. No debug
CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS" CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS"
......
...@@ -325,6 +325,19 @@ trim(trailing 'foo' from 'foo') ...@@ -325,6 +325,19 @@ trim(trailing 'foo' from 'foo')
select trim(leading 'foo' from 'foo'); select trim(leading 'foo' from 'foo');
trim(leading 'foo' from 'foo') trim(leading 'foo' from 'foo')
select quote(ltrim(concat(' ', 'a')));
quote(ltrim(concat(' ', 'a')))
'a'
select quote(trim(concat(' ', 'a')));
quote(trim(concat(' ', 'a')))
'a'
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
QUOTE('A')
'A'
'A'
'A'
DROP TABLE t1;
select 1=_latin1'1'; select 1=_latin1'1';
1=_latin1'1' 1=_latin1'1'
1 1
...@@ -691,12 +704,6 @@ select count(*) as total, left(c,10) as reg from t1 group by reg order by reg de ...@@ -691,12 +704,6 @@ select count(*) as total, left(c,10) as reg from t1 group by reg order by reg de
total reg total reg
10 2004-12-10 10 2004-12-10
drop table t1; drop table t1;
select quote(ltrim(concat(' ', 'a')));
quote(ltrim(concat(' ', 'a')))
'a'
select quote(trim(concat(' ', 'a')));
quote(trim(concat(' ', 'a')))
'a'
select trim(null from 'kate') as "must_be_null"; select trim(null from 'kate') as "must_be_null";
must_be_null must_be_null
NULL NULL
......
...@@ -195,6 +195,18 @@ select trim(trailing 'foo' from 'foo'); ...@@ -195,6 +195,18 @@ select trim(trailing 'foo' from 'foo');
select trim(leading 'foo' from 'foo'); select trim(leading 'foo' from 'foo');
# #
# crashing bug with QUOTE() and LTRIM() or TRIM() fixed
# Bug #7495
#
select quote(ltrim(concat(' ', 'a')));
select quote(trim(concat(' ', 'a')));
# Bad results from QUOTE(). Bug #8248
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
DROP TABLE t1;
# Test collation and coercibility # Test collation and coercibility
# #
...@@ -429,12 +441,6 @@ create table t1 (a int not null primary key, b varchar(40), c datetime); ...@@ -429,12 +441,6 @@ create table t1 (a int not null primary key, b varchar(40), c datetime);
insert into t1 (a,b,c) values (1,'Tom','2004-12-10 12:13:14'),(2,'ball games','2004-12-10 12:13:14'), (3,'Basil','2004-12-10 12:13:14'), (4,'Dean','2004-12-10 12:13:14'),(5,'Ellis','2004-12-10 12:13:14'), (6,'Serg','2004-12-10 12:13:14'), (7,'Sergei','2004-12-10 12:13:14'),(8,'Georg','2004-12-10 12:13:14'),(9,'Salle','2004-12-10 12:13:14'),(10,'Sinisa','2004-12-10 12:13:14'); insert into t1 (a,b,c) values (1,'Tom','2004-12-10 12:13:14'),(2,'ball games','2004-12-10 12:13:14'), (3,'Basil','2004-12-10 12:13:14'), (4,'Dean','2004-12-10 12:13:14'),(5,'Ellis','2004-12-10 12:13:14'), (6,'Serg','2004-12-10 12:13:14'), (7,'Sergei','2004-12-10 12:13:14'),(8,'Georg','2004-12-10 12:13:14'),(9,'Salle','2004-12-10 12:13:14'),(10,'Sinisa','2004-12-10 12:13:14');
select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12; select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12;
drop table t1; drop table t1;
# crashing bug with QUOTE() and LTRIM() or TRIM() fixed
# Bug #7495
#
select quote(ltrim(concat(' ', 'a')));
select quote(trim(concat(' ', 'a')));
# #
# Bug#7455 unexpected result: TRIM(<NULL> FROM <whatever>) gives NOT NULL # Bug#7455 unexpected result: TRIM(<NULL> FROM <whatever>) gives NOT NULL
......
...@@ -107,8 +107,11 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \ ...@@ -107,8 +107,11 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \ client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
client/mysqldump$BS client/mysqlimport$BS \ client/mysqldump$BS client/mysqlimport$BS \
client/mysqltest$BS client/mysqlcheck$BS \ client/mysqltest$BS client/mysqlcheck$BS \
client/mysqlbinlog$BS client/mysqlbinlog$BS \
"; tests/mysql_client_test$BS \
libmysqld/examples/mysql_client_test_embedded$BS \
libmysqld/examples/mysqltest_embedded$BS \
";
# Platform-specific bin dir files: # Platform-specific bin dir files:
if [ $BASE_SYSTEM = "netware" ] ; then if [ $BASE_SYSTEM = "netware" ] ; then
...@@ -127,8 +130,9 @@ else ...@@ -127,8 +130,9 @@ else
client/.libs/mysqltest client/.libs/mysqlcheck \ client/.libs/mysqltest client/.libs/mysqlcheck \
client/.libs/mysqlbinlog client/.libs/mysqlmanagerc \ client/.libs/mysqlbinlog client/.libs/mysqlmanagerc \
client/.libs/mysqlmanager-pwgen tools/.libs/mysqlmanager \ client/.libs/mysqlmanager-pwgen tools/.libs/mysqlmanager \
tests/.libs/mysql_client_test libmysqld/examples/mysql_client_test_embedded \ tests/.libs/mysql_client_test \
libmysqld/examples/mysqltest_embedded \ libmysqld/examples/.libs/mysql_client_test_embedded \
libmysqld/examples/.libs/mysqltest_embedded \
"; ";
fi fi
......
...@@ -2614,18 +2614,13 @@ String *Item_func_quote::val_str(String *str) ...@@ -2614,18 +2614,13 @@ String *Item_func_quote::val_str(String *str)
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
new_length+= get_esc_bit(escmask, (uchar) *from); new_length+= get_esc_bit(escmask, (uchar) *from);
/* if (tmp_value.alloc(new_length))
We have to use realloc() instead of alloc() as we want to keep the
old result in arg
*/
if (arg->realloc(new_length))
goto null; goto null;
/* /*
As 'arg' and 'str' may be the same string, we must replace characters We replace characters from the end to the beginning
from the end to the beginning
*/ */
to= (char*) arg->ptr() + new_length - 1; to= (char*) tmp_value.ptr() + new_length - 1;
*to--= '\''; *to--= '\'';
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
{ {
...@@ -2653,10 +2648,10 @@ String *Item_func_quote::val_str(String *str) ...@@ -2653,10 +2648,10 @@ String *Item_func_quote::val_str(String *str)
} }
} }
*to= '\''; *to= '\'';
arg->length(new_length); tmp_value.length(new_length);
str->set_charset(collation.collation); tmp_value.set_charset(collation.collation);
null_value= 0; null_value= 0;
return arg; return &tmp_value;
null: null:
null_value= 1; null_value= 1;
......
...@@ -588,6 +588,7 @@ class Item_func_inet_ntoa : public Item_str_func ...@@ -588,6 +588,7 @@ class Item_func_inet_ntoa : public Item_str_func
class Item_func_quote :public Item_str_func class Item_func_quote :public Item_str_func
{ {
String tmp_value;
public: public:
Item_func_quote(Item *a) :Item_str_func(a) {} Item_func_quote(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "quote"; } const char *func_name() const { return "quote"; }
......
...@@ -5215,6 +5215,7 @@ The minimum value for this variable is 4096.", ...@@ -5215,6 +5215,7 @@ The minimum value for this variable is 4096.",
(gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period,
(gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, (gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1,
0}, 0},
#ifdef DOES_NOTHING_YET
{"sync-replication", OPT_SYNC_REPLICATION, {"sync-replication", OPT_SYNC_REPLICATION,
"Enable synchronous replication", "Enable synchronous replication",
(gptr*) &global_system_variables.sync_replication, (gptr*) &global_system_variables.sync_replication,
...@@ -5230,6 +5231,7 @@ The minimum value for this variable is 4096.", ...@@ -5230,6 +5231,7 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.sync_replication_timeout, (gptr*) &global_system_variables.sync_replication_timeout,
(gptr*) &global_system_variables.sync_replication_timeout, (gptr*) &global_system_variables.sync_replication_timeout,
0, GET_ULONG, REQUIRED_ARG, 10, 0, ~0L, 0, 1, 0}, 0, GET_ULONG, REQUIRED_ARG, 10, 0, ~0L, 0, 1, 0},
#endif
{"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default",
(gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
0, 0, 0, 0}, 0, 0, 0, 0},
......
...@@ -660,6 +660,8 @@ static int check_connection(THD *thd) ...@@ -660,6 +660,8 @@ static int check_connection(THD *thd)
DBUG_PRINT("info", DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio))); ("New connection received on %s", vio_description(net->vio)));
vio_in_addr(net->vio,&thd->remote.sin_addr);
if (!thd->host) // If TCP/IP connection if (!thd->host) // If TCP/IP connection
{ {
char ip[30]; char ip[30];
...@@ -704,7 +706,6 @@ static int check_connection(THD *thd) ...@@ -704,7 +706,6 @@ static int check_connection(THD *thd)
DBUG_PRINT("info",("Host: %s",thd->host)); DBUG_PRINT("info",("Host: %s",thd->host));
thd->host_or_ip= thd->host; thd->host_or_ip= thd->host;
thd->ip= 0; thd->ip= 0;
bzero((char*) &thd->remote, sizeof(struct sockaddr));
} }
vio_keepalive(net->vio, TRUE); vio_keepalive(net->vio, TRUE);
ulong pkt_len= 0; ulong pkt_len= 0;
......
...@@ -57,11 +57,11 @@ int mysql_update(THD *thd, ...@@ -57,11 +57,11 @@ int mysql_update(THD *thd,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
bool ignore) bool ignore)
{ {
bool using_limit=limit != HA_POS_ERROR; bool using_limit=limit != HA_POS_ERROR;
bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool safe_update= thd->options & OPTION_SAFE_UPDATES;
bool used_key_is_modified, transactional_table, log_delayed; bool used_key_is_modified, transactional_table, log_delayed;
int error=0; int error=0;
uint used_index= MAX_KEY; uint used_index;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege; uint want_privilege;
#endif #endif
...@@ -71,7 +71,7 @@ int mysql_update(THD *thd, ...@@ -71,7 +71,7 @@ int mysql_update(THD *thd,
TABLE *table; TABLE *table;
SQL_SELECT *select; SQL_SELECT *select;
READ_RECORD info; READ_RECORD info;
TABLE_LIST *update_table_list= ((TABLE_LIST*) TABLE_LIST *update_table_list= ((TABLE_LIST*)
thd->lex->select_lex.table_list.first); thd->lex->select_lex.table_list.first);
DBUG_ENTER("mysql_update"); DBUG_ENTER("mysql_update");
...@@ -159,10 +159,11 @@ int mysql_update(THD *thd, ...@@ -159,10 +159,11 @@ int mysql_update(THD *thd,
init_ftfuncs(thd, &thd->lex->select_lex, 1); init_ftfuncs(thd, &thd->lex->select_lex, 1);
/* Check if we are modifying a key that we are used to search with */ /* Check if we are modifying a key that we are used to search with */
if (select && select->quick) if (select && select->quick)
{
used_index=select->quick->index;
used_key_is_modified= (!select->quick->unique_key_range() && used_key_is_modified= (!select->quick->unique_key_range() &&
check_if_key_used(table, check_if_key_used(table, used_index, fields));
(used_index=select->quick->index), }
fields));
else if ((used_index=table->file->key_used_on_scan) < MAX_KEY) else if ((used_index=table->file->key_used_on_scan) < MAX_KEY)
used_key_is_modified=check_if_key_used(table, used_index, fields); used_key_is_modified=check_if_key_used(table, used_index, fields);
else else
......
...@@ -276,7 +276,7 @@ void vio_in_addr(Vio *vio, struct in_addr *in) ...@@ -276,7 +276,7 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
{ {
DBUG_ENTER("vio_in_addr"); DBUG_ENTER("vio_in_addr");
if (vio->localhost) if (vio->localhost)
bzero((char*) in, sizeof(*in)); /* This should never be executed */ bzero((char*) in, sizeof(*in));
else else
*in=vio->remote.sin_addr; *in=vio->remote.sin_addr;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -259,7 +259,7 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in) ...@@ -259,7 +259,7 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
{ {
DBUG_ENTER("vio_ssl_in_addr"); DBUG_ENTER("vio_ssl_in_addr");
if (vio->localhost) if (vio->localhost)
bzero((char*) in, sizeof(*in)); /* This should never be executed */ bzero((char*) in, sizeof(*in));
else else
*in=vio->remote.sin_addr; *in=vio->remote.sin_addr;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment