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
7b85b730
Commit
7b85b730
authored
Apr 01, 2003
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More patches for informix compatibility.
parent
52bc8cad
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
772 additions
and
234 deletions
+772
-234
src/interfaces/ecpg/compatlib/informix.c
src/interfaces/ecpg/compatlib/informix.c
+49
-22
src/interfaces/ecpg/ecpglib/data.c
src/interfaces/ecpg/ecpglib/data.c
+11
-11
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/execute.c
+10
-12
src/interfaces/ecpg/include/decimal.h
src/interfaces/ecpg/include/decimal.h
+6
-6
src/interfaces/ecpg/include/pgtypes_date.h
src/interfaces/ecpg/include/pgtypes_date.h
+5
-5
src/interfaces/ecpg/include/pgtypes_error.h
src/interfaces/ecpg/include/pgtypes_error.h
+12
-11
src/interfaces/ecpg/include/pgtypes_interval.h
src/interfaces/ecpg/include/pgtypes_interval.h
+2
-4
src/interfaces/ecpg/include/pgtypes_numeric.h
src/interfaces/ecpg/include/pgtypes_numeric.h
+8
-8
src/interfaces/ecpg/include/pgtypes_timestamp.h
src/interfaces/ecpg/include/pgtypes_timestamp.h
+8
-2
src/interfaces/ecpg/pgtypeslib/common.c
src/interfaces/ecpg/pgtypeslib/common.c
+110
-2
src/interfaces/ecpg/pgtypeslib/datetime.c
src/interfaces/ecpg/pgtypeslib/datetime.c
+25
-43
src/interfaces/ecpg/pgtypeslib/dt.h
src/interfaces/ecpg/pgtypeslib/dt.h
+22
-17
src/interfaces/ecpg/pgtypeslib/dt_common.c
src/interfaces/ecpg/pgtypeslib/dt_common.c
+5
-0
src/interfaces/ecpg/pgtypeslib/extern.h
src/interfaces/ecpg/pgtypeslib/extern.h
+40
-4
src/interfaces/ecpg/pgtypeslib/interval.c
src/interfaces/ecpg/pgtypeslib/interval.c
+2
-2
src/interfaces/ecpg/pgtypeslib/numeric.c
src/interfaces/ecpg/pgtypeslib/numeric.c
+11
-23
src/interfaces/ecpg/pgtypeslib/timestamp.c
src/interfaces/ecpg/pgtypeslib/timestamp.c
+446
-62
No files found.
src/interfaces/ecpg/compatlib/informix.c
View file @
7b85b730
...
@@ -64,7 +64,7 @@ deccvasc(char *cp, int len, Numeric *np)
...
@@ -64,7 +64,7 @@ deccvasc(char *cp, int len, Numeric *np)
ret
=
-
1201
;
ret
=
-
1201
;
else
else
{
{
np
=
PGTYPESnumeric_
aton
(
str
,
NULL
);
np
=
PGTYPESnumeric_
from_asc
(
str
,
NULL
);
if
(
!
np
)
if
(
!
np
)
{
{
switch
(
errno
)
switch
(
errno
)
...
@@ -85,19 +85,19 @@ deccvasc(char *cp, int len, Numeric *np)
...
@@ -85,19 +85,19 @@ deccvasc(char *cp, int len, Numeric *np)
int
int
deccvdbl
(
double
dbl
,
Numeric
*
np
)
deccvdbl
(
double
dbl
,
Numeric
*
np
)
{
{
return
(
PGTYPESnumeric_
dton
(
dbl
,
np
));
return
(
PGTYPESnumeric_
from_double
(
dbl
,
np
));
}
}
int
int
deccvint
(
int
in
,
Numeric
*
np
)
deccvint
(
int
in
,
Numeric
*
np
)
{
{
return
(
PGTYPESnumeric_
iton
(
in
,
np
));
return
(
PGTYPESnumeric_
from_int
(
in
,
np
));
}
}
int
int
deccvlong
(
long
lng
,
Numeric
*
np
)
deccvlong
(
long
lng
,
Numeric
*
np
)
{
{
return
(
PGTYPESnumeric_
lton
(
lng
,
np
));
return
(
PGTYPESnumeric_
from_long
(
lng
,
np
));
}
}
int
int
...
@@ -159,9 +159,9 @@ dectoasc(Numeric *np, char *cp, int len, int right)
...
@@ -159,9 +159,9 @@ dectoasc(Numeric *np, char *cp, int len, int right)
char
*
str
;
char
*
str
;
if
(
right
>=
0
)
if
(
right
>=
0
)
str
=
PGTYPESnumeric_
ntoa
(
np
,
right
);
str
=
PGTYPESnumeric_
to_asc
(
np
,
right
);
else
else
str
=
PGTYPESnumeric_
ntoa
(
np
,
0
);
str
=
PGTYPESnumeric_
to_asc
(
np
,
0
);
if
(
!
str
)
if
(
!
str
)
return
-
1
;
return
-
1
;
...
@@ -176,13 +176,13 @@ dectoasc(Numeric *np, char *cp, int len, int right)
...
@@ -176,13 +176,13 @@ dectoasc(Numeric *np, char *cp, int len, int right)
int
int
dectodbl
(
Numeric
*
np
,
double
*
dblp
)
dectodbl
(
Numeric
*
np
,
double
*
dblp
)
{
{
return
(
PGTYPESnumeric_
ntod
(
np
,
dblp
));
return
(
PGTYPESnumeric_
to_double
(
np
,
dblp
));
}
}
int
int
dectoint
(
Numeric
*
np
,
int
*
ip
)
dectoint
(
Numeric
*
np
,
int
*
ip
)
{
{
int
ret
=
PGTYPESnumeric_
ntoi
(
np
,
ip
);
int
ret
=
PGTYPESnumeric_
to_int
(
np
,
ip
);
if
(
ret
==
PGTYPES_NUM_OVERFLOW
)
if
(
ret
==
PGTYPES_NUM_OVERFLOW
)
ret
=
-
1200
;
ret
=
-
1200
;
...
@@ -193,7 +193,7 @@ dectoint(Numeric *np, int *ip)
...
@@ -193,7 +193,7 @@ dectoint(Numeric *np, int *ip)
int
int
dectolong
(
Numeric
*
np
,
long
*
lngp
)
dectolong
(
Numeric
*
np
,
long
*
lngp
)
{
{
int
ret
=
PGTYPESnumeric_
ntol
(
np
,
lngp
);
int
ret
=
PGTYPESnumeric_
to_long
(
np
,
lngp
);
if
(
ret
==
PGTYPES_NUM_OVERFLOW
)
if
(
ret
==
PGTYPES_NUM_OVERFLOW
)
ret
=
-
1200
;
ret
=
-
1200
;
...
@@ -205,7 +205,7 @@ dectolong(Numeric *np, long *lngp)
...
@@ -205,7 +205,7 @@ dectolong(Numeric *np, long *lngp)
int
int
rdatestr
(
Date
d
,
char
*
str
)
rdatestr
(
Date
d
,
char
*
str
)
{
{
char
*
tmp
=
PGTYPESdate_
dtoa
(
d
);
char
*
tmp
=
PGTYPESdate_
to_asc
(
d
);
if
(
!
tmp
)
if
(
!
tmp
)
return
-
1210
;
return
-
1210
;
...
@@ -217,6 +217,15 @@ rdatestr (Date d, char *str)
...
@@ -217,6 +217,15 @@ rdatestr (Date d, char *str)
return
0
;
return
0
;
}
}
int
rstrdate
(
char
*
str
,
Date
*
d
)
{
Date
dat
=
PGTYPESdate_from_asc
(
str
,
NULL
);
/* XXX: ERROR handling hier und in datetime.c */
return
0
;
}
void
void
rtoday
(
Date
*
d
)
rtoday
(
Date
*
d
)
{
{
...
@@ -237,7 +246,7 @@ rdefmtdate (Date *d, char *fmt, char *str)
...
@@ -237,7 +246,7 @@ rdefmtdate (Date *d, char *fmt, char *str)
/* TODO: take care of DBCENTURY environment variable */
/* TODO: take care of DBCENTURY environment variable */
/* PGSQL functions allow all centuries */
/* PGSQL functions allow all centuries */
if
(
PGTYPESdate_defmt
date
(
d
,
fmt
,
str
)
==
0
)
if
(
PGTYPESdate_defmt
_asc
(
d
,
fmt
,
str
)
==
0
)
return
0
;
return
0
;
switch
(
errno
)
switch
(
errno
)
...
@@ -254,7 +263,7 @@ rdefmtdate (Date *d, char *fmt, char *str)
...
@@ -254,7 +263,7 @@ rdefmtdate (Date *d, char *fmt, char *str)
int
int
rfmtdate
(
Date
d
,
char
*
fmt
,
char
*
str
)
rfmtdate
(
Date
d
,
char
*
fmt
,
char
*
str
)
{
{
if
(
PGTYPESdate_fmt
date
(
d
,
fmt
,
str
)
==
0
)
if
(
PGTYPESdate_fmt
_asc
(
d
,
fmt
,
str
)
==
0
)
return
0
;
return
0
;
if
(
errno
==
ENOMEM
)
if
(
errno
==
ENOMEM
)
...
@@ -275,19 +284,36 @@ rmdyjul (short mdy[3], Date *d)
...
@@ -275,19 +284,36 @@ rmdyjul (short mdy[3], Date *d)
void
void
dtcurrent
(
Timestamp
*
ts
)
dtcurrent
(
Timestamp
*
ts
)
{
{
return
;
PGTYPEStimestamp_current
(
ts
)
;
}
}
int
int
dtcvasc
(
char
*
str
,
Timestamp
*
ts
)
dtcvasc
(
char
*
str
,
Timestamp
*
ts
)
{
{
Timestamp
ts_tmp
;
int
i
;
char
**
endptr
=
&
str
;
ts_tmp
=
PGTYPEStimestamp_from_asc
(
str
,
endptr
);
i
=
errno
;
if
(
i
)
{
return
i
;
}
if
(
**
endptr
)
{
/* extra characters exist at the end */
return
-
1264
;
}
/* everything went fine */
*
ts
=
ts_tmp
;
return
0
;
return
0
;
}
}
int
int
dtsub
(
Timestamp
*
ts1
,
Timestamp
*
ts2
,
Interval
*
iv
)
dtsub
(
Timestamp
*
ts1
,
Timestamp
*
ts2
,
Interval
*
iv
)
{
{
return
0
;
return
PGTYPEStimestamp_sub
(
ts1
,
ts2
,
iv
)
;
}
}
int
int
...
@@ -299,22 +325,21 @@ dttoasc (Timestamp *ts, char *output)
...
@@ -299,22 +325,21 @@ dttoasc (Timestamp *ts, char *output)
int
int
dttofmtasc
(
Timestamp
*
ts
,
char
*
output
,
int
str_len
,
char
*
fmtstr
)
dttofmtasc
(
Timestamp
*
ts
,
char
*
output
,
int
str_len
,
char
*
fmtstr
)
{
{
return
0
;
return
PGTYPEStimestamp_fmt_asc
(
ts
,
output
,
str_len
,
fmtstr
)
;
}
}
int
int
intoasc
(
Interval
*
i
,
char
*
str
)
intoasc
(
Interval
*
i
,
char
*
str
)
{
{
str
=
PGTYPESinterval_to_asc
(
i
);
if
(
!
str
)
return
-
errno
;
return
0
;
return
0
;
}
}
/* And finally some misc functions */
/* And finally some misc functions */
int
rstrdate
(
char
*
str
,
Date
*
d
)
{
return
0
;
}
int
int
rfmtlong
(
long
lvalue
,
char
*
format
,
char
*
outbuf
)
rfmtlong
(
long
lvalue
,
char
*
format
,
char
*
outbuf
)
{
{
...
@@ -352,8 +377,10 @@ rtypmsize(int type, int len)
...
@@ -352,8 +377,10 @@ rtypmsize(int type, int len)
}
}
void
void
rupshift
(
char
*
s
)
rupshift
(
char
*
s
tr
)
{
{
for
(;
*
str
!=
'\0'
;
str
++
)
if
(
islower
(
*
str
))
*
str
=
toupper
(
*
str
);
return
;
return
;
}
}
...
...
src/interfaces/ecpg/ecpglib/data.c
View file @
7b85b730
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.
3 2003/03/27 14:29:17
meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.
4 2003/04/01 14:37:25
meskes Exp $ */
#include "postgres_fe.h"
#include "postgres_fe.h"
...
@@ -384,9 +384,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -384,9 +384,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
if
(
pval
)
{
{
if
(
isarray
&&
*
pval
==
'"'
)
if
(
isarray
&&
*
pval
==
'"'
)
nres
=
PGTYPESnumeric_
aton
(
pval
+
1
,
&
scan_length
);
nres
=
PGTYPESnumeric_
from_asc
(
pval
+
1
,
&
scan_length
);
else
else
nres
=
PGTYPESnumeric_
aton
(
pval
,
&
scan_length
);
nres
=
PGTYPESnumeric_
from_asc
(
pval
,
&
scan_length
);
if
(
isarray
&&
*
scan_length
==
'"'
)
if
(
isarray
&&
*
scan_length
==
'"'
)
scan_length
++
;
scan_length
++
;
...
@@ -399,7 +399,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -399,7 +399,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
}
}
}
}
else
else
nres
=
PGTYPESnumeric_
aton
(
"0.0"
,
&
scan_length
);
nres
=
PGTYPESnumeric_
from_asc
(
"0.0"
,
&
scan_length
);
PGTYPESnumeric_copy
(
nres
,
(
Numeric
*
)(
var
+
offset
*
act_tuple
));
PGTYPESnumeric_copy
(
nres
,
(
Numeric
*
)(
var
+
offset
*
act_tuple
));
break
;
break
;
...
@@ -408,9 +408,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -408,9 +408,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
if
(
pval
)
{
{
if
(
isarray
&&
*
pval
==
'"'
)
if
(
isarray
&&
*
pval
==
'"'
)
ires
=
PGTYPESinterval_
atoi
(
pval
+
1
,
&
scan_length
);
ires
=
PGTYPESinterval_
from_asc
(
pval
+
1
,
&
scan_length
);
else
else
ires
=
PGTYPESinterval_
atoi
(
pval
,
&
scan_length
);
ires
=
PGTYPESinterval_
from_asc
(
pval
,
&
scan_length
);
if
(
isarray
&&
*
scan_length
==
'"'
)
if
(
isarray
&&
*
scan_length
==
'"'
)
scan_length
++
;
scan_length
++
;
...
@@ -423,7 +423,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -423,7 +423,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
}
}
}
}
else
else
ires
=
PGTYPESinterval_
atoi
(
"0 seconds"
,
NULL
);
ires
=
PGTYPESinterval_
from_asc
(
"0 seconds"
,
NULL
);
PGTYPESinterval_copy
(
ires
,
(
Interval
*
)(
var
+
offset
*
act_tuple
));
PGTYPESinterval_copy
(
ires
,
(
Interval
*
)(
var
+
offset
*
act_tuple
));
break
;
break
;
...
@@ -431,9 +431,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -431,9 +431,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
if
(
pval
)
{
{
if
(
isarray
&&
*
pval
==
'"'
)
if
(
isarray
&&
*
pval
==
'"'
)
ddres
=
PGTYPESdate_
atod
(
pval
+
1
,
&
scan_length
);
ddres
=
PGTYPESdate_
from_asc
(
pval
+
1
,
&
scan_length
);
else
else
ddres
=
PGTYPESdate_
atod
(
pval
,
&
scan_length
);
ddres
=
PGTYPESdate_
from_asc
(
pval
,
&
scan_length
);
if
(
isarray
&&
*
scan_length
==
'"'
)
if
(
isarray
&&
*
scan_length
==
'"'
)
scan_length
++
;
scan_length
++
;
...
@@ -453,9 +453,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
...
@@ -453,9 +453,9 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
if
(
pval
)
if
(
pval
)
{
{
if
(
isarray
&&
*
pval
==
'"'
)
if
(
isarray
&&
*
pval
==
'"'
)
tres
=
PGTYPEStimestamp_
atot
(
pval
+
1
,
&
scan_length
);
tres
=
PGTYPEStimestamp_
from_asc
(
pval
+
1
,
&
scan_length
);
else
else
tres
=
PGTYPEStimestamp_
atot
(
pval
,
&
scan_length
);
tres
=
PGTYPEStimestamp_
from_asc
(
pval
,
&
scan_length
);
if
(
isarray
&&
*
scan_length
==
'"'
)
if
(
isarray
&&
*
scan_length
==
'"'
)
scan_length
++
;
scan_length
++
;
...
...
src/interfaces/ecpg/ecpglib/execute.c
View file @
7b85b730
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.
7 2003/03/30 11:48:18
meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.
8 2003/04/01 14:37:25
meskes Exp $ */
/*
/*
* The aim is to get a simpler inteface to the database routines.
* The aim is to get a simpler inteface to the database routines.
...
@@ -847,7 +847,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -847,7 +847,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
{
{
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
{
{
str
=
PGTYPESnumeric_
ntoa
((
Numeric
*
)((
var
+
var
->
offset
*
element
)
->
value
),
0
);
str
=
PGTYPESnumeric_
to_asc
((
Numeric
*
)((
var
+
var
->
offset
*
element
)
->
value
),
0
);
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
...
@@ -863,7 +863,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -863,7 +863,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
}
else
else
{
{
str
=
PGTYPESnumeric_
ntoa
((
Numeric
*
)(
var
->
value
),
0
);
str
=
PGTYPESnumeric_
to_asc
((
Numeric
*
)(
var
->
value
),
0
);
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
...
@@ -888,7 +888,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -888,7 +888,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
{
{
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
{
{
str
=
PGTYPESinterval_
itoa
((
Interval
*
)((
var
+
var
->
offset
*
element
)
->
value
));
str
=
PGTYPESinterval_
to_asc
((
Interval
*
)((
var
+
var
->
offset
*
element
)
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
...
@@ -904,7 +904,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -904,7 +904,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
}
else
else
{
{
str
=
PGTYPESinterval_
itoa
((
Interval
*
)(
var
->
value
));
str
=
PGTYPESinterval_
to_asc
((
Interval
*
)(
var
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
...
@@ -929,7 +929,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -929,7 +929,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
{
{
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
{
{
str
=
PGTYPESdate_
dtoa
(
*
(
Date
*
)((
var
+
var
->
offset
*
element
)
->
value
));
str
=
PGTYPESdate_
to_asc
(
*
(
Date
*
)((
var
+
var
->
offset
*
element
)
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
...
@@ -945,7 +945,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -945,7 +945,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
}
else
else
{
{
str
=
PGTYPESdate_
dtoa
(
*
(
Date
*
)(
var
->
value
));
str
=
PGTYPESdate_
to_asc
(
*
(
Date
*
)(
var
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
...
@@ -970,7 +970,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -970,7 +970,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
{
{
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
{
{
str
=
PGTYPEStimestamp_t
toa
(
*
(
Timestamp
*
)((
var
+
var
->
offset
*
element
)
->
value
));
str
=
PGTYPEStimestamp_t
o_asc
(
*
(
Timestamp
*
)((
var
+
var
->
offset
*
element
)
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
...
@@ -986,7 +986,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
...
@@ -986,7 +986,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
}
else
else
{
{
str
=
PGTYPEStimestamp_t
toa
(
*
(
Timestamp
*
)(
var
->
value
));
str
=
PGTYPEStimestamp_t
o_asc
(
*
(
Timestamp
*
)(
var
->
value
));
slen
=
strlen
(
str
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
...
@@ -1239,9 +1239,7 @@ ECPGexecute(struct statement * stmt)
...
@@ -1239,9 +1239,7 @@ ECPGexecute(struct statement * stmt)
{
{
ECPGlog
(
"ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
ECPGlog
(
"ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
stmt
->
lineno
,
notify
->
relname
,
notify
->
be_pid
);
stmt
->
lineno
,
notify
->
relname
,
notify
->
be_pid
);
/* PQfreemem(notify);*/
PQfreemem
(
notify
);
free
(
notify
);
#warning Remove PQfreemem define
}
}
return
status
;
return
status
;
...
...
src/interfaces/ecpg/include/decimal.h
View file @
7b85b730
...
@@ -4,16 +4,16 @@
...
@@ -4,16 +4,16 @@
#define dec_t Numeric
#define dec_t Numeric
#endif
/* dec_t */
#endif
/* dec_t */
int
decadd
(
dec_t
*
,
Numeric
*
,
Numeric
*
);
int
decadd
(
dec_t
*
,
dec_t
*
,
dec_t
*
);
int
deccmp
(
dec_t
*
,
Numeric
*
);
int
deccmp
(
dec_t
*
,
dec_t
*
);
void
deccopy
(
dec_t
*
,
Numeric
*
);
void
deccopy
(
dec_t
*
,
dec_t
*
);
int
deccvasc
(
char
*
,
int
,
dec_t
*
);
int
deccvasc
(
char
*
,
int
,
dec_t
*
);
int
deccvdbl
(
double
,
dec_t
*
);
int
deccvdbl
(
double
,
dec_t
*
);
int
deccvint
(
int
,
dec_t
*
);
int
deccvint
(
int
,
dec_t
*
);
int
deccvlong
(
long
,
dec_t
*
);
int
deccvlong
(
long
,
dec_t
*
);
int
decdiv
(
dec_t
*
,
Numeric
*
,
Numeric
*
);
int
decdiv
(
dec_t
*
,
dec_t
*
,
dec_t
*
);
int
decmul
(
dec_t
*
,
Numeric
*
,
Numeric
*
);
int
decmul
(
dec_t
*
,
dec_t
*
,
dec_t
*
);
int
decsub
(
dec_t
*
,
Numeric
*
,
Numeric
*
);
int
decsub
(
dec_t
*
,
dec_t
*
,
dec_t
*
);
int
dectoasc
(
dec_t
*
,
char
*
,
int
,
int
);
int
dectoasc
(
dec_t
*
,
char
*
,
int
,
int
);
int
dectodbl
(
dec_t
*
,
double
*
);
int
dectodbl
(
dec_t
*
,
double
*
);
int
dectoint
(
dec_t
*
,
int
*
);
int
dectoint
(
dec_t
*
,
int
*
);
...
...
src/interfaces/ecpg/include/pgtypes_date.h
View file @
7b85b730
...
@@ -5,13 +5,13 @@
...
@@ -5,13 +5,13 @@
#define Date long
#define Date long
extern
Date
PGTYPESdate_
atod
(
char
*
,
char
**
);
extern
Date
PGTYPESdate_
from_asc
(
char
*
,
char
**
);
extern
char
*
PGTYPESdate_
dtoa
(
Date
);
extern
char
*
PGTYPESdate_
to_asc
(
Date
);
extern
Date
PGTYPESdate_
ttod
(
Timestamp
);
extern
Date
PGTYPESdate_
from_timestamp
(
Timestamp
);
extern
void
PGTYPESdate_julmdy
(
Date
,
int
*
);
extern
void
PGTYPESdate_julmdy
(
Date
,
int
*
);
extern
void
PGTYPESdate_mdyjul
(
int
*
,
Date
*
);
extern
void
PGTYPESdate_mdyjul
(
int
*
,
Date
*
);
extern
int
PGTYPESdate_dayofweek
(
Date
);
extern
int
PGTYPESdate_dayofweek
(
Date
);
extern
void
PGTYPESdate_today
(
Date
*
);
extern
void
PGTYPESdate_today
(
Date
*
);
extern
int
PGTYPESdate_defmt
date
(
Date
*
,
char
*
,
char
*
);
extern
int
PGTYPESdate_defmt
_asc
(
Date
*
,
char
*
,
char
*
);
extern
int
PGTYPESdate_fmt
date
(
Date
,
char
*
,
char
*
);
extern
int
PGTYPESdate_fmt
_asc
(
Date
,
char
*
,
char
*
);
#endif
/* PGTYPES_DATETIME */
#endif
/* PGTYPES_DATETIME */
src/interfaces/ecpg/include/pgtypes_error.h
View file @
7b85b730
#define PGTYPES_NUM_OVERFLOW
2
01
#define PGTYPES_NUM_OVERFLOW
3
01
#define PGTYPES_NUM_BAD_NUMERIC
2
02
#define PGTYPES_NUM_BAD_NUMERIC
3
02
#define PGTYPES_NUM_DIVIDE_ZERO
2
03
#define PGTYPES_NUM_DIVIDE_ZERO
3
03
#define PGTYPES_DATE_BAD_DATE
2
10
#define PGTYPES_DATE_BAD_DATE
3
10
#define PGTYPES_DATE_ERR_EARGS
2
11
#define PGTYPES_DATE_ERR_EARGS
3
11
#define PGTYPES_DATE_ERR_ENOSHORTDATE
2
12
#define PGTYPES_DATE_ERR_ENOSHORTDATE
3
12
#define PGTYPES_DATE_ERR_ENOTDMY
2
13
#define PGTYPES_DATE_ERR_ENOTDMY
3
13
#define PGTYPES_DATE_BAD_DAY
2
14
#define PGTYPES_DATE_BAD_DAY
3
14
#define PGTYPES_DATE_BAD_MONTH
2
15
#define PGTYPES_DATE_BAD_MONTH
3
15
#define PGTYPES_TS_BAD_TIMESTAMP 220
#define PGTYPES_TS_BAD_TIMESTAMP 320
#define PGTYPES_TS_ERR_EINFTIME 321
#define PGTYPES_INTVL_BAD_INTERVAL
2
30
#define PGTYPES_INTVL_BAD_INTERVAL
3
30
src/interfaces/ecpg/include/pgtypes_interval.h
View file @
7b85b730
#ifndef PGTYPES_INTERVAL
#ifndef PGTYPES_INTERVAL
#define PGTYPES_INTERVAL
#define PGTYPES_INTERVAL
#include <pgtypes_timestamp.h>
typedef
struct
typedef
struct
{
{
#ifdef HAVE_INT64_TIMESTAMP
#ifdef HAVE_INT64_TIMESTAMP
...
@@ -13,8 +11,8 @@ typedef struct
...
@@ -13,8 +11,8 @@ typedef struct
long
month
;
/* months and years, after time for alignment */
long
month
;
/* months and years, after time for alignment */
}
Interval
;
}
Interval
;
extern
Interval
*
PGTYPESinterval_
atoi
(
char
*
,
char
**
);
extern
Interval
*
PGTYPESinterval_
from_asc
(
char
*
,
char
**
);
extern
char
*
PGTYPESinterval_
itoa
(
Interval
*
);
extern
char
*
PGTYPESinterval_
to_asc
(
Interval
*
);
extern
int
PGTYPESinterval_copy
(
Interval
*
,
Interval
*
);
extern
int
PGTYPESinterval_copy
(
Interval
*
,
Interval
*
);
#endif
/* PGTYPES_INTERVAL */
#endif
/* PGTYPES_INTERVAL */
src/interfaces/ecpg/include/pgtypes_numeric.h
View file @
7b85b730
...
@@ -22,19 +22,19 @@ typedef struct
...
@@ -22,19 +22,19 @@ typedef struct
Numeric
*
PGTYPESnew
(
void
);
Numeric
*
PGTYPESnew
(
void
);
void
PGTYPESnumeric_free
(
Numeric
*
);
void
PGTYPESnumeric_free
(
Numeric
*
);
Numeric
*
PGTYPESnumeric_
aton
(
char
*
,
char
**
);
Numeric
*
PGTYPESnumeric_
from_asc
(
char
*
,
char
**
);
char
*
PGTYPESnumeric_
ntoa
(
Numeric
*
,
int
);
char
*
PGTYPESnumeric_
to_asc
(
Numeric
*
,
int
);
int
PGTYPESnumeric_add
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_add
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_sub
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_sub
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_mul
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_mul
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_div
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_div
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_cmp
(
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_cmp
(
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_
iton
(
signed
int
,
Numeric
*
);
int
PGTYPESnumeric_
from_int
(
signed
int
,
Numeric
*
);
int
PGTYPESnumeric_
lton
(
signed
long
int
,
Numeric
*
);
int
PGTYPESnumeric_
from_long
(
signed
long
int
,
Numeric
*
);
int
PGTYPESnumeric_copy
(
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_copy
(
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_
dton
(
double
,
Numeric
*
);
int
PGTYPESnumeric_
from_double
(
double
,
Numeric
*
);
int
PGTYPESnumeric_
ntod
(
Numeric
*
,
double
*
);
int
PGTYPESnumeric_
to_double
(
Numeric
*
,
double
*
);
int
PGTYPESnumeric_
ntoi
(
Numeric
*
,
int
*
);
int
PGTYPESnumeric_
to_int
(
Numeric
*
,
int
*
);
int
PGTYPESnumeric_
ntol
(
Numeric
*
,
long
*
);
int
PGTYPESnumeric_
to_long
(
Numeric
*
,
long
*
);
#endif
/* PGTYPES_NUMERIC */
#endif
/* PGTYPES_NUMERIC */
src/interfaces/ecpg/include/pgtypes_timestamp.h
View file @
7b85b730
#ifndef PGTYPES_TIMESTAMP
#ifndef PGTYPES_TIMESTAMP
#define PGTYPES_TIMESTAMP
#define PGTYPES_TIMESTAMP
#include <pgtypes_interval.h>
#ifdef HAVE_INT64_TIMESTAMP
#ifdef HAVE_INT64_TIMESTAMP
typedef
int64
Timestamp
;
typedef
int64
Timestamp
;
typedef
int64
TimestampTz
;
typedef
int64
TimestampTz
;
...
@@ -10,7 +12,11 @@ typedef double Timestamp;
...
@@ -10,7 +12,11 @@ typedef double Timestamp;
typedef
double
TimestampTz
;
typedef
double
TimestampTz
;
#endif
#endif
extern
Timestamp
PGTYPEStimestamp_atot
(
char
*
,
char
**
);
extern
Timestamp
PGTYPEStimestamp_from_asc
(
char
*
,
char
**
);
extern
char
*
PGTYPEStimestamp_ttoa
(
Timestamp
);
extern
char
*
PGTYPEStimestamp_to_asc
(
Timestamp
);
extern
int
PGTYPEStimestamp_sub
(
Timestamp
*
,
Timestamp
*
,
Interval
*
);
extern
int
PGTYPEStimestamp_fmt_asc
(
Timestamp
*
,
char
*
,
int
,
char
*
);
extern
void
PGTYPEStimestamp_current
(
Timestamp
*
);
#endif
/* PGTYPES_TIMESTAMP */
#endif
/* PGTYPES_TIMESTAMP */
src/interfaces/ecpg/pgtypeslib/common.c
View file @
7b85b730
#include <
errn
o.h>
#include <
stdi
o.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "extern.h"
#include "extern.h"
char
*
char
*
pgtypes_alloc
(
long
size
)
pgtypes_alloc
(
long
size
)
{
{
...
@@ -28,3 +30,109 @@ pgtypes_strdup(char *str)
...
@@ -28,3 +30,109 @@ pgtypes_strdup(char *str)
return
(
new
);
return
(
new
);
}
}
int
pgtypes_fmt_replace
(
union
un_fmt_replace
replace_val
,
int
replace_type
,
char
**
output
,
int
*
pstr_len
)
{
/* general purpose variable, set to 0 in order to fix compiler
* warning */
int
i
=
0
;
switch
(
replace_type
)
{
case
PGTYPES_REPLACE_NOTHING
:
break
;
case
PGTYPES_REPLACE_STRING_CONSTANT
:
case
PGTYPES_REPLACE_STRING_MALLOCED
:
i
=
strlen
(
replace_val
.
replace_str
);
if
(
i
+
1
<=
*
pstr_len
)
{
/* copy over i + 1 bytes, that includes the
* tailing terminator */
strncpy
(
*
output
,
replace_val
.
replace_str
,
i
+
1
);
*
pstr_len
-=
i
;
*
output
+=
i
;
if
(
replace_type
==
PGTYPES_REPLACE_STRING_MALLOCED
)
{
free
(
replace_val
.
replace_str
);
}
return
0
;
}
else
{
return
-
1
;
}
break
;
case
PGTYPES_REPLACE_CHAR
:
if
(
*
pstr_len
>=
2
)
{
(
*
output
)[
0
]
=
replace_val
.
replace_char
;
(
*
output
)[
1
]
=
'\0'
;
(
*
pstr_len
)
--
;
(
*
output
)
++
;
return
0
;
}
else
{
return
-
1
;
}
break
;
case
PGTYPES_REPLACE_DOUBLE_NF
:
case
PGTYPES_REPLACE_INT64
:
case
PGTYPES_REPLACE_UINT
:
case
PGTYPES_REPLACE_UINT_2_LZ
:
case
PGTYPES_REPLACE_UINT_2_LS
:
case
PGTYPES_REPLACE_UINT_3_LZ
:
case
PGTYPES_REPLACE_UINT_4_LZ
:
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_FMT_NUM_MAX_DIGITS
);
if
(
!
t
)
{
return
ENOMEM
;
}
switch
(
replace_type
)
{
case
PGTYPES_REPLACE_DOUBLE_NF
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%0.0g"
,
replace_val
.
replace_double
);
break
;
#ifdef HAVE_INT6
case
PGTYPES_REPLACE_INT64
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
INT64_FORMAT
,
replace_val
.
replace_int64
);
break
;
#endif
case
PGTYPES_REPLACE_UINT
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%u"
,
replace_val
.
replace_uint
);
break
;
case
PGTYPES_REPLACE_UINT_2_LZ
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%02u"
,
replace_val
.
replace_uint
);
break
;
case
PGTYPES_REPLACE_UINT_2_LS
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%2u"
,
replace_val
.
replace_uint
);
break
;
case
PGTYPES_REPLACE_UINT_3_LZ
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%03u"
,
replace_val
.
replace_uint
);
break
;
case
PGTYPES_REPLACE_UINT_4_LZ
:
i
=
snprintf
(
t
,
PGTYPES_FMT_NUM_MAX_DIGITS
,
"%04u"
,
replace_val
.
replace_uint
);
break
;
}
if
(
i
<
0
)
{
free
(
t
);
return
-
1
;
}
i
=
strlen
(
t
);
*
pstr_len
-=
i
;
/* if *pstr_len == 0, we don't have enough
* space for the terminator and the
* conversion fails */
if
(
*
pstr_len
<=
0
)
{
free
(
t
);
return
-
1
;
}
strcpy
(
*
output
,
t
);
*
output
+=
i
;
free
(
t
);
}
break
;
default:
break
;
}
return
0
;
}
src/interfaces/ecpg/pgtypeslib/datetime.c
View file @
7b85b730
...
@@ -4,18 +4,15 @@
...
@@ -4,18 +4,15 @@
#include <float.h>
#include <float.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include "dt.h"
#include "dt.h"
#include "extern.h"
#include "extern.h"
#include "pgtypes_error.h"
#include "pgtypes_error.h"
#include "pgtypes_date.h"
#include "pgtypes_date.h"
/* XXX: currently not used.
* pgsql: timestamp_date()
* Convert timestamp to date data type.
*/
Date
Date
PGTYPESdate_
ttod
(
Timestamp
dt
)
PGTYPESdate_
from_timestamp
(
Timestamp
dt
)
{
{
Date
dDate
;
Date
dDate
;
...
@@ -36,7 +33,7 @@ PGTYPESdate_ttod(Timestamp dt)
...
@@ -36,7 +33,7 @@ PGTYPESdate_ttod(Timestamp dt)
}
}
Date
Date
PGTYPESdate_
atod
(
char
*
str
,
char
**
endptr
)
PGTYPESdate_
from_asc
(
char
*
str
,
char
**
endptr
)
{
{
Date
dDate
;
Date
dDate
;
...
@@ -87,7 +84,7 @@ PGTYPESdate_atod(char *str, char **endptr)
...
@@ -87,7 +84,7 @@ PGTYPESdate_atod(char *str, char **endptr)
}
}
char
*
char
*
PGTYPESdate_
dtoa
(
Date
dDate
)
PGTYPESdate_
to_asc
(
Date
dDate
)
{
{
struct
tm
tt
,
*
tm
=
&
tt
;
struct
tm
tt
,
*
tm
=
&
tt
;
char
buf
[
MAXDATELEN
+
1
];
char
buf
[
MAXDATELEN
+
1
];
...
@@ -154,16 +151,8 @@ PGTYPESdate_today (Date *d)
...
@@ -154,16 +151,8 @@ PGTYPESdate_today (Date *d)
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT 5
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT 5
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG 6
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG 6
static
char
*
pgtypes_date_weekdays_short
[]
=
{
"Sun"
,
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
,
NULL
};
static
char
*
pgtypes_date_months
[]
=
{
"January"
,
"February"
,
"March"
,
"April"
,
"May"
,
"June"
,
"July"
,
"August"
,
"September"
,
"October"
,
"November"
,
"December"
,
NULL
};
static
char
*
pgtypes_date_months_short
[]
=
{
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
,
NULL
};
int
int
PGTYPESdate_fmt
date
(
Date
dDate
,
char
*
fmtstring
,
char
*
outbuf
)
{
PGTYPESdate_fmt
_asc
(
Date
dDate
,
char
*
fmtstring
,
char
*
outbuf
)
{
static
struct
{
static
struct
{
char
*
format
;
char
*
format
;
int
component
;
int
component
;
...
@@ -180,15 +169,6 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -180,15 +169,6 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
{
NULL
,
0
}
{
NULL
,
0
}
};
};
/* These are the constants that decide which printf() format we'll use in
* order to get a string representation of the value */
#define PGTYPES_DATE_REPLACE_STRING_MALLOCED 1
#define PGTYPES_DATE_REPLACE_STRING_CONSTANT 2
#define PGTYPES_DATE_REPLACE_UINT 3
#define PGTYPES_DATE_REPLACE_UINT_2_LZ 4
#define PGTYPES_DATE_REPLACE_UINT_4_LZ 5
union
{
union
{
char
*
replace_str
;
char
*
replace_str
;
unsigned
int
replace_uint
;
unsigned
int
replace_uint
;
...
@@ -213,44 +193,44 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -213,44 +193,44 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
switch
(
mapping
[
i
].
component
)
{
switch
(
mapping
[
i
].
component
)
{
case
PGTYPES_FMTDATE_DOW_LITERAL_SHORT
:
case
PGTYPES_FMTDATE_DOW_LITERAL_SHORT
:
replace_val
.
replace_str
=
pgtypes_date_weekdays_short
[
dow
];
replace_val
.
replace_str
=
pgtypes_date_weekdays_short
[
dow
];
replace_type
=
PGTYPES_
DATE_
REPLACE_STRING_CONSTANT
;
replace_type
=
PGTYPES_REPLACE_STRING_CONSTANT
;
break
;
break
;
case
PGTYPES_FMTDATE_DAY_DIGITS_LZ
:
case
PGTYPES_FMTDATE_DAY_DIGITS_LZ
:
replace_val
.
replace_uint
=
tm
.
tm_mday
;
replace_val
.
replace_uint
=
tm
.
tm_mday
;
replace_type
=
PGTYPES_
DATE_
REPLACE_UINT_2_LZ
;
replace_type
=
PGTYPES_REPLACE_UINT_2_LZ
;
break
;
break
;
case
PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
:
case
PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
:
replace_val
.
replace_str
=
pgtypes_date_months_short
[
tm
.
tm_mon
-
1
];
replace_val
.
replace_str
=
months
[
tm
.
tm_mon
-
1
];
replace_type
=
PGTYPES_
DATE_
REPLACE_STRING_CONSTANT
;
replace_type
=
PGTYPES_REPLACE_STRING_CONSTANT
;
break
;
break
;
case
PGTYPES_FMTDATE_MONTH_DIGITS_LZ
:
case
PGTYPES_FMTDATE_MONTH_DIGITS_LZ
:
replace_val
.
replace_uint
=
tm
.
tm_mon
;
replace_val
.
replace_uint
=
tm
.
tm_mon
;
replace_type
=
PGTYPES_
DATE_
REPLACE_UINT_2_LZ
;
replace_type
=
PGTYPES_REPLACE_UINT_2_LZ
;
break
;
break
;
case
PGTYPES_FMTDATE_YEAR_DIGITS_LONG
:
case
PGTYPES_FMTDATE_YEAR_DIGITS_LONG
:
replace_val
.
replace_uint
=
tm
.
tm_year
;
replace_val
.
replace_uint
=
tm
.
tm_year
;
replace_type
=
PGTYPES_
DATE_
REPLACE_UINT_4_LZ
;
replace_type
=
PGTYPES_REPLACE_UINT_4_LZ
;
break
;
break
;
case
PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
:
case
PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
:
replace_val
.
replace_uint
=
tm
.
tm_year
%
1000
;
replace_val
.
replace_uint
=
tm
.
tm_year
%
1000
;
replace_type
=
PGTYPES_
DATE_
REPLACE_UINT_2_LZ
;
replace_type
=
PGTYPES_REPLACE_UINT_2_LZ
;
break
;
break
;
default:
default:
/* should not happen, set something
/* should not happen, set something
* anyway */
* anyway */
replace_val
.
replace_str
=
" "
;
replace_val
.
replace_str
=
" "
;
replace_type
=
PGTYPES_
DATE_
REPLACE_STRING_CONSTANT
;
replace_type
=
PGTYPES_REPLACE_STRING_CONSTANT
;
}
}
switch
(
replace_type
)
{
switch
(
replace_type
)
{
case
PGTYPES_
DATE_
REPLACE_STRING_MALLOCED
:
case
PGTYPES_REPLACE_STRING_MALLOCED
:
case
PGTYPES_
DATE_
REPLACE_STRING_CONSTANT
:
case
PGTYPES_REPLACE_STRING_CONSTANT
:
strncpy
(
start_pattern
,
replace_val
.
replace_str
,
strncpy
(
start_pattern
,
replace_val
.
replace_str
,
strlen
(
replace_val
.
replace_str
));
strlen
(
replace_val
.
replace_str
));
if
(
replace_type
==
PGTYPES_
DATE_
REPLACE_STRING_MALLOCED
)
{
if
(
replace_type
==
PGTYPES_REPLACE_STRING_MALLOCED
)
{
free
(
replace_val
.
replace_str
);
free
(
replace_val
.
replace_str
);
}
}
break
;
break
;
case
PGTYPES_
DATE_
REPLACE_UINT
:
case
PGTYPES_REPLACE_UINT
:
{
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
if
(
!
t
)
{
...
@@ -262,7 +242,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -262,7 +242,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
free
(
t
);
free
(
t
);
}
}
break
;
break
;
case
PGTYPES_
DATE_
REPLACE_UINT_2_LZ
:
case
PGTYPES_REPLACE_UINT_2_LZ
:
{
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
if
(
!
t
)
{
...
@@ -274,7 +254,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -274,7 +254,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
free
(
t
);
free
(
t
);
}
}
break
;
break
;
case
PGTYPES_
DATE_
REPLACE_UINT_4_LZ
:
case
PGTYPES_REPLACE_UINT_4_LZ
:
{
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
if
(
!
t
)
{
...
@@ -289,7 +269,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -289,7 +269,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
default:
default:
/* doesn't happen (we set
/* doesn't happen (we set
* replace_type to
* replace_type to
* PGTYPES_
DATE_
REPLACE_STRING_CONSTANT
* PGTYPES_REPLACE_STRING_CONSTANT
* in case of an error above) */
* in case of an error above) */
break
;
break
;
}
}
...
@@ -300,7 +280,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -300,7 +280,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
/*
/*
* PGTYPESdate_
rdefmtdate
* PGTYPESdate_
defmt_asc
*
*
* function works as follows:
* function works as follows:
* - first we analyze the paramters
* - first we analyze the paramters
...
@@ -314,7 +294,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
...
@@ -314,7 +294,7 @@ PGTYPESdate_fmtdate(Date dDate, char* fmtstring, char* outbuf) {
#define PGTYPES_DATE_MONTH_MAXLENGTH 20
/* probably even less :-) */
#define PGTYPES_DATE_MONTH_MAXLENGTH 20
/* probably even less :-) */
int
int
PGTYPESdate_defmt
date
(
Date
*
d
,
char
*
fmt
,
char
*
str
)
PGTYPESdate_defmt
_asc
(
Date
*
d
,
char
*
fmt
,
char
*
str
)
{
{
/* token[2] = { 4,6 } means that token 2 starts at
/* token[2] = { 4,6 } means that token 2 starts at
* position 4 and ends at (including) position 6 */
* position 4 and ends at (including) position 6 */
...
@@ -537,7 +517,7 @@ PGTYPESdate_defmtdate(Date *d, char *fmt, char *str)
...
@@ -537,7 +517,7 @@ PGTYPESdate_defmtdate(Date *d, char *fmt, char *str)
* variable i */
* variable i */
if
(
list
==
pgtypes_date_months
)
{
if
(
list
==
pgtypes_date_months
)
{
if
(
list
[
i
+
1
]
==
NULL
)
{
if
(
list
[
i
+
1
]
==
NULL
)
{
list
=
pgtypes_date_months_short
;
list
=
months
;
i
=
-
1
;
i
=
-
1
;
}
}
}
}
...
@@ -613,6 +593,8 @@ PGTYPESdate_defmtdate(Date *d, char *fmt, char *str)
...
@@ -613,6 +593,8 @@ PGTYPESdate_defmtdate(Date *d, char *fmt, char *str)
return
-
1
;
return
-
1
;
}
}
/* XXX: DBCENTURY ? */
*
d
=
date2j
(
tm
.
tm_year
,
tm
.
tm_mon
,
tm
.
tm_mday
)
-
date2j
(
2000
,
1
,
1
);
*
d
=
date2j
(
tm
.
tm_year
,
tm
.
tm_mon
,
tm
.
tm_mday
)
-
date2j
(
2000
,
1
,
1
);
return
0
;
return
0
;
...
...
src/interfaces/ecpg/pgtypeslib/dt.h
View file @
7b85b730
...
@@ -272,33 +272,38 @@ extern int day_tab[2][13];
...
@@ -272,33 +272,38 @@ extern int day_tab[2][13];
#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND)
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j))
extern
int
DecodeTimeOnly
(
char
**
field
,
int
*
ftype
,
int
DecodeTimeOnly
(
char
**
field
,
int
*
ftype
,
int
nf
,
int
*
dtype
,
int
nf
,
int
*
dtype
,
struct
tm
*
tm
,
fsec_t
*
fsec
,
int
*
tzp
);
struct
tm
*
tm
,
fsec_t
*
fsec
,
int
*
tzp
);
extern
int
DecodeInterval
(
char
**
field
,
int
*
ftype
,
int
DecodeInterval
(
char
**
field
,
int
*
ftype
,
int
nf
,
int
*
dtype
,
int
nf
,
int
*
dtype
,
struct
tm
*
tm
,
fsec_t
*
fsec
);
struct
tm
*
tm
,
fsec_t
*
fsec
);
extern
int
EncodeTimeOnly
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
*
tzp
,
int
style
,
char
*
str
);
int
EncodeTimeOnly
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
*
tzp
,
int
style
,
char
*
str
);
extern
int
EncodeDateTime
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
*
tzp
,
char
**
tzn
,
int
style
,
char
*
str
,
bool
);
int
EncodeDateTime
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
*
tzp
,
char
**
tzn
,
int
style
,
char
*
str
,
bool
);
extern
int
EncodeInterval
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
style
,
char
*
str
);
int
EncodeInterval
(
struct
tm
*
tm
,
fsec_t
fsec
,
int
style
,
char
*
str
);
extern
int
DecodeUnits
(
int
field
,
char
*
lowtoken
,
int
*
val
);
int
DecodeUnits
(
int
field
,
char
*
lowtoken
,
int
*
val
);
extern
bool
ClearDateCache
(
bool
,
bool
,
bool
);
bool
ClearDateCache
(
bool
,
bool
,
bool
);
extern
int
j2day
(
int
jd
);
int
j2day
(
int
jd
);
extern
bool
CheckDateTokenTables
(
void
);
bool
CheckDateTokenTables
(
void
);
extern
int
EncodeDateOnly
(
struct
tm
*
,
int
,
char
*
,
bool
);
int
EncodeDateOnly
(
struct
tm
*
,
int
,
char
*
,
bool
);
extern
void
GetEpochTime
(
struct
tm
*
);
void
GetEpochTime
(
struct
tm
*
);
extern
int
ParseDateTime
(
char
*
,
char
*
,
char
**
,
int
*
,
int
,
int
*
,
char
**
);
int
ParseDateTime
(
char
*
,
char
*
,
char
**
,
int
*
,
int
,
int
*
,
char
**
);
extern
int
DecodeDateTime
(
char
**
,
int
*
,
int
,
int
*
,
struct
tm
*
,
fsec_t
*
,
int
*
,
bool
);
int
DecodeDateTime
(
char
**
,
int
*
,
int
,
int
*
,
struct
tm
*
,
fsec_t
*
,
int
*
,
bool
);
extern
void
j2date
(
int
,
int
*
,
int
*
,
int
*
);
void
j2date
(
int
,
int
*
,
int
*
,
int
*
);
extern
void
GetCurrentDateTime
(
struct
tm
*
);
void
GetCurrentDateTime
(
struct
tm
*
);
extern
int
date2j
(
int
,
int
,
int
);
int
date2j
(
int
,
int
,
int
);
extern
double
rint
(
double
x
);
double
rint
(
double
x
);
extern
char
*
pgtypes_date_weekdays_short
[];
extern
char
*
pgtypes_date_months
[];
extern
char
*
months
[];
extern
char
*
days
[];
#endif
/* DT_H */
#endif
/* DT_H */
src/interfaces/ecpg/pgtypeslib/dt_common.c
View file @
7b85b730
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#include <float.h>
#include <float.h>
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include "dt.h"
#include "dt.h"
#include "extern.h"
#include "extern.h"
...
@@ -505,6 +506,10 @@ char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
...
@@ -505,6 +506,10 @@ char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
char
*
days
[]
=
{
"Sunday"
,
"Monday"
,
"Tuesday"
,
"Wednesday"
,
"Thursday"
,
"Friday"
,
"Saturday"
,
NULL
};
char
*
days
[]
=
{
"Sunday"
,
"Monday"
,
"Tuesday"
,
"Wednesday"
,
"Thursday"
,
"Friday"
,
"Saturday"
,
NULL
};
char
*
pgtypes_date_weekdays_short
[]
=
{
"Sun"
,
"Mon"
,
"Tue"
,
"Wed"
,
"Thu"
,
"Fri"
,
"Sat"
,
NULL
};
char
*
pgtypes_date_months
[]
=
{
"January"
,
"February"
,
"March"
,
"April"
,
"May"
,
"June"
,
"July"
,
"August"
,
"September"
,
"October"
,
"November"
,
"December"
,
NULL
};
#ifndef HAVE_RINT
#ifndef HAVE_RINT
/* @(#)s_rint.c 5.1 93/09/24 */
/* @(#)s_rint.c 5.1 93/09/24 */
...
...
src/interfaces/ecpg/pgtypeslib/extern.h
View file @
7b85b730
#include <string.h>
#ifndef __PGTYPES_COMMON_H__
#define __PGTYPES_COMMON_H__
extern
char
*
pgtypes_alloc
(
long
);
extern
char
*
pgtypes_strdup
(
char
*
);
#include "pgtypes_error.h"
/* These are the constants that decide which printf() format we'll use in
* order to get a string representation of the value */
#define PGTYPES_REPLACE_NOTHING 0
#define PGTYPES_REPLACE_STRING_MALLOCED 1
#define PGTYPES_REPLACE_STRING_CONSTANT 2
#define PGTYPES_REPLACE_CHAR 3
#define PGTYPES_REPLACE_DOUBLE_NF 4
/* no fractional part */
#define PGTYPES_REPLACE_INT64 5
#define PGTYPES_REPLACE_UINT 6
#define PGTYPES_REPLACE_UINT_2_LZ 7
/* 2 digits, pad with leading zero */
#define PGTYPES_REPLACE_UINT_2_LS 8
/* 2 digits, pad with leading space */
#define PGTYPES_REPLACE_UINT_3_LZ 9
#define PGTYPES_REPLACE_UINT_4_LZ 10
#define PGTYPES_FMT_NUM_MAX_DIGITS 40
union
un_fmt_replace
{
char
*
replace_str
;
unsigned
int
replace_uint
;
char
replace_char
;
unsigned
long
int
replace_luint
;
double
replace_double
;
#ifdef HAVE_INT64_TIMESTAMP
int64
replace_int64
;
#endif
};
int
pgtypes_fmt_replace
(
union
un_fmt_replace
,
int
,
char
**
,
int
*
);
char
*
pgtypes_alloc
(
long
);
char
*
pgtypes_strdup
(
char
*
);
#endif
/* __PGTYPES_COMMON_H__ */
src/interfaces/ecpg/pgtypeslib/interval.c
View file @
7b85b730
...
@@ -745,7 +745,7 @@ tm2interval(struct tm * tm, fsec_t fsec, Interval *span)
...
@@ -745,7 +745,7 @@ tm2interval(struct tm * tm, fsec_t fsec, Interval *span)
}
/* tm2interval() */
}
/* tm2interval() */
Interval
*
Interval
*
PGTYPESinterval_
atoi
(
char
*
str
,
char
**
endptr
)
PGTYPESinterval_
from_asc
(
char
*
str
,
char
**
endptr
)
{
{
Interval
*
result
=
NULL
;
Interval
*
result
=
NULL
;
fsec_t
fsec
;
fsec_t
fsec
;
...
@@ -800,7 +800,7 @@ PGTYPESinterval_atoi(char *str, char **endptr)
...
@@ -800,7 +800,7 @@ PGTYPESinterval_atoi(char *str, char **endptr)
}
}
char
*
char
*
PGTYPESinterval_
itoa
(
Interval
*
span
)
PGTYPESinterval_
to_asc
(
Interval
*
span
)
{
{
struct
tm
tt
,
struct
tm
tt
,
*
tm
=
&
tt
;
*
tm
=
&
tt
;
...
...
src/interfaces/ecpg/pgtypeslib/numeric.c
View file @
7b85b730
...
@@ -362,14 +362,8 @@ get_str_from_var(Numeric *var, int dscale)
...
@@ -362,14 +362,8 @@ get_str_from_var(Numeric *var, int dscale)
return
str
;
return
str
;
}
}
/* ----------
* PGTYPESnumeric_aton() -
*
* Input function for numeric data type
* ----------
*/
Numeric
*
Numeric
*
PGTYPESnumeric_
aton
(
char
*
str
,
char
**
endptr
)
PGTYPESnumeric_
from_asc
(
char
*
str
,
char
**
endptr
)
{
{
Numeric
*
value
=
(
Numeric
*
)
pgtypes_alloc
(
sizeof
(
Numeric
));
Numeric
*
value
=
(
Numeric
*
)
pgtypes_alloc
(
sizeof
(
Numeric
));
int
ret
;
int
ret
;
...
@@ -394,14 +388,8 @@ PGTYPESnumeric_aton(char *str, char **endptr)
...
@@ -394,14 +388,8 @@ PGTYPESnumeric_aton(char *str, char **endptr)
return
(
value
);
return
(
value
);
}
}
/* ----------
* numeric_out() -
*
* Output function for numeric data type
* ----------
*/
char
*
char
*
PGTYPESnumeric_
ntoa
(
Numeric
*
num
,
int
dscale
)
PGTYPESnumeric_
to_asc
(
Numeric
*
num
,
int
dscale
)
{
{
if
(
dscale
<=
0
)
if
(
dscale
<=
0
)
dscale
=
num
->
dscale
;
dscale
=
num
->
dscale
;
...
@@ -1328,14 +1316,14 @@ PGTYPESnumeric_cmp(Numeric *var1, Numeric *var2) {
...
@@ -1328,14 +1316,14 @@ PGTYPESnumeric_cmp(Numeric *var1, Numeric *var2) {
}
}
int
int
PGTYPESnumeric_
iton
(
signed
int
int_val
,
Numeric
*
var
)
{
PGTYPESnumeric_
from_int
(
signed
int
int_val
,
Numeric
*
var
)
{
/* implicit conversion */
/* implicit conversion */
signed
long
int
long_int
=
int_val
;
signed
long
int
long_int
=
int_val
;
return
PGTYPESnumeric_
lton
(
long_int
,
var
);
return
PGTYPESnumeric_
from_long
(
long_int
,
var
);
}
}
int
int
PGTYPESnumeric_
lton
(
signed
long
int
long_val
,
Numeric
*
var
)
{
PGTYPESnumeric_
from_long
(
signed
long
int
long_val
,
Numeric
*
var
)
{
/* calculate the size of the long int number */
/* calculate the size of the long int number */
/* a number n needs log_10 n digits */
/* a number n needs log_10 n digits */
/* however we multiply by 10 each time and compare instead of
/* however we multiply by 10 each time and compare instead of
...
@@ -1408,7 +1396,7 @@ PGTYPESnumeric_copy(Numeric *src, Numeric *dst) {
...
@@ -1408,7 +1396,7 @@ PGTYPESnumeric_copy(Numeric *src, Numeric *dst) {
}
}
int
int
PGTYPESnumeric_
dton
(
double
d
,
Numeric
*
dst
)
PGTYPESnumeric_
from_double
(
double
d
,
Numeric
*
dst
)
{
{
char
buffer
[
100
];
char
buffer
[
100
];
Numeric
*
tmp
;
Numeric
*
tmp
;
...
@@ -1416,7 +1404,7 @@ PGTYPESnumeric_dton(double d, Numeric *dst)
...
@@ -1416,7 +1404,7 @@ PGTYPESnumeric_dton(double d, Numeric *dst)
if
(
sprintf
(
buffer
,
"%f"
,
d
)
==
0
)
if
(
sprintf
(
buffer
,
"%f"
,
d
)
==
0
)
return
-
1
;
return
-
1
;
if
((
tmp
=
PGTYPESnumeric_
aton
(
buffer
,
NULL
))
==
NULL
)
if
((
tmp
=
PGTYPESnumeric_
from_asc
(
buffer
,
NULL
))
==
NULL
)
return
-
1
;
return
-
1
;
if
(
PGTYPESnumeric_copy
(
tmp
,
dst
)
!=
0
)
if
(
PGTYPESnumeric_copy
(
tmp
,
dst
)
!=
0
)
return
-
1
;
return
-
1
;
...
@@ -1449,7 +1437,7 @@ numericvar_to_double_no_overflow(Numeric *var, double *dp)
...
@@ -1449,7 +1437,7 @@ numericvar_to_double_no_overflow(Numeric *var, double *dp)
}
}
int
int
PGTYPESnumeric_
ntod
(
Numeric
*
nv
,
double
*
dp
)
{
PGTYPESnumeric_
to_double
(
Numeric
*
nv
,
double
*
dp
)
{
double
tmp
;
double
tmp
;
int
i
;
int
i
;
...
@@ -1460,11 +1448,11 @@ PGTYPESnumeric_ntod(Numeric* nv, double* dp) {
...
@@ -1460,11 +1448,11 @@ PGTYPESnumeric_ntod(Numeric* nv, double* dp) {
}
}
int
int
PGTYPESnumeric_
ntoi
(
Numeric
*
nv
,
int
*
ip
)
{
PGTYPESnumeric_
to_int
(
Numeric
*
nv
,
int
*
ip
)
{
long
l
;
long
l
;
int
i
;
int
i
;
if
((
i
=
PGTYPESnumeric_
ntol
(
nv
,
&
l
))
!=
0
)
if
((
i
=
PGTYPESnumeric_
to_long
(
nv
,
&
l
))
!=
0
)
return
i
;
return
i
;
if
(
l
<
-
INT_MAX
||
l
>
INT_MAX
)
{
if
(
l
<
-
INT_MAX
||
l
>
INT_MAX
)
{
...
@@ -1477,7 +1465,7 @@ PGTYPESnumeric_ntoi(Numeric* nv, int* ip) {
...
@@ -1477,7 +1465,7 @@ PGTYPESnumeric_ntoi(Numeric* nv, int* ip) {
}
}
int
int
PGTYPESnumeric_
ntol
(
Numeric
*
nv
,
long
*
lp
)
{
PGTYPESnumeric_
to_long
(
Numeric
*
nv
,
long
*
lp
)
{
int
i
;
int
i
;
long
l
=
0
;
long
l
=
0
;
...
...
src/interfaces/ecpg/pgtypeslib/timestamp.c
View file @
7b85b730
This diff is collapsed.
Click to expand it.
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