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
81ac7a33
Commit
81ac7a33
authored
Jan 25, 2005
by
joreland@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/jonas/src/mysql-5.0
into mysql.com:/home/jonas/src/mysql-5.0-ndb
parents
1a94812b
6c3a4aee
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
163 additions
and
61 deletions
+163
-61
innobase/btr/btr0cur.c
innobase/btr/btr0cur.c
+2
-1
innobase/include/page0cur.h
innobase/include/page0cur.h
+2
-0
innobase/include/page0cur.ic
innobase/include/page0cur.ic
+4
-2
innobase/include/rem0rec.h
innobase/include/rem0rec.h
+21
-0
innobase/include/rem0rec.ic
innobase/include/rem0rec.ic
+47
-0
innobase/include/univ.i
innobase/include/univ.i
+3
-1
innobase/page/page0cur.c
innobase/page/page0cur.c
+21
-25
innobase/page/page0page.c
innobase/page/page0page.c
+28
-6
innobase/row/row0ins.c
innobase/row/row0ins.c
+6
-19
mysql-test/r/lowercase_table2.result
mysql-test/r/lowercase_table2.result
+11
-1
mysql-test/t/lowercase_table2.test
mysql-test/t/lowercase_table2.test
+12
-1
sql/sql_parse.cc
sql/sql_parse.cc
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+1
-1
sql/sql_table.cc
sql/sql_table.cc
+2
-1
tests/Makefile.am
tests/Makefile.am
+2
-2
No files found.
innobase/btr/btr0cur.c
View file @
81ac7a33
...
...
@@ -1022,7 +1022,8 @@ calculate_sizes_again:
/* Now, try the insert */
*
rec
=
page_cur_insert_rec_low
(
page_cursor
,
entry
,
index
,
NULL
,
mtr
);
*
rec
=
page_cur_insert_rec_low
(
page_cursor
,
entry
,
index
,
NULL
,
NULL
,
mtr
);
if
(
!
(
*
rec
))
{
/* If the record did not fit, reorganize */
btr_page_reorganize
(
page
,
index
,
mtr
);
...
...
innobase/include/page0cur.h
View file @
81ac7a33
...
...
@@ -144,6 +144,7 @@ page_cur_rec_insert(
page_cur_t
*
cursor
,
/* in: a page cursor */
rec_t
*
rec
,
/* in: record to insert */
dict_index_t
*
index
,
/* in: record descriptor */
ulint
*
offsets
,
/* in: rec_get_offsets(rec, index) */
mtr_t
*
mtr
);
/* in: mini-transaction handle */
/***************************************************************
Inserts a record next to page cursor. Returns pointer to inserted record if
...
...
@@ -160,6 +161,7 @@ page_cur_insert_rec_low(
dtuple_t
*
tuple
,
/* in: pointer to a data tuple or NULL */
dict_index_t
*
index
,
/* in: record descriptor */
rec_t
*
rec
,
/* in: pointer to a physical record or NULL */
ulint
*
offsets
,
/* in: rec_get_offsets(rec, index) or NULL */
mtr_t
*
mtr
);
/* in: mini-transaction handle */
/*****************************************************************
Copies records from page to a newly created page, from a given record onward,
...
...
innobase/include/page0cur.ic
View file @
81ac7a33
...
...
@@ -195,7 +195,7 @@ page_cur_tuple_insert(
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr) /* in: mini-transaction handle */
{
return(page_cur_insert_rec_low(cursor, tuple, index, NULL, mtr));
return(page_cur_insert_rec_low(cursor, tuple, index, NULL,
NULL,
mtr));
}
/***************************************************************
...
...
@@ -211,8 +211,10 @@ page_cur_rec_insert(
page_cur_t* cursor, /* in: a page cursor */
rec_t* rec, /* in: record to insert */
dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: rec_get_offsets(rec, index) */
mtr_t* mtr) /* in: mini-transaction handle */
{
return(page_cur_insert_rec_low(cursor, NULL, index, rec, mtr));
return(page_cur_insert_rec_low(cursor, NULL, index, rec,
offsets, mtr));
}
innobase/include/rem0rec.h
View file @
81ac7a33
...
...
@@ -133,6 +133,27 @@ rec_set_status(
rec_t
*
rec
,
/* in: physical record */
ulint
bits
);
/* in: info bits */
/**********************************************************
The following function is used to retrieve the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
ulint
rec_get_info_and_status_bits
(
/*==============*/
/* out: info bits */
rec_t
*
rec
,
/* in: physical record */
ibool
comp
);
/* in: TRUE=compact page format */
/**********************************************************
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits
(
/*==============*/
rec_t
*
rec
,
/* in: physical record */
ibool
comp
,
/* in: TRUE=compact page format */
ulint
bits
);
/* in: info bits */
/**********************************************************
The following function tells if record is delete marked. */
UNIV_INLINE
...
...
innobase/include/rem0rec.ic
View file @
81ac7a33
...
...
@@ -520,6 +520,53 @@ rec_set_status(
REC_NEW_STATUS_MASK, REC_NEW_STATUS_SHIFT);
}
/**********************************************************
The following function is used to retrieve the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
ulint
rec_get_info_and_status_bits(
/*==============*/
/* out: info bits */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
{
ulint bits;
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
# error "REC_NEW_STATUS_MASK and REC_INFO_BITS_MASK overlap"
#endif
if (comp) {
bits = rec_get_info_bits(rec, TRUE) | rec_get_status(rec);
} else {
bits = rec_get_info_bits(rec, FALSE);
ut_ad(!(bits & ~(REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)));
}
return(bits);
}
/**********************************************************
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
UNIV_INLINE
void
rec_set_info_and_status_bits(
/*==============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint bits) /* in: info bits */
{
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
# error "REC_NEW_STATUS_MASK and REC_INFO_BITS_MASK overlap"
#endif
if (comp) {
rec_set_status(rec, bits & REC_NEW_STATUS_MASK);
} else {
ut_ad(!(bits & ~(REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)));
}
rec_set_info_bits(rec, bits & ~REC_NEW_STATUS_MASK, comp);
}
/**********************************************************
The following function tells if record is delete marked. */
UNIV_INLINE
...
...
innobase/include/univ.i
View file @
81ac7a33
...
...
@@ -80,8 +80,10 @@ memory is read outside the allocated blocks. */
/* Make a non-inline debug version */
#
ifdef
DBUG_ON
#
define
UNIV_DEBUG
#
endif
/* DBUG_ON */
/*
#define UNIV_DEBUG
#define UNIV_MEM_DEBUG
#define UNIV_IBUF_DEBUG
#define UNIV_SYNC_DEBUG
...
...
innobase/page/page0cur.c
View file @
81ac7a33
...
...
@@ -605,8 +605,8 @@ page_cur_insert_rec_write_log(
log_end
=
&
log_ptr
[
5
+
1
+
5
+
5
+
MLOG_BUF_MARGIN
];
}
if
((
rec_get_info_bits
(
insert_rec
,
index
->
table
->
comp
)
!=
rec_get_info_bits
(
cursor_rec
,
index
->
table
->
comp
))
if
((
rec_get_info_
and_status_
bits
(
insert_rec
,
index
->
table
->
comp
)
!=
rec_get_info_
and_status_
bits
(
cursor_rec
,
index
->
table
->
comp
))
||
(
extra_size
!=
cur_extra_size
)
||
(
rec_size
!=
cur_rec_size
))
{
...
...
@@ -622,7 +622,8 @@ page_cur_insert_rec_write_log(
if
(
extra_info_yes
)
{
/* Write the info bits */
mach_write_to_1
(
log_ptr
,
rec_get_info_bits
(
insert_rec
,
index
->
table
->
comp
));
rec_get_info_and_status_bits
(
insert_rec
,
index
->
table
->
comp
));
log_ptr
++
;
/* Write the record origin offset */
...
...
@@ -673,7 +674,7 @@ page_cur_parse_insert_rec(
byte
buf1
[
1024
];
byte
*
buf
;
byte
*
ptr2
=
ptr
;
ulint
info_bits
=
0
;
/* remove warning */
ulint
info_
and_status_
bits
=
0
;
/* remove warning */
page_cur_t
cursor
;
mem_heap_t
*
heap
=
NULL
;
ulint
offsets_
[
100
]
=
{
100
,
};
...
...
@@ -723,7 +724,7 @@ page_cur_parse_insert_rec(
return
(
NULL
);
}
info_bits
=
mach_read_from_1
(
ptr
);
info_
and_status_
bits
=
mach_read_from_1
(
ptr
);
ptr
++
;
ptr
=
mach_parse_compressed
(
ptr
,
end_ptr
,
&
origin_offset
);
...
...
@@ -768,7 +769,8 @@ page_cur_parse_insert_rec(
ULINT_UNDEFINED
,
&
heap
);
if
(
extra_info_yes
==
0
)
{
info_bits
=
rec_get_info_bits
(
cursor_rec
,
index
->
table
->
comp
);
info_and_status_bits
=
rec_get_info_and_status_bits
(
cursor_rec
,
index
->
table
->
comp
);
origin_offset
=
rec_offs_extra_size
(
offsets
);
mismatch_index
=
rec_offs_size
(
offsets
)
-
end_seg_len
;
}
...
...
@@ -783,11 +785,12 @@ page_cur_parse_insert_rec(
if
(
mismatch_index
>=
UNIV_PAGE_SIZE
)
{
fprintf
(
stderr
,
"Is short %lu, info_bits %lu, offset %lu, "
"Is short %lu, info_
and_status_
bits %lu, offset %lu, "
"o_offset %lu
\n
"
"mismatch index %lu, end_seg_len %lu
\n
"
"parsed len %lu
\n
"
,
(
ulong
)
is_short
,
(
ulong
)
info_bits
,
(
ulong
)
offset
,
(
ulong
)
is_short
,
(
ulong
)
info_and_status_bits
,
(
ulong
)
offset
,
(
ulong
)
origin_offset
,
(
ulong
)
mismatch_index
,
(
ulong
)
end_seg_len
,
(
ulong
)
(
ptr
-
ptr2
));
...
...
@@ -803,21 +806,14 @@ page_cur_parse_insert_rec(
ut_memcpy
(
buf
,
rec_get_start
(
cursor_rec
,
offsets
),
mismatch_index
);
ut_memcpy
(
buf
+
mismatch_index
,
ptr
,
end_seg_len
);
rec_set_info_bits
(
buf
+
origin_offset
,
index
->
table
->
comp
,
info_bits
);
/* Set the status bits for new-style records. */
if
(
index
->
table
->
comp
)
{
/* Leaf pages (level 0) contain ordinary records;
non-leaf pages contain node pointer records. */
ulint
level
=
page_header_get_field
(
buf_frame_align
(
cursor_rec
),
PAGE_LEVEL
);
rec_set_status
(
buf
+
origin_offset
,
level
?
REC_STATUS_NODE_PTR
:
REC_STATUS_ORDINARY
);
}
rec_set_info_and_status_bits
(
buf
+
origin_offset
,
index
->
table
->
comp
,
info_and_status_bits
);
page_cur_position
(
cursor_rec
,
&
cursor
);
page_cur_rec_insert
(
&
cursor
,
buf
+
origin_offset
,
index
,
mtr
);
offsets
=
rec_get_offsets
(
buf
+
origin_offset
,
index
,
offsets
,
ULINT_UNDEFINED
,
&
heap
);
page_cur_rec_insert
(
&
cursor
,
buf
+
origin_offset
,
index
,
offsets
,
mtr
);
if
(
buf
!=
buf1
)
{
...
...
@@ -846,6 +842,7 @@ page_cur_insert_rec_low(
dtuple_t
*
tuple
,
/* in: pointer to a data tuple or NULL */
dict_index_t
*
index
,
/* in: record descriptor */
rec_t
*
rec
,
/* in: pointer to a physical record or NULL */
ulint
*
offsets
,
/* in: rec_get_offsets(rec, index) or NULL */
mtr_t
*
mtr
)
/* in: mini-transaction handle */
{
byte
*
insert_buf
=
NULL
;
...
...
@@ -863,8 +860,6 @@ page_cur_insert_rec_low(
rec_t
*
owner_rec
;
ulint
n_owned
;
mem_heap_t
*
heap
=
NULL
;
ulint
offsets_
[
100
]
=
{
100
,
};
ulint
*
offsets
=
offsets_
;
ibool
comp
=
index
->
table
->
comp
;
ut_ad
(
cursor
&&
mtr
);
...
...
@@ -882,8 +877,11 @@ page_cur_insert_rec_low(
if
(
tuple
!=
NULL
)
{
rec_size
=
rec_get_converted_size
(
index
,
tuple
);
}
else
{
offsets
=
rec_get_offsets
(
rec
,
index
,
offsets
,
if
(
!
offsets
)
{
offsets
=
rec_get_offsets
(
rec
,
index
,
offsets
,
ULINT_UNDEFINED
,
&
heap
);
}
ut_ad
(
rec_offs_validate
(
rec
,
index
,
offsets
));
rec_size
=
rec_offs_size
(
offsets
);
}
...
...
@@ -1131,8 +1129,6 @@ page_copy_rec_list_end_to_created_page(
slot_index
=
0
;
n_recs
=
0
;
heap
=
mem_heap_create
(
100
);
/* should be do ... until, comment by Jani */
while
(
rec
!=
page_get_supremum_rec
(
page
))
{
offsets
=
rec_get_offsets
(
rec
,
index
,
offsets
,
...
...
innobase/page/page0page.c
View file @
81ac7a33
...
...
@@ -463,6 +463,9 @@ page_copy_rec_list_end_no_locks(
page_cur_t
cur1
;
page_cur_t
cur2
;
rec_t
*
sup
;
mem_heap_t
*
heap
=
NULL
;
ulint
offsets_
[
100
]
=
{
100
,
};
ulint
*
offsets
=
offsets_
;
page_cur_position
(
rec
,
&
cur1
);
...
...
@@ -483,8 +486,11 @@ page_copy_rec_list_end_no_locks(
sup
=
page_get_supremum_rec
(
page
);
while
(
sup
!=
page_cur_get_rec
(
&
cur1
))
{
if
(
!
page_cur_rec_insert
(
&
cur2
,
page_cur_get_rec
(
&
cur1
),
index
,
mtr
))
{
rec_t
*
cur1_rec
=
page_cur_get_rec
(
&
cur1
);
offsets
=
rec_get_offsets
(
cur1_rec
,
index
,
offsets
,
ULINT_UNDEFINED
,
&
heap
);
if
(
!
page_cur_rec_insert
(
&
cur2
,
cur1_rec
,
index
,
offsets
,
mtr
))
{
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
...
...
@@ -503,7 +509,11 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next
(
&
cur1
);
page_cur_move_to_next
(
&
cur2
);
}
}
if
(
heap
)
{
mem_heap_free
(
heap
);
}
}
/*****************************************************************
Copies records from page to new_page, from a given record onward,
...
...
@@ -553,6 +563,9 @@ page_copy_rec_list_start(
page_cur_t
cur1
;
page_cur_t
cur2
;
rec_t
*
old_end
;
mem_heap_t
*
heap
=
NULL
;
ulint
offsets_
[
100
]
=
{
100
,
};
ulint
*
offsets
=
offsets_
;
page_cur_set_before_first
(
page
,
&
cur1
);
...
...
@@ -570,8 +583,13 @@ page_copy_rec_list_start(
/* Copy records from the original page to the new page */
while
(
page_cur_get_rec
(
&
cur1
)
!=
rec
)
{
ut_a
(
page_cur_rec_insert
(
&
cur2
,
page_cur_get_rec
(
&
cur1
),
index
,
mtr
));
rec_t
*
ins_rec
;
rec_t
*
cur1_rec
=
page_cur_get_rec
(
&
cur1
);
offsets
=
rec_get_offsets
(
cur1_rec
,
index
,
offsets
,
ULINT_UNDEFINED
,
&
heap
);
ins_rec
=
page_cur_rec_insert
(
&
cur2
,
cur1_rec
,
index
,
offsets
,
mtr
);
ut_a
(
ins_rec
);
page_cur_move_to_next
(
&
cur1
);
page_cur_move_to_next
(
&
cur2
);
...
...
@@ -584,7 +602,11 @@ page_copy_rec_list_start(
page_update_max_trx_id
(
new_page
,
page_get_max_trx_id
(
page
));
btr_search_move_or_delete_hash_entries
(
new_page
,
page
,
index
);
}
if
(
heap
)
{
mem_heap_free
(
heap
);
}
}
/**************************************************************
Writes a log record of a record list end or start deletion. */
...
...
innobase/row/row0ins.c
View file @
81ac7a33
...
...
@@ -1120,7 +1120,6 @@ row_ins_check_foreign_constraint(
dict_table_t
*
check_table
;
dict_index_t
*
check_index
;
ulint
n_fields_cmp
;
ibool
unique_search
;
rec_t
*
rec
;
btr_pcur_t
pcur
;
ibool
moved
;
...
...
@@ -1240,14 +1239,6 @@ run_again:
dtuple_set_n_fields_cmp
(
entry
,
foreign
->
n_fields
);
if
(
dict_index_get_n_unique
(
check_index
)
<=
foreign
->
n_fields
)
{
/* We can just set a LOCK_REC_NOT_GAP type lock */
unique_search
=
TRUE
;
}
else
{
unique_search
=
FALSE
;
}
btr_pcur_open
(
check_index
,
entry
,
PAGE_CUR_GE
,
BTR_SEARCH_LEAF
,
&
pcur
,
&
mtr
);
...
...
@@ -1289,18 +1280,14 @@ run_again:
break
;
}
}
else
{
/* Found a matching record */
ulint
lock_type
;
/* Found a matching record. Lock only
a record because we can allow inserts
into gaps */
if
(
unique_search
)
{
lock_type
=
LOCK_REC_NOT_GAP
;
}
else
{
lock_type
=
LOCK_ORDINARY
;
}
err
=
row_ins_set_shared_rec_lock
(
LOCK_REC_NOT_GAP
,
rec
,
check_index
,
offsets
,
thr
);
err
=
row_ins_set_shared_rec_lock
(
lock_type
,
rec
,
check_index
,
offsets
,
thr
);
if
(
err
!=
DB_SUCCESS
)
{
break
;
...
...
mysql-test/r/lowercase_table2.result
View file @
81ac7a33
DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3;
DROP TABLE IF EXISTS t1,t2,T1,T2,t3,T3
,tT
;
DROP DATABASE IF EXISTS `TEST_$1`;
DROP DATABASE IF EXISTS `test_$1`;
CREATE TABLE T1 (a int);
...
...
@@ -131,3 +131,13 @@ show tables like 't1%';
Tables_in_test (t1%)
t1
drop table t1;
create temporary table tT(a int(11), b varchar(8));
insert into tT values (1, 'abc');
select * from tT;
a b
1 abc
alter table tT add index (a);
select * from tT;
a b
1 abc
drop table tT;
mysql-test/t/lowercase_table2.test
View file @
81ac7a33
...
...
@@ -10,7 +10,7 @@ show variables like "lower_case_table_names";
enable_query_log
;
--
disable_warnings
DROP
TABLE
IF
EXISTS
t1
,
t2
,
T1
,
T2
,
t3
,
T3
;
DROP
TABLE
IF
EXISTS
t1
,
t2
,
T1
,
T2
,
t3
,
T3
,
tT
;
DROP
DATABASE
IF
EXISTS
`TEST_$1`
;
DROP
DATABASE
IF
EXISTS
`test_$1`
;
--
enable_warnings
...
...
@@ -100,3 +100,14 @@ show tables like 'T1%';
alter
table
t1
add
index
(
A
);
show
tables
like
't1%'
;
drop
table
t1
;
#
# Bug #7261: Alter table loses temp table
#
create
temporary
table
tT
(
a
int
(
11
),
b
varchar
(
8
));
insert
into
tT
values
(
1
,
'abc'
);
select
*
from
tT
;
alter
table
tT
add
index
(
a
);
select
*
from
tT
;
drop
table
tT
;
sql/sql_parse.cc
View file @
81ac7a33
...
...
@@ -5377,7 +5377,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
Initialize a new table list for a nested join
SYNOPSIS
init_
table_list
()
init_
nested_join
()
thd current thread
DESCRIPTION
...
...
sql/sql_select.cc
View file @
81ac7a33
...
...
@@ -12962,7 +12962,7 @@ static void print_join(THD *thd, String *str, List<TABLE_LIST> *tables)
{
TABLE_LIST
*
curr
=
*
tbl
;
if
(
curr
->
outer_join
)
str
->
append
(
" left join "
,
11
);
// MySQL conver
g
right to left joins
str
->
append
(
" left join "
,
11
);
// MySQL conver
ts
right to left joins
else
if
(
curr
->
straight
)
str
->
append
(
" straight_join "
,
15
);
else
...
...
sql/sql_table.cc
View file @
81ac7a33
...
...
@@ -3375,7 +3375,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
/* Remove link to old table and rename the new one */
close_temporary_table
(
thd
,
table
->
s
->
db
,
table_name
);
if
(
rename_temporary_table
(
thd
,
new_table
,
new_db
,
new_alias
))
/* Should pass the 'new_name' as we store table name in the cache */
if
(
rename_temporary_table
(
thd
,
new_table
,
new_db
,
new_name
))
{
// Fatal error
close_temporary_table
(
thd
,
new_db
,
tmp_name
);
my_free
((
gptr
)
new_table
,
MYF
(
0
));
...
...
tests/Makefile.am
View file @
81ac7a33
...
...
@@ -36,9 +36,9 @@ INCLUDES = -I$(top_srcdir)/include $(openssl_includes)
LIBS
=
@CLIENT_LIBS@
LDADD
=
@CLIENT_EXTRA_LDFLAGS@
\
$(top_builddir)
/libmysql/libmysqlclient.la
client_test_LDADD
=
$(LDADD)
$(CXXLDFLAGS)
\
mysql_client_test_LDADD
=
$(LDADD)
$(CXXLDFLAGS)
\
$(top_builddir)
/mysys/libmysys.a
client_test_SOURCES
=
mysql_client_test.c
mysql_client_test_SOURCES
=
mysql_client_test.c
insert_test_DEPENDENCIES
=
$(LIBRARIES)
$(pkglib_LTLIBRARIES)
select_test_DEPENDENCIES
=
$(LIBRARIES)
$(pkglib_LTLIBRARIES)
...
...
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