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
a5c75df3
Commit
a5c75df3
authored
Dec 06, 2000
by
monty@donna.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge work:/my/mysql into donna.mysql.com:/home/my/bk/mysql
parents
263811a4
3666dab5
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
2700 additions
and
8 deletions
+2700
-8
BitKeeper/etc/logging_ok
BitKeeper/etc/logging_ok
+1
-1
Docs/manual.texi
Docs/manual.texi
+2
-0
client/mysql.cc
client/mysql.cc
+4
-4
sql/Makefile.am
sql/Makefile.am
+4
-2
sql/ha_innobase.cc
sql/ha_innobase.cc
+2431
-0
sql/ha_innobase.h
sql/ha_innobase.h
+182
-0
sql/handler.cc
sql/handler.cc
+8
-0
sql/handler.h
sql/handler.h
+1
-0
sql/mysqld.cc
sql/mysqld.cc
+57
-1
sql/sql_class.cc
sql/sql_class.cc
+1
-0
sql/sql_db.cc
sql/sql_db.cc
+8
-0
sql/sql_table.cc
sql/sql_table.cc
+1
-0
No files found.
BitKeeper/etc/logging_ok
View file @
a5c75df3
...
...
@@ -6,6 +6,7 @@ monty@donna.mysql.com
monty@narttu.mysql.fi
mwagner@evoq.home.mwagner.org
mwagner@work.mysql.com
sasha@donna.mysql.com
sasha@laptop.slkc.uswest.net
sasha@mysql.sashanet.com
sasha@work.mysql.com
...
...
@@ -14,4 +15,3 @@ tim@threads.polyesthetic.msg
tim@work.mysql.com
yfaktoro@nbyfaktoro.bedford.progress.com
yfaktoro@nslinuxw2.bedford.progress.com
sasha@donna.mysql.com
Docs/manual.texi
View file @
a5c75df3
...
...
@@ -39275,6 +39275,8 @@ though, so Version 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.29
@itemize @bullet
@item
Fixed that @code{DROP DATABASE} works on OS/2.
@item
Fixed bug when doing a @code{SELECT DISTINCT ... table1 LEFT JOIN
table2..} when table2 was empty.
@item
client/mysql.cc
View file @
a5c75df3
...
...
@@ -39,7 +39,7 @@
#include "my_readline.h"
#include <signal.h>
const
char
*
VER
=
"11.
8
"
;
const
char
*
VER
=
"11.
9
"
;
gptr
sql_alloc
(
unsigned
size
);
// Don't use mysqld alloc for these
void
sql_element_free
(
void
*
ptr
);
...
...
@@ -377,7 +377,7 @@ enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET,
static
struct
option
long_options
[]
=
{
{
"i-am-a-dummy"
,
no
_argument
,
0
,
'U'
},
{
"i-am-a-dummy"
,
optional
_argument
,
0
,
'U'
},
{
"batch"
,
no_argument
,
0
,
'B'
},
{
"character-sets-dir"
,
required_argument
,
0
,
OPT_CHARSETS_DIR
},
{
"compress"
,
no_argument
,
0
,
'C'
},
...
...
@@ -413,7 +413,7 @@ static struct option long_options[] =
{
"quick"
,
no_argument
,
0
,
'q'
},
{
"set-variable"
,
required_argument
,
0
,
'O'
},
{
"raw"
,
no_argument
,
0
,
'r'
},
{
"safe-updates"
,
no
_argument
,
0
,
'U'
},
{
"safe-updates"
,
optional
_argument
,
0
,
'U'
},
{
"silent"
,
no_argument
,
0
,
's'
},
{
"skip-column-names"
,
no_argument
,
0
,
'N'
},
{
"skip-line-numbers"
,
no_argument
,
0
,
'L'
},
...
...
@@ -558,7 +558,7 @@ static int get_options(int argc, char **argv)
set_all_changeable_vars
(
changeable_vars
);
while
((
c
=
getopt_long
(
argc
,
argv
,
"?ABCD:LfgGHinNoqrstTUvVwWEe:h:O:P:S:u:#::p::"
,
"?ABCD:LfgGHinNoqrstTU
::
vVwWEe:h:O:P:S:u:#::p::"
,
long_options
,
&
option_index
))
!=
EOF
)
{
switch
(
c
)
{
...
...
sql/Makefile.am
View file @
a5c75df3
...
...
@@ -43,8 +43,9 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_create.h mysql_priv.h
\
procedure.h sql_class.h sql_lex.h sql_list.h
\
sql_manager.h sql_map.h sql_string.h unireg.h
\
field.h handler.h ha_isammrg.h ha_isam.h ha_myisammrg.h
\
ha_heap.h ha_myisam.h ha_berkeley.h
\
field.h handler.h
\
ha_isammrg.h ha_isam.h ha_myisammrg.h
\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h
\
opt_range.h opt_ft.h
\
sql_select.h structs.h table.h sql_udf.h hash_filo.h
\
lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h
\
...
...
@@ -66,6 +67,7 @@ mysqld_SOURCES = sql_lex.cc \
records.cc filesort.cc handler.cc
\
ha_isam.cc ha_isammrg.cc ha_heap.cc
\
ha_myisam.cc ha_myisammrg.cc ha_berkeley.cc
\
ha_innobase.cc
\
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc
\
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc
\
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc
\
...
...
sql/ha_innobase.cc
0 → 100644
View file @
a5c75df3
This diff is collapsed.
Click to expand it.
sql/ha_innobase.h
0 → 100644
View file @
a5c75df3
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
&& Innobase Oy
-This file is modified from ha_berkeley.h of MySQL distribution-
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma interface
/* gcc class implementation */
#endif
/* This file defines the Innobase handler: the interface between MySQL and
Innobase */
extern
"C"
{
#include <data0types.h>
#include <dict0types.h>
#include <row0types.h>
}
typedef
struct
st_innobase_share
{
THR_LOCK
lock
;
pthread_mutex_t
mutex
;
char
*
table_name
;
uint
table_name_length
,
use_count
;
}
INNOBASE_SHARE
;
/* The class defining a handle to an Innobase table */
class
ha_innobase
:
public
handler
{
void
*
innobase_table_handle
;
/* (dict_table_t*) pointer to a table
in Innobase data dictionary cache */
void
*
innobase_prebuilt
;
/* (row_prebuilt_t*) prebuilt
structs in Innobase, used to save
CPU */
THD
*
user_thd
;
/* the thread handle of the user
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA
lock
;
INNOBASE_SHARE
*
share
;
gptr
alloc_ptr
;
byte
*
rec_buff
;
/* buffer used in converting
rows from MySQL format
to Innobase format */
byte
*
upd_buff
;
/* buffer used in updates */
byte
*
key_val_buff
;
/* buffer used in converting
search key values from MySQL format
to Innobase format */
uint
ref_stored_len
;
/* length of the key value stored to
'ref' buffer of the handle, if any */
ulong
int_option_flag
;
uint
primary_key
;
uint
last_dup_key
;
uint
last_match_mode
;
/* match mode of the latest search:
ROW_SEL_EXACT or
ROW_SEL_EXACT_PREFIX or undefined */
ulong
max_row_length
(
const
byte
*
buf
);
uint
store_key_val_for_row
(
uint
keynr
,
char
*
buff
,
const
byte
*
record
);
void
convert_row_to_innobase
(
dtuple_t
*
row
,
char
*
record
);
void
convert_row_to_mysql
(
char
*
record
,
dtuple_t
*
row
);
dtuple_t
*
convert_key_to_innobase
(
dtuple_t
*
tuple
,
byte
*
buf
,
dict_index_t
*
index
,
KEY
*
key
,
byte
*
key_ptr
,
int
key_len
);
int
calc_row_difference
(
upd_t
*
uvect
,
byte
*
old_row
,
byte
*
new_row
);
int
update_thd
(
THD
*
thd
);
int
change_active_index
(
uint
keynr
);
int
general_fetch
(
byte
*
buf
,
uint
direction
,
uint
match_mode
);
/* Init values for the class: */
public:
ha_innobase
(
TABLE
*
table
)
:
handler
(
table
),
rec_buff
(
0
),
int_option_flag
(
HA_READ_NEXT
|
HA_READ_PREV
|
HA_READ_ORDER
|
HA_REC_NOT_IN_SEQ
|
HA_KEYPOS_TO_RNDPOS
|
HA_LASTKEY_ORDER
|
HA_HAVE_KEY_READ_ONLY
|
HA_READ_NOT_EXACT_KEY
|
HA_LONGLONG_KEYS
|
HA_NULL_KEY
|
HA_NO_BLOBS
|
HA_NOT_EXACT_COUNT
|
HA_NO_WRITE_DELAYED
|
HA_PRIMARY_KEY_IN_READ_INDEX
|
HA_DROP_BEFORE_CREATE
),
last_dup_key
((
uint
)
-
1
)
{
}
~
ha_innobase
()
{}
const
char
*
table_type
()
const
{
return
(
"Innobase"
);}
const
char
**
bas_ext
()
const
;
ulong
option_flag
()
const
{
return
int_option_flag
;
}
uint
max_record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_keys
()
const
{
return
MAX_KEY
;
}
uint
max_key_parts
()
const
{
return
MAX_REF_PARTS
;
}
uint
max_key_length
()
const
{
return
MAX_KEY_LENGTH
;
}
bool
fast_key_read
()
{
return
1
;}
bool
has_transactions
()
{
return
1
;}
int
open
(
const
char
*
name
,
int
mode
,
int
test_if_locked
);
void
initialize
(
void
);
int
close
(
void
);
double
scan_time
();
int
write_row
(
byte
*
buf
);
int
update_row
(
const
byte
*
old_data
,
byte
*
new_data
);
int
delete_row
(
const
byte
*
buf
);
int
index_init
(
uint
index
);
int
index_end
();
int
index_read
(
byte
*
buf
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
);
int
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
uint
key_len
,
enum
ha_rkey_function
find_flag
);
int
index_next
(
byte
*
buf
);
int
index_next_same
(
byte
*
buf
,
const
byte
*
key
,
uint
keylen
);
int
index_prev
(
byte
*
buf
);
int
index_first
(
byte
*
buf
);
int
index_last
(
byte
*
buf
);
int
rnd_init
(
bool
scan
=
1
);
int
rnd_end
();
int
rnd_next
(
byte
*
buf
);
int
rnd_pos
(
byte
*
buf
,
byte
*
pos
);
void
position
(
const
byte
*
record
);
void
info
(
uint
);
int
extra
(
enum
ha_extra_function
operation
);
int
reset
(
void
);
int
external_lock
(
THD
*
thd
,
int
lock_type
);
void
position
(
byte
*
record
);
ha_rows
records_in_range
(
int
inx
,
const
byte
*
start_key
,
uint
start_key_len
,
enum
ha_rkey_function
start_search_flag
,
const
byte
*
end_key
,
uint
end_key_len
,
enum
ha_rkey_function
end_search_flag
);
int
create
(
const
char
*
name
,
register
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
int
delete_table
(
const
char
*
name
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
);
};
extern
bool
innobase_skip
;
extern
uint
innobase_init_flags
,
innobase_lock_type
;
extern
ulong
innobase_cache_size
;
extern
char
*
innobase_home
,
*
innobase_tmpdir
,
*
innobase_logdir
;
extern
long
innobase_lock_scan_time
;
extern
long
innobase_mirrored_log_groups
,
innobase_mirrored_log_groups
;
extern
long
innobase_log_file_size
,
innobase_log_buffer_size
;
extern
long
innobase_buffer_pool_size
,
innobase_additional_mem_pool_size
;
extern
long
innobase_file_io_threads
;
extern
char
*
innobase_data_home_dir
,
*
innobase_data_file_path
;
extern
char
*
innobase_log_group_home_dir
,
*
innobase_log_arch_dir
;
extern
bool
innobase_flush_log_at_trx_commit
,
innobase_log_archive
;
extern
TYPELIB
innobase_lock_typelib
;
bool
innobase_init
(
void
);
bool
innobase_end
(
void
);
bool
innobase_flush_logs
(
void
);
int
innobase_commit
(
THD
*
thd
);
int
innobase_rollback
(
THD
*
thd
);
int
innobase_close_connection
(
THD
*
thd
);
sql/handler.cc
View file @
a5c75df3
...
...
@@ -174,6 +174,14 @@ int ha_panic(enum ha_panic_function flag)
}
/* ha_panic */
void
ha_close_connection
(
THD
*
thd
)
{
#ifdef HAVE_INNOBASE_DB
if
(
!
innobase_skip
)
innobase_close_connection
(
THD
*
thd
);
#endif
}
/*
This is used to commit or rollback a single statement depending
on the value of error
...
...
sql/handler.h
View file @
a5c75df3
...
...
@@ -315,6 +315,7 @@ my_off_t ha_get_ptr(byte *ptr, uint pack_length);
void
ha_store_ptr
(
byte
*
buff
,
uint
pack_length
,
my_off_t
pos
);
int
ha_init
(
void
);
int
ha_panic
(
enum
ha_panic_function
flag
);
void
ha_close_connection
(
THD
*
thd
);
enum
db_type
ha_checktype
(
enum
db_type
database_type
);
int
ha_create_table
(
const
char
*
name
,
HA_CREATE_INFO
*
create_info
,
bool
update_create_info
);
...
...
sql/mysqld.cc
View file @
a5c75df3
...
...
@@ -2217,7 +2217,11 @@ enum options {
OPT_SKIP_INNOBASE
,
OPT_SAFEMALLOC_MEM_LIMIT
,
OPT_REPLICATE_DO_TABLE
,
OPT_REPLICATE_IGNORE_TABLE
,
OPT_REPLICATE_WILD_DO_TABLE
,
OPT_REPLICATE_WILD_IGNORE_TABLE
,
OPT_DISCONNECT_SLAVE_EVENT_COUNT
,
OPT_ABORT_SLAVE_EVENT_COUNT
OPT_DISCONNECT_SLAVE_EVENT_COUNT
,
OPT_ABORT_SLAVE_EVENT_COUNT
,
OPT_INNOBASE_DATA_HOME_DIR
,
OPT_INNOBASE_DATA_FILE_PATH
,
OPT_INNOBASE_LOG_GROUP_HOME_DIR
,
OPT_INNOBASE_LOG_ARCH_DIR
,
OPT_INNOBASE_LOG_ARCHIVE
,
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT
};
static
struct
option
long_options
[]
=
{
...
...
@@ -2253,6 +2257,20 @@ static struct option long_options[] = {
{
"enable-locking"
,
no_argument
,
0
,
(
int
)
OPT_ENABLE_LOCK
},
{
"exit-info"
,
optional_argument
,
0
,
'T'
},
{
"flush"
,
no_argument
,
0
,
(
int
)
OPT_FLUSH
},
#ifdef HAVE_INNOBASE_DB
{
"innobase_data_home_dir"
,
required_argument
,
0
,
OPT_INNOBASE_DATA_HOME_DIR
},
{
"innobase_data_file_path"
,
required_argument
,
0
,
OPT_INNOBASE_DATA_FILE_PATH
},
{
"innobase_log_group_home_dir"
,
required_argument
,
0
,
OPT_INNOBASE_LOG_GROUP_HOME_DIR
},
{
"innobase_log_arch_dir"
,
required_argument
,
0
,
OPT_INNOBASE_LOG_ARCH_DIR
},
{
"innobase_log_archive"
,
optional_argument
,
0
,
OPT_INNOBASE_LOG_ARCHIVE
},
{
"innobase_flush_log_at_trx_commit"
,
optional_argument
,
0
,
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT
},
#endif
{
"help"
,
no_argument
,
0
,
'?'
},
{
"init-file"
,
required_argument
,
0
,
(
int
)
OPT_INIT_FILE
},
{
"log"
,
optional_argument
,
0
,
'l'
},
...
...
@@ -2358,6 +2376,26 @@ CHANGEABLE_VAR changeable_vars[] = {
DELAYED_QUEUE_SIZE
,
1
,
~
0L
,
0
,
1
},
{
"flush_time"
,
(
long
*
)
&
flush_time
,
FLUSH_TIME
,
0
,
~
0L
,
0
,
1
},
#ifdef HAVE_INNOBASE_DB
{
"innobase_mirrored_log_groups"
,
(
long
*
)
&
innobase_mirrored_log_groups
,
1
,
1
,
10
,
0
,
1
},
{
"innobase_log_files_in_group"
,
(
long
*
)
&
innobase_mirrored_log_groups
,
2
,
2
,
100
,
0
,
1
},
{
"innobase_log_file_size"
,
(
long
*
)
&
innobase_log_file_size
,
5
*
1024
*
1024L
,
1
*
1024
*
1024L
,
~
0L
,
0
,
1024
*
1024L
},
{
"innobase_log_buffer_size"
,
(
long
*
)
&
innobase_log_buffer_size
,
1024
*
1024L
,
256
*
1024L
,
~
0L
,
0
,
1024
},
{
"innobase_buffer_pool_size"
,
(
long
*
)
&
innobase_buffer_pool_size
,
8
*
1024
*
1024L
,
1024
*
1024L
,
~
0L
,
0
,
1024
*
1024L
},
{
"innobase_additional_mem_pool_size_mb"
,
(
long
*
)
&
innobase_additional_mem_pool_size
,
1
*
1024
*
1024L
,
512
*
1024L
,
~
0L
,
0
,
1024
},
{
"innobase_file_io_threads"
,
(
long
*
)
&
innobase_file_io_threads
,
9
,
4
,
64
,
0
,
1
},
#endif
{
"interactive_timeout"
,
(
long
*
)
&
net_interactive_timeout
,
NET_WAIT_TIMEOUT
,
1
,
31
*
24
*
60
*
60
,
0
,
1
},
{
"join_buffer_size"
,
(
long
*
)
&
join_buff_size
,
...
...
@@ -3194,6 +3232,24 @@ static void get_options(int argc,char **argv)
case
OPT_INNOBASE_SKIP
:
innobase_skip
=
1
;
break
;
case
OPT_INNOBASE_DATA_HOME_DIR
:
innobase_data_home_dir
=
optarg
;
break
;
case
OPT_INNOBASE_DATA_FILE_PATH
:
innobase_data_file_path
=
optarg
;
break
;
case
OPT_INNOBASE_LOG_GROUP_HOME_DIR
:
innobase_log_group_home_dir
=
optarg
;
break
;
case
OPT_INNOBASE_LOG_ARCH_DIR
:
innobase_log_arch_dir
=
optarg
;
break
;
case
OPT_INNOBASE_LOG_ARCHIVE
:
innobase_log_archive
=
optarg
?
test
(
atoi
(
optarg
))
:
1
;
break
;
case
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT
:
innobase_flush_log_at_trx_commit
=
optarg
?
test
(
atoi
(
optarg
))
:
1
;
break
;
#endif
case
OPT_MYISAM_RECOVER
:
{
...
...
sql/sql_class.cc
View file @
a5c75df3
...
...
@@ -148,6 +148,7 @@ THD::~THD()
close_temporary_tables
(
this
);
#ifdef USING_TRANSACTIONS
close_cached_file
(
&
transaction
.
trans_log
);
ha_close_connection
(
this
);
#endif
if
(
global_read_lock
)
{
...
...
sql/sql_db.cc
View file @
a5c75df3
...
...
@@ -182,6 +182,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
char
newpath
[
FN_REFLEN
];
MY_DIR
*
new_dirp
;
strxmov
(
newpath
,
path
,
"/"
,
file
->
name
,
NullS
);
unpack_filename
(
newpath
,
newpath
);
if
((
new_dirp
=
my_dir
(
newpath
,
MYF
(
MY_DONT_SORT
))))
{
DBUG_PRINT
(
"my"
,(
"New subdir found: %s"
,
newpath
));
...
...
@@ -199,6 +200,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
continue
;
}
strxmov
(
filePath
,
path
,
"/"
,
file
->
name
,
NullS
);
unpack_filename
(
filePath
,
filePath
);
if
(
my_delete
(
filePath
,
MYF
(
MY_WME
)))
{
net_printf
(
&
thd
->
net
,
ER_DB_DROP_DELETE
,
filePath
,
my_error
);
...
...
@@ -223,6 +225,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
if
(
!
found_other_files
)
{
#ifdef HAVE_READLINK
char
tmp_path
[
FN_REFLEN
];
path
=
unpack_filename
(
tmp_path
,
path
);
int
linkcount
=
readlink
(
path
,
filePath
,
sizeof
(
filePath
)
-
1
);
if
(
linkcount
>
0
)
// If the path was a symbolic link
{
...
...
@@ -238,6 +242,10 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path,
path
=
filePath
;
}
#endif
/* Remove last FN_LIBCHAR to not cause a probelm on OS/2 */
char
*
pos
=
strend
(
path
);
if
(
pos
>
path
&&
pos
[
-
1
]
==
FN_LIBCHAR
)
*--
pos
=
0
;
/* Don't give errors if we can't delete 'RAID' directory */
if
(
rmdir
(
path
)
<
0
&&
!
level
)
{
...
...
sql/sql_table.cc
View file @
a5c75df3
...
...
@@ -178,6 +178,7 @@ int quick_rm_table(enum db_type base,const char *db,
if
(
my_delete
(
path
,
MYF
(
0
)))
error
=
1
;
/* purecov: inspected */
sprintf
(
path
,
"%s/%s/%s"
,
mysql_data_home
,
db
,
table_name
);
unpack_filename
(
path
,
path
);
return
ha_delete_table
(
base
,
path
)
||
error
;
}
...
...
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