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
807b5085
Commit
807b5085
authored
May 27, 2002
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Hiding internal pointers of SELECT_LEX structures
parent
e640e2e2
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
64 additions
and
37 deletions
+64
-37
sql/item_subselect.cc
sql/item_subselect.cc
+1
-1
sql/item_sum.cc
sql/item_sum.cc
+1
-1
sql/sql_derived.cc
sql/sql_derived.cc
+1
-1
sql/sql_lex.cc
sql/sql_lex.cc
+7
-6
sql/sql_lex.h
sql/sql_lex.h
+35
-9
sql/sql_parse.cc
sql/sql_parse.cc
+5
-5
sql/sql_select.cc
sql/sql_select.cc
+4
-4
sql/sql_union.cc
sql/sql_union.cc
+1
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+9
-9
No files found.
sql/item_subselect.cc
View file @
807b5085
...
@@ -108,7 +108,7 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
...
@@ -108,7 +108,7 @@ bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
(
ORDER
*
)
select_lex
->
group_list
.
first
,
(
ORDER
*
)
select_lex
->
group_list
.
first
,
select_lex
->
having
,
select_lex
->
having
,
(
ORDER
*
)
0
,
select_lex
,
(
ORDER
*
)
0
,
select_lex
,
(
SELECT_LEX_UNIT
*
)
select_lex
->
master
))
select_lex
->
master_unit
()
))
return
1
;
return
1
;
thd
->
lex
.
select
=
save_select
;
thd
->
lex
.
select
=
save_select
;
return
0
;
return
0
;
...
...
sql/item_sum.cc
View file @
807b5085
...
@@ -965,7 +965,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
...
@@ -965,7 +965,7 @@ bool Item_sum_count_distinct::setup(THD *thd)
if
(
!
(
table
=
create_tmp_table
(
thd
,
tmp_table_param
,
list
,
(
ORDER
*
)
0
,
1
,
if
(
!
(
table
=
create_tmp_table
(
thd
,
tmp_table_param
,
list
,
(
ORDER
*
)
0
,
1
,
0
,
0
,
0
,
0
,
select_lex
->
options
|
thd
->
options
,
select_lex
->
options
|
thd
->
options
,
(
SELECT_LEX_UNIT
*
)
select_lex
->
master
)))
select_lex
->
master_unit
()
)))
return
1
;
return
1
;
table
->
file
->
extra
(
HA_EXTRA_NO_ROWS
);
// Don't update rows
table
->
file
->
extra
(
HA_EXTRA_NO_ROWS
);
// Don't update rows
table
->
no_rows
=
1
;
table
->
no_rows
=
1
;
...
...
sql/sql_derived.cc
View file @
807b5085
...
@@ -34,7 +34,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
...
@@ -34,7 +34,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
TODO: make derived tables with union inside (now only 1 SELECT may be
TODO: make derived tables with union inside (now only 1 SELECT may be
procesed)
procesed)
*/
*/
SELECT_LEX
*
sl
=
(
SELECT_LEX
*
)
unit
->
slave
;
SELECT_LEX
*
sl
=
unit
->
first_select
()
;
List
<
Item
>
item_list
;
List
<
Item
>
item_list
;
TABLE
*
table
;
TABLE
*
table
;
int
res
;
int
res
;
...
...
sql/sql_lex.cc
View file @
807b5085
...
@@ -1021,18 +1021,19 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
...
@@ -1021,18 +1021,19 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
TABLE_LIST
*
slave_list_first
=
0
,
**
slave_list_last
=
&
slave_list_first
;
TABLE_LIST
*
slave_list_first
=
0
,
**
slave_list_last
=
&
slave_list_first
;
TABLE_LIST
**
new_table_list
=
*
result
,
*
aux
;
TABLE_LIST
**
new_table_list
=
*
result
,
*
aux
;
SELECT_LEX
*
sl
=
(
SELECT_LEX
*
)
slave
;
SELECT_LEX
*
sl
=
(
SELECT_LEX
*
)
slave
;
for
(;
sl
;
sl
=
(
SELECT_LEX
*
)
sl
->
next
)
for
(;
sl
;
sl
=
sl
->
next_select
()
)
{
{
// check usage of ORDER BY in union
// check usage of ORDER BY in union
if
(
sl
->
order_list
.
first
&&
sl
->
next
&&
!
sl
->
braces
)
if
(
sl
->
order_list
.
first
&&
sl
->
next
_select
()
&&
!
sl
->
braces
)
{
{
net_printf
(
&
thd
->
net
,
ER_WRONG_USAGE
,
"UNION"
,
"ORDER BY"
);
net_printf
(
&
thd
->
net
,
ER_WRONG_USAGE
,
"UNION"
,
"ORDER BY"
);
return
1
;
return
1
;
}
}
if
(
sl
->
slave
)
for
(
SELECT_LEX_UNIT
*
inner
=
sl
->
first_inner_unit
();
if
(((
SELECT_LEX_UNIT
*
)
inner
;
sl
->
slave
)
->
create_total_list_n_last_return
(
thd
,
lex
,
inner
=
inner
->
next_unit
())
&
slave_list_last
))
if
(
inner
->
create_total_list_n_last_return
(
thd
,
lex
,
&
slave_list_last
))
return
1
;
return
1
;
if
((
aux
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
))
if
((
aux
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
))
{
{
...
...
sql/sql_lex.h
View file @
807b5085
...
@@ -186,11 +186,15 @@ enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE,
...
@@ -186,11 +186,15 @@ enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE,
Base class for st_select_lex (SELECT_LEX) &
Base class for st_select_lex (SELECT_LEX) &
st_select_lex_unit (SELECT_LEX_UNIT)
st_select_lex_unit (SELECT_LEX_UNIT)
*/
*/
struct
st_select_lex_node
{
class
st_select_lex_node
{
enum
sub_select_type
linkage
;
protected:
st_select_lex_node
*
next
,
**
prev
,
/* neighbor list */
st_select_lex_node
*
next
,
**
prev
,
/* neighbor list */
*
master
,
*
slave
,
/* vertical links */
*
master
,
*
slave
,
/* vertical links */
*
link_next
,
**
link_prev
;
/* list of whole SELECT_LEX */
*
link_next
,
**
link_prev
;
/* list of whole SELECT_LEX */
public:
ulong
options
;
enum
sub_select_type
linkage
;
//uint sort_default;
SQL_LIST
order_list
;
/* ORDER clause */
SQL_LIST
order_list
;
/* ORDER clause */
ha_rows
select_limit
,
offset_limit
;
/* LIMIT clause parameters */
ha_rows
select_limit
,
offset_limit
;
/* LIMIT clause parameters */
void
init_query
();
void
init_query
();
...
@@ -207,9 +211,10 @@ struct st_select_lex_node {
...
@@ -207,9 +211,10 @@ struct st_select_lex_node {
SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group
SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group
SELECT_LEXs
SELECT_LEXs
*/
*/
struct
st_lex
;
class
st_lex
;
struct
st_select_lex
;
class
st_select_lex
;
struct
st_select_lex_unit
:
public
st_select_lex_node
{
class
st_select_lex_unit
:
public
st_select_lex_node
{
public:
/*
/*
Pointer to 'last' select or pointer to unit where stored
Pointer to 'last' select or pointer to unit where stored
global parameters for union
global parameters for union
...
@@ -219,8 +224,11 @@ struct st_select_lex_unit: public st_select_lex_node {
...
@@ -219,8 +224,11 @@ struct st_select_lex_unit: public st_select_lex_node {
ha_rows
select_limit_cnt
,
offset_limit_cnt
;
ha_rows
select_limit_cnt
,
offset_limit_cnt
;
void
init_query
();
void
init_query
();
bool
create_total_list
(
THD
*
thd
,
st_lex
*
lex
,
TABLE_LIST
**
result
);
bool
create_total_list
(
THD
*
thd
,
st_lex
*
lex
,
TABLE_LIST
**
result
);
st_select_lex
*
outer_select
()
{
return
(
st_select_lex
*
)
master
;
}
st_select_lex
*
first_select
()
{
return
(
st_select_lex
*
)
slave
;
}
st_select_lex
*
first_select
()
{
return
(
st_select_lex
*
)
slave
;
}
st_select_lex_unit
*
next_unit
()
{
return
(
st_select_lex_unit
*
)
next
;
}
st_select_lex_unit
*
next_unit
()
{
return
(
st_select_lex_unit
*
)
next
;
}
friend
void
mysql_init_query
(
THD
*
thd
);
private:
private:
bool
create_total_list_n_last_return
(
THD
*
thd
,
st_lex
*
lex
,
bool
create_total_list_n_last_return
(
THD
*
thd
,
st_lex
*
lex
,
TABLE_LIST
***
result
);
TABLE_LIST
***
result
);
...
@@ -230,10 +238,10 @@ typedef struct st_select_lex_unit SELECT_LEX_UNIT;
...
@@ -230,10 +238,10 @@ typedef struct st_select_lex_unit SELECT_LEX_UNIT;
/*
/*
SELECT_LEX - store information of parsed SELECT_LEX statment
SELECT_LEX - store information of parsed SELECT_LEX statment
*/
*/
struct
st_select_lex
:
public
st_select_lex_node
{
class
st_select_lex
:
public
st_select_lex_node
{
public:
char
*
db
,
*
db1
,
*
table1
,
*
db2
,
*
table2
;
/* For outer join using .. */
char
*
db
,
*
db1
,
*
table1
,
*
db2
,
*
table2
;
/* For outer join using .. */
Item
*
where
,
*
having
;
/* WHERE & HAVING clauses */
Item
*
where
,
*
having
;
/* WHERE & HAVING clauses */
ulong
options
;
List
<
List_item
>
expr_list
;
List
<
List_item
>
expr_list
;
List
<
List_item
>
when_list
;
/* WHEN clause */
List
<
List_item
>
when_list
;
/* WHEN clause */
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
SQL_LIST
table_list
,
group_list
;
/* FROM & GROUP BY clauses */
...
@@ -241,14 +249,32 @@ struct st_select_lex: public st_select_lex_node {
...
@@ -241,14 +249,32 @@ struct st_select_lex: public st_select_lex_node {
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
List
<
String
>
interval_list
,
use_index
,
*
use_index_ptr
,
ignore_index
,
*
ignore_index_ptr
;
ignore_index
,
*
ignore_index_ptr
;
List
<
Item_func_match
>
ftfunc_list
;
List
<
Item_func_match
>
ftfunc_list
;
uint
in_sum_expr
,
sort_default
;
uint
in_sum_expr
;
bool
create_refs
,
bool
create_refs
,
braces
,
/* SELECT ... UNION (SELECT ... ) <- this braces */
braces
,
/* SELECT ... UNION (SELECT ... ) <- this braces */
depended
;
/* depended from outer select subselect */
depended
;
/* depended from outer select subselect */
void
init_query
();
void
init_query
();
void
init_select
();
void
init_select
();
st_select_lex
*
outer_select
()
{
return
(
st_select_lex
*
)
master
->
master
;
}
st_select_lex_unit
*
master_unit
()
{
return
(
st_select_lex_unit
*
)
master
;
}
st_select_lex_unit
*
first_inner_unit
()
{
return
(
st_select_lex_unit
*
)
slave
;
}
st_select_lex
*
outer_select
()
{
return
(
st_select_lex
*
)
master_unit
()
->
outer_select
();
}
st_select_lex
*
next_select
()
{
return
(
st_select_lex
*
)
next
;
}
st_select_lex
*
next_select
()
{
return
(
st_select_lex
*
)
next
;
}
st_select_lex
*
next_select_in_list
()
{
return
(
st_select_lex
*
)
link_next
;
}
st_select_lex_node
**
next_select_in_list_addr
()
{
return
&
link_next
;
}
friend
void
mysql_init_query
(
THD
*
thd
);
};
};
typedef
struct
st_select_lex
SELECT_LEX
;
typedef
struct
st_select_lex
SELECT_LEX
;
...
...
sql/sql_parse.cc
View file @
807b5085
...
@@ -65,7 +65,7 @@ static void decrease_user_connections(UC *uc);
...
@@ -65,7 +65,7 @@ static void decrease_user_connections(UC *uc);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
static
bool
check_dup
(
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
static
bool
check_dup
(
const
char
*
db
,
const
char
*
name
,
TABLE_LIST
*
tables
);
static
void
mysql_init_query
(
THD
*
thd
);
void
mysql_init_query
(
THD
*
thd
);
static
void
remove_escape
(
char
*
name
);
static
void
remove_escape
(
char
*
name
);
static
void
refresh_status
(
void
);
static
void
refresh_status
(
void
);
static
bool
append_file_to_dir
(
THD
*
thd
,
char
**
filename_ptr
,
static
bool
append_file_to_dir
(
THD
*
thd
,
char
**
filename_ptr
,
...
@@ -1246,7 +1246,7 @@ mysql_execute_command(void)
...
@@ -1246,7 +1246,7 @@ mysql_execute_command(void)
cursor
))
cursor
))
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
if
((
lex
->
select_lex
.
link_next
&&
if
((
lex
->
select_lex
.
next_select_in_list
()
&&
lex
->
unit
.
create_total_list
(
thd
,
lex
,
&
tables
))
||
lex
->
unit
.
create_total_list
(
thd
,
lex
,
&
tables
))
||
(
table_rules_on
&&
tables
&&
thd
->
slave_thread
&&
(
table_rules_on
&&
tables
&&
thd
->
slave_thread
&&
!
tables_ok
(
thd
,
tables
)))
!
tables_ok
(
thd
,
tables
)))
...
@@ -2664,7 +2664,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
...
@@ -2664,7 +2664,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
Initialize global thd variables needed for query
Initialize global thd variables needed for query
****************************************************************************/
****************************************************************************/
static
void
void
mysql_init_query
(
THD
*
thd
)
mysql_init_query
(
THD
*
thd
)
{
{
DBUG_ENTER
(
"mysql_init_query"
);
DBUG_ENTER
(
"mysql_init_query"
);
...
@@ -2720,8 +2720,8 @@ mysql_new_select(LEX *lex, bool move_down)
...
@@ -2720,8 +2720,8 @@ mysql_new_select(LEX *lex, bool move_down)
else
else
select_lex
->
include_neighbour
(
lex
->
select
);
select_lex
->
include_neighbour
(
lex
->
select
);
((
SELECT_LEX_UNIT
*
)
select_lex
->
master
)
->
global_parameters
=
select_lex
;
select_lex
->
master_unit
(
)
->
global_parameters
=
select_lex
;
select_lex
->
include_global
(
&
lex
->
select
->
link_next
);
select_lex
->
include_global
(
lex
->
select
->
next_select_in_list_addr
()
);
lex
->
select
=
select_lex
;
lex
->
select
=
select_lex
;
return
0
;
return
0
;
}
}
...
...
sql/sql_select.cc
View file @
807b5085
...
@@ -156,12 +156,12 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
...
@@ -156,12 +156,12 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
{
{
int
res
;
int
res
;
register
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
register
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
if
(
select_lex
->
link_next
)
if
(
select_lex
->
next_select_in_list
()
)
{
{
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
for
(
SELECT_LEX
*
sl
=
select_lex
;
for
(
SELECT_LEX
*
sl
=
select_lex
;
sl
;
sl
;
sl
=
(
SELECT_LEX
*
)
sl
->
link_next
)
sl
=
sl
->
next_select_in_list
()
)
{
{
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
for
(
TABLE_LIST
*
cursor
=
(
TABLE_LIST
*
)
sl
->
table_list
.
first
;
cursor
;
cursor
;
...
@@ -169,7 +169,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
...
@@ -169,7 +169,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
cursor
->
table
=
cursor
->
table_list
->
table
;
cursor
->
table
=
cursor
->
table_list
->
table
;
}
}
}
}
if
(
select_lex
->
next
)
if
(
select_lex
->
next
_select
()
)
res
=
mysql_union
(
thd
,
lex
,
result
);
res
=
mysql_union
(
thd
,
lex
,
result
);
else
else
res
=
mysql_select
(
thd
,(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
,
res
=
mysql_select
(
thd
,(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
,
...
@@ -7275,7 +7275,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
...
@@ -7275,7 +7275,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
result
->
send_error
(
0
,
NullS
);
result
->
send_error
(
0
,
NullS
);
}
}
}
}
if
(
!
join
->
thd
->
lex
.
select
->
next
)
if
(
!
join
->
thd
->
lex
.
select
->
next
_select
()
)
{
{
save_lock
=
thd
->
lock
;
save_lock
=
thd
->
lock
;
thd
->
lock
=
(
MYSQL_LOCK
*
)
0
;
thd
->
lock
=
(
MYSQL_LOCK
*
)
0
;
...
...
sql/sql_union.cc
View file @
807b5085
...
@@ -104,7 +104,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
...
@@ -104,7 +104,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
}
}
union_result
->
save_time_stamp
=!
describe
;
union_result
->
save_time_stamp
=!
describe
;
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
(
SELECT_LEX
*
)
sl
->
next
)
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
sl
->
next_select
()
)
{
{
lex
->
select
=
sl
;
lex
->
select
=
sl
;
unit
->
offset_limit_cnt
=
sl
->
offset_limit
;
unit
->
offset_limit_cnt
=
sl
->
offset_limit
;
...
...
sql/sql_yacc.yy
View file @
807b5085
...
@@ -1477,8 +1477,8 @@ select_init:
...
@@ -1477,8 +1477,8 @@ select_init:
SELECT_LEX * sel=Select;
SELECT_LEX * sel=Select;
sel->braces=true;
sel->braces=true;
/* select in braces, can't contain global parameters */
/* select in braces, can't contain global parameters */
((SELECT_LEX_UNIT*)sel->master
)->global_parameters=
sel->master_unit(
)->global_parameters=
sel->master
;
sel->master_unit()
;
} union_opt
} union_opt
...
@@ -2186,8 +2186,8 @@ join_table:
...
@@ -2186,8 +2186,8 @@ join_table:
| '(' SELECT_SYM select_part3 ')' opt_table_alias
| '(' SELECT_SYM select_part3 ')' opt_table_alias
{
{
LEX *lex=Lex;
LEX *lex=Lex;
SELECT_LEX_UNIT *unit=
(SELECT_LEX_UNIT*) lex->select->master
;
SELECT_LEX_UNIT *unit=
lex->select->master_unit()
;
lex->select=
(SELECT_LEX*) unit->master
;
lex->select=
unit->outer_select()
;
if (!($$= add_table_to_list(new Table_ident(unit),
if (!($$= add_table_to_list(new Table_ident(unit),
$5,0,TL_UNLOCK)))
$5,0,TL_UNLOCK)))
YYABORT;
YYABORT;
...
@@ -2325,7 +2325,7 @@ order_clause:
...
@@ -2325,7 +2325,7 @@ order_clause:
LEX *lex=Lex;
LEX *lex=Lex;
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
YYABORT;
YYABORT;
lex->select->sort_default=1;
/*lex->select->sort_default=1;*/
} order_list
} order_list
order_list:
order_list:
...
@@ -3859,13 +3859,13 @@ optional_order_or_limit:
...
@@ -3859,13 +3859,13 @@ optional_order_or_limit:
LEX *lex=Lex;
LEX *lex=Lex;
if (!lex->select->braces)
if (!lex->select->braces)
YYABORT;
YYABORT;
((SELECT_LEX_UNIT*)lex->select->master
)->global_parameters=
lex->select->master_unit(
)->global_parameters=
lex->select->master;
lex->select->master
_unit()
;
/*
/*
Following type conversion looks like hack, but all that need SELECT_LEX
Following type conversion looks like hack, but all that need SELECT_LEX
fields always check linkage type.
fields always check linkage type.
*/
*/
lex->select= (SELECT_LEX*)lex->select->master;
lex->select= (SELECT_LEX*)lex->select->master
_unit()
;
lex->select->select_limit=lex->thd->default_select_limit;
lex->select->select_limit=lex->thd->default_select_limit;
}
}
opt_order_clause limit_clause
opt_order_clause limit_clause
...
@@ -3898,5 +3898,5 @@ subselect_end:
...
@@ -3898,5 +3898,5 @@ subselect_end:
')'
')'
{
{
LEX *lex=Lex;
LEX *lex=Lex;
lex->select =
(SELECT_LEX*)lex->select->master->master
;
lex->select =
lex->select->outer_select()
;
}
}
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