Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
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
Abuhujair Javed
Postgres FD Implementation
Commits
f9179685
Commit
f9179685
authored
Apr 09, 2014
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Several fixes to array handling in ecpg.
Patches by Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>
parent
0c4ea7a3
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
556 additions
and
38 deletions
+556
-38
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/preproc/type.c
+13
-4
src/interfaces/ecpg/test/ecpg_schedule
src/interfaces/ecpg/test/ecpg_schedule
+1
-0
src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
+4
-4
src/interfaces/ecpg/test/expected/preproc-outofscope.c
src/interfaces/ecpg/test/expected/preproc-outofscope.c
+20
-20
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.c
...interfaces/ecpg/test/expected/preproc-pointer_to_struct.c
+293
-0
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stderr
...faces/ecpg/test/expected/preproc-pointer_to_struct.stderr
+86
-0
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stdout
...faces/ecpg/test/expected/preproc-pointer_to_struct.stdout
+25
-0
src/interfaces/ecpg/test/expected/preproc-type.c
src/interfaces/ecpg/test/expected/preproc-type.c
+3
-3
src/interfaces/ecpg/test/expected/preproc-variable.c
src/interfaces/ecpg/test/expected/preproc-variable.c
+6
-6
src/interfaces/ecpg/test/preproc/Makefile
src/interfaces/ecpg/test/preproc/Makefile
+5
-1
src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc
src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc
+100
-0
No files found.
src/interfaces/ecpg/preproc/type.c
View file @
f9179685
...
@@ -303,7 +303,8 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const int bra
...
@@ -303,7 +303,8 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type, const int bra
ECPGdump_a_simple
(
o
,
name
,
ECPGdump_a_simple
(
o
,
name
,
type
->
u
.
element
->
type
,
type
->
u
.
element
->
type
,
type
->
u
.
element
->
size
,
type
->
size
,
NULL
,
prefix
,
type
->
u
.
element
->
counter
);
type
->
u
.
element
->
size
,
type
->
size
,
struct_sizeof
?
struct_sizeof
:
NULL
,
prefix
,
type
->
u
.
element
->
counter
);
if
(
ind_type
!=
NULL
)
if
(
ind_type
!=
NULL
)
{
{
...
@@ -519,11 +520,19 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
...
@@ -519,11 +520,19 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
sprintf
(
offset
,
"sizeof(%s)"
,
ecpg_type_name
(
type
));
sprintf
(
offset
,
"sizeof(%s)"
,
ecpg_type_name
(
type
));
break
;
break
;
}
}
if
(
atoi
(
arrsize
)
<
0
)
/*
* Array size would be -1 for addresses of members within structure,
* when pointer to structure is being dumped.
*/
if
(
atoi
(
arrsize
)
<
0
&&
!
siz
)
strcpy
(
arrsize
,
"1"
);
strcpy
(
arrsize
,
"1"
);
if
(
siz
==
NULL
||
strlen
(
siz
)
==
0
||
strcmp
(
arrsize
,
"0"
)
==
0
||
strcmp
(
arrsize
,
"1"
)
==
0
)
/*
* If siz i.e. the size of structure of which this variable is part of,
* that gives the offset to the next element, if required
*/
if
(
siz
==
NULL
||
strlen
(
siz
)
==
0
)
fprintf
(
o
,
"
\n\t
%s,%s,(long)%s,(long)%s,%s, "
,
get_type
(
type
),
variable
,
varcharsize
,
arrsize
,
offset
);
fprintf
(
o
,
"
\n\t
%s,%s,(long)%s,(long)%s,%s, "
,
get_type
(
type
),
variable
,
varcharsize
,
arrsize
,
offset
);
else
else
fprintf
(
o
,
"
\n\t
%s,%s,(long)%s,(long)%s,%s, "
,
get_type
(
type
),
variable
,
varcharsize
,
arrsize
,
siz
);
fprintf
(
o
,
"
\n\t
%s,%s,(long)%s,(long)%s,%s, "
,
get_type
(
type
),
variable
,
varcharsize
,
arrsize
,
siz
);
...
...
src/interfaces/ecpg/test/ecpg_schedule
View file @
f9179685
...
@@ -17,6 +17,7 @@ test: pgtypeslib/num_test
...
@@ -17,6 +17,7 @@ test: pgtypeslib/num_test
test: pgtypeslib/num_test2
test: pgtypeslib/num_test2
test: pgtypeslib/nan_test
test: pgtypeslib/nan_test
test: preproc/array_of_struct
test: preproc/array_of_struct
test: preproc/pointer_to_struct
test: preproc/autoprep
test: preproc/autoprep
test: preproc/comment
test: preproc/comment
test: preproc/cursor
test: preproc/cursor
...
...
src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
View file @
f9179685
...
@@ -235,10 +235,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
...
@@ -235,10 +235,10 @@ if (sqlca.sqlcode < 0) sqlprint();}
}
}
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 1"
,
ECPGt_EOIT
,
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 1"
,
ECPGt_EOIT
,
ECPGt_varchar
,
&
(
custs4
.
name
),(
long
)
50
,(
long
)
1
,
sizeof
(
struct
varchar_4
),
ECPGt_varchar
,
&
(
custs4
.
name
),(
long
)
50
,(
long
)
1
,
sizeof
(
struct
customer4
),
ECPGt_short
,
&
(
inds
[
0
].
name_ind
),(
long
)
1
,(
long
)
1
,
sizeof
(
short
),
ECPGt_short
,
&
(
inds
[
0
].
name_ind
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
ind
),
ECPGt_int
,
&
(
custs4
.
phone
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
(
custs4
.
phone
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
customer4
),
ECPGt_short
,
&
(
inds
[
0
].
phone_ind
),(
long
)
1
,(
long
)
1
,
sizeof
(
short
),
ECPGt_EORT
);
ECPGt_short
,
&
(
inds
[
0
].
phone_ind
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
ind
),
ECPGt_EORT
);
#line 80 "array_of_struct.pgc"
#line 80 "array_of_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
...
...
src/interfaces/ecpg/test/expected/preproc-outofscope.c
View file @
f9179685
...
@@ -202,16 +202,16 @@ static void
...
@@ -202,16 +202,16 @@ static void
open_cur1
(
void
)
open_cur1
(
void
)
{
{
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"declare mycur cursor for select * from a1"
,
ECPGt_EOIT
,
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"declare mycur cursor for select * from a1"
,
ECPGt_EOIT
,
ECPGt_int
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
t
),(
long
)
64
,(
long
)
1
,
(
64
)
*
sizeof
(
char
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
t
),(
long
)
64
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
t
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
t
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
double
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
double
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
c
),(
long
)
30
,(
long
)
1
,
(
30
)
*
sizeof
(
char
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
c
),(
long
)
30
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
c
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_EORT
);
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
c
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_EORT
);
#line 40 "outofscope.pgc"
#line 40 "outofscope.pgc"
if
(
sqlca
.
sqlcode
<
0
)
exit
(
1
);}
if
(
sqlca
.
sqlcode
<
0
)
exit
(
1
);}
...
@@ -226,16 +226,16 @@ static void
...
@@ -226,16 +226,16 @@ static void
get_record1
(
void
)
get_record1
(
void
)
{
{
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"fetch mycur"
,
ECPGt_EOIT
,
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"fetch mycur"
,
ECPGt_EOIT
,
ECPGt_int
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
id
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
t
),(
long
)
64
,(
long
)
1
,
(
64
)
*
sizeof
(
char
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
t
),(
long
)
64
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
t
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
t
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
double
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d1
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
double
),
ECPGt_double
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
d2
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
c
),(
long
)
30
,(
long
)
1
,
(
30
)
*
sizeof
(
char
),
ECPGt_char
,
&
((
*
(
MYTYPE
*
)(
ECPGget_var
(
0
))
).
c
),(
long
)
30
,(
long
)
1
,
sizeof
(
struct
mytype
),
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
c
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_EORT
);
ECPGt_int
,
&
((
*
(
MYNULLTYPE
*
)(
ECPGget_var
(
1
))
).
c
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
mynulltype
),
ECPGt_EORT
);
#line 49 "outofscope.pgc"
#line 49 "outofscope.pgc"
if
(
sqlca
.
sqlcode
<
0
)
exit
(
1
);}
if
(
sqlca
.
sqlcode
<
0
)
exit
(
1
);}
...
...
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.c
0 → 100644
View file @
f9179685
/* Processed by ecpg (regression mode) */
/* These include files are added by the preprocessor */
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
/* End of automatic include section */
#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
#line 1 "pointer_to_struct.pgc"
#include <stdio.h>
#include <stdlib.h>
#line 1 "regression.h"
#line 4 "pointer_to_struct.pgc"
/* exec sql whenever sqlerror sqlprint ; */
#line 6 "pointer_to_struct.pgc"
/* exec sql whenever sql_warning sqlprint ; */
#line 7 "pointer_to_struct.pgc"
/* exec sql whenever not found sqlprint ; */
#line 8 "pointer_to_struct.pgc"
typedef
struct
{
#line 13 "pointer_to_struct.pgc"
struct
varchar_1
{
int
len
;
char
arr
[
50
];
}
name
;
#line 14 "pointer_to_struct.pgc"
int
phone
;
}
customer
;
#line 15 "pointer_to_struct.pgc"
typedef
struct
ind
{
#line 20 "pointer_to_struct.pgc"
short
name_ind
;
#line 21 "pointer_to_struct.pgc"
short
phone_ind
;
}
cust_ind
;
#line 22 "pointer_to_struct.pgc"
int
main
()
{
/* exec sql begin declare section */
typedef
struct
{
#line 31 "pointer_to_struct.pgc"
struct
varchar_2
{
int
len
;
char
arr
[
50
];
}
name
;
#line 32 "pointer_to_struct.pgc"
int
phone
;
}
customer2
;
#line 33 "pointer_to_struct.pgc"
#line 27 "pointer_to_struct.pgc"
customer
*
custs1
=
(
customer
*
)
malloc
(
sizeof
(
customer
)
*
10
)
;
#line 28 "pointer_to_struct.pgc"
cust_ind
*
inds
=
(
cust_ind
*
)
malloc
(
sizeof
(
cust_ind
)
*
10
)
;
#line 34 "pointer_to_struct.pgc"
customer2
*
custs2
=
(
customer2
*
)
malloc
(
sizeof
(
customer2
)
*
10
)
;
#line 40 "pointer_to_struct.pgc"
struct
customer3
{
#line 38 "pointer_to_struct.pgc"
char
name
[
50
]
;
#line 39 "pointer_to_struct.pgc"
int
phone
;
}
*
custs3
=
(
struct
customer3
*
)
malloc
(
sizeof
(
struct
customer3
)
*
10
)
;
#line 46 "pointer_to_struct.pgc"
struct
customer4
{
#line 44 "pointer_to_struct.pgc"
struct
varchar_3
{
int
len
;
char
arr
[
50
];
}
name
;
#line 45 "pointer_to_struct.pgc"
int
phone
;
}
*
custs4
=
(
struct
customer4
*
)
malloc
(
sizeof
(
struct
customer4
)
)
;
#line 48 "pointer_to_struct.pgc"
int
r
;
#line 49 "pointer_to_struct.pgc"
struct
varchar_4
{
int
len
;
char
arr
[
50
];
}
onlyname
[
2
]
;
/* exec sql end declare section */
#line 50 "pointer_to_struct.pgc"
ECPGdebug
(
1
,
stderr
);
{
ECPGconnect
(
__LINE__
,
0
,
"regress1"
,
NULL
,
NULL
,
NULL
,
0
);
#line 54 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 54 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 54 "pointer_to_struct.pgc"
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"create table customers ( c varchar ( 50 ) , p int )"
,
ECPGt_EOIT
,
ECPGt_EORT
);
#line 56 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 56 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 56 "pointer_to_struct.pgc"
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"insert into customers values ( 'John Doe' , '12345' )"
,
ECPGt_EOIT
,
ECPGt_EORT
);
#line 57 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 57 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 57 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 57 "pointer_to_struct.pgc"
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"insert into customers values ( 'Jane Doe' , '67890' )"
,
ECPGt_EOIT
,
ECPGt_EORT
);
#line 58 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 58 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 58 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 58 "pointer_to_struct.pgc"
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 2"
,
ECPGt_EOIT
,
ECPGt_varchar
,
&
(
custs1
->
name
),(
long
)
50
,(
long
)
-
1
,
sizeof
(
customer
),
ECPGt_short
,
&
(
inds
->
name_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_int
,
&
(
custs1
->
phone
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
customer
),
ECPGt_short
,
&
(
inds
->
phone_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_EORT
);
#line 60 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 60 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 60 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 60 "pointer_to_struct.pgc"
printf
(
"custs1:
\n
"
);
for
(
r
=
0
;
r
<
2
;
r
++
)
{
printf
(
"name - %s
\n
"
,
custs1
[
r
].
name
.
arr
);
printf
(
"phone - %d
\n
"
,
custs1
[
r
].
phone
);
}
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 2"
,
ECPGt_EOIT
,
ECPGt_varchar
,
&
(
custs2
->
name
),(
long
)
50
,(
long
)
-
1
,
sizeof
(
customer2
),
ECPGt_short
,
&
(
inds
->
name_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_int
,
&
(
custs2
->
phone
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
customer2
),
ECPGt_short
,
&
(
inds
->
phone_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_EORT
);
#line 68 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 68 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 68 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 68 "pointer_to_struct.pgc"
printf
(
"
\n
custs2:
\n
"
);
for
(
r
=
0
;
r
<
2
;
r
++
)
{
printf
(
"name - %s
\n
"
,
custs2
[
r
].
name
.
arr
);
printf
(
"phone - %d
\n
"
,
custs2
[
r
].
phone
);
}
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 2"
,
ECPGt_EOIT
,
ECPGt_char
,
&
(
custs3
->
name
),(
long
)
50
,(
long
)
-
1
,
sizeof
(
struct
customer3
),
ECPGt_short
,
&
(
inds
->
name_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_int
,
&
(
custs3
->
phone
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
customer3
),
ECPGt_short
,
&
(
inds
->
phone_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_EORT
);
#line 76 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 76 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 76 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 76 "pointer_to_struct.pgc"
printf
(
"
\n
custs3:
\n
"
);
for
(
r
=
0
;
r
<
2
;
r
++
)
{
printf
(
"name - %s
\n
"
,
custs3
[
r
].
name
);
printf
(
"phone - %d
\n
"
,
custs3
[
r
].
phone
);
}
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select * from customers limit 1"
,
ECPGt_EOIT
,
ECPGt_varchar
,
&
(
custs4
->
name
),(
long
)
50
,(
long
)
-
1
,
sizeof
(
struct
customer4
),
ECPGt_short
,
&
(
inds
->
name_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_int
,
&
(
custs4
->
phone
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
customer4
),
ECPGt_short
,
&
(
inds
->
phone_ind
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
ind
),
ECPGt_EORT
);
#line 84 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 84 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 84 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 84 "pointer_to_struct.pgc"
printf
(
"
\n
custs4:
\n
"
);
printf
(
"name - %s
\n
"
,
custs4
->
name
.
arr
);
printf
(
"phone - %d
\n
"
,
custs4
->
phone
);
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select c from customers limit 2"
,
ECPGt_EOIT
,
ECPGt_varchar
,(
onlyname
),(
long
)
50
,(
long
)
2
,
sizeof
(
struct
varchar_4
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_EORT
);
#line 89 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
==
ECPG_NOT_FOUND
)
sqlprint
();
#line 89 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 89 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 89 "pointer_to_struct.pgc"
printf
(
"
\n
name:
\n
"
);
for
(
r
=
0
;
r
<
2
;
r
++
)
{
printf
(
"name - %s
\n
"
,
onlyname
[
r
].
arr
);
}
{
ECPGdisconnect
(
__LINE__
,
"ALL"
);
#line 96 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlwarn
[
0
]
==
'W'
)
sqlprint
();
#line 96 "pointer_to_struct.pgc"
if
(
sqlca
.
sqlcode
<
0
)
sqlprint
();}
#line 96 "pointer_to_struct.pgc"
/* All the memory will anyway be freed at the end */
return
(
0
);
}
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stderr
0 → 100644
View file @
f9179685
[NO_PID]: ECPGdebug: set to 1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 56: query: create table customers ( c varchar ( 50 ) , p int ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 56: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 56: OK: CREATE TABLE
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: query: insert into customers values ( 'John Doe' , '12345' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 57: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 57: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 58: query: insert into customers values ( 'Jane Doe' , '67890' ); with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 58: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 58: OK: INSERT 0 1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 60: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 60: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 60: correctly got 2 tuples with 2 fields
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 60: RESULT: John Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 60: RESULT: Jane Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 60: RESULT: 12345 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 60: RESULT: 67890 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 68: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 68: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 68: correctly got 2 tuples with 2 fields
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 68: RESULT: John Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 68: RESULT: Jane Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 68: RESULT: 12345 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 68: RESULT: 67890 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 76: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 76: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 76: correctly got 2 tuples with 2 fields
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 76: RESULT: John Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 76: RESULT: Jane Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 76: RESULT: 12345 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 76: RESULT: 67890 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 84: query: select * from customers limit 1; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 84: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 84: correctly got 1 tuples with 2 fields
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 84: RESULT: John Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 84: RESULT: 12345 offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 89: query: select c from customers limit 2; with 0 parameter(s) on connection regress1
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_execute on line 89: using PQexec
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_process_output on line 89: correctly got 2 tuples with 1 fields
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 89: RESULT: John Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_get_data on line 89: RESULT: Jane Doe offset: -1; array: no
[NO_PID]: sqlca: code: 0, state: 00000
[NO_PID]: ecpg_finish: connection regress1 closed
[NO_PID]: sqlca: code: 0, state: 00000
src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stdout
0 → 100644
View file @
f9179685
custs1:
name - John Doe
phone - 12345
name - Jane Doe
phone - 67890
custs2:
name - John Doe
phone - 12345
name - Jane Doe
phone - 67890
custs3:
name - John Doe
phone - 12345
name - Jane Doe
phone - 67890
custs4:
name - John Doe
phone - 12345
name:
name - John Doe
name - Jane Doe
src/interfaces/ecpg/test/expected/preproc-type.c
View file @
f9179685
...
@@ -140,11 +140,11 @@ main (void)
...
@@ -140,11 +140,11 @@ main (void)
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select idnum , name , accs , string1 , string2 , string3 from empl where idnum = $1 "
,
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"select idnum , name , accs , string1 , string2 , string3 from empl where idnum = $1 "
,
ECPGt_long
,
&
(
empl
.
idnum
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_long
,
&
(
empl
.
idnum
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_EOIT
,
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_EOIT
,
ECPGt_long
,
&
(
empl
.
idnum
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_long
,
&
(
empl
.
idnum
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
TBempl
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_char
,
&
(
empl
.
name
),(
long
)
21
,(
long
)
1
,
(
21
)
*
sizeof
(
char
),
ECPGt_char
,
&
(
empl
.
name
),(
long
)
21
,(
long
)
1
,
sizeof
(
struct
TBempl
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_short
,
&
(
empl
.
accs
),(
long
)
1
,(
long
)
1
,
sizeof
(
short
),
ECPGt_short
,
&
(
empl
.
accs
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
TBempl
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_char
,(
str
),(
long
)
11
,(
long
)
1
,(
11
)
*
sizeof
(
char
),
ECPGt_char
,(
str
),(
long
)
11
,(
long
)
1
,(
11
)
*
sizeof
(
char
),
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
ECPGt_NO_INDICATOR
,
NULL
,
0L
,
0L
,
0L
,
...
...
src/interfaces/ecpg/test/expected/preproc-variable.c
View file @
f9179685
...
@@ -207,12 +207,12 @@ if (sqlca.sqlcode < 0) exit (1);}
...
@@ -207,12 +207,12 @@ if (sqlca.sqlcode < 0) exit (1);}
while
(
1
)
{
while
(
1
)
{
strcpy
(
msg
,
"fetch"
);
strcpy
(
msg
,
"fetch"
);
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"fetch cur"
,
ECPGt_EOIT
,
{
ECPGdo
(
__LINE__
,
0
,
1
,
NULL
,
0
,
ECPGst_normal
,
"fetch cur"
,
ECPGt_EOIT
,
ECPGt_varchar
,
&
(
p
->
name
),(
long
)
BUFFERSIZ
,(
long
)
1
,
sizeof
(
struct
varchar_1
),
ECPGt_varchar
,
&
(
p
->
name
),(
long
)
BUFFERSIZ
,(
long
)
-
1
,
sizeof
(
struct
birthinfo
),
ECPGt_int
,
&
(
i
->
ind_name
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
(
i
->
ind_name
),(
long
)
1
,(
long
)
-
1
,
sizeof
(
struct
birthinfo
),
ECPGt_long
,
&
(
p
->
birth
.
born
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_long
,
&
(
p
->
birth
.
born
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
birthinfo
),
ECPGt_long
,
&
(
i
->
ind_birth
.
born
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_long
,
&
(
i
->
ind_birth
.
born
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
birthinfo
),
ECPGt_short
,
&
(
p
->
birth
.
age
),(
long
)
1
,(
long
)
1
,
sizeof
(
short
),
ECPGt_short
,
&
(
p
->
birth
.
age
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
birthinfo
),
ECPGt_short
,
&
(
i
->
ind_birth
.
age
),(
long
)
1
,(
long
)
1
,
sizeof
(
short
),
ECPGt_short
,
&
(
i
->
ind_birth
.
age
),(
long
)
1
,(
long
)
1
,
sizeof
(
struct
birthinfo
),
ECPGt_char
,
&
(
married
),(
long
)
0
,(
long
)
1
,(
1
)
*
sizeof
(
char
),
ECPGt_char
,
&
(
married
),(
long
)
0
,(
long
)
1
,(
1
)
*
sizeof
(
char
),
ECPGt_long
,
&
(
ind_married
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_long
,
&
(
ind_married
),(
long
)
1
,(
long
)
1
,
sizeof
(
long
),
ECPGt_int
,
&
(
children
.
integer
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
ECPGt_int
,
&
(
children
.
integer
),(
long
)
1
,(
long
)
1
,
sizeof
(
int
),
...
...
src/interfaces/ecpg/test/preproc/Makefile
View file @
f9179685
...
@@ -14,13 +14,17 @@ TESTS = array_of_struct array_of_struct.c \
...
@@ -14,13 +14,17 @@ TESTS = array_of_struct array_of_struct.c \
outofscope outofscope.c
\
outofscope outofscope.c
\
type
type.c
\
type
type.c
\
variable variable.c
\
variable variable.c
\
whenever whenever.c
whenever whenever.c
\
pointer_to_struct pointer_to_struct.c
all
:
$(TESTS)
all
:
$(TESTS)
array_of_struct.c
:
array_of_struct.pgc ../regression.h
array_of_struct.c
:
array_of_struct.pgc ../regression.h
$(ECPG)
-c
-o
$@
-I
$(srcdir)
$<
$(ECPG)
-c
-o
$@
-I
$(srcdir)
$<
pointer_to_struct.c
:
pointer_to_struct.pgc ../regression.h
$(ECPG)
-c
-o
$@
-I
$(srcdir)
$<
autoprep.c
:
autoprep.pgc ../regression.h
autoprep.c
:
autoprep.pgc ../regression.h
$(ECPG)
-r
prepare
-o
$@
-I
$(srcdir)
$<
$(ECPG)
-r
prepare
-o
$@
-I
$(srcdir)
$<
...
...
src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc
0 → 100644
View file @
f9179685
#include <stdio.h>
#include <stdlib.h>
exec sql include ../regression;
EXEC SQL WHENEVER sqlerror sqlprint;
EXEC SQL WHENEVER sqlwarning sqlprint;
EXEC SQL WHENEVER not found sqlprint;
EXEC SQL TYPE customer IS
struct
{
varchar name[50];
int phone;
};
EXEC SQL TYPE cust_ind IS
struct ind
{
short name_ind;
short phone_ind;
};
int main()
{
EXEC SQL begin declare section;
customer *custs1 = (customer *) malloc(sizeof(customer) * 10);
cust_ind *inds = (cust_ind *) malloc(sizeof(cust_ind) * 10);
typedef struct
{
varchar name[50];
int phone;
} customer2;
customer2 *custs2 = (customer2 *) malloc(sizeof(customer2) * 10);
struct customer3
{
char name[50];
int phone;
} *custs3 = (struct customer3 *) malloc(sizeof(struct customer3) * 10);
struct customer4
{
varchar name[50];
int phone;
} *custs4 = (struct customer4 *) malloc(sizeof(struct customer4));
int r;
varchar onlyname[2][50];
EXEC SQL end declare section;
ECPGdebug(1, stderr);
EXEC SQL connect to REGRESSDB1;
EXEC SQL create table customers (c varchar(50), p int);
EXEC SQL insert into customers values ('John Doe', '12345');
EXEC SQL insert into customers values ('Jane Doe', '67890');
EXEC SQL select * INTO :custs1:inds from customers limit 2;
printf("custs1:\n");
for (r = 0; r < 2; r++)
{
printf( "name - %s\n", custs1[r].name.arr );
printf( "phone - %d\n", custs1[r].phone );
}
EXEC SQL select * INTO :custs2:inds from customers limit 2;
printf("\ncusts2:\n");
for (r = 0; r < 2; r++)
{
printf( "name - %s\n", custs2[r].name.arr );
printf( "phone - %d\n", custs2[r].phone );
}
EXEC SQL select * INTO :custs3:inds from customers limit 2;
printf("\ncusts3:\n");
for (r = 0; r < 2; r++)
{
printf( "name - %s\n", custs3[r].name );
printf( "phone - %d\n", custs3[r].phone );
}
EXEC SQL select * INTO :custs4:inds from customers limit 1;
printf("\ncusts4:\n");
printf( "name - %s\n", custs4->name.arr );
printf( "phone - %d\n", custs4->phone );
EXEC SQL select c INTO :onlyname from customers limit 2;
printf("\nname:\n");
for (r = 0; r < 2; r++)
{
printf( "name - %s\n", onlyname[r].arr );
}
EXEC SQL disconnect all;
/* All the memory will anyway be freed at the end */
return( 0 );
}
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