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
999f1298
Commit
999f1298
authored
Mar 30, 2003
by
Michael Meskes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved Informix stuff to its own compat library. Interval datetype is now fully functional.
parent
82a91eb5
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
807 additions
and
346 deletions
+807
-346
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/ChangeLog
+10
-0
src/interfaces/ecpg/Makefile
src/interfaces/ecpg/Makefile
+2
-0
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/execute.c
+6
-4
src/interfaces/ecpg/include/ecpg_informix.h
src/interfaces/ecpg/include/ecpg_informix.h
+3
-0
src/interfaces/ecpg/include/pgtypes_date.h
src/interfaces/ecpg/include/pgtypes_date.h
+9
-4
src/interfaces/ecpg/include/pgtypes_error.h
src/interfaces/ecpg/include/pgtypes_error.h
+12
-5
src/interfaces/ecpg/include/pgtypes_numeric.h
src/interfaces/ecpg/include/pgtypes_numeric.h
+1
-1
src/interfaces/ecpg/pgtypeslib/Makefile
src/interfaces/ecpg/pgtypeslib/Makefile
+2
-2
src/interfaces/ecpg/pgtypeslib/datetime.c
src/interfaces/ecpg/pgtypeslib/datetime.c
+514
-43
src/interfaces/ecpg/pgtypeslib/dt.h
src/interfaces/ecpg/pgtypeslib/dt.h
+1
-0
src/interfaces/ecpg/pgtypeslib/dt_common.c
src/interfaces/ecpg/pgtypeslib/dt_common.c
+105
-1
src/interfaces/ecpg/pgtypeslib/numeric.c
src/interfaces/ecpg/pgtypeslib/numeric.c
+16
-207
src/interfaces/ecpg/pgtypeslib/timestamp.c
src/interfaces/ecpg/pgtypeslib/timestamp.c
+6
-66
src/interfaces/ecpg/test/dt_test.pgc
src/interfaces/ecpg/test/dt_test.pgc
+120
-13
No files found.
src/interfaces/ecpg/ChangeLog
View file @
999f1298
...
...
@@ -1376,7 +1376,17 @@ Thu Mar 27 15:23:58 CET 2003
- Some more updates to pgtypeslib.
- Set optimization to -O1 until I find the reason why code is broken
with -O2.
Sat Mar 29 22:03:16 CET 2003
- Moved Informix compatibility stuff its own library.
- Added interval datetypes.
Sun Mar 30 13:43:13 CEST 2003
- Interval datetype now fully functional.
- Set ecpg version to 2.12.0.
- Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0
- Set compat library to 1.0.0
src/interfaces/ecpg/Makefile
View file @
999f1298
...
...
@@ -6,11 +6,13 @@ all install installdirs uninstall dep depend distprep:
$(MAKE)
-C
include
$@
$(MAKE)
-C
ecpglib
$@
$(MAKE)
-C
pgtypeslib
$@
$(MAKE)
-C
compatlib
$@
$(MAKE)
-C
preproc
$@
clean distclean maintainer-clean
:
-
$(MAKE)
-C
include
$@
-
$(MAKE)
-C
ecpglib
$@
-
$(MAKE)
-C
pgtypeslib
$@
-
$(MAKE)
-C
compatlib
$@
-
$(MAKE)
-C
preproc
$@
-
$(MAKE)
-C
test
clean
src/interfaces/ecpg/ecpglib/execute.c
View file @
999f1298
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.
6 2003/03/27 14:29:17
meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.
7 2003/03/30 11:48:18
meskes Exp $ */
/*
* 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,
{
for
(
element
=
0
;
element
<
var
->
arrsize
;
element
++
)
{
str
=
PGTYPESnumeric_ntoa
((
Numeric
*
)((
var
+
var
->
offset
*
element
)
->
value
));
str
=
PGTYPESnumeric_ntoa
((
Numeric
*
)((
var
+
var
->
offset
*
element
)
->
value
)
,
0
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGrealloc
(
mallocedval
,
strlen
(
mallocedval
)
+
slen
+
5
,
stmt
->
lineno
)))
...
...
@@ -863,7 +863,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
}
else
{
str
=
PGTYPESnumeric_ntoa
((
Numeric
*
)(
var
->
value
));
str
=
PGTYPESnumeric_ntoa
((
Numeric
*
)(
var
->
value
)
,
0
);
slen
=
strlen
(
str
);
if
(
!
(
mallocedval
=
ECPGalloc
(
slen
+
1
,
stmt
->
lineno
)))
...
...
@@ -1239,7 +1239,9 @@ ECPGexecute(struct statement * stmt)
{
ECPGlog
(
"ECPGexecute line %d: ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
stmt
->
lineno
,
notify
->
relname
,
notify
->
be_pid
);
PQfreemem
(
notify
);
/* PQfreemem(notify);*/
free
(
notify
);
#warning Remove PQfreemem define
}
return
status
;
...
...
src/interfaces/ecpg/include/ecpg_informix.h
View file @
999f1298
...
...
@@ -2,6 +2,9 @@
* This file contains stuff needed to be as compatible to Informix as possible.
*/
#include <decimal.h>
#include <datetime.h>
#define SQLNOTFOUND 100
#ifndef Date
...
...
src/interfaces/ecpg/include/pgtypes_date.h
View file @
999f1298
#ifndef PGTYPES_DATETIME
#define PGTYPES_DATETIME
#include <pgtypes_timestamp.h>
#define Date long
extern
Date
PGTYPESdate_atod
(
char
*
,
char
**
);
extern
char
*
PGTYPESdate_dtoa
(
Date
);
extern
int
PGTYPESdate_julmdy
(
Date
,
int
*
);
extern
int
PGTYPESdate_mdyjul
(
int
*
,
Date
*
);
extern
int
PGTYPESdate_day
(
Date
);
extern
Date
PGTYPESdate_ttod
(
Timestamp
);
extern
void
PGTYPESdate_julmdy
(
Date
,
int
*
);
extern
void
PGTYPESdate_mdyjul
(
int
*
,
Date
*
);
extern
int
PGTYPESdate_dayofweek
(
Date
);
extern
void
PGTYPESdate_today
(
Date
*
);
extern
int
PGTYPESdate_defmtdate
(
Date
*
,
char
*
,
char
*
);
extern
int
PGTYPESdate_fmtdate
(
Date
,
char
*
,
char
*
);
#endif
/* PGTYPES_DATETIME */
src/interfaces/ecpg/include/pgtypes_error.h
View file @
999f1298
#define PGTYPES_
OVERFLOW
201
#define PGTYPES_
BAD_NUMERIC
202
#define PGTYPES_
DIVIDE_ZERO
203
#define PGTYPES_
NUM_OVERFLOW
201
#define PGTYPES_
NUM_BAD_NUMERIC
202
#define PGTYPES_
NUM_DIVIDE_ZERO
203
#define PGTYPES_BAD_DATE 210
#define PGTYPES_DATE_BAD_DATE 210
#define PGTYPES_DATE_ERR_EARGS 211
#define PGTYPES_DATE_ERR_ENOSHORTDATE 212
#define PGTYPES_DATE_ERR_ENOTDMY 213
#define PGTYPES_DATE_BAD_DAY 214
#define PGTYPES_DATE_BAD_MONTH 215
#define PGTYPES_BAD_TIMESTAMP 220
#define PGTYPES_TS_BAD_TIMESTAMP 220
#define PGTYPES_INTVL_BAD_INTERVAL 230
src/interfaces/ecpg/include/pgtypes_numeric.h
View file @
999f1298
...
...
@@ -23,7 +23,7 @@ typedef struct
Numeric
*
PGTYPESnew
(
void
);
void
PGTYPESnumeric_free
(
Numeric
*
);
Numeric
*
PGTYPESnumeric_aton
(
char
*
,
char
**
);
char
*
PGTYPESnumeric_ntoa
(
Numeric
*
);
char
*
PGTYPESnumeric_ntoa
(
Numeric
*
,
int
);
int
PGTYPESnumeric_add
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_sub
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
int
PGTYPESnumeric_mul
(
Numeric
*
,
Numeric
*
,
Numeric
*
);
...
...
src/interfaces/ecpg/pgtypeslib/Makefile
View file @
999f1298
...
...
@@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/Makefile,v 1.
3 2003/03/27 14:29:17
meskes Exp $
# $Header: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/Makefile,v 1.
4 2003/03/30 11:48:18
meskes Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -18,7 +18,7 @@ SO_MINOR_VERSION= 0.0
override CPPFLAGS
:
= -O1 -g -I$(top_srcdir)/src/interfaces/ecpg/include -I$(top_srcdir)/src/include/utils $(CPPFLAGS)
OBJS
=
numeric.o datetime.o common.o dt_common.o timestamp.o
OBJS
=
numeric.o datetime.o common.o dt_common.o timestamp.o
interval.o
all
:
all-lib
...
...
src/interfaces/ecpg/pgtypeslib/datetime.c
View file @
999f1298
...
...
@@ -9,7 +9,31 @@
#include "extern.h"
#include "pgtypes_error.h"
#include "pgtypes_date.h"
#include "ecpg_informix.h"
/* XXX: currently not used.
* pgsql: timestamp_date()
* Convert timestamp to date data type.
*/
Date
PGTYPESdate_ttod
(
Timestamp
dt
)
{
Date
dDate
;
dDate
=
0
;
/* suppress compiler warning */
if
(
TIMESTAMP_NOT_FINITE
(
dt
))
return
#ifdef HAVE_INT64_TIMESTAMP
/* Microseconds to days */
dDate
=
(
dt
/
INT64CONST
(
86400000000
));
#else
/* Seconds to days */
dDate
=
(
dt
/
86400
.
0
);
#endif
return
dDate
;
}
Date
PGTYPESdate_atod
(
char
*
str
,
char
**
endptr
)
...
...
@@ -32,14 +56,14 @@ PGTYPESdate_atod(char *str, char **endptr)
if
(
strlen
(
str
)
>=
sizeof
(
lowstr
))
{
errno
=
PGTYPES_BAD_DATE
;
errno
=
PGTYPES_
DATE_
BAD_DATE
;
return
-
1
;
}
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
,
ptr
)
!=
0
)
||
(
DecodeDateTime
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
,
&
tzp
,
EuroDates
)
!=
0
))
{
errno
=
PGTYPES_BAD_DATE
;
errno
=
PGTYPES_
DATE_
BAD_DATE
;
return
-
1
;
}
...
...
@@ -53,7 +77,7 @@ PGTYPESdate_atod(char *str, char **endptr)
break
;
default:
errno
=
PGTYPES_BAD_DATE
;
errno
=
PGTYPES_
DATE_
BAD_DATE
;
return
-
1
;
}
...
...
@@ -75,74 +99,521 @@ PGTYPESdate_dtoa(Date dDate)
return
pgtypes_strdup
(
buf
);
}
int
void
PGTYPESdate_julmdy
(
Date
jd
,
int
*
mdy
)
{
printf
(
"day: %d
\n
"
,
mdy
[
0
]);
printf
(
"month: %d
\n
"
,
mdy
[
1
]);
printf
(
"year: %d
\n
"
,
mdy
[
2
]);
j2date
((
int
)
jd
,
mdy
+
2
,
mdy
+
1
,
mdy
+
0
);
return
0
;
int
y
,
m
,
d
;
j2date
((
int
)
jd
,
&
y
,
&
m
,
&
d
);
mdy
[
0
]
=
(
short
int
)
m
;
mdy
[
1
]
=
(
short
int
)
d
;
mdy
[
2
]
=
(
short
int
)
y
;
}
int
void
PGTYPESdate_mdyjul
(
int
*
mdy
,
Date
*
jdate
)
{
/* month is mdy[0] */
/* day is mdy[1] */
/* year is mdy[2] */
printf
(
"day: %d
\n
"
,
mdy
[
1
]);
printf
(
"month: %d
\n
"
,
mdy
[
0
]);
printf
(
"year: %d
\n
"
,
mdy
[
2
]);
*
jdate
=
(
Date
)
date2j
(
mdy
[
2
],
mdy
[
0
],
mdy
[
1
]);
return
0
;
}
int
PGTYPESdate_day
(
Date
dDate
)
{
return
j2day
(
dDate
);
*
jdate
=
(
Date
)
date2j
(
mdy
[
2
],
mdy
[
0
],
mdy
[
1
]);
}
int
rdatestr
(
Date
d
,
char
*
str
)
PGTYPESdate_dayofweek
(
Date
dDate
)
{
return
0
;
/*
Sunday: 0
Monday: 1
Tuesday: 2
Wednesday: 3
Thursday: 4
Friday: 5
Saturday: 6
*/
return
6
-
j2day
(
dDate
+
3
);
}
void
r
today
(
Date
*
d
)
PGTYPESdate_
today
(
Date
*
d
)
{
struct
tm
ts
;
GetCurrentDateTime
(
&
ts
);
*
d
=
date2j
(
ts
.
tm_year
,
ts
.
tm_mon
,
ts
.
tm_mday
)
-
date2j
(
2000
,
1
,
1
);
return
;
}
int
rjulmdy
(
Date
d
,
short
mdy
[
3
])
{
return
0
;
}
#define PGTYPES_DATE_NUM_MAX_DIGITS 20
/* should suffice for most years... */
int
rdefmtdate
(
Date
*
d
,
char
*
fmt
,
char
*
str
)
{
return
0
;
}
#define PGTYPES_FMTDATE_DAY_DIGITS_LZ 1
/* LZ means "leading zeroes" */
#define PGTYPES_FMTDATE_DOW_LITERAL_SHORT 2
#define PGTYPES_FMTDATE_MONTH_DIGITS_LZ 3
#define PGTYPES_FMTDATE_MONTH_LITERAL_SHORT 4
#define PGTYPES_FMTDATE_YEAR_DIGITS_SHORT 5
#define PGTYPES_FMTDATE_YEAR_DIGITS_LONG 6
int
rfmtdate
(
Date
d
,
char
*
fmt
,
char
*
str
)
{
return
0
;
}
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
rmdyjul
(
short
mdy
[
3
],
Date
*
d
)
{
PGTYPESdate_fmtdate
(
Date
dDate
,
char
*
fmtstring
,
char
*
outbuf
)
{
static
struct
{
char
*
format
;
int
component
;
}
mapping
[]
=
{
/* format items have to be sorted according to their length,
* since the first pattern that matches gets replaced by its
* value */
{
"ddd"
,
PGTYPES_FMTDATE_DOW_LITERAL_SHORT
},
{
"dd"
,
PGTYPES_FMTDATE_DAY_DIGITS_LZ
},
{
"mmm"
,
PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
},
{
"mm"
,
PGTYPES_FMTDATE_MONTH_DIGITS_LZ
},
{
"yyyy"
,
PGTYPES_FMTDATE_YEAR_DIGITS_LONG
},
{
"yy"
,
PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
},
{
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
{
char
*
replace_str
;
unsigned
int
replace_uint
;
}
replace_val
;
int
replace_type
;
int
i
;
int
dow
;
char
*
start_pattern
;
struct
tm
tm
;
/* XXX error handling ? */
/* copy the string over */
strcpy
(
outbuf
,
fmtstring
);
/* get the date */
j2date
((
dDate
+
date2j
(
2000
,
1
,
1
)),
&
(
tm
.
tm_year
),
&
(
tm
.
tm_mon
),
&
(
tm
.
tm_mday
));
dow
=
PGTYPESdate_dayofweek
(
dDate
);
for
(
i
=
0
;
mapping
[
i
].
format
!=
NULL
;
i
++
)
{
while
((
start_pattern
=
strstr
(
outbuf
,
mapping
[
i
].
format
))
!=
NULL
)
{
switch
(
mapping
[
i
].
component
)
{
case
PGTYPES_FMTDATE_DOW_LITERAL_SHORT
:
replace_val
.
replace_str
=
pgtypes_date_weekdays_short
[
dow
];
replace_type
=
PGTYPES_DATE_REPLACE_STRING_CONSTANT
;
break
;
case
PGTYPES_FMTDATE_DAY_DIGITS_LZ
:
replace_val
.
replace_uint
=
tm
.
tm_mday
;
replace_type
=
PGTYPES_DATE_REPLACE_UINT_2_LZ
;
break
;
case
PGTYPES_FMTDATE_MONTH_LITERAL_SHORT
:
replace_val
.
replace_str
=
pgtypes_date_months_short
[
tm
.
tm_mon
-
1
];
replace_type
=
PGTYPES_DATE_REPLACE_STRING_CONSTANT
;
break
;
case
PGTYPES_FMTDATE_MONTH_DIGITS_LZ
:
replace_val
.
replace_uint
=
tm
.
tm_mon
;
replace_type
=
PGTYPES_DATE_REPLACE_UINT_2_LZ
;
break
;
case
PGTYPES_FMTDATE_YEAR_DIGITS_LONG
:
replace_val
.
replace_uint
=
tm
.
tm_year
;
replace_type
=
PGTYPES_DATE_REPLACE_UINT_4_LZ
;
break
;
case
PGTYPES_FMTDATE_YEAR_DIGITS_SHORT
:
replace_val
.
replace_uint
=
tm
.
tm_year
%
1000
;
replace_type
=
PGTYPES_DATE_REPLACE_UINT_2_LZ
;
break
;
default:
/* should not happen, set something
* anyway */
replace_val
.
replace_str
=
" "
;
replace_type
=
PGTYPES_DATE_REPLACE_STRING_CONSTANT
;
}
switch
(
replace_type
)
{
case
PGTYPES_DATE_REPLACE_STRING_MALLOCED
:
case
PGTYPES_DATE_REPLACE_STRING_CONSTANT
:
strncpy
(
start_pattern
,
replace_val
.
replace_str
,
strlen
(
replace_val
.
replace_str
));
if
(
replace_type
==
PGTYPES_DATE_REPLACE_STRING_MALLOCED
)
{
free
(
replace_val
.
replace_str
);
}
break
;
case
PGTYPES_DATE_REPLACE_UINT
:
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
return
-
1
;
}
snprintf
(
t
,
PGTYPES_DATE_NUM_MAX_DIGITS
,
"%u"
,
replace_val
.
replace_uint
);
strncpy
(
start_pattern
,
t
,
strlen
(
t
));
free
(
t
);
}
break
;
case
PGTYPES_DATE_REPLACE_UINT_2_LZ
:
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
return
-
1
;
}
snprintf
(
t
,
PGTYPES_DATE_NUM_MAX_DIGITS
,
"%02u"
,
replace_val
.
replace_uint
);
strncpy
(
start_pattern
,
t
,
strlen
(
t
));
free
(
t
);
}
break
;
case
PGTYPES_DATE_REPLACE_UINT_4_LZ
:
{
char
*
t
=
pgtypes_alloc
(
PGTYPES_DATE_NUM_MAX_DIGITS
);
if
(
!
t
)
{
return
-
1
;
}
snprintf
(
t
,
PGTYPES_DATE_NUM_MAX_DIGITS
,
"%04u"
,
replace_val
.
replace_uint
);
strncpy
(
start_pattern
,
t
,
strlen
(
t
));
free
(
t
);
}
break
;
default:
/* doesn't happen (we set
* replace_type to
* PGTYPES_DATE_REPLACE_STRING_CONSTANT
* in case of an error above) */
break
;
}
}
}
return
0
;
}
/*
* PGTYPESdate_rdefmtdate
*
* function works as follows:
* - first we analyze the paramters
* - if this is a special case with no delimiters, add delimters
* - find the tokens. First we look for numerical values. If we have found
* less than 3 tokens, we check for the months' names and thereafter for
* the abbreviations of the months' names.
* - then we see which parameter should be the date, the month and the
* year and from these values we calculate the date
*/
#define PGTYPES_DATE_MONTH_MAXLENGTH 20
/* probably even less :-) */
int
rstrdate
(
char
*
str
,
Date
*
d
)
PGTYPESdate_defmtdate
(
Date
*
d
,
char
*
fmt
,
char
*
str
)
{
/* token[2] = { 4,6 } means that token 2 starts at
* position 4 and ends at (including) position 6 */
int
token
[
3
][
2
];
int
token_values
[
3
]
=
{
-
1
,
-
1
,
-
1
};
char
*
fmt_token_order
;
char
*
fmt_ystart
,
*
fmt_mstart
,
*
fmt_dstart
;
int
i
;
int
reading_digit
;
int
token_count
;
char
*
str_copy
;
struct
tm
tm
;
if
(
!
d
||
!
str
||
!
fmt
)
{
errno
=
PGTYPES_DATE_ERR_EARGS
;
return
-
1
;
}
/* analyze the fmt string */
fmt_ystart
=
strstr
(
fmt
,
"yy"
);
fmt_mstart
=
strstr
(
fmt
,
"mm"
);
fmt_dstart
=
strstr
(
fmt
,
"dd"
);
if
(
!
fmt_ystart
||
!
fmt_mstart
||
!
fmt_dstart
)
{
errno
=
PGTYPES_DATE_ERR_EARGS
;
return
-
1
;
}
if
(
fmt_ystart
<
fmt_mstart
)
{
/* y m */
if
(
fmt_dstart
<
fmt_ystart
)
{
/* d y m */
fmt_token_order
=
"dym"
;
}
else
if
(
fmt_dstart
>
fmt_mstart
)
{
/* y m d */
fmt_token_order
=
"ymd"
;
}
else
{
/* y d m */
fmt_token_order
=
"ydm"
;
}
}
else
{
/* fmt_ystart > fmt_mstart */
/* m y */
if
(
fmt_dstart
<
fmt_mstart
)
{
/* d m y */
fmt_token_order
=
"dmy"
;
}
else
if
(
fmt_dstart
>
fmt_ystart
)
{
/* m y d */
fmt_token_order
=
"myd"
;
}
else
{
/* m d y */
fmt_token_order
=
"mdy"
;
}
}
/* handle the special cases where there is no delimiter between the
* digits. If we see this:
*
* only digits, 6 or 8 bytes then it might be ddmmyy and ddmmyyyy
* (or similar)
*
* we reduce it to a string with delimiters and continue processing
* */
/* check if we have only digits */
reading_digit
=
1
;
for
(
i
=
0
;
str
[
i
];
i
++
)
{
if
(
!
isdigit
(
str
[
i
]))
{
reading_digit
=
0
;
break
;
}
}
if
(
reading_digit
)
{
int
frag_length
[
3
];
int
target_pos
;
i
=
strlen
(
str
);
if
(
i
!=
8
&&
i
!=
6
)
{
errno
=
PGTYPES_DATE_ERR_ENOSHORTDATE
;
return
-
1
;
}
/* okay, this really is the special case */
/* as long as the string, one additional byte for the
* terminator and 2 for the delimiters between the 3 fiedls
* */
str_copy
=
pgtypes_alloc
(
strlen
(
str
)
+
1
+
2
);
if
(
!
str_copy
)
{
return
-
1
;
}
/* determine length of the fragments */
if
(
i
==
6
)
{
frag_length
[
0
]
=
2
;
frag_length
[
1
]
=
2
;
frag_length
[
2
]
=
2
;
}
else
{
if
(
fmt_token_order
[
0
]
==
'y'
)
{
frag_length
[
0
]
=
4
;
frag_length
[
1
]
=
2
;
frag_length
[
2
]
=
2
;
}
else
if
(
fmt_token_order
[
1
]
==
'y'
)
{
frag_length
[
0
]
=
2
;
frag_length
[
1
]
=
4
;
frag_length
[
2
]
=
2
;
}
else
{
frag_length
[
0
]
=
2
;
frag_length
[
1
]
=
2
;
frag_length
[
2
]
=
4
;
}
}
target_pos
=
0
;
/* XXX: Here we could calculate the positions of the tokens
* and save the for loop down there where we again check
* with isdigit() for digits. */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
int
start_pos
=
0
;
if
(
i
>=
1
)
{
start_pos
+=
frag_length
[
0
];
}
if
(
i
==
2
)
{
start_pos
+=
frag_length
[
1
];
}
strncpy
(
str_copy
+
target_pos
,
str
+
start_pos
,
frag_length
[
i
]);
target_pos
+=
frag_length
[
i
];
if
(
i
!=
2
)
{
str_copy
[
target_pos
]
=
' '
;
target_pos
++
;
}
}
str_copy
[
target_pos
]
=
'\0'
;
}
else
{
str_copy
=
pgtypes_strdup
(
str
);
if
(
!
str_copy
)
{
return
-
1
;
}
/* convert the whole string to lower case */
for
(
i
=
0
;
str_copy
[
i
];
i
++
)
{
str_copy
[
i
]
=
(
char
)
tolower
(
str_copy
[
i
]);
}
}
/* look for numerical tokens */
reading_digit
=
0
;
token_count
=
0
;
for
(
i
=
0
;
i
<
strlen
(
str_copy
);
i
++
)
{
if
(
!
isdigit
(
str_copy
[
i
])
&&
reading_digit
)
{
/* the token is finished */
token
[
token_count
][
1
]
=
i
-
1
;
reading_digit
=
0
;
token_count
++
;
}
else
if
(
isdigit
(
str_copy
[
i
])
&&
!
reading_digit
)
{
/* we have found a token */
token
[
token_count
][
0
]
=
i
;
reading_digit
=
1
;
}
}
/* we're at the end of the input string, but maybe we are still reading a
* number... */
if
(
reading_digit
)
{
token
[
token_count
][
1
]
=
i
-
1
;
token_count
++
;
}
if
(
token_count
<
2
)
{
/* not all tokens found, no way to find 2 missing tokens
* with string matches */
free
(
str_copy
);
errno
=
PGTYPES_DATE_ERR_ENOTDMY
;
return
-
1
;
}
if
(
token_count
!=
3
)
{
/* not all tokens found but we may find another one with
* string matches by testing for the months names and months
* abbreviations */
char
*
month_lower_tmp
=
pgtypes_alloc
(
PGTYPES_DATE_MONTH_MAXLENGTH
);
char
*
start_pos
;
int
j
;
int
offset
;
int
found
=
0
;
char
**
list
;
if
(
!
month_lower_tmp
)
{
/* free variables we alloc'ed before */
free
(
str_copy
);
return
-
1
;
}
list
=
pgtypes_date_months
;
for
(
i
=
0
;
list
[
i
];
i
++
)
{
for
(
j
=
0
;
j
<
PGTYPES_DATE_MONTH_MAXLENGTH
;
j
++
)
{
month_lower_tmp
[
j
]
=
(
char
)
tolower
(
list
[
i
][
j
]);
if
(
!
month_lower_tmp
[
j
])
{
/* properly terminated */
break
;
}
}
if
((
start_pos
=
strstr
(
str_copy
,
month_lower_tmp
)))
{
offset
=
start_pos
-
str_copy
;
/* sort the new token into the numeric
* tokens, shift them if necessary */
if
(
offset
<
token
[
0
][
0
])
{
token
[
2
][
0
]
=
token
[
1
][
0
];
token
[
2
][
1
]
=
token
[
1
][
1
];
token
[
1
][
0
]
=
token
[
0
][
0
];
token
[
1
][
1
]
=
token
[
0
][
1
];
token_count
=
0
;
}
else
if
(
offset
<
token
[
1
][
0
])
{
token
[
2
][
0
]
=
token
[
1
][
0
];
token
[
2
][
1
]
=
token
[
1
][
1
];
token_count
=
1
;
}
else
{
token_count
=
2
;
}
token
[
token_count
][
0
]
=
offset
;
token
[
token_count
][
1
]
=
offset
+
strlen
(
month_lower_tmp
)
-
1
;
/* the value is the index of the month in
* the array of months + 1 (January is month
* 0) */
token_values
[
token_count
]
=
i
+
1
;
found
=
1
;
break
;
}
/* evil[tm] hack:
* if we read the pgtypes_date_months and haven't
* found a match, reset list to point to
* pgtypes_date_months_short and reset the counter
* variable i */
if
(
list
==
pgtypes_date_months
)
{
if
(
list
[
i
+
1
]
==
NULL
)
{
list
=
pgtypes_date_months_short
;
i
=
-
1
;
}
}
}
if
(
!
found
)
{
free
(
month_lower_tmp
);
free
(
str_copy
);
errno
=
PGTYPES_DATE_ERR_ENOTDMY
;
return
-
1
;
}
/* here we found a month. token[token_count] and
* token_values[token_count] reflect the month's details.
*
* only the month can be specified with a literal. Here we can do a
* quick check if the month is at the right position according to
* the format string because we can check if the token that
* we expect to be the month is at the position of the only
* token that already has a value. If we wouldn't check here
* we could say "December 4 1990" with a fmt string of
* "dd mm yy" for 12 April 1990.
*/
if
(
fmt_token_order
[
token_count
]
!=
'm'
)
{
/* deal with the error later on */
token_values
[
token_count
]
=
-
1
;
}
free
(
month_lower_tmp
);
}
/* terminate the tokens with ASCII-0 and get their values */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
*
(
str_copy
+
token
[
i
][
1
]
+
1
)
=
'\0'
;
/* A month already has a value set, check for token_value == -1 */
if
(
token_values
[
i
]
==
-
1
)
{
errno
=
0
;
token_values
[
i
]
=
strtol
(
str_copy
+
token
[
i
][
0
],
(
char
**
)
NULL
,
10
);
/* strtol sets errno in case of an error */
if
(
errno
)
{
token_values
[
i
]
=
-
1
;
}
}
if
(
fmt_token_order
[
i
]
==
'd'
)
{
tm
.
tm_mday
=
token_values
[
i
];
}
else
if
(
fmt_token_order
[
i
]
==
'm'
)
{
tm
.
tm_mon
=
token_values
[
i
];
}
else
if
(
fmt_token_order
[
i
]
==
'y'
)
{
tm
.
tm_year
=
token_values
[
i
];
}
}
free
(
str_copy
);
if
(
tm
.
tm_mday
<
1
||
tm
.
tm_mday
>
31
)
{
errno
=
PGTYPES_DATE_BAD_DAY
;
return
-
1
;
}
if
(
tm
.
tm_mon
<
1
||
tm
.
tm_mon
>
12
)
{
errno
=
PGTYPES_DATE_BAD_MONTH
;
return
-
1
;
}
if
(
tm
.
tm_mday
==
31
&&
(
tm
.
tm_mon
==
4
||
tm
.
tm_mon
==
6
||
tm
.
tm_mon
==
9
||
tm
.
tm_mon
==
11
))
{
errno
=
PGTYPES_DATE_BAD_DAY
;
return
-
1
;
}
if
(
tm
.
tm_mon
==
2
&&
tm
.
tm_mday
>
29
)
{
errno
=
PGTYPES_DATE_BAD_DAY
;
return
-
1
;
}
*
d
=
date2j
(
tm
.
tm_year
,
tm
.
tm_mon
,
tm
.
tm_mday
)
-
date2j
(
2000
,
1
,
1
);
return
0
;
}
src/interfaces/ecpg/pgtypeslib/dt.h
View file @
999f1298
...
...
@@ -296,6 +296,7 @@ extern void GetEpochTime(struct tm *);
extern
int
ParseDateTime
(
char
*
,
char
*
,
char
**
,
int
*
,
int
,
int
*
,
char
**
);
extern
int
DecodeDateTime
(
char
**
,
int
*
,
int
,
int
*
,
struct
tm
*
,
fsec_t
*
,
int
*
,
bool
);
extern
void
j2date
(
int
,
int
*
,
int
*
,
int
*
);
extern
void
GetCurrentDateTime
(
struct
tm
*
);
extern
int
date2j
(
int
,
int
,
int
);
extern
double
rint
(
double
x
);
...
...
src/interfaces/ecpg/pgtypeslib/dt_common.c
View file @
999f1298
...
...
@@ -426,10 +426,81 @@ static datetkn datetktbl[] = {
{
ZULU
,
TZ
,
POS
(
0
)},
/* UTC */
};
static
datetkn
deltatktbl
[]
=
{
/* text, token, lexval */
{
"@"
,
IGNORE_DTF
,
0
},
/* postgres relative prefix */
{
DAGO
,
AGO
,
0
},
/* "ago" indicates negative time offset */
{
"c"
,
UNITS
,
DTK_CENTURY
},
/* "century" relative */
{
"cent"
,
UNITS
,
DTK_CENTURY
},
/* "century" relative */
{
"centuries"
,
UNITS
,
DTK_CENTURY
},
/* "centuries" relative */
{
DCENTURY
,
UNITS
,
DTK_CENTURY
},
/* "century" relative */
{
"d"
,
UNITS
,
DTK_DAY
},
/* "day" relative */
{
DDAY
,
UNITS
,
DTK_DAY
},
/* "day" relative */
{
"days"
,
UNITS
,
DTK_DAY
},
/* "days" relative */
{
"dec"
,
UNITS
,
DTK_DECADE
},
/* "decade" relative */
{
DDECADE
,
UNITS
,
DTK_DECADE
},
/* "decade" relative */
{
"decades"
,
UNITS
,
DTK_DECADE
},
/* "decades" relative */
{
"decs"
,
UNITS
,
DTK_DECADE
},
/* "decades" relative */
{
"h"
,
UNITS
,
DTK_HOUR
},
/* "hour" relative */
{
DHOUR
,
UNITS
,
DTK_HOUR
},
/* "hour" relative */
{
"hours"
,
UNITS
,
DTK_HOUR
},
/* "hours" relative */
{
"hr"
,
UNITS
,
DTK_HOUR
},
/* "hour" relative */
{
"hrs"
,
UNITS
,
DTK_HOUR
},
/* "hours" relative */
{
INVALID
,
RESERV
,
DTK_INVALID
},
/* reserved for invalid time */
{
"m"
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative */
{
"microsecon"
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative */
{
"mil"
,
UNITS
,
DTK_MILLENNIUM
},
/* "millennium" relative */
{
"millennia"
,
UNITS
,
DTK_MILLENNIUM
},
/* "millennia" relative */
{
DMILLENNIUM
,
UNITS
,
DTK_MILLENNIUM
},
/* "millennium" relative */
{
"millisecon"
,
UNITS
,
DTK_MILLISEC
},
/* relative */
{
"mils"
,
UNITS
,
DTK_MILLENNIUM
},
/* "millennia" relative */
{
"min"
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative */
{
"mins"
,
UNITS
,
DTK_MINUTE
},
/* "minutes" relative */
{
DMINUTE
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative */
{
"minutes"
,
UNITS
,
DTK_MINUTE
},
/* "minutes" relative */
{
"mon"
,
UNITS
,
DTK_MONTH
},
/* "months" relative */
{
"mons"
,
UNITS
,
DTK_MONTH
},
/* "months" relative */
{
DMONTH
,
UNITS
,
DTK_MONTH
},
/* "month" relative */
{
"months"
,
UNITS
,
DTK_MONTH
},
{
"ms"
,
UNITS
,
DTK_MILLISEC
},
{
"msec"
,
UNITS
,
DTK_MILLISEC
},
{
DMILLISEC
,
UNITS
,
DTK_MILLISEC
},
{
"mseconds"
,
UNITS
,
DTK_MILLISEC
},
{
"msecs"
,
UNITS
,
DTK_MILLISEC
},
{
"qtr"
,
UNITS
,
DTK_QUARTER
},
/* "quarter" relative */
{
DQUARTER
,
UNITS
,
DTK_QUARTER
},
/* "quarter" relative */
{
"reltime"
,
IGNORE_DTF
,
0
},
/* pre-v6.1 "Undefined Reltime" */
{
"s"
,
UNITS
,
DTK_SECOND
},
{
"sec"
,
UNITS
,
DTK_SECOND
},
{
DSECOND
,
UNITS
,
DTK_SECOND
},
{
"seconds"
,
UNITS
,
DTK_SECOND
},
{
"secs"
,
UNITS
,
DTK_SECOND
},
{
DTIMEZONE
,
UNITS
,
DTK_TZ
},
/* "timezone" time offset */
{
"timezone_h"
,
UNITS
,
DTK_TZ_HOUR
},
/* timezone hour units */
{
"timezone_m"
,
UNITS
,
DTK_TZ_MINUTE
},
/* timezone minutes units */
{
"undefined"
,
RESERV
,
DTK_INVALID
},
/* pre-v6.1 invalid time */
{
"us"
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative */
{
"usec"
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative */
{
DMICROSEC
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative */
{
"useconds"
,
UNITS
,
DTK_MICROSEC
},
/* "microseconds" relative */
{
"usecs"
,
UNITS
,
DTK_MICROSEC
},
/* "microseconds" relative */
{
"w"
,
UNITS
,
DTK_WEEK
},
/* "week" relative */
{
DWEEK
,
UNITS
,
DTK_WEEK
},
/* "week" relative */
{
"weeks"
,
UNITS
,
DTK_WEEK
},
/* "weeks" relative */
{
"y"
,
UNITS
,
DTK_YEAR
},
/* "year" relative */
{
DYEAR
,
UNITS
,
DTK_YEAR
},
/* "year" relative */
{
"years"
,
UNITS
,
DTK_YEAR
},
/* "years" relative */
{
"yr"
,
UNITS
,
DTK_YEAR
},
/* "year" relative */
{
"yrs"
,
UNITS
,
DTK_YEAR
},
/* "years" relative */
};
static
unsigned
int
szdatetktbl
=
sizeof
datetktbl
/
sizeof
datetktbl
[
0
];
static
unsigned
int
szdeltatktbl
=
sizeof
deltatktbl
/
sizeof
deltatktbl
[
0
];
static
datetkn
*
datecache
[
MAXDATEFIELDS
]
=
{
NULL
};
static
datetkn
*
deltacache
[
MAXDATEFIELDS
]
=
{
NULL
};
char
*
months
[]
=
{
"Jan"
,
"Feb"
,
"Mar"
,
"Apr"
,
"May"
,
"Jun"
,
"Jul"
,
"Aug"
,
"Sep"
,
"Oct"
,
"Nov"
,
"Dec"
,
NULL
};
char
*
days
[]
=
{
"Sunday"
,
"Monday"
,
"Tuesday"
,
"Wednesday"
,
"Thursday"
,
"Friday"
,
"Saturday"
,
NULL
};
...
...
@@ -561,6 +632,39 @@ datebsearch(char *key, datetkn *base, unsigned int nel)
return
NULL
;
}
/* DecodeUnits()
* Decode text string using lookup table.
* This routine supports time interval decoding.
*/
int
DecodeUnits
(
int
field
,
char
*
lowtoken
,
int
*
val
)
{
int
type
;
datetkn
*
tp
;
if
((
deltacache
[
field
]
!=
NULL
)
&&
(
strncmp
(
lowtoken
,
deltacache
[
field
]
->
token
,
TOKMAXLEN
)
==
0
))
tp
=
deltacache
[
field
];
else
tp
=
datebsearch
(
lowtoken
,
deltatktbl
,
szdeltatktbl
);
deltacache
[
field
]
=
tp
;
if
(
tp
==
NULL
)
{
type
=
UNKNOWN_FIELD
;
*
val
=
0
;
}
else
{
type
=
tp
->
type
;
if
((
type
==
TZ
)
||
(
type
==
DTZ
))
*
val
=
FROMVAL
(
tp
);
else
*
val
=
tp
->
value
;
}
return
type
;
}
/* DecodeUnits() */
/*
* Calendar time to Julian date conversions.
* Julian date is commonly used in astronomical applications,
...
...
@@ -1088,7 +1192,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
#endif
}
static
void
void
GetCurrentDateTime
(
struct
tm
*
tm
)
{
int
tz
;
...
...
src/interfaces/ecpg/pgtypeslib/numeric.c
View file @
999f1298
...
...
@@ -9,7 +9,6 @@
#include "c.h"
#include "extern.h"
#include "pgtypes_error.h"
#include "decimal.h"
#define Max(x, y) ((x) > (y) ? (x) : (y))
#define Min(x, y) ((x) < (y) ? (x) : (y))
...
...
@@ -96,7 +95,7 @@ apply_typmod(Numeric *var, long typmod)
if (tweight >= maxweight && i < var->ndigits)
{
errno = PGTYPES_OVERFLOW;
errno = PGTYPES_
NUM_
OVERFLOW;
return -1;
}
}
...
...
@@ -188,7 +187,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
if
(
!
isdigit
((
unsigned
char
)
*
(
*
ptr
)))
{
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
...
...
@@ -206,7 +205,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
{
if
(
have_dp
)
{
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
have_dp
=
TRUE
;
...
...
@@ -227,14 +226,14 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
exponent
=
strtol
((
*
ptr
),
&
endptr
,
10
);
if
(
endptr
==
(
*
ptr
))
{
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
(
*
ptr
)
=
endptr
;
if
(
exponent
>
NUMERIC_MAX_PRECISION
||
exponent
<
-
NUMERIC_MAX_PRECISION
)
{
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
dest
->
weight
+=
(
int
)
exponent
;
...
...
@@ -248,7 +247,7 @@ set_var_from_str(char *str, char **ptr, Numeric *dest)
{
if
(
!
isspace
((
unsigned
char
)
*
(
*
ptr
)))
{
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
(
*
ptr
)
++
;
...
...
@@ -402,9 +401,12 @@ PGTYPESnumeric_aton(char *str, char **endptr)
* ----------
*/
char
*
PGTYPESnumeric_ntoa
(
Numeric
*
num
)
PGTYPESnumeric_ntoa
(
Numeric
*
num
,
int
dscale
)
{
return
(
get_str_from_var
(
num
,
num
->
dscale
));
if
(
dscale
<=
0
)
dscale
=
num
->
dscale
;
return
(
get_str_from_var
(
num
,
dscale
));
}
/* ----------
...
...
@@ -1117,7 +1119,7 @@ PGTYPESnumeric_div(Numeric *var1, Numeric *var2, Numeric *result)
ndigits_tmp
=
var2
->
ndigits
+
1
;
if
(
ndigits_tmp
==
1
)
{
errno
=
PGTYPES_DIVIDE_ZERO
;
errno
=
PGTYPES_
NUM_
DIVIDE_ZERO
;
return
-
1
;
}
...
...
@@ -1320,7 +1322,7 @@ PGTYPESnumeric_cmp(Numeric *var1, Numeric *var2) {
return
-
1
;
}
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
INT_MAX
;
}
...
...
@@ -1438,7 +1440,7 @@ numericvar_to_double_no_overflow(Numeric *var, double *dp)
{
/* shouldn't happen ... */
free
(
tmp
);
errno
=
PGTYPES_BAD_NUMERIC
;
errno
=
PGTYPES_
NUM_
BAD_NUMERIC
;
return
-
1
;
}
*
dp
=
val
;
...
...
@@ -1466,7 +1468,7 @@ PGTYPESnumeric_ntoi(Numeric* nv, int* ip) {
return
i
;
if
(
l
<
-
INT_MAX
||
l
>
INT_MAX
)
{
errno
=
PGTYPES_OVERFLOW
;
errno
=
PGTYPES_
NUM_
OVERFLOW
;
return
-
1
;
}
...
...
@@ -1488,7 +1490,7 @@ PGTYPESnumeric_ntol(Numeric* nv, long* lp) {
l
++
;
}
if
(
l
>
LONG_MAX
||
l
<
0
)
{
errno
=
PGTYPES_OVERFLOW
;
errno
=
PGTYPES_
NUM_
OVERFLOW
;
return
-
1
;
}
...
...
@@ -1499,196 +1501,3 @@ PGTYPESnumeric_ntol(Numeric* nv, long* lp) {
return
0
;
}
/* Finally we need some wrappers for the INFORMIX functions */
int
decadd
(
Numeric
*
arg1
,
Numeric
*
arg2
,
Numeric
*
sum
)
{
int
i
=
PGTYPESnumeric_add
(
arg1
,
arg2
,
sum
);
if
(
i
==
0
)
/* No error */
return
0
;
if
(
errno
==
PGTYPES_OVERFLOW
)
return
-
1200
;
return
-
1201
;
}
int
deccmp
(
Numeric
*
arg1
,
Numeric
*
arg2
)
{
int
i
=
PGTYPESnumeric_cmp
(
arg1
,
arg2
);
/* TODO: Need to return DECUNKNOWN instead of PGTYPES_BAD_NUMERIC */
return
(
i
);
}
void
deccopy
(
Numeric
*
src
,
Numeric
*
target
)
{
PGTYPESnumeric_copy
(
src
,
target
);
}
static
char
*
strndup
(
char
*
str
,
int
len
)
{
int
real_len
=
strlen
(
str
);
int
use_len
=
(
real_len
>
len
)
?
len
:
real_len
;
char
*
new
=
pgtypes_alloc
(
use_len
+
1
);
if
(
new
)
{
memcpy
(
str
,
new
,
use_len
);
new
[
use_len
]
=
'\0'
;
}
return
new
;
}
int
deccvasc
(
char
*
cp
,
int
len
,
Numeric
*
np
)
{
char
*
str
=
strndup
(
cp
,
len
);
/* Numeric_in always converts the complete string */
int
ret
=
0
;
if
(
!
str
)
ret
=
-
1201
;
else
{
np
=
PGTYPESnumeric_aton
(
str
,
NULL
);
if
(
!
np
)
{
switch
(
errno
)
{
case
PGTYPES_OVERFLOW
:
ret
=
-
1200
;
break
;
case
PGTYPES_BAD_NUMERIC
:
ret
=
-
1213
;
break
;
default:
ret
=
-
1216
;
break
;
}
}
}
return
ret
;
}
int
deccvdbl
(
double
dbl
,
Numeric
*
np
)
{
return
(
PGTYPESnumeric_dton
(
dbl
,
np
));
}
int
deccvint
(
int
in
,
Numeric
*
np
)
{
return
(
PGTYPESnumeric_iton
(
in
,
np
));
}
int
deccvlong
(
long
lng
,
Numeric
*
np
)
{
return
(
PGTYPESnumeric_lton
(
lng
,
np
));
}
int
decdiv
(
Numeric
*
n1
,
Numeric
*
n2
,
Numeric
*
n3
)
{
int
i
=
PGTYPESnumeric_div
(
n1
,
n2
,
n3
),
ret
=
0
;
if
(
i
!=
0
)
switch
(
errno
)
{
case
PGTYPES_DIVIDE_ZERO
:
ret
=
-
1202
;
break
;
case
PGTYPES_OVERFLOW
:
ret
=
-
1200
;
break
;
default:
ret
=
-
1201
;
break
;
}
return
ret
;
}
int
decmul
(
Numeric
*
n1
,
Numeric
*
n2
,
Numeric
*
n3
)
{
int
i
=
PGTYPESnumeric_mul
(
n1
,
n2
,
n3
),
ret
=
0
;
if
(
i
!=
0
)
switch
(
errno
)
{
case
PGTYPES_OVERFLOW
:
ret
=
-
1200
;
break
;
default:
ret
=
-
1201
;
break
;
}
return
ret
;
}
int
decsub
(
Numeric
*
n1
,
Numeric
*
n2
,
Numeric
*
n3
)
{
int
i
=
PGTYPESnumeric_sub
(
n1
,
n2
,
n3
),
ret
=
0
;
if
(
i
!=
0
)
switch
(
errno
)
{
case
PGTYPES_OVERFLOW
:
ret
=
-
1200
;
break
;
default:
ret
=
-
1201
;
break
;
}
return
ret
;
}
int
dectoasc
(
Numeric
*
np
,
char
*
cp
,
int
len
,
int
right
)
{
char
*
str
;
if
(
right
>=
0
)
str
=
get_str_from_var
(
np
,
right
);
else
str
=
get_str_from_var
(
np
,
np
->
dscale
);
if
(
!
str
)
return
-
1
;
/* TODO: have to take care of len here and create exponatial notion if necessary */
strncpy
(
cp
,
str
,
len
);
free
(
str
);
return
0
;
}
int
dectodbl
(
Numeric
*
np
,
double
*
dblp
)
{
return
(
PGTYPESnumeric_ntod
(
np
,
dblp
));
}
int
dectoint
(
Numeric
*
np
,
int
*
ip
)
{
int
ret
=
PGTYPESnumeric_ntoi
(
np
,
ip
);
if
(
ret
==
PGTYPES_OVERFLOW
)
ret
=
-
1200
;
return
ret
;
}
int
dectolong
(
Numeric
*
np
,
long
*
lngp
)
{
int
ret
=
PGTYPESnumeric_ntol
(
np
,
lngp
);
if
(
ret
==
PGTYPES_OVERFLOW
)
ret
=
-
1200
;
return
ret
;
}
src/interfaces/ecpg/pgtypeslib/timestamp.c
View file @
999f1298
...
...
@@ -13,7 +13,6 @@
#include "extern.h"
#include "pgtypes_error.h"
#include "pgtypes_timestamp.h"
#include "pgtypes_interval.h"
#include "datetime.h"
#ifdef HAVE_INT64_TIMESTAMP
...
...
@@ -288,14 +287,14 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
errno
=
0
;
if
(
strlen
(
str
)
>=
sizeof
(
lowstr
))
{
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
(
noresult
);
}
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
,
ptr
)
!=
0
)
||
(
DecodeDateTime
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
,
&
tz
,
0
)
!=
0
))
{
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
(
noresult
);
}
...
...
@@ -304,7 +303,7 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
case
DTK_DATE
:
if
(
tm2timestamp
(
tm
,
fsec
,
NULL
,
&
result
)
!=
0
)
{
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
(
noresult
);;
}
break
;
...
...
@@ -322,11 +321,11 @@ PGTYPEStimestamp_atot(char *str, char **endptr)
break
;
case
DTK_INVALID
:
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
(
noresult
);
default:
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
(
noresult
);
}
...
...
@@ -350,67 +349,8 @@ PGTYPEStimestamp_ttoa(Timestamp tstamp)
EncodeDateTime
(
tm
,
fsec
,
NULL
,
&
tzn
,
DateStyle
,
buf
,
0
);
else
{
errno
=
PGTYPES_BAD_TIMESTAMP
;
errno
=
PGTYPES_
TS_
BAD_TIMESTAMP
;
return
NULL
;
}
return
pgtypes_strdup
(
buf
);
}
void
dtcurrent
(
Timestamp
*
ts
)
{
return
;
}
int
dtcvasc
(
char
*
str
,
Timestamp
*
ts
)
{
return
0
;
}
int
dtsub
(
Timestamp
*
ts1
,
Timestamp
*
ts2
,
Interval
*
iv
)
{
return
0
;
}
int
dttoasc
(
Timestamp
*
ts
,
char
*
output
)
{
return
0
;
}
int
dttofmtasc
(
Timestamp
*
ts
,
char
*
output
,
int
str_len
,
char
*
fmtstr
)
{
return
0
;
}
int
intoasc
(
Interval
*
i
,
char
*
str
)
{
return
0
;
}
Interval
*
PGTYPESinterval_atoi
(
char
*
str
,
char
**
endptr
)
{
Interval
*
result
=
NULL
;
return
result
;
}
char
*
PGTYPESinterval_itoa
(
Interval
*
intvl
)
{
char
buf
[
MAXDATELEN
+
1
];
return
pgtypes_strdup
(
buf
);
}
int
PGTYPESinterval_copy
(
Interval
*
intvlsrc
,
Interval
*
intrcldest
)
{
return
0
;
}
src/interfaces/ecpg/test/dt_test.pgc
View file @
999f1298
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pgtypes_date.h>
#include <pgtypes_timestamp.h>
#include <pgtypes_interval.h>
int
main()
...
...
@@ -8,38 +11,142 @@ main()
exec sql begin declare section;
date date1;
timestamp ts1;
interval iv1;
char *text;
exec sql end declare section;
#if 0
Date date2;
short int mdy[3] = { 4, 19, 1998 };
#endif
int mdy[3] = { 4, 19, 1998 };
char *fmt, *out, *in;
FILE *dbgs;
if ((dbgs = fopen("log", "w")) != NULL)
ECPGdebug(1, dbgs);
exec sql whenever sqlerror do sqlprint();
exec sql connect to mm;
exec sql create table date_test (d date, ts timestamp);
exec sql create table date_test (d date, ts timestamp
, iv interval
);
exec sql insert into date_test(d, ts
) values ('Mon Jan 17 1966', '2000-7-12 17:34:29
');
exec sql insert into date_test(d, ts
, iv) values ('Mon Jan 17 1966', '2000-7-12 17:34:29', now()-'Mon Jan 17 1966
');
exec sql select * into :date1, :ts1 from date_test;
exec sql select * into :date1, :ts1
, :iv1
from date_test;
text = PGTYPESdate_dtoa(date1);
printf ("Date: %s\n", text);
ts1 = PGTYPEStimestamp_atot("2000-7-12 17:34:29", NULL);
text = PGTYPEStimestamp_ttoa(ts1);
printf ("timestamp: %s\n", text);
#if 0
text = PGTYPESinterval_itoa(&iv1);
printf ("interval: %s\n", text);
PGTYPESdate_mdyjul(mdy, &date2);
printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
/* reset */
mdy[0] = mdy[1] = mdy[2] = 0;
printf("date seems to get encoded to julian %ld\n", date2);
PGTYPESdate_julmdy(date2, mdy);
printf("m: %d, d: %d, y: %d\n", mdy[0], mdy[1], mdy[2]);
#endif
ts1 = PGTYPEStimestamp_atot("2003-12-04 17:34:29", NULL);
text = PGTYPEStimestamp_ttoa(ts1);
printf("date_day of %s is %d\n", text, PGTYPESdate_dayofweek(ts1));
PGTYPESdate_today(&date1);
text = PGTYPESdate_dtoa(date1);
printf("today is %s\n", text);
fmt = "(ddd), mmm. dd, yyyy, repeat: (ddd), mmm. dd, yyyy. end";
out = (char*) malloc(strlen(fmt) + 1);
PGTYPESdate_fmtdate(date1, fmt, out);
printf("Today in format \"%s\" is \"%s\"\n", fmt, out);
free(out);
/* rdefmtdate() */
date1 = 0; text = "";
fmt = "yy/mm/dd";
in = "In the year 1995, the month of December, it is the 25th day";
/* 0123456789012345678901234567890123456789012345678901234567890
* 0 1 2 3 4 5 6
*/
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate1: %s\n", text);
date1 = 0; text = "";
fmt = "mmmm. dd. yyyy";
in = "12/25/95";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate2: %s\n", text);
date1 = 0; text = "";
fmt = "yy/mm/dd";
in = "95/12/25";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate3: %s\n", text);
date1 = 0; text = "";
fmt = "yy/mm/dd";
in = "1995, December 25th";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate4: %s\n", text);
date1 = 0; text = "";
fmt = "dd-mm-yy";
in = "This is 25th day of December, 1995";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate5: %s\n", text);
date1 = 0; text = "";
fmt = "mmddyy";
in = "Dec. 25th, 1995";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate6: %s\n", text);
date1 = 0; text = "";
fmt = "mmm. dd. yyyy";
in = "dec 25th 1995";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate7: %s\n", text);
date1 = 0; text = "";
fmt = "mmm. dd. yyyy";
in = "DEC-25-1995";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate8: %s\n", text);
date1 = 0; text = "";
fmt = "mm yy dd.";
in = "12199525";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate9: %s\n", text);
date1 = 0; text = "";
fmt = "yyyy fierj mm dd.";
in = "19951225";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate10: %s\n", text);
date1 = 0; text = "";
fmt = "mm/dd/yy";
in = "122595";
PGTYPESdate_defmtdate(&date1, fmt, in);
text = PGTYPESdate_dtoa(date1);
printf("defmtdate12: %s\n", text);
exec sql rollback;
exec sql disconnect;
...
...
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