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
53d8be3b
Commit
53d8be3b
authored
Mar 14, 1997
by
Marc G. Fournier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Date/Time updates from Thomas...
parent
71fd8d4a
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
3375 additions
and
943 deletions
+3375
-943
src/backend/access/rtree/rtproc.c
src/backend/access/rtree/rtproc.c
+2
-2
src/backend/access/rtree/rtree.c
src/backend/access/rtree/rtree.c
+2
-2
src/backend/access/transam/xact.c
src/backend/access/transam/xact.c
+10
-3
src/backend/bootstrap/bootstrap.c
src/backend/bootstrap/bootstrap.c
+2
-2
src/backend/utils/adt/Makefile
src/backend/utils/adt/Makefile
+4
-3
src/backend/utils/adt/bool.c
src/backend/utils/adt/bool.c
+5
-5
src/backend/utils/adt/char.c
src/backend/utils/adt/char.c
+58
-58
src/backend/utils/adt/date.c
src/backend/utils/adt/date.c
+61
-82
src/backend/utils/adt/datetime.c
src/backend/utils/adt/datetime.c
+743
-0
src/backend/utils/adt/dt.c
src/backend/utils/adt/dt.c
+2161
-24
src/backend/utils/adt/geo_ops.c
src/backend/utils/adt/geo_ops.c
+2
-2
src/backend/utils/adt/geo_selfuncs.c
src/backend/utils/adt/geo_selfuncs.c
+2
-2
src/backend/utils/adt/int.c
src/backend/utils/adt/int.c
+26
-26
src/backend/utils/adt/nabstime.c
src/backend/utils/adt/nabstime.c
+221
-656
src/backend/utils/adt/name.c
src/backend/utils/adt/name.c
+18
-18
src/backend/utils/adt/oid.c
src/backend/utils/adt/oid.c
+5
-5
src/backend/utils/adt/varchar.c
src/backend/utils/adt/varchar.c
+33
-33
src/backend/utils/adt/varlena.c
src/backend/utils/adt/varlena.c
+20
-20
No files found.
src/backend/access/rtree/rtproc.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.
5 1996/11/10 02:58:53 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.
6 1997/03/14 23:17:41 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
#include <postgres.h>
#include <postgres.h>
#include <utils/builtins.h>
#include <utils/builtins.h>
#include <utils/geo
-
decls.h>
#include <utils/geo
_
decls.h>
#ifndef HAVE_MEMMOVE
#ifndef HAVE_MEMMOVE
# include <regex/utils.h>
# include <regex/utils.h>
#else
#else
...
...
src/backend/access/rtree/rtree.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.1
1 1997/01/10 09:47:28 vadim
Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.1
2 1997/03/14 23:17:46 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
#include <storage/lmgr.h>
#include <storage/lmgr.h>
#include <access/rtree.h>
#include <access/rtree.h>
#include <storage/bufmgr.h>
#include <storage/bufmgr.h>
#include <utils/geo
-
decls.h>
#include <utils/geo
_
decls.h>
#include <executor/executor.h>
#include <executor/executor.h>
#include <access/heapam.h>
#include <access/heapam.h>
#include <fmgr.h>
#include <fmgr.h>
...
...
src/backend/access/transam/xact.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.
7 1997/03/12 20:41:14
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.
8 1997/03/14 23:18:16
scrappy Exp $
*
*
* NOTES
* NOTES
* Transaction aborts can now occur two ways:
* Transaction aborts can now occur two ways:
...
@@ -171,7 +171,14 @@ TransactionState CurrentTransactionState =
...
@@ -171,7 +171,14 @@ TransactionState CurrentTransactionState =
&
CurrentTransactionStateData
;
&
CurrentTransactionStateData
;
/* ----------------
/* ----------------
* info returned when the system is desabled
* info returned when the system is disabled
*
* Apparently a lot of this code is inherited from other prototype systems.
* For DisabledStartTime, use a symbolic value to make the relationships clearer.
* The old value of 1073741823 corresponds to a date in y2004, which is coming closer
* every day. It appears that if we return a value guaranteed larger than
* any real time associated with a transaction then comparisons in other
* modules will still be correct. Let's use BIG_ABSTIME for this. tgl 2/14/97
*
*
* Note: I have no idea what the significance of the
* Note: I have no idea what the significance of the
* 1073741823 in DisabledStartTime.. I just carried
* 1073741823 in DisabledStartTime.. I just carried
...
@@ -183,7 +190,7 @@ TransactionId DisabledTransactionId = (TransactionId)-1;
...
@@ -183,7 +190,7 @@ TransactionId DisabledTransactionId = (TransactionId)-1;
CommandId
DisabledCommandId
=
(
CommandId
)
-
1
;
CommandId
DisabledCommandId
=
(
CommandId
)
-
1
;
AbsoluteTime
DisabledStartTime
=
(
AbsoluteTime
)
1073741823
;
AbsoluteTime
DisabledStartTime
=
(
AbsoluteTime
)
BIG_ABSTIME
;
/* 1073741823; */
/* ----------------
/* ----------------
* overflow flag
* overflow flag
...
...
src/backend/bootstrap/bootstrap.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Copyright (c) 1994, Regents of the University of California
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.1
6 1997/03/12 20:57:33
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.1
7 1997/03/14 23:18:32
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -89,7 +89,7 @@
...
@@ -89,7 +89,7 @@
#include "catalog/catname.h"
#include "catalog/catname.h"
#include "utils/geo
-
decls.h"
#include "utils/geo
_
decls.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
#include "catalog/index.h"
#include "catalog/index.h"
...
...
src/backend/utils/adt/Makefile
View file @
53d8be3b
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
# Makefile for utils/adt
# Makefile for utils/adt
#
#
# IDENTIFICATION
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.
6 1997/03/12 21:27:03
scrappy Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.
7 1997/03/14 23:19:50
scrappy Exp $
#
#
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
...
@@ -20,8 +20,9 @@ CFLAGS+=$(INCLUDE_OPT)
...
@@ -20,8 +20,9 @@ CFLAGS+=$(INCLUDE_OPT)
OBJS
=
acl.o arrayfuncs.o arrayutils.o bool.o char.o chunk.o date.o
\
OBJS
=
acl.o arrayfuncs.o arrayutils.o bool.o char.o chunk.o date.o
\
datum.o dt.o filename.o float.o geo_ops.o geo_selfuncs.o int.o
\
datum.o dt.o filename.o float.o geo_ops.o geo_selfuncs.o int.o
\
misc.o nabstime.o name.o not_in.o numutils.o oid.o
\
misc.o nabstime.o name.o not_in.o numutils.o oid.o
\
oidname.o oidint2.o oidint4.o oracle_compat.o regexp.o regproc.o selfuncs.o
\
oidname.o oidint2.o oidint4.o oracle_compat.o regexp.o regproc.o
\
tid.o varchar.o varlena.o sets.o datetimes.o like.o timestamp.o
selfuncs.o
\
tid.o varchar.o varlena.o sets.o datetime.o like.o timestamp.o
all
:
SUBSYS.o
all
:
SUBSYS.o
...
...
src/backend/utils/adt/bool.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.
2 1996/11/03 06:53:03
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/bool.c,v 1.
3 1997/03/14 23:19:52
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -24,12 +24,12 @@
...
@@ -24,12 +24,12 @@
/*
/*
* boolin - converts "t" or "f" to 1 or 0
* boolin - converts "t" or "f" to 1 or 0
*/
*/
int32
bool
boolin
(
char
*
b
)
boolin
(
char
*
b
)
{
{
if
(
b
==
NULL
)
if
(
b
==
NULL
)
elog
(
WARN
,
"Bad input string for type bool"
);
elog
(
WARN
,
"Bad input string for type bool"
);
return
((
int32
)
(
*
b
==
't'
)
||
(
*
b
==
'T'
));
return
((
bool
)
(
*
b
==
't'
)
||
(
*
b
==
'T'
));
}
}
/*
/*
...
@@ -49,13 +49,13 @@ boolout(long b)
...
@@ -49,13 +49,13 @@ boolout(long b)
* PUBLIC ROUTINES *
* PUBLIC ROUTINES *
*****************************************************************************/
*****************************************************************************/
int32
bool
booleq
(
int8
arg1
,
int8
arg2
)
booleq
(
int8
arg1
,
int8
arg2
)
{
{
return
(
arg1
==
arg2
);
return
(
arg1
==
arg2
);
}
}
int32
bool
boolne
(
int8
arg1
,
int8
arg2
)
boolne
(
int8
arg1
,
int8
arg2
)
{
{
return
(
arg1
!=
arg2
);
return
(
arg1
!=
arg2
);
...
...
src/backend/utils/adt/char.c
View file @
53d8be3b
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.
2 1996/09/10 06:41:3
4 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.
3 1997/03/14 23:19:5
4 scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -127,25 +127,25 @@ char *char16out(char *s)
...
@@ -127,25 +127,25 @@ char *char16out(char *s)
* PUBLIC ROUTINES *
* PUBLIC ROUTINES *
*****************************************************************************/
*****************************************************************************/
int32
chareq
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
chareq
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
==
arg2
);
}
int32
charne
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
!=
arg2
);
}
bool
charne
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
!=
arg2
);
}
#ifdef UNSIGNED_CHAR_TEXT
#ifdef UNSIGNED_CHAR_TEXT
int32
charlt
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
<
(
uint8
)
arg2
);
}
bool
charlt
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
<
(
uint8
)
arg2
);
}
int32
charle
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
<=
(
uint8
)
arg2
);
}
bool
charle
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
<=
(
uint8
)
arg2
);
}
int32
chargt
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
>
(
uint8
)
arg2
);
}
bool
chargt
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
>
(
uint8
)
arg2
);
}
int32
charge
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
>=
(
uint8
)
arg2
);
}
bool
charge
(
int8
arg1
,
int8
arg2
)
{
return
((
uint8
)
arg1
>=
(
uint8
)
arg2
);
}
#else
#else
int32
charlt
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
<
arg2
);
}
bool
charlt
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
<
arg2
);
}
int32
charle
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
<=
arg2
);
}
bool
charle
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
<=
arg2
);
}
int32
chargt
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
>
arg2
);
}
bool
chargt
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
>
arg2
);
}
int32
charge
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
>=
arg2
);
}
bool
charge
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
>=
arg2
);
}
#endif
#endif
int8
charpl
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
+
arg2
);
}
int8
charpl
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
+
arg2
);
}
int8
charmi
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
-
arg2
);
}
int8
charmi
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
-
arg2
);
}
int8
charmul
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
*
arg2
);
}
int8
charmul
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
*
arg2
);
}
int8
chardiv
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
/
arg2
);
}
int8
chardiv
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
/
arg2
);
}
int32
cideq
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
cideq
(
int8
arg1
,
int8
arg2
)
{
return
(
arg1
==
arg2
);
}
/*
/*
* char16eq - returns 1 iff arguments are equal
* char16eq - returns 1 iff arguments are equal
...
@@ -161,48 +161,48 @@ int32 cideq(int8 arg1, int8 arg2) { return(arg1 == arg2); }
...
@@ -161,48 +161,48 @@ int32 cideq(int8 arg1, int8 arg2) { return(arg1 == arg2); }
* char16ge - returns 1 iff a <= b
* char16ge - returns 1 iff a <= b
*
*
*/
*/
int32
char16eq
(
char
*
arg1
,
char
*
arg2
)
bool
char16eq
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
16
)
==
0
);
return
(
strncmp
(
arg1
,
arg2
,
16
)
==
0
);
}
}
int32
char16ne
(
char
*
arg1
,
char
*
arg2
)
bool
char16ne
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
16
)
!=
0
);
return
(
strncmp
(
arg1
,
arg2
,
16
)
!=
0
);
}
}
int32
char16lt
(
char
*
arg1
,
char
*
arg2
)
bool
char16lt
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
,
arg2
,
16
)
<
0
));
return
((
bool
)
(
strncmp
(
arg1
,
arg2
,
16
)
<
0
));
}
}
int32
char16le
(
char
*
arg1
,
char
*
arg2
)
bool
char16le
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
,
arg2
,
16
)
<=
0
));
return
((
bool
)
(
strncmp
(
arg1
,
arg2
,
16
)
<=
0
));
}
}
int32
char16gt
(
char
*
arg1
,
char
*
arg2
)
bool
char16gt
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
,
arg2
,
16
)
>
0
));
return
((
bool
)
(
strncmp
(
arg1
,
arg2
,
16
)
>
0
));
}
}
int32
char16ge
(
char
*
arg1
,
char
*
arg2
)
bool
char16ge
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
,
arg2
,
16
)
>=
0
));
return
((
bool
)
(
strncmp
(
arg1
,
arg2
,
16
)
>=
0
));
}
}
...
@@ -229,32 +229,32 @@ char *char2out(uint16 s)
...
@@ -229,32 +229,32 @@ char *char2out(uint16 s)
return
(
result
);
return
(
result
);
}
}
int32
char2eq
(
uint16
a
,
uint16
b
)
bool
char2eq
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
==
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
==
0
);
}
}
int32
char2ne
(
uint16
a
,
uint16
b
)
bool
char2ne
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
!=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
!=
0
);
}
}
int32
char2lt
(
uint16
a
,
uint16
b
)
bool
char2lt
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
<
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
<
0
);
}
}
int32
char2le
(
uint16
a
,
uint16
b
)
bool
char2le
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
<=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
<=
0
);
}
}
int32
char2gt
(
uint16
a
,
uint16
b
)
bool
char2gt
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
>
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
>
0
);
}
}
int32
char2ge
(
uint16
a
,
uint16
b
)
bool
char2ge
(
uint16
a
,
uint16
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
>=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
2
)
>=
0
);
}
}
...
@@ -289,32 +289,32 @@ char *char4out(s)
...
@@ -289,32 +289,32 @@ char *char4out(s)
return
(
result
);
return
(
result
);
}
}
int32
char4eq
(
uint32
a
,
uint32
b
)
bool
char4eq
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
==
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
==
0
);
}
}
int32
char4ne
(
uint32
a
,
uint32
b
)
bool
char4ne
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
!=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
!=
0
);
}
}
int32
char4lt
(
uint32
a
,
uint32
b
)
bool
char4lt
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
<
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
<
0
);
}
}
int32
char4le
(
uint32
a
,
uint32
b
)
bool
char4le
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
<=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
<=
0
);
}
}
int32
char4gt
(
uint32
a
,
uint32
b
)
bool
char4gt
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
>
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
>
0
);
}
}
int32
char4ge
(
uint32
a
,
uint32
b
)
bool
char4ge
(
uint32
a
,
uint32
b
)
{
{
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
>=
0
);
return
(
strncmp
((
char
*
)
&
a
,
(
char
*
)
&
b
,
4
)
>=
0
);
}
}
...
@@ -351,46 +351,46 @@ char *char8out(char *s)
...
@@ -351,46 +351,46 @@ char *char8out(char *s)
return
(
result
);
return
(
result
);
}
}
int32
char8eq
(
char
*
arg1
,
char
*
arg2
)
bool
char8eq
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
==
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
==
0
);
}
}
int32
char8ne
(
char
*
arg1
,
char
*
arg2
)
bool
char8ne
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
!=
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
!=
0
);
}
}
int32
char8lt
(
char
*
arg1
,
char
*
arg2
)
bool
char8lt
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
<
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
<
0
);
}
}
int32
char8le
(
char
*
arg1
,
char
*
arg2
)
bool
char8le
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
<=
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
<=
0
);
}
}
int32
char8gt
(
char
*
arg1
,
char
*
arg2
)
bool
char8gt
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
>
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
>
0
);
}
}
int32
char8ge
(
char
*
arg1
,
char
*
arg2
)
bool
char8ge
(
char
*
arg1
,
char
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
,
arg2
,
8
)
>=
0
);
return
(
(
bool
)
strncmp
(
arg1
,
arg2
,
8
)
>=
0
);
}
}
int32
char8cmp
(
char
*
arg1
,
char
*
arg2
)
int32
char8cmp
(
char
*
arg1
,
char
*
arg2
)
...
...
src/backend/utils/adt/date.c
View file @
53d8be3b
/*-------------------------------------------------------------------------
/*-------------------------------------------------------------------------
*
*
* date.c--
* date.c--
*
Functions for the built-in type "AbsoluteTime"
.
*
Utilities for the built-in type "AbsoluteTime" (defined in nabstime)
.
* Functions for the built-in type "RelativeTime".
* Functions for the built-in type "RelativeTime".
* Functions for the built-in type "TimeInterval".
* Functions for the built-in type "TimeInterval".
*
*
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.
5 1997/02/14 04:17:35 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.
6 1997/03/14 23:19:57 scrappy
Exp $
*
*
* NOTES
* NOTES
* This code is actually (almost) unused.
* This code is actually (almost) unused.
...
@@ -35,25 +35,11 @@
...
@@ -35,25 +35,11 @@
#include "access/xact.h"
#include "access/xact.h"
#include "utils/builtins.h"
/* where function declarations go */
#include "utils/builtins.h"
/* where function declarations go */
#include "utils/palloc.h"
#include "utils/palloc.h"
#include "utils/dt.h"
#define TM_YEAR_BASE 1900
/* compatible to UNIX time */
#ifndef USE_NEW_TIME_CODE
#define EPOCH_YEAR 1970
/* compatible to UNIX time */
#define USE_NEW_TIME_CODE 1
#define YEAR_MAX 2038
/* otherwise overflow */
#endif
#define YEAR_MIN 1902
/* otherwise overflow */
#define DAYS_PER_LYEAR 366
#define DAYS_PER_NYEAR 365
#define HOURS_PER_DAY 24
#define MINS_PER_HOUR 60
#define SECS_PER_MIN 60
#define MAX_LONG 2147483647
/* 2^31 */
/* absolute time definitions */
#define TIME_NOW_STR "now"
/* represents time now */
#define TIME_EPOCH_STR "epoch"
/* Jan 1 00:00:00 1970 GMT */
#define TIME_EPOCH_STR_LEN (sizeof(TIME_EPOCH_STR)-1)
#define INVALID_ABSTIME_STR "Undefined AbsTime"
#define INVALID_ABSTIME_STR_LEN (sizeof(INVALID_ABSTIME_STR)-1)
#define INVALID_RELTIME_STR "Undefined RelTime"
#define INVALID_RELTIME_STR "Undefined RelTime"
#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
#define INVALID_RELTIME_STR_LEN (sizeof(INVALID_RELTIME_STR)-1)
...
@@ -66,10 +52,7 @@
...
@@ -66,10 +52,7 @@
* sixty-eight years on either side of that.
* sixty-eight years on either side of that.
*/
*/
#define IsCharDigit(C) isdigit(C)
#define IsCharA_Z(C) isalpha(C)
#define IsSpace(C) ((C) == ' ')
#define IsSpace(C) ((C) == ' ')
#define IsNull(C) ((C) == NULL)
#define T_INTERVAL_INVAL 0
/* data represents no valid interval */
#define T_INTERVAL_INVAL 0
/* data represents no valid interval */
#define T_INTERVAL_VALID 1
/* data represents a valid interval */
#define T_INTERVAL_VALID 1
/* data represents a valid interval */
...
@@ -101,20 +84,13 @@ static int sec_tab[] = {
...
@@ -101,20 +84,13 @@ static int sec_tab[] = {
3600
,
3600
,
86400
,
86400
,
604800
,
604800
,
3600
,
3600
,
86400
,
86400
,
604800
,
604800
,
2592000
,
2592000
,
31536000
,
31536000
};
2592000
,
2592000
,
31536000
,
31536000
};
/* maximal values (in seconds) per unit which can be represented */
static
int
unit_max_quantity
[]
=
{
2144448000
,
2144448000
,
35740800
,
35740800
,
595680
,
595680
,
24820
,
24820
,
3545
,
3545
,
827
,
827
,
68
,
68
};
struct
timeb
*
TimeDifferenceFromGMT
=
NULL
;
/*
/*
* Function prototypes -- internal to this file only
* Function prototypes -- internal to this file only
*/
*/
static
int
correct_unit
(
char
unit
[],
int
*
unptr
);
static
int
correct_unit
(
char
unit
[],
int
*
unptr
);
static
int
correct_dir
(
char
direction
[],
int
*
signptr
);
static
int
correct_dir
(
char
direction
[],
int
*
signptr
);
static
int
istinterval
(
char
*
i_string
,
static
int
istinterval
(
char
*
i_string
,
AbsoluteTime
*
i_start
,
AbsoluteTime
*
i_start
,
AbsoluteTime
*
i_end
);
AbsoluteTime
*
i_end
);
...
@@ -126,41 +102,45 @@ static int istinterval(char *i_string,
...
@@ -126,41 +102,45 @@ static int istinterval(char *i_string,
/*
/*
* reltimein - converts a reltime string in an internal format
* reltimein - converts a reltime string in an internal format
*/
*/
int32
/* RelativeTime */
RelativeTime
reltimein
(
char
*
timestring
)
reltimein
(
char
*
str
)
{
{
int
error
;
RelativeTime
result
;
int32
/* RelativeTime */
timeinsec
;
int
sign
,
unitnr
;
long
quantity
;
error
=
isreltime
(
timestring
,
&
sign
,
&
quantity
,
&
unitnr
);
struct
tm
tt
,
*
tm
=
&
tt
;
double
fsec
;
int
dtype
;
char
*
field
[
MAXDATEFIELDS
];
int
nf
,
ftype
[
MAXDATEFIELDS
];
char
lowstr
[
MAXDATELEN
+
1
];
#ifdef DATEDEBUG
if
(
!
PointerIsValid
(
str
))
elog
(
DEBUG
,
"reltimein: isreltime(%s) returns error=%d, %d, %d, %d"
,
elog
(
WARN
,
"Bad (null) date external representation"
,
NULL
);
timestring
,
error
,
sign
,
quantity
,
unitnr
);
#endif
/* !DATEDEBUG */
if
(
strlen
(
str
)
>
MAXDATELEN
)
elog
(
WARN
,
"Bad (length) reltime external representation '%s'"
,
str
);
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
||
(
DecodeDateDelta
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
)
!=
0
))
elog
(
WARN
,
"Bad reltime external representation '%s'"
,
str
);
if
(
error
!=
1
)
{
timeinsec
=
INVALID_RELTIME
;
/*invalid time representation */
}
else
{
/* this check is necessary, while no control on overflow */
if
(
quantity
>
unit_max_quantity
[
unitnr
]
||
quantity
<
0
)
{
#ifdef DATEDEBUG
elog
(
DEBUG
,
"reltimein: illegal quantity %d (< %d)"
,
quantity
,
unit_max_quantity
[
unitnr
]);
#endif
/* DATEDEBUG */
timeinsec
=
INVALID_RELTIME
;
/* illegal quantity */
}
else
{
timeinsec
=
sign
*
quantity
*
sec_tab
[
unitnr
];
#ifdef DATEDEBUG
#ifdef DATEDEBUG
elog
(
DEBUG
,
"reltimein: computed timeinsec %d"
,
printf
(
"reltimein- %d fields are type %d (DTK_DATE=%d)
\n
"
,
nf
,
dtype
,
DTK_DATE
);
timeinsec
);
#endif
#endif
/* DATEDEBUG */
}
switch
(
dtype
)
{
}
case
DTK_DELTA
:
return
(
timeinsec
);
result
=
((((
tm
->
tm_hour
*
60
)
+
tm
->
tm_min
)
*
60
)
+
tm
->
tm_sec
);
}
result
+=
(((
tm
->
tm_year
*
365
)
+
(
tm
->
tm_mon
*
30
)
+
tm
->
tm_mday
)
*
(
24
*
60
*
60
));
return
(
result
);
default:
return
(
INVALID_RELTIME
);
};
elog
(
WARN
,
"Bad reltime (internal coding error) '%s'"
,
str
);
return
(
INVALID_RELTIME
);
}
/* reltimein() */
/*
/*
...
@@ -379,42 +359,42 @@ AbsoluteTime timenow()
...
@@ -379,42 +359,42 @@ AbsoluteTime timenow()
* reltimele - returns 1, iff t1 less than or equal to t2
* reltimele - returns 1, iff t1 less than or equal to t2
* reltimege - returns 1, iff t1 greater than or equal to t2
* reltimege - returns 1, iff t1 greater than or equal to t2
*/
*/
int32
reltimeeq
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimeeq
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
return
(
t1
==
t2
);
return
(
t1
==
t2
);
}
}
int32
reltimene
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimene
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
return
(
t1
!=
t2
);
return
(
t1
!=
t2
);
}
}
int32
reltimelt
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimelt
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
return
(
t1
<
t2
);
return
(
t1
<
t2
);
}
}
int32
reltimegt
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimegt
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
return
(
t1
>
t2
);
return
(
t1
>
t2
);
}
}
int32
reltimele
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimele
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
return
(
t1
<=
t2
);
return
(
t1
<=
t2
);
}
}
int32
reltimege
(
RelativeTime
t1
,
RelativeTime
t2
)
bool
reltimege
(
RelativeTime
t1
,
RelativeTime
t2
)
{
{
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
if
(
t1
==
INVALID_RELTIME
||
t2
==
INVALID_RELTIME
)
return
0
;
return
0
;
...
@@ -425,7 +405,7 @@ int32 reltimege(RelativeTime t1, RelativeTime t2)
...
@@ -425,7 +405,7 @@ int32 reltimege(RelativeTime t1, RelativeTime t2)
/*
/*
* intervaleq - returns 1, iff interval i1 is equal to interval i2
* intervaleq - returns 1, iff interval i1 is equal to interval i2
*/
*/
int32
intervaleq
(
TimeInterval
i1
,
TimeInterval
i2
)
bool
intervaleq
(
TimeInterval
i1
,
TimeInterval
i2
)
{
{
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
return
(
0
);
/* invalid interval */
return
(
0
);
/* invalid interval */
...
@@ -437,7 +417,7 @@ int32 intervaleq(TimeInterval i1, TimeInterval i2)
...
@@ -437,7 +417,7 @@ int32 intervaleq(TimeInterval i1, TimeInterval i2)
* intervalleneq - returns 1, iff length of interval i is equal to
* intervalleneq - returns 1, iff length of interval i is equal to
* reltime t
* reltime t
*/
*/
int32
intervalleneq
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervalleneq
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -451,7 +431,7 @@ int32 intervalleneq(TimeInterval i, RelativeTime t)
...
@@ -451,7 +431,7 @@ int32 intervalleneq(TimeInterval i, RelativeTime t)
* intervallenne - returns 1, iff length of interval i is not equal
* intervallenne - returns 1, iff length of interval i is not equal
* to reltime t
* to reltime t
*/
*/
int32
intervallenne
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervallenne
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -465,7 +445,7 @@ int32 intervallenne(TimeInterval i, RelativeTime t)
...
@@ -465,7 +445,7 @@ int32 intervallenne(TimeInterval i, RelativeTime t)
* intervallenlt - returns 1, iff length of interval i is less than
* intervallenlt - returns 1, iff length of interval i is less than
* reltime t
* reltime t
*/
*/
int32
intervallenlt
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervallenlt
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -479,7 +459,7 @@ int32 intervallenlt(TimeInterval i, RelativeTime t)
...
@@ -479,7 +459,7 @@ int32 intervallenlt(TimeInterval i, RelativeTime t)
* intervallengt - returns 1, iff length of interval i is greater than
* intervallengt - returns 1, iff length of interval i is greater than
* reltime t
* reltime t
*/
*/
int32
intervallengt
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervallengt
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -493,7 +473,7 @@ int32 intervallengt(TimeInterval i, RelativeTime t)
...
@@ -493,7 +473,7 @@ int32 intervallengt(TimeInterval i, RelativeTime t)
* intervallenle - returns 1, iff length of interval i is less or equal
* intervallenle - returns 1, iff length of interval i is less or equal
* than reltime t
* than reltime t
*/
*/
int32
intervallenle
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervallenle
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -507,7 +487,7 @@ int32 intervallenle(TimeInterval i, RelativeTime t)
...
@@ -507,7 +487,7 @@ int32 intervallenle(TimeInterval i, RelativeTime t)
* intervallenge - returns 1, iff length of interval i is greater or
* intervallenge - returns 1, iff length of interval i is greater or
* equal than reltime t
* equal than reltime t
*/
*/
int32
intervallenge
(
TimeInterval
i
,
RelativeTime
t
)
bool
intervallenge
(
TimeInterval
i
,
RelativeTime
t
)
{
{
RelativeTime
rt
;
RelativeTime
rt
;
...
@@ -520,7 +500,7 @@ int32 intervallenge(TimeInterval i, RelativeTime t)
...
@@ -520,7 +500,7 @@ int32 intervallenge(TimeInterval i, RelativeTime t)
/*
/*
* intervalct - returns 1, iff interval i1 contains interval i2
* intervalct - returns 1, iff interval i1 contains interval i2
*/
*/
int32
intervalct
(
TimeInterval
i1
,
TimeInterval
i2
)
bool
intervalct
(
TimeInterval
i1
,
TimeInterval
i2
)
{
{
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
return
(
0
);
return
(
0
);
...
@@ -531,7 +511,7 @@ int32 intervalct(TimeInterval i1, TimeInterval i2)
...
@@ -531,7 +511,7 @@ int32 intervalct(TimeInterval i1, TimeInterval i2)
/*
/*
* intervalov - returns 1, iff interval i1 (partially) overlaps i2
* intervalov - returns 1, iff interval i1 (partially) overlaps i2
*/
*/
int32
intervalov
(
TimeInterval
i1
,
TimeInterval
i2
)
bool
intervalov
(
TimeInterval
i1
,
TimeInterval
i2
)
{
{
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
if
(
i1
->
status
==
T_INTERVAL_INVAL
||
i2
->
status
==
T_INTERVAL_INVAL
)
return
(
0
);
return
(
0
);
...
@@ -736,7 +716,6 @@ static int correct_dir(char direction[], int *signptr)
...
@@ -736,7 +716,6 @@ static int correct_dir(char direction[], int *signptr)
return
(
0
);
/* invalid direction descriptor */
return
(
0
);
/* invalid direction descriptor */
}
}
/*
/*
* istinterval - returns 1, iff i_string is a valid interval descr.
* istinterval - returns 1, iff i_string is a valid interval descr.
* 0, iff i_string is NOT a valid interval desc.
* 0, iff i_string is NOT a valid interval desc.
...
...
src/backend/utils/adt/datetime
s
.c
→
src/backend/utils/adt/datetime.c
View file @
53d8be3b
/*-------------------------------------------------------------------------
/*-------------------------------------------------------------------------
*
*
* datetime
s
.c--
* datetime.c--
* implements DATE and TIME data types specified in SQL-92 standard
* implements DATE and TIME data types specified in SQL-92 standard
*
*
* Copyright (c) 1994-5, Regents of the University of California
* Copyright (c) 1994-5, Regents of the University of California
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/
Attic/datetimes.c,v 1.9 1997/03/02 02:05:33 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/
datetime.c,v 1.1 1997/03/14 23:20:01 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -17,96 +17,248 @@
...
@@ -17,96 +17,248 @@
#include <postgres.h>
#include <postgres.h>
#include <miscadmin.h>
#include <miscadmin.h>
#include <utils/builtins.h>
#include <utils/builtins.h>
#include <utils/nabstime.h>
#include <utils/datetime.h>
#include <utils/datetime.h>
static
int
day_tab
[
2
][
12
]
=
{
static
int
day_tab
[
2
][
12
]
=
{
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
},
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
};
{
31
,
29
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
};
static
int
#define isleap(y) (((y % 4) == 0 && (y % 100) != 0) || (y % 400) == 0)
isleap
(
int
year
)
{
return
(((
year
%
4
)
==
0
&&
(
year
%
100
)
!=
0
)
||
(
year
%
400
)
==
0
);
}
/*****************************************************************************
/*****************************************************************************
* Date ADT
* Date ADT
*****************************************************************************/
*****************************************************************************/
/* date_in()
* Given date text string, convert to internal date format.
*/
#if USE_NEW_DATE
DateADT
date_in
(
char
*
str
)
{
DateADT
date
;
#else
int4
int4
date_in
(
char
*
date
str
)
date_in
(
char
*
str
)
{
{
int
d
,
m
,
y
;
int4
result
;
int4
result
;
DateADT
*
date
=
(
DateADT
*
)
&
result
;
DateADT
*
date
=
(
DateADT
*
)
&
result
;
#if 0
# ifdef USE_SHORT_YEAR
# define CHECK_DATE_LEN(datestr) (strlen(datestr) >= 8)
# else
# define CHECK_DATE_LEN(datestr) (strlen(datestr) == 10)
# endif
/* USE_SHORT_YEAR */
#else
# define CHECK_DATE_LEN(datestr) 1
#endif
#endif
if
(
EuroDates
==
1
)
{
/* Expect european format dates */
double
fsec
;
if
(
!
CHECK_DATE_LEN
(
datestr
)
||
struct
tm
tt
,
*
tm
=
&
tt
;
sscanf
(
datestr
,
"%d%*c%d%*c%d"
,
&
d
,
&
m
,
&
y
)
!=
3
)
{
int
tzp
;
elog
(
WARN
,
"date_in: date
\"
%s
\"
not of the form dd-mm-yyyy"
,
int
dtype
;
datestr
);
int
nf
;
}
char
*
field
[
MAXDATEFIELDS
];
int
ftype
[
MAXDATEFIELDS
];
char
lowstr
[
MAXDATELEN
+
1
];
if
(
!
PointerIsValid
(
str
))
elog
(
WARN
,
"Bad (null) date external representation"
,
NULL
);
#ifdef DATEDEBUG
printf
(
"date_in- input string is %s
\n
"
,
str
);
#endif
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
||
(
DecodeDateTime
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
,
&
tzp
)
!=
0
))
elog
(
WARN
,
"Bad date external representation %s"
,
str
);
switch
(
dtype
)
{
#if FALSE
case
DTK_DATE
:
date
=
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
);
time
=
time2j
(
tm
->
tm_hour
,
tm
->
tm_min
,(
double
)
tm
->
tm_sec
);
if
(
tzp
!=
0
)
{
j2local
(
&
date
,
&
time
,
-
(
tzp
*
60
));
}
else
{
}
else
{
if
(
!
CHECK_DATE_LEN
(
datestr
)
||
j2local
(
&
date
,
&
time
,
-
timezone
);
sscanf
(
datestr
,
"%d%*c%d%*c%d"
,
&
m
,
&
d
,
&
y
)
!=
3
)
{
};
elog
(
WARN
,
"date_in: date
\"
%s
\"
not of the form mm-dd-yyyy"
,
break
;
datestr
);
#endif
}
}
case
DTK_EPOCH
:
if
(
y
<
0
||
y
>
32767
)
tm
->
tm_year
=
1970
;
elog
(
WARN
,
"date_in: year must be limited to values 0 through 32767 in
\"
%s
\"
"
,
datestr
);
tm
->
tm_mon
=
1
;
if
(
m
<
1
||
m
>
12
)
tm
->
tm_mday
=
1
;
elog
(
WARN
,
"date_in: month must be limited to values 1 through 12 in
\"
%s
\"
"
,
datestr
);
case
DTK_DATE
:
if
(
d
<
1
||
d
>
day_tab
[
isleap
(
y
)][
m
-
1
])
break
;
elog
(
WARN
,
"date_in: day must be limited to values 1 through %d in
\"
%s
\"
"
,
day_tab
[
isleap
(
y
)][
m
-
1
],
datestr
);
default:
elog
(
WARN
,
"Unrecognized date external representation %s"
,
str
);
#ifdef USE_SHORT_YEAR
};
if
(
y
<
100
)
y
+=
1900
;
/* hack! */
#if FALSE
#endif
/* USE_SHORT_YEAR */
if
(
tm
->
tm_year
<
70
)
tm
->
tm_year
+=
2000
;
date
->
day
=
d
;
else
if
(
tm
->
tm_year
<
100
)
date
->
month
=
m
;
tm
->
tm_year
+=
1900
;
date
->
year
=
y
;
#endif
return
result
;
}
if
(
tm
->
tm_year
<
0
||
tm
->
tm_year
>
32767
)
elog
(
WARN
,
"date_in: year must be limited to values 0 through 32767 in '%s'"
,
str
);
if
(
tm
->
tm_mon
<
1
||
tm
->
tm_mon
>
12
)
elog
(
WARN
,
"date_in: month must be limited to values 1 through 12 in '%s'"
,
str
);
if
(
tm
->
tm_mday
<
1
||
tm
->
tm_mday
>
day_tab
[
isleap
(
tm
->
tm_year
)][
tm
->
tm_mon
-
1
])
elog
(
WARN
,
"date_in: day must be limited to values 1 through %d in '%s'"
,
day_tab
[
isleap
(
tm
->
tm_year
)][
tm
->
tm_mon
-
1
],
str
);
#if USE_NEW_DATE
date
=
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
-
date2j
(
2000
,
1
,
1
));
return
(
date
);
#else
date
->
day
=
tm
->
tm_mday
;
date
->
month
=
tm
->
tm_mon
;
date
->
year
=
tm
->
tm_year
;
return
(
result
);
#endif
}
/* date_in() */
/* date_out()
* Given internal format date, convert to text string.
*/
#if USE_NEW_DATE
char
*
date_out
(
DateADT
date
)
{
#else
char
*
char
*
date_out
(
int4
dateVal
)
date_out
(
int4
dateVal
)
{
{
char
*
datestr
=
palloc
(
11
);
DateADT
*
date
=
(
DateADT
*
)
&
dateVal
;
int4
dateStore
;
DateADT
*
date
;
#endif
char
*
result
;
char
buf
[
MAXDATELEN
+
1
];
int
year
,
month
,
day
;
#if USE_NEW_DATE
j2date
(
(((
int
)
date
)
+
date2j
(
2000
,
1
,
1
)),
&
year
,
&
month
,
&
day
);
#else
/* DateADT is a structure that happens to be four bytes long,
day
=
date
->
day
;
trust me on this.... */
month
=
date
->
month
;
date
=
(
DateADT
*
)
&
dateStore
;
year
=
date
->
year
;
dateStore
=
dateVal
;
if
(
EuroDates
==
1
)
/* Output european format dates */
#endif
sprintf
(
datestr
,
"%02d-%02d-%04d"
,
(
int
)
date
->
day
,
(
int
)
date
->
month
,
(
int
)
date
->
year
);
if
(
EuroDates
==
1
)
/* Output European-format dates */
sprintf
(
buf
,
"%02d-%02d-%04d"
,
day
,
month
,
year
);
else
else
sprintf
(
datestr
,
"%02d-%02d-%04d"
,
sprintf
(
buf
,
"%02d-%02d-%04d"
,
month
,
day
,
year
);
(
int
)
date
->
month
,
(
int
)
date
->
day
,
(
int
)
date
->
year
);
if
(
!
PointerIsValid
(
result
=
PALLOC
(
strlen
(
buf
)
+
1
)))
elog
(
WARN
,
"Memory allocation failed, can't output date"
,
NULL
);
strcpy
(
result
,
buf
);
return
(
result
);
}
/* date_out() */
#if USE_NEW_DATE
return
datestr
;
bool
date_eq
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
==
dateVal2
);
}
}
bool
date_ne
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
!=
dateVal2
);
}
bool
date_lt
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
<
dateVal2
);
}
/* date_lt() */
bool
date_le
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
<=
dateVal2
);
}
/* date_le() */
bool
date_gt
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
>
dateVal2
);
}
/* date_gt() */
bool
date_ge
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
>=
dateVal2
);
}
/* date_ge() */
int
int
date_cmp
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
if
(
dateVal1
<
dateVal2
)
{
return
-
1
;
}
else
if
(
dateVal1
>
dateVal2
)
{
return
1
;
};
return
0
;
}
/* date_cmp() */
DateADT
date_larger
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
date_gt
(
dateVal1
,
dateVal2
)
?
dateVal1
:
dateVal2
);
}
/* date_larger() */
DateADT
date_smaller
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
date_lt
(
dateVal1
,
dateVal2
)
?
dateVal1
:
dateVal2
);
}
/* date_smaller() */
/* Compute difference between two dates in days. */
int4
date_mi
(
DateADT
dateVal1
,
DateADT
dateVal2
)
{
return
(
dateVal1
-
dateVal2
);
}
/* date_mi() */
/* Add a number of days to a date, giving a new date.
Must handle both positive and negative numbers of days. */
DateADT
date_pli
(
DateADT
dateVal
,
int4
days
)
{
return
(
dateVal
+
days
);
}
/* date_pli() */
/* Subtract a number of days from a date, giving a new date. */
DateADT
date_mii
(
DateADT
dateVal
,
int4
days
)
{
return
(
date_pli
(
dateVal
,
-
days
));
}
/* date_mii() */
#else
bool
date_eq
(
int4
dateVal1
,
int4
dateVal2
)
date_eq
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dateStore1
=
dateVal1
;
int4
dateStore1
=
dateVal1
;
...
@@ -121,7 +273,7 @@ date_eq(int4 dateVal1, int4 dateVal2)
...
@@ -121,7 +273,7 @@ date_eq(int4 dateVal1, int4 dateVal2)
date1
->
year
==
date2
->
year
);
date1
->
year
==
date2
->
year
);
}
}
int
bool
date_ne
(
int4
dateVal1
,
int4
dateVal2
)
date_ne
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dateStore1
=
dateVal1
;
int4
dateStore1
=
dateVal1
;
...
@@ -135,7 +287,7 @@ date_ne(int4 dateVal1, int4 dateVal2)
...
@@ -135,7 +287,7 @@ date_ne(int4 dateVal1, int4 dateVal2)
date1
->
year
!=
date2
->
year
);
date1
->
year
!=
date2
->
year
);
}
}
int
bool
date_lt
(
int4
dateVal1
,
int4
dateVal2
)
date_lt
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dateStore1
=
dateVal1
;
int4
dateStore1
=
dateVal1
;
...
@@ -152,7 +304,7 @@ date_lt(int4 dateVal1, int4 dateVal2)
...
@@ -152,7 +304,7 @@ date_lt(int4 dateVal1, int4 dateVal2)
return
(
date1
->
day
<
date2
->
day
);
return
(
date1
->
day
<
date2
->
day
);
}
}
int
bool
date_le
(
int4
dateVal1
,
int4
dateVal2
)
date_le
(
int4
dateVal1
,
int4
dateVal2
)
{
{
...
@@ -170,7 +322,7 @@ date_le(int4 dateVal1, int4 dateVal2)
...
@@ -170,7 +322,7 @@ date_le(int4 dateVal1, int4 dateVal2)
return
(
date1
->
day
<=
date2
->
day
);
return
(
date1
->
day
<=
date2
->
day
);
}
}
int
bool
date_gt
(
int4
dateVal1
,
int4
dateVal2
)
date_gt
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dateStore1
=
dateVal1
;
int4
dateStore1
=
dateVal1
;
...
@@ -188,7 +340,7 @@ date_gt(int4 dateVal1, int4 dateVal2)
...
@@ -188,7 +340,7 @@ date_gt(int4 dateVal1, int4 dateVal2)
return
(
date1
->
day
>
date2
->
day
);
return
(
date1
->
day
>
date2
->
day
);
}
}
int
bool
date_ge
(
int4
dateVal1
,
int4
dateVal2
)
date_ge
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dateStore1
=
dateVal1
;
int4
dateStore1
=
dateVal1
;
...
@@ -240,7 +392,19 @@ date_smaller(int4 dateVal1, int4 dateVal2)
...
@@ -240,7 +392,19 @@ date_smaller(int4 dateVal1, int4 dateVal2)
int32
int32
date_mi
(
int4
dateVal1
,
int4
dateVal2
)
date_mi
(
int4
dateVal1
,
int4
dateVal2
)
{
{
int4
dv1
,
dv2
;
#if USE_NEW_TIME_CODE
DateADT
*
date1
,
*
date2
;
int
days
;
date1
=
(
DateADT
*
)
&
dateVal1
;
date2
=
(
DateADT
*
)
&
dateVal2
;
days
=
(
date2j
(
date1
->
year
,
date1
->
month
,
date1
->
day
)
-
date2j
(
date2
->
year
,
date2
->
month
,
date2
->
day
));
#else
DateADT
dv1
,
dv2
;
DateADT
*
date1
,
*
date2
;
DateADT
*
date1
,
*
date2
;
int32
days
=
0
;
int32
days
=
0
;
int
i
;
int
i
;
...
@@ -254,31 +418,31 @@ date_mi(int4 dateVal1, int4 dateVal2)
...
@@ -254,31 +418,31 @@ date_mi(int4 dateVal1, int4 dateVal2)
/* Sum number of days in each full year between date1 and date2. */
/* Sum number of days in each full year between date1 and date2. */
for
(
i
=
date1
->
year
+
1
;
i
<
date2
->
year
;
++
i
)
for
(
i
=
date1
->
year
+
1
;
i
<
date2
->
year
;
++
i
)
days
+=
isleap
(
i
)
?
366
:
365
;
days
+=
isleap
(
i
)
?
366
:
365
;
if
(
days
)
if
(
days
)
{
{
/* We need to wrap around the year. Add in number of days in each
/* We need to wrap around the year. Add in number of days in each
full month from date1 to end of year. */
full month from date1 to end of year. */
for
(
i
=
date1
->
month
+
1
;
i
<=
12
;
++
i
)
for
(
i
=
date1
->
month
+
1
;
i
<=
12
;
++
i
)
days
+=
day_tab
[
isleap
(
date1
->
year
)][
i
-
1
];
days
+=
day_tab
[
isleap
(
date1
->
year
)][
i
-
1
];
/* Add in number of days in each full month from start of year to
/* Add in number of days in each full month from start of year to
date2. */
date2. */
for
(
i
=
1
;
i
<
date2
->
month
;
++
i
)
for
(
i
=
1
;
i
<
date2
->
month
;
++
i
)
days
+=
day_tab
[
isleap
(
date2
->
year
)][
i
-
1
];
days
+=
day_tab
[
isleap
(
date2
->
year
)][
i
-
1
];
}
}
else
else
{
{
/* Add in number of days in each full month from date1 to date2. */
/* Add in number of days in each full month from date1 to date2. */
for
(
i
=
date1
->
month
+
1
;
i
<
date2
->
month
;
++
i
)
for
(
i
=
date1
->
month
+
1
;
i
<
date2
->
month
;
++
i
)
days
+=
day_tab
[
isleap
(
date1
->
year
)][
i
-
1
];
days
+=
day_tab
[
isleap
(
date1
->
year
)][
i
-
1
];
}
}
if
(
days
||
date1
->
month
!=
date2
->
month
)
if
(
days
||
date1
->
month
!=
date2
->
month
)
{
{
/* Add in number of days left in month for date1. */
/* Add in number of days left in month for date1. */
days
+=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
]
-
date1
->
day
;
days
+=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
]
-
date1
->
day
;
/* Add in day of month of date2. */
/* Add in day of month of date2. */
days
+=
date2
->
day
;
days
+=
date2
->
day
;
...
@@ -289,6 +453,8 @@ date_mi(int4 dateVal1, int4 dateVal2)
...
@@ -289,6 +453,8 @@ date_mi(int4 dateVal1, int4 dateVal2)
days
=
date2
->
day
-
date1
->
day
;
days
=
date2
->
day
-
date1
->
day
;
}
}
#endif
return
(
days
);
return
(
days
);
}
}
...
@@ -297,127 +463,226 @@ date_mi(int4 dateVal1, int4 dateVal2)
...
@@ -297,127 +463,226 @@ date_mi(int4 dateVal1, int4 dateVal2)
int4
int4
date_pli
(
int4
dateVal
,
int32
days
)
date_pli
(
int4
dateVal
,
int32
days
)
{
{
#if USE_NEW_TIME_CODE
DateADT
*
date1
=
(
DateADT
*
)
&
dateVal
;
int
date
,
year
,
month
,
day
;
date
=
(
date2j
(
date1
->
year
,
date1
->
month
,
date1
->
day
)
+
days
);
j2date
(
date
,
&
year
,
&
month
,
&
day
);
date1
->
year
=
year
;
date1
->
month
=
month
;
date1
->
day
=
day
;
#else
DateADT
*
date1
=
(
DateADT
*
)
&
dateVal
;
DateADT
*
date1
=
(
DateADT
*
)
&
dateVal
;
/* Use separate day variable because date1->day is a narrow type. */
/* Use separate day variable because date1->day is a narrow type. */
int32
day
=
date1
->
day
+
days
;
int32
day
=
date1
->
day
+
days
;
if
(
days
>
0
)
if
(
days
>
0
)
{
{
/* Loop as long as day has wrapped around end of month. */
/* Loop as long as day has wrapped around end of month. */
while
(
day
>
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
])
while
(
day
>
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
])
{
{
day
-=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
];
day
-=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
];
if
(
++
date1
->
month
>
12
)
{
if
(
++
date1
->
month
>
12
)
{
/* Month wrapped around. */
/* Month wrapped around. */
date1
->
month
=
1
;
date1
->
month
=
1
;
++
date1
->
year
;
++
date1
->
year
;
}
}
}
}
}
else
}
else
{
{
/* Loop as long as day has wrapped around beginning of month. */
/* Loop as long as day has wrapped around beginning of month. */
while
(
day
<
1
)
while
(
day
<
1
)
{
{
/* Decrement month first, because a negative day number
/* Decrement month first, because a negative day number
should be held as relative to the previous month's end. */
should be held as relative to the previous month's end. */
if
(
--
date1
->
month
<
1
)
if
(
--
date1
->
month
<
1
)
{
{
/* Month wrapped around. */
/* Month wrapped around. */
date1
->
month
=
12
;
date1
->
month
=
12
;
--
date1
->
year
;
--
date1
->
year
;
}
}
day
+=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
];
day
+=
day_tab
[
isleap
(
date1
->
year
)][
date1
->
month
-
1
];
}
}
}
}
date1
->
day
=
day
;
date1
->
day
=
day
;
#endif
return
(
dateVal
);
return
(
dateVal
);
}
}
/* date_pli() */
/* Subtract a number of days from a date, giving a new date. */
/* Subtract a number of days from a date, giving a new date. */
int4
int4
date_mii
(
int4
dateVal
,
int32
days
)
date_mii
(
int4
dateVal
,
int32
days
)
{
{
return
(
date_pli
(
dateVal
,
-
days
));
return
(
date_pli
(
dateVal
,
-
days
));
}
}
#endif
/*****************************************************************************
/*****************************************************************************
* Time ADT
* Time ADT
*****************************************************************************/
*****************************************************************************/
char
*
time_in
(
char
*
timestr
)
TimeADT
*
time_in
(
char
*
str
)
{
{
int
h
,
m
;
float
sec
;
TimeADT
*
time
;
TimeADT
*
time
;
if
(
sscanf
(
timestr
,
"%d%*c%d%*c%f"
,
&
h
,
&
m
,
&
sec
)
!=
3
)
{
double
fsec
;
sec
=
0
.
0
;
struct
tm
tt
,
*
tm
=
&
tt
;
if
(
sscanf
(
timestr
,
"%d%*c%d"
,
&
h
,
&
m
)
!=
2
)
{
elog
(
WARN
,
"time_in: time
\"
%s
\"
not of the form hh:mm:ss"
,
int
nf
;
timestr
);
char
lowstr
[
MAXDATELEN
+
1
];
}
char
*
field
[
MAXDATEFIELDS
];
}
int
dtype
;
int
ftype
[
MAXDATEFIELDS
];
if
(
!
PointerIsValid
(
str
))
elog
(
WARN
,
"Bad (null) time external representation"
,
NULL
);
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
||
(
DecodeTimeOnly
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
)
!=
0
))
elog
(
WARN
,
"Bad time external representation '%s'"
,
str
);
if
((
tm
->
tm_hour
<
0
)
||
(
tm
->
tm_hour
>
23
))
elog
(
WARN
,
"Hour must be limited to values 0 through 23 in '%s'"
,
str
);
if
((
tm
->
tm_min
<
0
)
||
(
tm
->
tm_min
>
59
))
elog
(
WARN
,
"Minute must be limited to values 0 through 59 in '%s'"
,
str
);
if
((
tm
->
tm_sec
<
0
)
||
((
tm
->
tm_sec
+
fsec
)
>=
60
))
elog
(
WARN
,
"Second must be limited to values 0 through < 60 in '%s'"
,
str
);
if
(
!
PointerIsValid
(
time
=
PALLOCTYPE
(
TimeADT
)))
elog
(
WARN
,
"Memory allocation failed, can't input time '%s'"
,
str
);
#if USE_NEW_TIME
*
time
=
((((
tm
->
tm_hour
*
60
)
+
tm
->
tm_min
)
*
60
)
+
tm
->
tm_sec
+
fsec
);
#else
time
->
hr
=
tm
->
tm_hour
;
time
->
min
=
tm
->
tm_min
;
time
->
sec
=
(
tm
->
tm_sec
+
fsec
);
#endif
return
(
time
);
}
/* time_in() */
if
(
h
<
0
||
h
>
23
)
elog
(
WARN
,
"time_in: hour must be limited to values 0 through 23 in
\"
%s
\"
"
,
timestr
);
if
(
m
<
0
||
m
>
59
)
elog
(
WARN
,
"time_in: minute must be limited to values 0 through 59 in
\"
%s
\"
"
,
timestr
);
if
(
sec
<
0
||
sec
>=
60
.
0
)
elog
(
WARN
,
"time_in: second must be limited to values 0 through 59.999 in
\"
%s
\"
"
,
timestr
);
time
=
(
TimeADT
*
)
palloc
(
sizeof
(
TimeADT
));
time
->
hr
=
h
;
time
->
min
=
m
;
time
->
sec
=
sec
;
return
(
char
*
)
time
;
}
char
*
char
*
time_out
(
TimeADT
*
time
)
time_out
(
TimeADT
*
time
)
{
{
char
*
timestr
=
palloc
(
32
);
char
*
result
;
int
n
;
char
buf
[
32
];
float
f
;
if
(
!
PointerIsValid
(
time
))
return
NULL
;
if
(
time
->
sec
==
0
.
0
)
{
if
(
time
->
sec
==
0
.
0
)
{
sprintf
(
timestr
,
"%02d:%02d"
,
sprintf
(
buf
,
"%02d:%02d"
,
(
int
)
time
->
hr
,
(
int
)
time
->
min
);
(
int
)
time
->
hr
,
(
int
)
time
->
min
);
}
else
{
}
else
{
n
=
(
int
)
time
->
sec
;
if
(((
int
)
time
->
sec
)
==
time
->
sec
)
{
f
=
(
float
)
n
;
sprintf
(
buf
,
"%02d:%02d:%02d"
,
if
(
f
==
time
->
sec
)
{
(
int
)
time
->
hr
,
(
int
)
time
->
min
,
(
int
)
time
->
sec
);
sprintf
(
timestr
,
"%02d:%02d:%02d"
,
(
int
)
time
->
hr
,
(
int
)
time
->
min
,
n
);
}
else
{
}
else
{
sprintf
(
timestr
,
"%02d:%02d:%09.6f"
,
sprintf
(
buf
,
"%02d:%02d:%09.6f"
,
(
int
)
time
->
hr
,
(
int
)
time
->
min
,
time
->
sec
);
(
int
)
time
->
hr
,
(
int
)
time
->
min
,
time
->
sec
);
}
}
;
}
}
;
return
timestr
;
if
(
!
PointerIsValid
(
result
=
PALLOC
(
strlen
(
buf
)
+
1
)))
}
elog
(
WARN
,
"Memory allocation failed, can't output time"
,
NULL
);
strcpy
(
result
,
buf
);
return
(
result
);
}
/* time_out() */
#if USE_NEW_TIME
bool
time_eq
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
==
*
time2
);
}
/* time_eq() */
bool
time_ne
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
!=
*
time2
);
}
/* time_eq() */
bool
time_lt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
<
*
time2
);
}
/* time_eq() */
bool
time_le
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
<=
*
time2
);
}
/* time_eq() */
bool
time_gt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
>
*
time2
);
}
/* time_eq() */
bool
time_ge
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
if
(
!
PointerIsValid
(
time1
)
||
!
PointerIsValid
(
time2
))
return
(
FALSE
);
return
(
*
time1
>=
*
time2
);
}
/* time_eq() */
int
int
time_cmp
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
return
((
*
time1
<
*
time2
)
?
-
1
:
(((
*
time1
<
*
time2
)
?
1
:
0
)));
}
/* time_cmp() */
#else
bool
time_eq
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_eq
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
return
(
time1
->
sec
==
time2
->
sec
&&
time1
->
min
==
time2
->
min
&&
return
(
time1
->
sec
==
time2
->
sec
&&
time1
->
min
==
time2
->
min
&&
time1
->
hr
==
time2
->
hr
);
time1
->
hr
==
time2
->
hr
);
}
}
int
bool
time_ne
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_ne
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
return
(
time1
->
sec
!=
time2
->
sec
||
time1
->
min
!=
time2
->
min
||
return
(
time1
->
sec
!=
time2
->
sec
||
time1
->
min
!=
time2
->
min
||
time1
->
hr
!=
time2
->
hr
);
time1
->
hr
!=
time2
->
hr
);
}
}
int
bool
time_lt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_lt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
if
(
time1
->
hr
!=
time2
->
hr
)
if
(
time1
->
hr
!=
time2
->
hr
)
...
@@ -427,7 +692,7 @@ time_lt(TimeADT *time1, TimeADT *time2)
...
@@ -427,7 +692,7 @@ time_lt(TimeADT *time1, TimeADT *time2)
return
(
time1
->
sec
<
time2
->
sec
);
return
(
time1
->
sec
<
time2
->
sec
);
}
}
int
bool
time_le
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_le
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
if
(
time1
->
hr
!=
time2
->
hr
)
if
(
time1
->
hr
!=
time2
->
hr
)
...
@@ -437,7 +702,7 @@ time_le(TimeADT *time1, TimeADT *time2)
...
@@ -437,7 +702,7 @@ time_le(TimeADT *time1, TimeADT *time2)
return
(
time1
->
sec
<=
time2
->
sec
);
return
(
time1
->
sec
<=
time2
->
sec
);
}
}
int
bool
time_gt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_gt
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
if
(
time1
->
hr
!=
time2
->
hr
)
if
(
time1
->
hr
!=
time2
->
hr
)
...
@@ -447,7 +712,7 @@ time_gt(TimeADT *time1, TimeADT *time2)
...
@@ -447,7 +712,7 @@ time_gt(TimeADT *time1, TimeADT *time2)
return
(
time1
->
sec
>
time2
->
sec
);
return
(
time1
->
sec
>
time2
->
sec
);
}
}
int
bool
time_ge
(
TimeADT
*
time1
,
TimeADT
*
time2
)
time_ge
(
TimeADT
*
time1
,
TimeADT
*
time2
)
{
{
if
(
time1
->
hr
!=
time2
->
hr
)
if
(
time1
->
hr
!=
time2
->
hr
)
...
@@ -469,6 +734,8 @@ time_cmp(TimeADT *time1, TimeADT *time2)
...
@@ -469,6 +734,8 @@ time_cmp(TimeADT *time1, TimeADT *time2)
return
0
;
return
0
;
}
}
#endif
int32
/* RelativeTime */
int32
/* RelativeTime */
int42reltime
(
int32
timevalue
)
int42reltime
(
int32
timevalue
)
{
{
...
...
src/backend/utils/adt/dt.c
View file @
53d8be3b
...
@@ -7,52 +7,2189 @@
...
@@ -7,52 +7,2189 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.
2 1996/11/03 06:53:04
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.
3 1997/03/14 23:20:10
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include "postgres.h"
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
/* where function declarations go */
extern
int
EuroDates
;
#define MAXDATEFIELDS 25
#define USE_DATE_CACHE 1
extern
char
*
tzname
[
2
];
extern
long
int
timezone
;
extern
int
daylight
;
#define JTIME_INVALID (infnan(0))
#define DATETIME_INVALID(j) {*j = JTIME_INVALID;}
#define DATETIME_IS_INVALID(j) (isnan(*j))
#define JTIME_NOBEGIN (infnan(-ERANGE))
#define DATETIME_NOBEGIN(j) {*j = JTIME_NOBEGIN;}
#define DATETIME_IS_NOBEGIN(j) (*j == JTIME_NOBEGIN)
#define JTIME_NOEND (infnan(ERANGE))
#define DATETIME_NOEND(j) {*j = JTIME_NOEND;}
#define DATETIME_IS_NOEND(j) (*j == JTIME_NOEND)
#define JTIME_CURRENT (MINDOUBLE)
#define DATETIME_CURRENT(j) {*j = JTIME_CURRENT;}
#define DATETIME_IS_CURRENT(j) (*j == MINDOUBLE)
#define JTIME_EPOCH (-MINDOUBLE)
#define DATETIME_EPOCH(j) {*j = JTIME_EPOCH;}
#define DATETIME_IS_EPOCH(j) (*j == JTIME_EPOCH)
#define DATETIME_IS_RESERVED(j) (*j < 0)
#undef DATETIME_IS_RESERVED
#define DATETIME_IS_RESERVED(j) (DATETIME_IS_INVALID(j) \
|| DATETIME_IS_NOBEGIN(j) || DATETIME_IS_NOEND(j) \
|| DATETIME_IS_CURRENT(j) || DATETIME_IS_EPOCH(j))
#define TIME_PREC 1e-6
#define JROUND(j) (rint(((double) j)/TIME_PREC)*TIME_PREC)
/*****************************************************************************
/*****************************************************************************
* USER I/O ROUTINES *
* USER I/O ROUTINES *
*****************************************************************************/
*****************************************************************************/
/*
* dtin - converts "nseconds" to internal representation
/* datetime_in()
*
* Convert a string to internal form.
* XXX Currently, just creates an integer.
*/
*/
int32
dtin
(
char
*
datetime
)
DateTime
*
datetime_in
(
char
*
str
)
{
{
if
(
datetime
==
NULL
)
DateTime
*
result
;
return
((
int32
)
0
);
return
((
int32
)
atol
(
datetime
));
}
/*
double
date
,
time
;
* dtout - converts internal form to "..."
double
fsec
;
struct
tm
tt
,
*
tm
=
&
tt
;
int
tzp
;
int
dtype
;
int
nf
;
char
*
field
[
MAXDATEFIELDS
];
int
ftype
[
MAXDATEFIELDS
];
char
lowstr
[
MAXDATELEN
];
if
(
!
PointerIsValid
(
str
))
elog
(
WARN
,
"Bad (null) datetime external representation"
,
NULL
);
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
||
(
DecodeDateTime
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
,
&
tzp
)
!=
0
))
elog
(
WARN
,
"Bad datetime external representation %s"
,
str
);
if
(
!
PointerIsValid
(
result
=
PALLOCTYPE
(
DateTime
)))
elog
(
WARN
,
"Memory allocation failed, can't input datetime '%s'"
,
str
);
switch
(
dtype
)
{
case
DTK_DATE
:
date
=
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
-
date2j
(
2000
,
1
,
1
));
time
=
time2t
(
tm
->
tm_hour
,
tm
->
tm_min
,(
tm
->
tm_sec
+
fsec
));
*
result
=
(
date
*
86400
+
time
);
#ifdef DATEDEBUG
printf
(
"datetime_in- date is %f (%f %f %d)
\n
"
,
*
result
,
date
,
time
,
(((
tm
->
tm_hour
*
60
)
+
tm
->
tm_min
)
*
60
+
tm
->
tm_sec
));
printf
(
"datetime_in- time is %f %02d:%02d:%02d %f
\n
"
,
time
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
fsec
);
#endif
if
(
tzp
!=
0
)
{
*
result
=
dt2local
(
*
result
,
-
tzp
);
}
else
{
*
result
=
dt2local
(
*
result
,
-
timezone
);
};
#ifdef DATEDEBUG
printf
(
"datetime_in- date is %f
\n
"
,
*
result
);
#endif
break
;
case
DTK_EPOCH
:
DATETIME_EPOCH
(
result
);
break
;
case
DTK_CURRENT
:
DATETIME_CURRENT
(
result
);
break
;
case
DTK_LATE
:
DATETIME_NOEND
(
result
);
break
;
case
DTK_EARLY
:
DATETIME_NOBEGIN
(
result
);
break
;
case
DTK_INVALID
:
DATETIME_INVALID
(
result
);
break
;
default:
elog
(
WARN
,
"Internal coding error, can't input datetime '%s'"
,
str
);
};
return
(
result
);
}
/* datetime_in() */
/* datetime_out()
* Convert a datetime to external form.
*/
char
*
datetime_out
(
DateTime
*
dt
)
{
char
*
result
;
struct
tm
tt
,
*
tm
=
&
tt
;
double
date
,
time
,
sec
,
fsec
;
char
buf
[
MAXDATELEN
];
if
(
!
PointerIsValid
(
dt
))
return
(
NULL
);
if
(
DATETIME_IS_RESERVED
(
dt
))
{
EncodeSpecialDateTime
(
dt
,
buf
);
}
else
{
time
=
(
modf
(
dt2local
(
*
dt
,
timezone
)
/
86400
,
&
date
)
*
86400
);
date
+=
date2j
(
2000
,
1
,
1
);
if
(
time
<
0
)
{
time
+=
86400
;
date
-=
1
;
};
#ifdef DATEDEBUG
printf
(
"datetime_out- date is %f (%f %f)
\n
"
,
*
dt
,
date
,
time
);
#endif
j2date
((
int
)
date
,
&
tm
->
tm_year
,
&
tm
->
tm_mon
,
&
tm
->
tm_mday
);
dt2time
(
time
,
&
tm
->
tm_hour
,
&
tm
->
tm_min
,
&
sec
);
#ifdef DATEDEBUG
printf
(
"datetime_out- date is %d.%02d.%02d
\n
"
,
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
);
printf
(
"datetime_out- time is %02d:%02d:%2.2f
\n
"
,
tm
->
tm_hour
,
tm
->
tm_min
,
sec
);
#endif
fsec
=
modf
(
JROUND
(
sec
),
&
sec
);
tm
->
tm_sec
=
sec
;
#ifdef DATEDEBUG
printf
(
"datetime_out- time is %02d:%02d:%02d %.7f
\n
"
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
fsec
);
#endif
tm
->
tm_isdst
=
-
1
;
#ifdef DATEDEBUG
printf
(
"datetime_out- timezone is %s/%s; offset is %ld; daylight is %d
\n
"
,
tzname
[
0
],
tzname
[
1
],
timezone
,
daylight
);
#endif
EncodePostgresDate
(
tm
,
fsec
,
buf
);
};
if
(
!
PointerIsValid
(
result
=
PALLOC
(
strlen
(
buf
)
+
1
)))
elog
(
WARN
,
"Memory allocation failed, can't output datetime"
,
NULL
);
strcpy
(
result
,
buf
);
return
(
result
);
}
/* datetime_out() */
/* timespan_in()
* Convert a string to internal form.
*
*
* XXX assumes sign, 10 digits max, '\0'
* External format(s):
* Uses the generic date/time parsing and decoding routines.
*/
TimeSpan
*
timespan_in
(
char
*
str
)
{
TimeSpan
*
span
;
double
fsec
;
struct
tm
tt
,
*
tm
=
&
tt
;
int
dtype
;
int
nf
;
char
*
field
[
MAXDATEFIELDS
];
int
ftype
[
MAXDATEFIELDS
];
char
lowstr
[
MAXDATELEN
];
tm
->
tm_year
=
0
;
tm
->
tm_mon
=
0
;
tm
->
tm_mday
=
0
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
fsec
=
0
;
if
(
!
PointerIsValid
(
str
))
elog
(
WARN
,
"Bad (null) timespan external representation"
,
NULL
);
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
||
(
DecodeDateDelta
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
)
!=
0
))
elog
(
WARN
,
"Bad timespan external representation %s"
,
str
);
if
(
!
PointerIsValid
(
span
=
PALLOCTYPE
(
TimeSpan
)))
elog
(
WARN
,
"Memory allocation failed, can't input timespan '%s'"
,
str
);
switch
(
dtype
)
{
case
DTK_DELTA
:
span
->
month
=
((
tm
->
tm_year
*
12
)
+
tm
->
tm_mon
);
span
->
time
=
((((((
tm
->
tm_mday
*
24
)
+
tm
->
tm_hour
)
*
60
)
+
tm
->
tm_min
)
*
60
)
+
tm
->
tm_sec
);
span
->
time
=
JROUND
(
span
->
time
+
fsec
);
#ifdef DATEDEBUG
printf
(
"timespan_in- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f
\n
"
,
span
->
month
,
span
->
time
,
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
fsec
);
#endif
break
;
default:
elog
(
WARN
,
"Internal coding error, can't input timespan '%s'"
,
str
);
};
return
(
span
);
}
/* timespan_in() */
/* timespan_out()
* Convert a time span to external form.
*/
*/
char
*
dtout
(
int32
datetime
)
char
*
timespan_out
(
TimeSpan
*
span
)
{
{
char
*
result
;
char
*
result
;
result
=
(
char
*
)
palloc
(
12
);
struct
tm
tt
,
*
tm
=
&
tt
;
Assert
(
result
);
double
time
,
iunit
,
funit
,
fsec
=
0
;
ltoa
(
datetime
,
result
);
char
buf
[
MAXDATELEN
];
return
(
result
);
}
if
(
!
PointerIsValid
(
span
))
return
(
NULL
);
if
(
span
->
month
!=
0
)
{
tm
->
tm_year
=
span
->
month
/
12
;
tm
->
tm_mon
=
span
->
month
%
12
;
}
else
{
tm
->
tm_year
=
0
;
tm
->
tm_mon
=
0
;
};
#if FALSE
time
=
JROUND
(
span
->
time
);
#endif
time
=
span
->
time
;
funit
=
modf
(
(
time
/
86400
),
&
iunit
);
tm
->
tm_mday
=
iunit
;
if
(
tm
->
tm_mday
!=
0
)
time
-=
rint
(
tm
->
tm_mday
*
86400
);
funit
=
modf
(
(
time
/
3600
),
&
iunit
);
tm
->
tm_hour
=
iunit
;
if
(
tm
->
tm_hour
!=
0
)
time
-=
rint
(
tm
->
tm_hour
*
3600e0
);
funit
=
modf
(
(
time
/
60
),
&
iunit
);
tm
->
tm_min
=
iunit
;
if
(
tm
->
tm_min
!=
0
)
time
-=
rint
(
tm
->
tm_min
*
60e0
);
funit
=
modf
(
time
,
&
iunit
);
tm
->
tm_sec
=
iunit
;
if
(
tm
->
tm_sec
!=
0
)
time
-=
tm
->
tm_sec
;
fsec
=
time
;
#ifdef DATEDEBUG
printf
(
"timespan_out- %d %f = %04d-%02d-%02d %02d:%02d:%02d %.2f
\n
"
,
span
->
month
,
span
->
time
,
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
fsec
);
#endif
if
(
EncodePostgresSpan
(
tm
,
fsec
,
buf
)
!=
0
)
elog
(
WARN
,
"Unable to format timespan"
,
NULL
);
if
(
!
PointerIsValid
(
result
=
PALLOC
(
strlen
(
buf
)
+
1
)))
elog
(
WARN
,
"Memory allocation failed, can't output timespan"
,
NULL
);
strcpy
(
result
,
buf
);
return
(
result
);
}
/* timespan_out() */
/*****************************************************************************
/*****************************************************************************
* PUBLIC ROUTINES *
* PUBLIC ROUTINES *
*****************************************************************************/
*****************************************************************************/
/* (see int.c for comparison/operation routines) */
/* (see int.c for comparison/operation routines) */
/*****************************************************************************
/*****************************************************************************
* PRIVATE ROUTINES *
* PRIVATE ROUTINES *
*****************************************************************************/
*****************************************************************************/
/* (none) */
#if USE_NEW_TIME_CODE
#define DATE_MAXLEN 47
#endif
/* definitions for squeezing values into "value" */
#define ABS_SIGNBIT 0200
#define VALMASK 0177
#define NEG(n) ((n)|ABS_SIGNBIT)
#define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))
#define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 10)
/* uncompress */
#define TOVAL(tp, v) ((tp)->value = ((v) < 0? NEG((-(v))/10): (v)/10))
/*
* to keep this table reasonably small, we divide the lexval for TZ and DTZ
* entries by 10 and truncate the text field at MAXTOKLEN characters.
* the text field is not guaranteed to be NULL-terminated.
*/
static
datetkn
datetktbl
[]
=
{
/* text token lexval */
{
EARLY
,
RESERV
,
DTK_EARLY
},
/* "-infinity" reserved for "early time" */
{
"acsst"
,
DTZ
,
63
},
/* Cent. Australia */
{
"acst"
,
TZ
,
57
},
/* Cent. Australia */
{
DA_D
,
ADBC
,
AD
},
/* "ad" for years >= 0 */
{
"abstime"
,
IGNORE
,
0
},
/* "abstime" for pre-v6.1 "Invalid Abstime" */
{
"adt"
,
DTZ
,
NEG
(
18
)},
/* Atlantic Daylight Time */
{
"aesst"
,
DTZ
,
66
},
/* E. Australia */
{
"aest"
,
TZ
,
60
},
/* Australia Eastern Std Time */
{
"ahst"
,
TZ
,
60
},
/* Alaska-Hawaii Std Time */
{
"allballs"
,
RESERV
,
DTK_ZULU
},
/* 00:00:00 */
{
"am"
,
AMPM
,
AM
},
{
"apr"
,
MONTH
,
4
},
{
"april"
,
MONTH
,
4
},
{
"ast"
,
TZ
,
NEG
(
24
)},
/* Atlantic Std Time (Canada) */
{
"at"
,
IGNORE
,
0
},
/* "at" (throwaway) */
{
"aug"
,
MONTH
,
8
},
{
"august"
,
MONTH
,
8
},
{
"awsst"
,
DTZ
,
54
},
/* W. Australia */
{
"awst"
,
TZ
,
48
},
/* W. Australia */
{
DB_C
,
ADBC
,
BC
},
/* "bc" for years < 0 */
{
"bst"
,
TZ
,
6
},
/* British Summer Time */
{
"bt"
,
TZ
,
18
},
/* Baghdad Time */
{
"cadt"
,
DTZ
,
63
},
/* Central Australian DST */
{
"cast"
,
TZ
,
57
},
/* Central Australian ST */
{
"cat"
,
TZ
,
NEG
(
60
)},
/* Central Alaska Time */
{
"cct"
,
TZ
,
48
},
/* China Coast */
{
"cdt"
,
DTZ
,
NEG
(
30
)},
/* Central Daylight Time */
{
"cet"
,
TZ
,
6
},
/* Central European Time */
{
"cetdst"
,
DTZ
,
12
},
/* Central European Dayl.Time */
{
"cst"
,
TZ
,
NEG
(
36
)},
/* Central Standard Time */
{
DCURRENT
,
RESERV
,
DTK_CURRENT
},
/* "current" is always now */
{
"dec"
,
MONTH
,
12
},
{
"december"
,
MONTH
,
12
},
{
"dnt"
,
TZ
,
6
},
/* Dansk Normal Tid */
{
"dst"
,
IGNORE
,
0
},
{
"east"
,
TZ
,
NEG
(
60
)},
/* East Australian Std Time */
{
"edt"
,
DTZ
,
NEG
(
24
)},
/* Eastern Daylight Time */
{
"eet"
,
TZ
,
12
},
/* East. Europe, USSR Zone 1 */
{
"eetdst"
,
DTZ
,
18
},
/* Eastern Europe */
{
EPOCH
,
RESERV
,
DTK_EPOCH
},
/* "epoch" reserved for system epoch time */
{
"est"
,
TZ
,
NEG
(
30
)},
/* Eastern Standard Time */
{
"feb"
,
MONTH
,
2
},
{
"february"
,
MONTH
,
2
},
{
"fri"
,
DOW
,
5
},
{
"friday"
,
DOW
,
5
},
{
"fst"
,
TZ
,
6
},
/* French Summer Time */
{
"fwt"
,
DTZ
,
12
},
/* French Winter Time */
{
"gmt"
,
TZ
,
0
},
/* Greenwish Mean Time */
{
"gst"
,
TZ
,
60
},
/* Guam Std Time, USSR Zone 9 */
{
"hdt"
,
DTZ
,
NEG
(
54
)},
/* Hawaii/Alaska */
{
"hmt"
,
DTZ
,
18
},
/* Hellas ? ? */
{
"hst"
,
TZ
,
NEG
(
60
)},
/* Hawaii Std Time */
{
"idle"
,
TZ
,
72
},
/* Intl. Date Line, East */
{
"idlw"
,
TZ
,
NEG
(
72
)},
/* Intl. Date Line, West */
{
LATE
,
RESERV
,
DTK_LATE
},
/* "infinity" reserved for "late time" */
{
INVALID
,
RESERV
,
DTK_INVALID
},
/* "invalid" reserved for invalid time */
{
"ist"
,
TZ
,
12
},
/* Israel */
{
"it"
,
TZ
,
22
},
/* Iran Time */
{
"jan"
,
MONTH
,
1
},
{
"january"
,
MONTH
,
1
},
{
"jst"
,
TZ
,
54
},
/* Japan Std Time,USSR Zone 8 */
{
"jt"
,
TZ
,
45
},
/* Java Time */
{
"jul"
,
MONTH
,
7
},
{
"july"
,
MONTH
,
7
},
{
"jun"
,
MONTH
,
6
},
{
"june"
,
MONTH
,
6
},
{
"kst"
,
TZ
,
54
},
/* Korea Standard Time */
{
"ligt"
,
TZ
,
60
},
/* From Melbourne, Australia */
{
"mar"
,
MONTH
,
3
},
{
"march"
,
MONTH
,
3
},
{
"may"
,
MONTH
,
5
},
{
"mdt"
,
DTZ
,
NEG
(
36
)},
/* Mountain Daylight Time */
{
"mest"
,
DTZ
,
12
},
/* Middle Europe Summer Time */
{
"met"
,
TZ
,
6
},
/* Middle Europe Time */
{
"metdst"
,
DTZ
,
12
},
/* Middle Europe Daylight Time*/
{
"mewt"
,
TZ
,
6
},
/* Middle Europe Winter Time */
{
"mez"
,
TZ
,
6
},
/* Middle Europe Zone */
{
"mon"
,
DOW
,
1
},
{
"monday"
,
DOW
,
1
},
{
"mst"
,
TZ
,
NEG
(
42
)},
/* Mountain Standard Time */
{
"mt"
,
TZ
,
51
},
/* Moluccas Time */
{
"ndt"
,
DTZ
,
NEG
(
15
)},
/* Nfld. Daylight Time */
{
"nft"
,
TZ
,
NEG
(
21
)},
/* Newfoundland Standard Time */
{
"nor"
,
TZ
,
6
},
/* Norway Standard Time */
{
"nov"
,
MONTH
,
11
},
{
"november"
,
MONTH
,
11
},
{
NOW
,
RESERV
,
DTK_NOW
},
/* current transaction time */
{
"nst"
,
TZ
,
NEG
(
21
)},
/* Nfld. Standard Time */
{
"nt"
,
TZ
,
NEG
(
66
)},
/* Nome Time */
{
"nzdt"
,
DTZ
,
78
},
/* New Zealand Daylight Time */
{
"nzst"
,
TZ
,
72
},
/* New Zealand Standard Time */
{
"nzt"
,
TZ
,
72
},
/* New Zealand Time */
{
"oct"
,
MONTH
,
10
},
{
"october"
,
MONTH
,
10
},
{
"on"
,
IGNORE
,
0
},
/* "on" (throwaway) */
{
"pdt"
,
DTZ
,
NEG
(
42
)},
/* Pacific Daylight Time */
{
"pm"
,
AMPM
,
PM
},
{
"pst"
,
TZ
,
NEG
(
48
)},
/* Pacific Standard Time */
{
"sadt"
,
DTZ
,
63
},
/* S. Australian Dayl. Time */
{
"sast"
,
TZ
,
57
},
/* South Australian Std Time */
{
"sat"
,
DOW
,
6
},
{
"saturday"
,
DOW
,
6
},
{
"sep"
,
MONTH
,
9
},
{
"sept"
,
MONTH
,
9
},
{
"september"
,
MONTH
,
9
},
{
"set"
,
TZ
,
NEG
(
6
)},
/* Seychelles Time ?? */
{
"sst"
,
DTZ
,
12
},
/* Swedish Summer Time */
{
"sun"
,
DOW
,
0
},
{
"sunday"
,
DOW
,
0
},
{
"swt"
,
TZ
,
6
},
/* Swedish Winter Time */
{
"thu"
,
DOW
,
4
},
{
"thur"
,
DOW
,
4
},
{
"thurs"
,
DOW
,
4
},
{
"thursday"
,
DOW
,
4
},
{
TODAY
,
RESERV
,
DTK_TODAY
},
/* midnight */
{
TOMORROW
,
RESERV
,
DTK_TOMORROW
},
/* tomorrow midnight */
{
"tue"
,
DOW
,
2
},
{
"tues"
,
DOW
,
2
},
{
"tuesday"
,
DOW
,
2
},
{
"undefined"
,
RESERV
,
DTK_INVALID
},
/* "undefined" pre-v6.1 invalid time */
{
"ut"
,
TZ
,
0
},
{
"utc"
,
TZ
,
0
},
{
"wadt"
,
DTZ
,
48
},
/* West Australian DST */
{
"wast"
,
TZ
,
42
},
/* West Australian Std Time */
{
"wat"
,
TZ
,
NEG
(
6
)},
/* West Africa Time */
{
"wdt"
,
DTZ
,
54
},
/* West Australian DST */
{
"wed"
,
DOW
,
3
},
{
"wednesday"
,
DOW
,
3
},
{
"weds"
,
DOW
,
3
},
{
"wet"
,
TZ
,
0
},
/* Western Europe */
{
"wetdst"
,
DTZ
,
6
},
/* Western Europe */
{
"wst"
,
TZ
,
48
},
/* West Australian Std Time */
{
"ydt"
,
DTZ
,
NEG
(
48
)},
/* Yukon Daylight Time */
{
YESTERDAY
,
RESERV
,
DTK_YESTERDAY
},
/* yesterday midnight */
{
"yst"
,
TZ
,
NEG
(
54
)},
/* Yukon Standard Time */
{
"zp4"
,
TZ
,
NEG
(
24
)},
/* GMT +4 hours. */
{
"zp5"
,
TZ
,
NEG
(
30
)},
/* GMT +5 hours. */
{
"zp6"
,
TZ
,
NEG
(
36
)},
/* GMT +6 hours. */
{
ZULU
,
RESERV
,
DTK_ZULU
},
/* 00:00:00 */
};
static
unsigned
int
szdatetktbl
=
sizeof
datetktbl
/
sizeof
datetktbl
[
0
];
static
datetkn
deltatktbl
[]
=
{
/* text token lexval */
{
"@"
,
IGNORE
,
0
},
/* postgres relative time prefix */
{
DAGO
,
AGO
,
0
},
/* "ago" indicates negative time offset */
{
"c"
,
UNITS
,
DTK_CENTURY
},
/* "century" relative time units */
{
"cent"
,
UNITS
,
DTK_CENTURY
},
/* "century" relative time units */
{
"centuries"
,
UNITS
,
DTK_CENTURY
},
/* "centuries" relative time units */
{
DCENTURY
,
UNITS
,
DTK_CENTURY
},
/* "century" relative time units */
{
"d"
,
UNITS
,
DTK_DAY
},
/* "day" relative time units */
{
DDAY
,
UNITS
,
DTK_DAY
},
/* "day" relative time units */
{
"days"
,
UNITS
,
DTK_DAY
},
/* "days" relative time units */
{
"dec"
,
UNITS
,
DTK_DECADE
},
/* "decade" relative time units */
{
"decs"
,
UNITS
,
DTK_DECADE
},
/* "decades" relative time units */
{
DDECADE
,
UNITS
,
DTK_DECADE
},
/* "decade" relative time units */
{
"decades"
,
UNITS
,
DTK_DECADE
},
/* "decades" relative time units */
{
"h"
,
UNITS
,
DTK_HOUR
},
/* "hour" relative time units */
{
DHOUR
,
UNITS
,
DTK_HOUR
},
/* "hour" relative time units */
{
"hours"
,
UNITS
,
DTK_HOUR
},
/* "hours" relative time units */
{
"hr"
,
UNITS
,
DTK_HOUR
},
/* "hour" relative time units */
{
"hrs"
,
UNITS
,
DTK_HOUR
},
/* "hours" relative time units */
{
INVALID
,
RESERV
,
DTK_INVALID
},
/* "invalid" reserved for invalid time */
{
"m"
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative time units */
{
"microsecon"
,
UNITS
,
DTK_MILLISEC
},
/* "microsecond" relative time units */
{
"mil"
,
UNITS
,
DTK_MILLENIUM
},
/* "millenium" relative time units */
{
"mils"
,
UNITS
,
DTK_MILLENIUM
},
/* "millenia" relative time units */
{
"millenia"
,
UNITS
,
DTK_MILLENIUM
},
/* "millenia" relative time units */
{
DMILLENIUM
,
UNITS
,
DTK_MILLENIUM
},
/* "millenium" relative time units */
{
"milliseco"
,
UNITS
,
DTK_MILLISEC
},
/* "millisecond" relative time units */
{
"min"
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative time units */
{
"mins"
,
UNITS
,
DTK_MINUTE
},
/* "minutes" relative time units */
{
"mins"
,
UNITS
,
DTK_MINUTE
},
/* "minutes" relative time units */
{
DMINUTE
,
UNITS
,
DTK_MINUTE
},
/* "minute" relative time units */
{
"minutes"
,
UNITS
,
DTK_MINUTE
},
/* "minutes" relative time units */
{
"mon"
,
UNITS
,
DTK_MONTH
},
/* "months" relative time units */
{
"mons"
,
UNITS
,
DTK_MONTH
},
/* "months" relative time units */
{
DMONTH
,
UNITS
,
DTK_MONTH
},
/* "month" relative time units */
{
"months"
,
UNITS
,
DTK_MONTH
},
/* "months" relative time units */
{
"ms"
,
UNITS
,
DTK_MILLISEC
},
/* "millisecond" relative time units */
{
"msec"
,
UNITS
,
DTK_MILLISEC
},
/* "millisecond" relative time units */
{
DMILLISEC
,
UNITS
,
DTK_MILLISEC
},
/* "millisecond" relative time units */
{
"mseconds"
,
UNITS
,
DTK_MILLISEC
},
/* "milliseconds" relative time units */
{
"msecs"
,
UNITS
,
DTK_MILLISEC
},
/* "milliseconds" relative time units */
{
"reltime"
,
IGNORE
,
0
},
/* "reltime" for pre-v6.1 "Undefined Reltime" */
{
"s"
,
UNITS
,
DTK_SECOND
},
/* "second" relative time units */
{
"sec"
,
UNITS
,
DTK_SECOND
},
/* "second" relative time units */
{
DSECOND
,
UNITS
,
DTK_SECOND
},
/* "second" relative time units */
{
"seconds"
,
UNITS
,
DTK_SECOND
},
/* "seconds" relative time units */
{
"secs"
,
UNITS
,
DTK_SECOND
},
/* "seconds" relative time units */
{
"undefined"
,
RESERV
,
DTK_INVALID
},
/* "undefined" pre-v6.1 invalid time */
{
"us"
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative time units */
{
"usec"
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative time units */
{
DMICROSEC
,
UNITS
,
DTK_MICROSEC
},
/* "microsecond" relative time units */
{
"useconds"
,
UNITS
,
DTK_MICROSEC
},
/* "microseconds" relative time units */
{
"usecs"
,
UNITS
,
DTK_MICROSEC
},
/* "microseconds" relative time units */
{
"w"
,
UNITS
,
DTK_WEEK
},
/* "week" relative time units */
{
DWEEK
,
UNITS
,
DTK_WEEK
},
/* "week" relative time units */
{
"weeks"
,
UNITS
,
DTK_WEEK
},
/* "weeks" relative time units */
{
"y"
,
UNITS
,
DTK_YEAR
},
/* "year" relative time units */
{
DYEAR
,
UNITS
,
DTK_YEAR
},
/* "year" relative time units */
{
"years"
,
UNITS
,
DTK_YEAR
},
/* "years" relative time units */
{
"yr"
,
UNITS
,
DTK_YEAR
},
/* "year" relative time units */
{
"yrs"
,
UNITS
,
DTK_YEAR
},
/* "years" relative time units */
};
static
unsigned
int
szdeltatktbl
=
sizeof
deltatktbl
/
sizeof
deltatktbl
[
0
];
#if USE_DATE_CACHE
datetkn
*
datecache
[
MAXDATEFIELDS
]
=
{
NULL
};
datetkn
*
deltacache
[
MAXDATEFIELDS
]
=
{
NULL
};
#endif
/*
* Calendar time to Julian date conversions.
* Julian date is commonly used in astronomical applications,
* since it is numerically accurate and computationally simple.
* The algorithms here will accurately convert between Julian day
* and calendar date for all non-negative Julian days
* (i.e. from Nov 23, -4713 on).
*
* Ref: Explanatory Supplement to the Astronomical Almanac, 1992.
* University Science Books, 20 Edgehill Rd. Mill Valley CA 94941.
*
* These routines will be used by other date/time packages - tgl 97/02/25
*/
#define USE_FLIEGEL 1
int
date2j
(
int
y
,
int
m
,
int
d
)
{
#if USE_FLIEGEL
int
m12
=
(
m
-
14
)
/
12
;
return
((
1461
*
(
y
+
4800
+
m12
))
/
4
+
(
367
*
(
m
-
2
-
12
*
(
m12
)))
/
12
-
(
3
*
((
y
+
4900
+
m12
)
/
100
))
/
4
+
d
-
32075
);
#else
int
c
,
ya
;
if
(
m
>
2
)
{
m
-=
3
;
}
else
{
m
+=
9
;
y
--
;
};
c
=
y
/
100
;
ya
=
y
-
100
*
c
;
return
((
146097
*
c
)
/
4
+
(
1461
*
ya
)
/
4
+
(
153
*
m
+
2
)
/
5
+
d
+
1721119
);
#endif
}
/* date2j() */
void
j2date
(
int
jd
,
int
*
year
,
int
*
month
,
int
*
day
)
{
int
j
,
y
,
m
,
d
;
#if USE_FLIEGEL
int
i
,
l
,
n
;
l
=
jd
+
68569
;
n
=
(
4
*
l
)
/
146097
;
l
-=
(
146097
*
n
+
3
)
/
4
;
i
=
(
4000
*
(
l
+
1
))
/
1461001
;
l
+=
31
-
(
1461
*
i
)
/
4
;
j
=
(
80
*
l
)
/
2447
;
d
=
l
-
(
2447
*
j
)
/
80
;
l
=
j
/
11
;
m
=
(
j
+
2
)
-
(
12
*
l
);
y
=
100
*
(
n
-
49
)
+
i
+
l
;
#else
j
=
jd
-
1721119
;
y
=
(
4
*
j
-
1
)
/
146097
;
j
=
4
*
j
-
1
-
146097
*
y
;
d
=
j
/
4
;
j
=
(
4
*
d
+
3
)
/
1461
;
d
=
4
*
d
+
3
-
1461
*
j
;
d
=
(
d
+
4
)
/
4
;
m
=
(
5
*
d
-
3
)
/
153
;
d
=
5
*
d
-
3
-
153
*
m
;
d
=
(
d
+
5
)
/
5
;
y
=
100
*
y
+
j
;
if
(
m
<
10
)
{
m
+=
3
;
}
else
{
m
-=
9
;
y
++
;
};
#endif
*
year
=
y
;
*
month
=
m
;
*
day
=
d
;
return
;
}
/* j2date() */
int
j2day
(
int
date
)
{
int
day
;
day
=
(
date
+
1
)
%
7
;
return
(
day
);
}
/* j2day() */
DateTime
dt2local
(
DateTime
dt
,
int
timezone
)
{
dt
-=
timezone
;
dt
=
JROUND
(
dt
);
return
(
dt
);
}
/* dt2local() */
double
time2t
(
const
int
hour
,
const
int
min
,
const
double
sec
)
{
return
((((
hour
*
60
)
+
min
)
*
60
)
+
sec
);
}
/* time2t() */
void
dt2time
(
DateTime
jd
,
int
*
hour
,
int
*
min
,
double
*
sec
)
{
double
time
;
time
=
jd
;
*
hour
=
(
time
/
3600
);
time
-=
((
*
hour
)
*
3600
);
*
min
=
(
time
/
60
);
time
-=
((
*
min
)
*
60
);
*
sec
=
JROUND
(
time
);
return
;
}
/* dt2time() */
/*
* parse and convert date in timestr (the normal interface)
*
* Returns the number of seconds since epoch (J2000)
*/
#ifndef USE_POSIX_TIME
long
int
timezone
;
long
int
daylight
;
#endif
/* ParseDateTime()
* Break string into tokens based on a date/time context.
*/
int
ParseDateTime
(
char
*
timestr
,
char
*
lowstr
,
char
*
field
[],
int
ftype
[],
int
maxfields
,
int
*
numfields
)
{
int
nf
=
0
;
char
*
cp
=
timestr
;
char
*
lp
=
lowstr
;
#ifdef DATEDEBUG
printf
(
"ParseDateTime- input string is %s
\n
"
,
timestr
);
#endif
/* outer loop through fields */
while
(
*
cp
!=
'\0'
)
{
field
[
nf
]
=
lp
;
/* leading digit? then date or time */
if
(
isdigit
(
*
cp
))
{
*
lp
++
=
*
cp
++
;
while
(
isdigit
(
*
cp
))
*
lp
++
=
*
cp
++
;
/* time field? */
if
(
*
cp
==
':'
)
{
ftype
[
nf
]
=
DTK_TIME
;
while
(
isdigit
(
*
cp
)
||
(
*
cp
==
':'
)
||
(
*
cp
==
'.'
))
*
lp
++
=
*
cp
++
;
/* date field? allow embedded text month */
}
else
if
((
*
cp
==
'-'
)
||
(
*
cp
==
'/'
)
||
(
*
cp
==
'.'
))
{
ftype
[
nf
]
=
DTK_DATE
;
while
(
isalnum
(
*
cp
)
||
(
*
cp
==
'-'
)
||
(
*
cp
==
'/'
)
||
(
*
cp
==
'.'
))
*
lp
++
=
tolower
(
*
cp
++
);
/* otherwise, number only and will determine year, month, or day later */
}
else
{
ftype
[
nf
]
=
DTK_NUMBER
;
};
/* text? then date string, month, day of week, special, or timezone */
}
else
if
(
isalpha
(
*
cp
))
{
ftype
[
nf
]
=
DTK_STRING
;
*
lp
++
=
tolower
(
*
cp
++
);
while
(
isalpha
(
*
cp
))
*
lp
++
=
tolower
(
*
cp
++
);
/* full date string with leading text month? */
if
((
*
cp
==
'-'
)
||
(
*
cp
==
'/'
)
||
(
*
cp
==
'.'
))
{
ftype
[
nf
]
=
DTK_DATE
;
while
(
isdigit
(
*
cp
)
||
(
*
cp
==
'-'
)
||
(
*
cp
==
'/'
)
||
(
*
cp
==
'.'
))
*
lp
++
=
tolower
(
*
cp
++
);
};
/* skip leading spaces */
}
else
if
(
isspace
(
*
cp
))
{
cp
++
;
continue
;
/* sign? then special or numeric timezone */
}
else
if
((
*
cp
==
'+'
)
||
(
*
cp
==
'-'
))
{
*
lp
++
=
*
cp
++
;
/* soak up leading whitespace */
while
(
isspace
(
*
cp
))
cp
++
;
/* numeric timezone? */
if
(
isdigit
(
*
cp
))
{
ftype
[
nf
]
=
DTK_TZ
;
*
lp
++
=
*
cp
++
;
while
(
isdigit
(
*
cp
)
||
(
*
cp
==
':'
))
*
lp
++
=
*
cp
++
;
/* special? */
}
else
if
(
isalpha
(
*
cp
))
{
ftype
[
nf
]
=
DTK_SPECIAL
;
*
lp
++
=
tolower
(
*
cp
++
);
while
(
isalpha
(
*
cp
))
*
lp
++
=
tolower
(
*
cp
++
);
/* otherwise something wrong... */
}
else
{
return
-
1
;
};
/* ignore punctuation but use as delimiter */
}
else
if
(
ispunct
(
*
cp
))
{
cp
++
;
continue
;
}
else
{
return
-
1
;
};
/* force in a delimiter */
*
lp
++
=
'\0'
;
nf
++
;
if
(
nf
>
MAXDATEFIELDS
)
{
return
-
1
;
};
#ifdef DATEDEBUG
printf
(
"ParseDateTime- set field[%d] to %s type %d
\n
"
,
(
nf
-
1
),
field
[
nf
-
1
],
ftype
[
nf
-
1
]);
#endif
};
*
numfields
=
nf
;
return
0
;
}
/* ParseDateTime() */
/* DecodeDateTime()
* Interpret previously parsed fields for general date and time.
* Return 0 if full date, 1 if only time, and -1 if problems.
* External format(s):
* "<weekday> <month>-<day>-<year> <hour>:<minute>:<second>"
* "Fri Feb-7-1997 15:23:27"
* "Feb-7-1997 15:23:27"
* "2-7-1997 15:23:27"
* "1997-2-7 15:23:27"
* "1997.038 15:23:27" (day of year 1-366)
* Also supports input in compact time:
* "970207 152327"
* "97038 152327"
*/
int
DecodeDateTime
(
char
*
field
[],
int
ftype
[],
int
nf
,
int
*
dtype
,
struct
tm
*
tm
,
double
*
fsec
,
int
*
tzp
)
{
int
fmask
=
0
,
tmask
,
type
;
int
i
;
int
flen
,
val
;
int
mer
=
HR24
;
int
bc
=
FALSE
;
*
dtype
=
DTK_DATE
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
tm
->
tm_isdst
=
-
1
;
/* don't know daylight savings time status apriori */
if
(
tzp
!=
NULL
)
*
tzp
=
timezone
;
for
(
i
=
0
;
i
<
nf
;
i
++
)
{
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- field[%d] is %s (type %d)
\n
"
,
i
,
field
[
i
],
ftype
[
i
]);
#endif
switch
(
ftype
[
i
])
{
case
DTK_DATE
:
if
(
DecodeDate
(
field
[
i
],
fmask
,
&
tmask
,
tm
)
!=
0
)
return
-
1
;
break
;
case
DTK_TIME
:
if
(
DecodeTime
(
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
break
;
case
DTK_TZ
:
if
(
tzp
==
NULL
)
return
-
1
;
if
(
DecodeTimezone
(
field
[
i
],
tzp
)
!=
0
)
return
-
1
;
tmask
=
DTK_M
(
TZ
);
break
;
case
DTK_NUMBER
:
flen
=
strlen
(
field
[
i
]);
if
(
flen
>
4
)
{
if
(
DecodeNumberField
(
flen
,
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
}
else
{
if
(
DecodeNumber
(
flen
,
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
};
break
;
case
DTK_STRING
:
case
DTK_SPECIAL
:
type
=
DecodeSpecial
(
i
,
field
[
i
],
&
val
);
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- special field[%d] %s type=%d value=%d
\n
"
,
i
,
field
[
i
],
type
,
val
);
#endif
if
(
type
==
IGNORE
)
continue
;
tmask
=
DTK_M
(
type
);
switch
(
type
)
{
case
RESERV
:
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- RESERV field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
switch
(
val
)
{
case
DTK_NOW
:
tmask
=
(
DTK_DATE_M
|
DTK_TIME_M
);
*
dtype
=
DTK_DATE
;
GetCurrentTime
(
tm
);
break
;
case
DTK_YESTERDAY
:
tmask
=
DTK_DATE_M
;
*
dtype
=
DTK_DATE
;
GetCurrentTime
(
tm
);
j2date
(
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
-
1
),
&
tm
->
tm_year
,
&
tm
->
tm_mon
,
&
tm
->
tm_mday
);
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
break
;
case
DTK_TODAY
:
tmask
=
DTK_DATE_M
;
*
dtype
=
DTK_DATE
;
GetCurrentTime
(
tm
);
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
break
;
case
DTK_TOMORROW
:
tmask
=
DTK_DATE_M
;
*
dtype
=
DTK_DATE
;
GetCurrentTime
(
tm
);
j2date
(
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
+
1
),
&
tm
->
tm_year
,
&
tm
->
tm_mon
,
&
tm
->
tm_mday
);
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
break
;
case
DTK_ZULU
:
tmask
=
(
DTK_TIME_M
|
DTK_M
(
TZ
));
*
dtype
=
DTK_DATE
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
*
tzp
=
0
;
break
;
default:
*
dtype
=
val
;
};
break
;
case
MONTH
:
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- month field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
tm
->
tm_mon
=
val
;
break
;
case
DTZ
:
tm
->
tm_isdst
=
0
;
/* FALLTHROUGH! */
case
TZ
:
if
(
tzp
==
NULL
)
return
-
1
;
*
tzp
=
val
*
60
;
break
;
case
IGNORE
:
break
;
case
AMPM
:
mer
=
val
;
break
;
case
ADBC
:
bc
=
(
val
==
BC
);
break
;
case
DOW
:
tm
->
tm_wday
=
val
;
break
;
default:
return
-
1
;
};
break
;
default:
return
-
1
;
};
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- field[%d] %s (%08x/%08x) value is %d
\n
"
,
i
,
field
[
i
],
fmask
,
tmask
,
val
);
#endif
if
(
tmask
&
fmask
)
return
-
1
;
fmask
|=
tmask
;
};
/* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
if
(
bc
)
tm
->
tm_year
=
-
(
tm
->
tm_year
-
1
);
if
((
mer
!=
HR24
)
&&
(
tm
->
tm_hour
>
12
))
return
-
1
;
if
(
mer
==
PM
)
tm
->
tm_hour
+=
12
;
#ifdef DATEDEBUG
printf
(
"DecodeDateTime- mask %08x (%08x)"
,
fmask
,
DTK_DATE_M
);
printf
(
" set y%04d m%02d d%02d"
,
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
);
printf
(
" %02d:%02d:%02d
\n
"
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
);
#endif
if
((
*
dtype
==
DTK_DATE
)
&&
((
fmask
&
DTK_DATE_M
)
!=
DTK_DATE_M
))
return
(((
fmask
&
DTK_TIME_M
)
==
DTK_TIME_M
)
?
1
:
-
1
);
return
0
;
}
/* DecodeDateTime() */
/* DecodeTimeOnly()
* Interpret parsed string as time fields only.
*/
int
DecodeTimeOnly
(
char
*
field
[],
int
ftype
[],
int
nf
,
int
*
dtype
,
struct
tm
*
tm
,
double
*
fsec
)
{
int
fmask
,
tmask
,
type
;
int
i
;
int
flen
,
val
;
int
mer
=
HR24
;
*
dtype
=
DTK_TIME
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
tm
->
tm_isdst
=
-
1
;
/* don't know daylight savings time status apriori */
fmask
=
DTK_DATE_M
;
for
(
i
=
0
;
i
<
nf
;
i
++
)
{
#ifdef DATEDEBUG
printf
(
"DecodeTimeOnly- field[%d] is %s (type %d)
\n
"
,
i
,
field
[
i
],
ftype
[
i
]);
#endif
switch
(
ftype
[
i
])
{
case
DTK_TIME
:
if
(
DecodeTime
(
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
break
;
case
DTK_NUMBER
:
flen
=
strlen
(
field
[
i
]);
if
(
DecodeNumberField
(
flen
,
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
break
;
case
DTK_STRING
:
case
DTK_SPECIAL
:
type
=
DecodeSpecial
(
i
,
field
[
i
],
&
val
);
#ifdef DATEDEBUG
printf
(
"DecodeTimeOnly- special field[%d] %s type=%d value=%d
\n
"
,
i
,
field
[
i
],
type
,
val
);
#endif
if
(
type
==
IGNORE
)
continue
;
tmask
=
DTK_M
(
type
);
switch
(
type
)
{
case
RESERV
:
#ifdef DATEDEBUG
printf
(
"DecodeTimeOnly- RESERV field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
switch
(
val
)
{
case
DTK_NOW
:
tmask
=
DTK_TIME_M
;
*
dtype
=
DTK_TIME
;
GetCurrentTime
(
tm
);
break
;
case
DTK_ZULU
:
tmask
=
(
DTK_TIME_M
|
DTK_M
(
TZ
));
*
dtype
=
DTK_TIME
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
tm
->
tm_isdst
=
-
1
;
break
;
default:
return
-
1
;
};
break
;
case
IGNORE
:
break
;
case
AMPM
:
mer
=
val
;
break
;
default:
return
-
1
;
};
break
;
default:
return
-
1
;
};
if
(
tmask
&
fmask
)
return
-
1
;
fmask
|=
tmask
;
#ifdef DATEDEBUG
printf
(
"DecodeTimeOnly- field[%d] %s value is %d
\n
"
,
i
,
field
[
i
],
val
);
#endif
};
#ifdef DATEDEBUG
printf
(
"DecodeTimeOnly- mask %08x (%08x)"
,
fmask
,
DTK_TIME_M
);
printf
(
" %02d:%02d:%02d (%f)
\n
"
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
,
*
fsec
);
#endif
if
((
mer
!=
HR24
)
&&
(
tm
->
tm_hour
>
12
))
return
-
1
;
if
(
mer
==
PM
)
tm
->
tm_hour
+=
12
;
if
((
fmask
&
DTK_TIME_M
)
!=
DTK_TIME_M
)
return
-
1
;
return
0
;
}
/* DecodeTimeOnly() */
/* DecodeDate()
* Decode date string which includes delimiters.
* Insist on a complete set of fields.
*/
int
DecodeDate
(
char
*
str
,
int
fmask
,
int
*
tmask
,
struct
tm
*
tm
)
{
double
fsec
;
int
nf
=
0
;
int
i
,
len
;
int
type
,
val
,
dmask
=
0
;
char
*
field
[
MAXDATEFIELDS
];
/* parse this string... */
while
((
*
str
!=
'\0'
)
&&
(
nf
<
MAXDATEFIELDS
))
{
/* skip field separators */
while
(
!
isalnum
(
*
str
))
str
++
;
field
[
nf
]
=
str
;
if
(
isdigit
(
*
str
))
{
while
(
isdigit
(
*
str
))
str
++
;
}
else
if
(
isalpha
(
*
str
))
{
while
(
isalpha
(
*
str
))
str
++
;
};
if
(
*
str
!=
'\0'
)
*
str
++
=
'\0'
;
nf
++
;
};
/* don't allow too many fields */
if
(
nf
>
3
)
return
-
1
;
*
tmask
=
0
;
for
(
i
=
0
;
i
<
nf
;
i
++
)
{
str
=
field
[
i
];
len
=
strlen
(
str
);
if
(
len
<=
0
)
return
-
1
;
if
(
isdigit
(
*
str
))
{
if
(
DecodeNumber
(
len
,
str
,
fmask
,
&
dmask
,
tm
,
&
fsec
)
!=
0
)
return
-
1
;
}
else
if
(
isalpha
(
*
str
))
{
type
=
DecodeSpecial
(
i
,
field
[
i
],
&
val
);
if
(
type
==
IGNORE
)
continue
;
dmask
=
DTK_M
(
type
);
switch
(
type
)
{
case
YEAR
:
#ifdef DATEDEBUG
printf
(
"DecodeDate- year field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
tm
->
tm_mon
=
val
;
break
;
case
MONTH
:
#ifdef DATEDEBUG
printf
(
"DecodeDate- month field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
tm
->
tm_mon
=
val
;
break
;
case
DAY
:
#ifdef DATEDEBUG
printf
(
"DecodeDate- month field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
tm
->
tm_mon
=
val
;
break
;
default:
#ifdef DATEDEBUG
printf
(
"DecodeDate- illegal field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
return
-
1
;
};
};
if
(
fmask
&
dmask
)
return
-
1
;
fmask
|=
dmask
;
*
tmask
|=
dmask
;
};
return
0
;
}
/* DecodeDate() */
/* DecodeTime()
* Decode time string which includes delimiters.
*/
int
DecodeTime
(
char
*
str
,
int
fmask
,
int
*
tmask
,
struct
tm
*
tm
,
double
*
fsec
)
{
char
*
cp
;
*
tmask
=
DTK_TIME_M
;
tm
->
tm_hour
=
strtol
(
str
,
&
cp
,
10
);
if
(
*
cp
!=
':'
)
return
-
1
;
str
=
cp
+
1
;
tm
->
tm_min
=
strtol
(
str
,
&
cp
,
10
);
if
(
*
cp
==
'\0'
)
{
tm
->
tm_sec
=
0
;
*
fsec
=
0
;
}
else
if
(
*
cp
!=
':'
)
{
return
-
1
;
}
else
{
str
=
cp
+
1
;
tm
->
tm_sec
=
strtol
(
str
,
&
cp
,
10
);
if
(
*
cp
==
'\0'
)
{
*
fsec
=
0
;
}
else
if
(
*
cp
==
'.'
)
{
str
=
cp
;
*
fsec
=
strtod
(
str
,
&
cp
);
if
(
cp
==
str
)
return
-
1
;
}
else
{
return
-
1
;
};
};
return
0
;
}
/* DecodeTime() */
/* DecodeNumber()
* Interpret numeric field as a date value in context.
*/
int
DecodeNumber
(
int
flen
,
char
*
str
,
int
fmask
,
int
*
tmask
,
struct
tm
*
tm
,
double
*
fsec
)
{
int
val
;
char
*
cp
;
*
tmask
=
0
;
val
=
strtol
(
str
,
&
cp
,
10
);
if
(
cp
==
str
)
return
-
1
;
if
(
*
cp
==
'.'
)
{
*
fsec
=
strtod
(
cp
,
&
cp
);
if
(
*
cp
!=
'\0'
)
return
-
1
;
};
#ifdef DATEDEBUG
printf
(
"DecodeNumber- %s is %d fmask=%08x tmask=%08x
\n
"
,
str
,
val
,
fmask
,
*
tmask
);
#endif
/* enough digits to be unequivocal year? */
if
(
flen
==
4
)
{
#ifdef DATEDEBUG
printf
(
"DecodeNumber- match %d (%s) as year
\n
"
,
val
,
str
);
#endif
*
tmask
=
DTK_M
(
YEAR
);
tm
->
tm_year
=
val
;
/* special case day of year? */
}
else
if
((
flen
==
3
)
&&
(
fmask
&
DTK_M
(
YEAR
))
&&
((
val
>=
1
)
&&
(
val
<=
366
)))
{
*
tmask
=
(
DTK_M
(
DOY
)
|
DTK_M
(
MONTH
)
|
DTK_M
(
DAY
));
tm
->
tm_yday
=
val
;
j2date
((
date2j
(
tm
->
tm_year
,
1
,
1
)
+
tm
->
tm_yday
-
1
),
&
tm
->
tm_year
,
&
tm
->
tm_mon
,
&
tm
->
tm_mday
);
/* already have year? then could be month */
}
else
if
((
fmask
&&
DTK_M
(
YEAR
))
&&
(
!
(
fmask
&
DTK_M
(
MONTH
)))
&&
((
val
>=
1
)
&&
(
val
<=
12
)))
{
#ifdef DATEDEBUG
printf
(
"DecodeNumber- match %d (%s) as month
\n
"
,
val
,
str
);
#endif
*
tmask
=
DTK_M
(
MONTH
);
tm
->
tm_mon
=
val
;
/* no year and EuroDates enabled? then could be day */
#if USE_EURODATES
}
else
if
((
EuroDates
||
(
fmask
&
DTK_M
(
MONTH
)))
#else
}
else
if
((
fmask
&
DTK_M
(
MONTH
))
#endif
&&
(
!
((
fmask
&
DTK_M
(
YEAR
))
&&
(
fmask
&
DTK_M
(
DAY
))))
&&
((
val
>=
1
)
&&
(
val
<=
31
)))
{
#ifdef DATEDEBUG
printf
(
"DecodeNumber- match %d (%s) as day
\n
"
,
val
,
str
);
#endif
*
tmask
=
DTK_M
(
DAY
);
tm
->
tm_mday
=
val
;
}
else
if
((
!
(
fmask
&
DTK_M
(
MONTH
)))
&&
((
val
>=
1
)
&&
(
val
<=
12
)))
{
#ifdef DATEDEBUG
printf
(
"DecodeNumber- (2) match %d (%s) as month
\n
"
,
val
,
str
);
#endif
*
tmask
=
DTK_M
(
MONTH
);
tm
->
tm_mon
=
val
;
}
else
if
(
!
(
fmask
&
DTK_M
(
YEAR
)))
{
#ifdef DATEDEBUG
printf
(
"DecodeNumber- (2) match %d (%s) as year
\n
"
,
val
,
str
);
#endif
*
tmask
=
DTK_M
(
YEAR
);
tm
->
tm_year
=
val
;
if
(
tm
->
tm_year
<
70
)
{
tm
->
tm_year
+=
2000
;
}
else
if
(
tm
->
tm_year
<
100
)
{
tm
->
tm_year
+=
1900
;
};
}
else
{
return
-
1
;
};
return
0
;
}
/* DecodeNumber() */
/* DecodeNumberField()
* Interpret numeric string as a concatenated date field.
*/
int
DecodeNumberField
(
int
len
,
char
*
str
,
int
fmask
,
int
*
tmask
,
struct
tm
*
tm
,
double
*
fsec
)
{
char
*
cp
;
/* yyyymmdd? */
if
(
len
==
8
)
{
#ifdef DATEDEBUG
printf
(
"DecodeNumberField- %s is 8 character date fmask=%08x tmask=%08x
\n
"
,
str
,
fmask
,
*
tmask
);
#endif
*
tmask
=
DTK_DATE_M
;
tm
->
tm_mday
=
atoi
(
str
+
6
);
*
(
str
+
6
)
=
'\0'
;
tm
->
tm_mon
=
atoi
(
str
+
4
);
*
(
str
+
4
)
=
'\0'
;
tm
->
tm_year
=
atoi
(
str
+
0
);
/* yymmdd or hhmmss? */
}
else
if
(
len
==
6
)
{
#ifdef DATEDEBUG
printf
(
"DecodeNumberField- %s is 6 characters fmask=%08x tmask=%08x
\n
"
,
str
,
fmask
,
*
tmask
);
#endif
if
(
fmask
&
DTK_DATE_M
)
{
#ifdef DATEDEBUG
printf
(
"DecodeNumberField- %s is time field fmask=%08x tmask=%08x
\n
"
,
str
,
fmask
,
*
tmask
);
#endif
*
tmask
=
DTK_TIME_M
;
tm
->
tm_sec
=
atoi
(
str
+
4
);
*
(
str
+
4
)
=
'\0'
;
tm
->
tm_min
=
atoi
(
str
+
2
);
*
(
str
+
2
)
=
'\0'
;
tm
->
tm_hour
=
atoi
(
str
+
0
);
}
else
{
#ifdef DATEDEBUG
printf
(
"DecodeNumberField- %s is date field fmask=%08x tmask=%08x
\n
"
,
str
,
fmask
,
*
tmask
);
#endif
*
tmask
=
DTK_DATE_M
;
tm
->
tm_mday
=
atoi
(
str
+
4
);
*
(
str
+
4
)
=
'\0'
;
tm
->
tm_mon
=
atoi
(
str
+
2
);
*
(
str
+
2
)
=
'\0'
;
tm
->
tm_year
=
atoi
(
str
+
0
);
};
}
else
if
(
index
(
str
,
'.'
)
!=
NULL
)
{
#ifdef DATEDEBUG
printf
(
"DecodeNumberField- %s is time field fmask=%08x tmask=%08x
\n
"
,
str
,
fmask
,
*
tmask
);
#endif
*
tmask
=
DTK_TIME_M
;
tm
->
tm_sec
=
strtod
(
(
str
+
4
),
&
cp
);
if
(
cp
==
(
str
+
4
))
return
-
1
;
if
(
*
cp
==
'.'
)
{
*
fsec
=
strtod
(
cp
,
NULL
);
};
*
(
str
+
4
)
=
'\0'
;
tm
->
tm_min
=
strtod
(
(
str
+
2
),
&
cp
);
*
(
str
+
2
)
=
'\0'
;
tm
->
tm_hour
=
strtod
(
(
str
+
0
),
&
cp
);
}
else
{
return
-
1
;
};
return
0
;
}
/* DecodeNumberField() */
/* DecodeTimezone()
* Interpret string as a numeric timezone.
*/
int
DecodeTimezone
(
char
*
str
,
int
*
tzp
)
{
int
tz
;
int
hr
,
min
;
char
*
cp
;
int
len
;
/* assume leading character is "+" or "-" */
hr
=
strtol
(
(
str
+
1
),
&
cp
,
10
);
/* explicit delimiter? */
if
(
*
cp
==
':'
)
{
min
=
strtol
(
(
cp
+
1
),
&
cp
,
10
);
/* otherwise, might have run things together... */
}
else
if
((
*
cp
==
'\0'
)
&&
((
len
=
strlen
(
str
))
>
3
))
{
min
=
strtol
(
(
str
+
len
-
2
),
&
cp
,
10
);
*
(
str
+
len
-
2
)
=
'\0'
;
hr
=
strtol
(
(
str
+
1
),
&
cp
,
10
);
}
else
{
min
=
0
;
};
tz
=
(
hr
*
60
+
min
)
*
60
;
if
(
*
str
==
'-'
)
tz
=
-
tz
;
*
tzp
=
-
tz
;
return
(
*
cp
!=
'\0'
);
}
/* DecodeTimezone() */
/* DecodeSpecial()
* Decode text string using lookup table.
* Implement a cache lookup since it is likely that dates
* will be related in format.
*/
int
DecodeSpecial
(
int
field
,
char
*
lowtoken
,
int
*
val
)
{
int
type
;
datetkn
*
tp
;
#if USE_DATE_CACHE
if
((
datecache
[
field
]
!=
NULL
)
&&
(
strncmp
(
lowtoken
,
datecache
[
field
]
->
token
,
TOKMAXLEN
)
==
0
))
{
tp
=
datecache
[
field
];
}
else
{
#endif
tp
=
datebsearch
(
lowtoken
,
datetktbl
,
szdatetktbl
);
#if USE_DATE_CACHE
};
datecache
[
field
]
=
tp
;
#endif
if
(
tp
==
NULL
)
{
type
=
IGNORE
;
*
val
=
0
;
}
else
{
type
=
tp
->
type
;
if
((
type
==
TZ
)
||
(
type
==
DTZ
))
{
*
val
=
FROMVAL
(
tp
);
}
else
{
*
val
=
tp
->
value
;
};
};
return
(
type
);
}
/* DecodeSpecial() */
/* DecodeDateDelta()
* Interpret previously parsed fields for general time interval.
* Return 0 if decoded and -1 if problems.
*
* If code is changed to read fields from first to last,
* then use READ_FORWARD-bracketed code to allow sign
* to persist to subsequent unsigned fields.
*/
int
DecodeDateDelta
(
char
*
field
[],
int
ftype
[],
int
nf
,
int
*
dtype
,
struct
tm
*
tm
,
double
*
fsec
)
{
int
is_before
=
FALSE
;
#if READ_FORWARD
int
is_neg
=
FALSE
;
#endif
int
fmask
=
0
,
tmask
,
type
;
int
i
,
ii
;
int
flen
,
val
;
char
*
cp
;
double
sec
;
*
dtype
=
DTK_DELTA
;
type
=
DTK_SECOND
;
tm
->
tm_year
=
0
;
tm
->
tm_mon
=
0
;
tm
->
tm_mday
=
0
;
tm
->
tm_hour
=
0
;
tm
->
tm_min
=
0
;
tm
->
tm_sec
=
0
;
*
fsec
=
0
;
/* read through list forwards to pick up initial time fields, if any */
for
(
ii
=
0
;
ii
<
nf
;
ii
++
)
{
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- field[%d] is %s (type %d)
\n
"
,
ii
,
field
[
ii
],
ftype
[
ii
]);
#endif
if
(
ftype
[
ii
]
==
DTK_TIME
)
{
if
(
DecodeTime
(
field
[
ii
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
}
else
{
break
;
};
};
/* read through remaining list backwards to pick up units before values */
for
(
i
=
nf
-
1
;
i
>=
ii
;
i
--
)
{
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- field[%d] is %s (type %d)
\n
"
,
i
,
field
[
i
],
ftype
[
i
]);
#endif
switch
(
ftype
[
i
])
{
case
DTK_TIME
:
#if FALSE
if
(
DecodeTime
(
field
[
i
],
fmask
,
&
tmask
,
tm
,
fsec
)
!=
0
)
return
-
1
;
#endif
return
-
1
;
break
;
case
DTK_TZ
:
/* timezone is a token with a leading sign character */
#if READ_FORWARD
is_neg
=
(
*
field
[
i
]
==
'-'
);
#endif
case
DTK_NUMBER
:
val
=
strtol
(
field
[
i
],
&
cp
,
10
);
#if READ_FORWARD
if
(
is_neg
&&
(
val
>
0
))
val
=
-
val
;
#endif
if
(
*
cp
==
'.'
)
{
*
fsec
=
strtod
(
cp
,
NULL
);
if
(
val
<
0
)
*
fsec
=
-
(
*
fsec
);
};
flen
=
strlen
(
field
[
i
]);
tmask
=
DTK_M
(
type
);
switch
(
type
)
{
case
DTK_MICROSEC
:
*
fsec
+=
(
val
*
1e-6
);
break
;
case
DTK_MILLISEC
:
*
fsec
+=
(
val
*
1e-3
);
break
;
case
DTK_SECOND
:
tm
->
tm_sec
+=
val
;
break
;
case
DTK_MINUTE
:
tm
->
tm_min
+=
val
;
break
;
case
DTK_HOUR
:
tm
->
tm_hour
+=
val
;
break
;
case
DTK_DAY
:
tm
->
tm_mday
+=
val
;
break
;
case
DTK_WEEK
:
tm
->
tm_mday
+=
val
*
7
;
break
;
case
DTK_MONTH
:
tm
->
tm_mon
+=
val
;
break
;
case
DTK_YEAR
:
tm
->
tm_year
+=
val
;
break
;
case
DTK_DECADE
:
tm
->
tm_year
+=
val
*
10
;
break
;
case
DTK_CENTURY
:
tm
->
tm_year
+=
val
*
100
;
break
;
case
DTK_MILLENIUM
:
tm
->
tm_year
+=
val
*
1000
;
break
;
default:
return
-
1
;
};
break
;
case
DTK_STRING
:
case
DTK_SPECIAL
:
type
=
DecodeUnits
(
i
,
field
[
i
],
&
val
);
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- special field[%d] %s type=%d value=%d
\n
"
,
i
,
field
[
i
],
type
,
val
);
#endif
if
(
type
==
IGNORE
)
continue
;
tmask
=
0
;
/* DTK_M(type); */
switch
(
type
)
{
case
UNITS
:
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- UNITS field %s value is %d
\n
"
,
field
[
i
],
val
);
#endif
type
=
val
;
break
;
case
AGO
:
is_before
=
TRUE
;
type
=
val
;
break
;
case
RESERV
:
type
=
(
DTK_DATE_M
||
DTK_TIME_M
);
*
dtype
=
val
;
break
;
default:
return
-
1
;
};
break
;
default:
return
-
1
;
};
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- (%08x/%08x) field[%d] %s value is %d
\n
"
,
fmask
,
tmask
,
i
,
field
[
i
],
val
);
#endif
if
(
tmask
&
fmask
)
return
-
1
;
fmask
|=
tmask
;
};
if
(
*
fsec
!=
0
)
{
*
fsec
=
modf
(
*
fsec
,
&
sec
);
tm
->
tm_sec
+=
sec
;
};
if
(
is_before
)
{
*
fsec
=
-
(
*
fsec
);
tm
->
tm_sec
=
-
(
tm
->
tm_sec
);
tm
->
tm_min
=
-
(
tm
->
tm_min
);
tm
->
tm_hour
=
-
(
tm
->
tm_hour
);
tm
->
tm_mday
=
-
(
tm
->
tm_mday
);
tm
->
tm_mon
=
-
(
tm
->
tm_mon
);
tm
->
tm_year
=
-
(
tm
->
tm_year
);
};
#ifdef DATEDEBUG
printf
(
"DecodeDateDelta- mask %08x (%08x)"
,
fmask
,
DTK_DATE_M
);
printf
(
" set y%04d m%02d d%02d"
,
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
);
printf
(
" %02d:%02d:%02d
\n
"
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
);
#endif
/* ensure that at least one time field has been found */
return
((
fmask
!=
0
)
?
0
:
-
1
);
}
/* DecodeDateDelta() */
/* 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 USE_DATE_CACHE
if
((
deltacache
[
field
]
!=
NULL
)
&&
(
strncmp
(
lowtoken
,
deltacache
[
field
]
->
token
,
TOKMAXLEN
)
==
0
))
{
tp
=
deltacache
[
field
];
}
else
{
#endif
tp
=
datebsearch
(
lowtoken
,
deltatktbl
,
szdeltatktbl
);
#if USE_DATE_CACHE
};
deltacache
[
field
]
=
tp
;
#endif
if
(
tp
==
NULL
)
{
type
=
IGNORE
;
*
val
=
0
;
}
else
{
type
=
tp
->
type
;
if
((
type
==
TZ
)
||
(
type
==
DTZ
))
{
*
val
=
FROMVAL
(
tp
);
}
else
{
*
val
=
tp
->
value
;
};
};
return
(
type
);
}
/* DecodeUnits() */
/*
* Binary search -- from Knuth (6.2.1) Algorithm B. Special case like this
* is WAY faster than the generic bsearch().
*/
datetkn
*
datebsearch
(
char
*
key
,
datetkn
*
base
,
unsigned
int
nel
)
{
register
datetkn
*
last
=
base
+
nel
-
1
,
*
position
;
register
int
result
;
while
(
last
>=
base
)
{
position
=
base
+
((
last
-
base
)
>>
1
);
result
=
key
[
0
]
-
position
->
token
[
0
];
if
(
result
==
0
)
{
result
=
strncmp
(
key
,
position
->
token
,
TOKMAXLEN
);
if
(
result
==
0
)
return
position
;
}
if
(
result
<
0
)
last
=
position
-
1
;
else
base
=
position
+
1
;
}
return
NULL
;
}
/***************************************************************************/
/***************************************************************************/
/***************************************************************************/
#if FALSE
#ifndef PALLOCTYPE
#define PALLOCTYPE(p) palloc(sizeof(p))
#endif
#endif
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
};
#if FALSE
int
EncodeMonth
(
int
mon
,
char
*
str
);
int
EncodeMonth
(
int
mon
,
char
*
str
)
{
strcpy
(
str
,
months
[
mon
-
1
]);
return
(
TRUE
);
}
/* EncodeMonth() */
#endif
#define EncodeMonth(m,s) strcpy(s,months[m-1])
int
EncodeSpecialDateTime
(
DateTime
*
dt
,
char
*
str
)
{
if
(
DATETIME_IS_RESERVED
(
dt
))
{
if
(
DATETIME_IS_INVALID
(
dt
))
{
strcpy
(
str
,
INVALID
);
}
else
if
(
DATETIME_IS_NOBEGIN
(
dt
))
{
strcpy
(
str
,
EARLY
);
}
else
if
(
DATETIME_IS_NOEND
(
dt
))
{
strcpy
(
str
,
LATE
);
}
else
if
(
DATETIME_IS_CURRENT
(
dt
))
{
strcpy
(
str
,
DCURRENT
);
}
else
if
(
DATETIME_IS_EPOCH
(
dt
))
{
strcpy
(
str
,
EPOCH
);
}
else
{
#ifdef DATEDEBUG
printf
(
"EncodeSpecialDateTime- unrecognized date
\n
"
);
#endif
strcpy
(
str
,
INVALID
);
};
return
(
TRUE
);
};
return
(
FALSE
);
}
/* EncodeSpecialDateTime() */
int
EncodePostgresDate
(
struct
tm
*
tm
,
double
fsec
,
char
*
str
)
{
char
mabbrev
[
4
],
dabbrev
[
4
];
int
day
;
double
sec
;
char
buf
[
MAXDATELEN
];
sec
=
(
tm
->
tm_sec
+
fsec
);
tm
->
tm_isdst
=
-
1
;
#ifdef DATEDEBUG
printf
(
"EncodePostgresDate- timezone is %s/%s; offset is %ld; daylight is %d
\n
"
,
tzname
[
0
],
tzname
[
1
],
timezone
,
daylight
);
#endif
day
=
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
);
#ifdef DATEDEBUG
printf
(
"EncodePostgresDate- day is %d
\n
"
,
day
);
#endif
tm
->
tm_wday
=
j2day
(
day
);
strncpy
(
dabbrev
,
days
[
tm
->
tm_wday
],
3
);
dabbrev
[
3
]
=
'\0'
;
if
((
tm
->
tm_mon
<
1
)
||
(
tm
->
tm_mon
>
12
))
return
-
1
;
strcpy
(
mabbrev
,
months
[
tm
->
tm_mon
-
1
]);
if
(
EuroDates
)
{
sprintf
(
str
,
"%3s %02d/%02d/%04d %02d:%02d:%02d %s"
,
dabbrev
,
tm
->
tm_mday
,
tm
->
tm_mon
,
tm
->
tm_year
,
tm
->
tm_hour
,
tm
->
tm_min
,
(
int
)
rint
(
sec
),
tzname
[
0
]);
}
else
if
(
tm
->
tm_year
>
0
)
{
#if FALSE
sprintf
(
str
,
"%3s %3s %02d %02d:%02d:%02d %04d %s"
,
dabbrev
,
mabbrev
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
(
int
)
rint
(
sec
),
tm
->
tm_year
,
tzname
[
0
]);
#endif
sprintf
(
str
,
"%3s %3s %02d %02d:%02d:%5.2f %04d %s"
,
dabbrev
,
mabbrev
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
sec
,
tm
->
tm_year
,
tzname
[
0
]);
/* XXX brute-force fill in leading zero on seconds */
if
(
*
(
str
+
17
)
==
' '
)
*
(
str
+
17
)
=
'0'
;
}
else
{
sprintf
(
str
,
"%3s %3s %02d %02d:%02d:%02d %04d %s"
,
dabbrev
,
mabbrev
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
(
int
)
rint
(
sec
),
-
(
tm
->
tm_year
-
1
),
"BC"
);
};
#ifdef DATEDEBUG
printf
(
"EncodePostgresDate- date result is %s
\n
"
,
str
);
#endif
if
(
tm
->
tm_year
>=
1000
)
tm
->
tm_year
-=
1900
;
tm
->
tm_mon
-=
1
;
strftime
(
buf
,
sizeof
(
buf
),
"%y.%m.%d %H:%M:%S %Z"
,
tm
);
#if FALSE
time
=
mktime
(
tm
);
strftime
(
buf
,
sizeof
(
buf
),
"%y.%m.%d %H:%M:%S %Z"
,
localtime
(
&
time
));
strcpy
(
str
,
buf
);
#endif
#ifdef DATEDEBUG
printf
(
"EncodePostgresDate- strftime result is %s
\n
"
,
buf
);
#endif
return
(
TRUE
);
}
/* EncodePostgresDate() */
int
EncodePostgresSpan
(
struct
tm
*
tm
,
double
fsec
,
char
*
str
)
{
int
is_before
=
FALSE
;
int
is_nonzero
=
FALSE
;
char
*
cp
;
strcpy
(
str
,
"@"
);
cp
=
str
+
strlen
(
str
);
if
(
tm
->
tm_year
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_year
<
0
);
sprintf
(
cp
,
" %d year%s"
,
abs
(
tm
->
tm_year
),
((
abs
(
tm
->
tm_year
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
tm
->
tm_mon
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_mon
<
0
);
sprintf
(
cp
,
" %d mon%s"
,
abs
(
tm
->
tm_mon
),
((
abs
(
tm
->
tm_mon
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
tm
->
tm_mday
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_mday
<
0
);
sprintf
(
cp
,
" %d day%s"
,
abs
(
tm
->
tm_mday
),
((
abs
(
tm
->
tm_mday
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
tm
->
tm_hour
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_hour
<
0
);
sprintf
(
cp
,
" %d hour%s"
,
abs
(
tm
->
tm_hour
),
((
abs
(
tm
->
tm_hour
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
tm
->
tm_min
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_min
<
0
);
sprintf
(
cp
,
" %d min%s"
,
abs
(
tm
->
tm_min
),
((
abs
(
tm
->
tm_min
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
tm
->
tm_sec
!=
0
)
{
is_nonzero
=
TRUE
;
is_before
|=
(
tm
->
tm_sec
<
0
);
sprintf
(
cp
,
" %d sec%s"
,
abs
(
tm
->
tm_sec
),
((
abs
(
tm
->
tm_sec
)
!=
1
)
?
"s"
:
""
));
cp
+=
strlen
(
cp
);
};
if
(
!
is_nonzero
)
{
strcat
(
cp
,
" 0"
);
cp
+=
strlen
(
cp
);
};
if
(
is_before
)
{
strcat
(
cp
,
" ago"
);
cp
+=
strlen
(
cp
);
};
#ifdef DATEDEBUG
printf
(
"EncodePostgresSpan- result is %s
\n
"
,
str
);
#endif
return
0
;
}
/* EncodePostgresSpan() */
#if FALSE
/*----------------------------------------------------------
* Relational operators for JDATEs.
*---------------------------------------------------------*/
#define JDATElt(a,b) (((a).date < (b).date) || (((a).date == (b).date) && ((a).time < (b).time)))
#define JDATEle(a,b) (((a).date < (b).date) || (((a).date == (b).date) && ((a).time <= (b).time)))
#define JDATEeq(a,b) (((a).date == (b).date) && ((a).time == (b).time))
#define JDATEge(a,b) (((a).date > (b).date) || (((a).date == (b).date) && ((a).time >= (b).time)))
#define JDATEgt(a,b) (((a).date > (b).date) || (((a).date == (b).date) && ((a).time > (b).time)))
/* jintervals identical?
*/
bool
jinterval_same
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEeq
(
jinterval1
->
bdate
,
jinterval2
->
bdate
)
&&
JDATEeq
(
jinterval1
->
edate
,
jinterval2
->
edate
));
}
/* jinterval_overlap - does jinterval1 overlap jinterval2?
*/
bool
jinterval_overlap
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEle
(
jinterval1
->
bdate
,
jinterval2
->
edate
)
&&
JDATEge
(
jinterval1
->
edate
,
jinterval2
->
bdate
));
}
/* jinterval_overleft - is the right edge of jinterval1 to the left of
* the right edge of jinterval2?
*/
bool
jinterval_overleft
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEle
(
jinterval1
->
edate
,
jinterval2
->
edate
));
}
/* jinterval_left - is jinterval1 strictly left of jinterval2?
*/
bool
jinterval_left
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEle
(
jinterval1
->
edate
,
jinterval2
->
bdate
));
}
/* jinterval_right - is jinterval1 strictly right of jinterval2?
*/
bool
jinterval_right
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEge
(
jinterval1
->
edate
,
jinterval2
->
bdate
));
}
/* jinterval_overright - is the left edge of jinterval1 to the right of
* the left edge of jinterval2?
*/
bool
jinterval_overright
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEge
(
jinterval1
->
bdate
,
jinterval2
->
bdate
));
}
/* jinterval_contained - is jinterval1 contained by jinterval2?
*/
bool
jinterval_contained
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEge
(
jinterval1
->
bdate
,
jinterval2
->
bdate
)
&&
JDATEle
(
jinterval1
->
edate
,
jinterval2
->
edate
));
}
/* jinterval_contain - does jinterval1 contain jinterval2?
*/
bool
jinterval_contain
(
JINTERVAL
*
jinterval1
,
JINTERVAL
*
jinterval2
)
{
return
(
JDATEle
(
jinterval1
->
bdate
,
jinterval2
->
bdate
)
&&
JDATEge
(
jinterval1
->
edate
,
jinterval2
->
edate
));
}
/* jdate_relop - is jdate1 relop jdate2
*/
bool
jdate_lt
(
JDATE
*
jdate1
,
JDATE
*
jdate2
)
{
return
(
JDATElt
(
*
jdate1
,
*
jdate2
));
}
bool
jdate_gt
(
JDATE
*
jdate1
,
JDATE
*
jdate2
)
{
return
(
JDATEgt
(
*
jdate1
,
*
jdate2
));
}
bool
jdate_eq
(
JDATE
*
jdate1
,
JDATE
*
jdate2
)
{
return
(
JDATEeq
(
*
jdate1
,
*
jdate2
));
}
bool
jdate_le
(
JDATE
*
jdate1
,
JDATE
*
jdate2
)
{
return
(
JDATEle
(
*
jdate1
,
*
jdate2
));
}
bool
jdate_ge
(
JDATE
*
jdate1
,
JDATE
*
jdate2
)
{
return
(
JDATEge
(
*
jdate1
,
*
jdate2
));
}
#endif
/*----------------------------------------------------------
* "Arithmetic" operators on date/times.
* datetime_foo returns foo as an object (pointer) that
can be passed between languages.
* datetime_xx is an internal routine which returns the
* actual value.
*---------------------------------------------------------*/
/*----------------------------------------------------------
* Conversion operators.
*---------------------------------------------------------*/
TimeSpan
*
datetime_sub
(
DateTime
*
dt1
,
DateTime
*
dt2
)
{
TimeSpan
*
result
;
if
((
!
PointerIsValid
(
dt1
))
||
(
!
PointerIsValid
(
dt2
)))
return
NULL
;
if
(
!
PointerIsValid
(
result
=
PALLOCTYPE
(
TimeSpan
)))
elog
(
WARN
,
"Memory allocation failed, can't subtract dates"
,
NULL
);
#if USE_JULIAN_DAY
result
->
time
=
((
*
dt1
-
*
dt2
)
*
86400
);
result
->
month
=
0
;
#else
result
->
time
=
JROUND
(
*
dt1
-
*
dt2
);
result
->
month
=
0
;
#endif
return
(
result
);
}
/* datetime_sub() */
DateTime
*
datetime_add_span
(
DateTime
*
dt
,
TimeSpan
*
span
)
{
DateTime
*
result
;
double
date
,
time
;
int
year
,
mon
,
mday
;
if
((
!
PointerIsValid
(
dt
))
||
(
!
PointerIsValid
(
span
)))
return
NULL
;
if
(
!
PointerIsValid
(
result
=
PALLOCTYPE
(
DateTime
)))
elog
(
WARN
,
"Memory allocation failed, can't add dates"
,
NULL
);
#ifdef DATEDEBUG
printf
(
"date_add- add %f to %d %f
\n
"
,
*
dt
,
span
->
month
,
span
->
time
);
#endif
if
(
span
->
month
!=
0
)
{
#if USE_JULIAN_DAY
time
=
modf
(
*
dt
,
&
date
);
#else
time
=
JROUND
(
modf
(
(
*
dt
/
86400
),
&
date
)
*
86400
);
date
+=
date2j
(
2000
,
1
,
1
);
#endif
j2date
(
((
int
)
date
),
&
year
,
&
mon
,
&
mday
);
mon
+=
span
->
month
;
if
(
mon
>
12
)
{
year
+=
mon
/
12
;
mon
%=
12
;
};
#if USE_JULIAN_DAY
*
result
=
date2j
(
year
,
mon
,
mday
);
#else
*
result
=
((
date2j
(
year
,
mon
,
mday
)
-
date2j
(
2000
,
1
,
1
))
*
86400
);
#endif
*
result
+=
time
;
}
else
{
*
result
=
*
dt
;
};
#if USE_JULIAN_DAY
*
result
+=
(
span
->
time
/
86400
);
#else
*
result
=
JROUND
(
*
result
+
span
->
time
);
#endif
return
(
result
);
}
/* datetime_add_span() */
DateTime
*
datetime_sub_span
(
DateTime
*
dt
,
TimeSpan
*
span
)
{
DateTime
*
result
;
TimeSpan
tspan
;
if
((
!
PointerIsValid
(
dt
))
||
(
!
PointerIsValid
(
span
)))
return
NULL
;
tspan
.
month
=
-
span
->
month
;
tspan
.
time
=
-
span
->
time
;
result
=
datetime_add_span
(
dt
,
&
tspan
);
return
(
result
);
}
/* datetime_sub_span() */
/***********************************************************************
**
** Routines for time spans.
**
***********************************************************************/
/*----------------------------------------------------------
* Formatting and conversion routines.
*---------------------------------------------------------*/
/*----------------------------------------------------------
* "Arithmetic" operators on date/times.
* datetime_foo returns foo as an object (pointer) that
can be passed between languages.
* datetime_xx is an internal routine which returns the
* actual value.
*---------------------------------------------------------*/
/*----------------------------------------------------------
* Conversion operators.
*---------------------------------------------------------*/
TimeSpan
*
timespan_add
(
TimeSpan
*
span1
,
TimeSpan
*
span2
)
{
TimeSpan
*
result
;
if
((
!
PointerIsValid
(
span1
))
||
(
!
PointerIsValid
(
span2
)))
return
NULL
;
if
(
!
PointerIsValid
(
result
=
PALLOCTYPE
(
TimeSpan
)))
elog
(
WARN
,
"Memory allocation failed, can't add timespans"
,
NULL
);
result
->
month
=
(
span1
->
month
+
span2
->
month
);
result
->
time
=
JROUND
(
span1
->
time
+
span2
->
time
);
return
(
result
);
}
/* timespan_add() */
TimeSpan
*
timespan_sub
(
TimeSpan
*
span1
,
TimeSpan
*
span2
)
{
TimeSpan
*
result
;
if
((
!
PointerIsValid
(
span1
))
||
(
!
PointerIsValid
(
span2
)))
return
NULL
;
if
(
!
PointerIsValid
(
result
=
PALLOCTYPE
(
TimeSpan
)))
elog
(
WARN
,
"Memory allocation failed, can't subtract timespans"
,
NULL
);
result
->
month
=
(
span1
->
month
-
span2
->
month
);
result
->
time
=
JROUND
(
span1
->
time
-
span2
->
time
);
return
(
result
);
}
/* timespan_sub() */
src/backend/utils/adt/geo_ops.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.
1 1997/03/09 20:40:55 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.
2 1997/03/14 23:20:15 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
#include "postgres.h"
#include "postgres.h"
#include "utils/geo
-
decls.h"
#include "utils/geo
_
decls.h"
#include "utils/palloc.h"
#include "utils/palloc.h"
#define LDELIM '('
#define LDELIM '('
...
...
src/backend/utils/adt/geo_selfuncs.c
View file @
53d8be3b
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.
1 1997/03/09 20:40:57 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.
2 1997/03/14 23:20:20 scrappy
Exp $
*
*
* XXX These are totally bogus.
* XXX These are totally bogus.
*
*
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
#include "postgres.h"
#include "postgres.h"
#include "access/attnum.h"
#include "access/attnum.h"
#include "utils/geo
-
decls.h"
/* where function declarations go */
#include "utils/geo
_
decls.h"
/* where function declarations go */
#include "utils/palloc.h"
#include "utils/palloc.h"
#include "utils/builtins.h"
#include "utils/builtins.h"
...
...
src/backend/utils/adt/int.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.
3 1996/11/06 10:30:55
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.
4 1997/03/14 23:20:26
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -225,36 +225,36 @@ int16 i4toi2(int32 arg1)
...
@@ -225,36 +225,36 @@ int16 i4toi2(int32 arg1)
* intgt - returns 1 iff arg1 > arg2
* intgt - returns 1 iff arg1 > arg2
* intge - returns 1 iff arg1 >= arg2
* intge - returns 1 iff arg1 >= arg2
*/
*/
int32
int4eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
int4eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
int32
int4ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
bool
int4ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
int32
int4lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
bool
int4lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
int32
int4le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
bool
int4le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
int32
int4gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
bool
int4gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
int32
int4ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
bool
int4ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
int32
int2eq
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
int2eq
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
==
arg2
);
}
int32
int2ne
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
!=
arg2
);
}
bool
int2ne
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
!=
arg2
);
}
int32
int2lt
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
<
arg2
);
}
bool
int2lt
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
<
arg2
);
}
int32
int2le
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
<=
arg2
);
}
bool
int2le
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
<=
arg2
);
}
int32
int2gt
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
>
arg2
);
}
bool
int2gt
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
>
arg2
);
}
int32
int2ge
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
>=
arg2
);
}
bool
int2ge
(
int16
arg1
,
int16
arg2
)
{
return
(
arg1
>=
arg2
);
}
int32
int24eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
int24eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
int32
int24ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
bool
int24ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
int32
int24lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
bool
int24lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
int32
int24le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
bool
int24le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
int32
int24gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
bool
int24gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
int32
int24ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
bool
int24ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
int32
int42eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
bool
int42eq
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
==
arg2
);
}
int32
int42ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
bool
int42ne
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
!=
arg2
);
}
int32
int42lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
bool
int42lt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<
arg2
);
}
int32
int42le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
bool
int42le
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
<=
arg2
);
}
int32
int42gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
bool
int42gt
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>
arg2
);
}
int32
int42ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
bool
int42ge
(
int32
arg1
,
int32
arg2
)
{
return
(
arg1
>=
arg2
);
}
int32
keyfirsteq
(
int16
*
arg1
,
int16
arg2
)
{
return
(
*
arg1
==
arg2
);
}
bool
keyfirsteq
(
int16
*
arg1
,
int16
arg2
)
{
return
(
*
arg1
==
arg2
);
}
/*
/*
* int[24]pl - returns arg1 + arg2
* int[24]pl - returns arg1 + arg2
...
...
src/backend/utils/adt/nabstime.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.1
3 1997/01/27 01:51:2
1 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.1
4 1997/03/14 23:20:3
1 scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -22,494 +22,174 @@
...
@@ -22,494 +22,174 @@
#endif
#endif
#include "access/xact.h"
#include "access/xact.h"
#if USE_EURODATES
extern
int
EuroDates
;
#endif
#if FALSE
#define MAXDATELEN 47
#define MAXDATEFIELDS 25
#define MAXDATEFIELDS 25
#endif
#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\t')
/* this is fast but dirty. note the return's in the middle. */
#define GOBBLE_NUM(cp, c, x, ip) \
(c) = *(cp)++; \
if ((c) < '0' || (c) > '9') \
return -1;
/* missing digit */
\
(x) = (c) - '0'; \
(c) = *(cp)++; \
if ((c) >= '0' && (c) <= '9') { \
(x) = 10*(x) + (c) - '0'; \
(c) = *(cp)++; \
} \
if ((c) != ':' && (c) != '\0' && !ISSPACE(c)) \
return -1;
/* missing colon */
\
*(ip) = (x)
/* N.B.: no semi-colon here */
#define EPOCH 1970
#define DAYS_PER_400YRS (time_t)146097
#define DAYS_PER_4YRS (time_t)1461
#define SECS_PER_DAY 86400
#define SECS_PER_HOUR 3600
#define DIVBY4(n) ((n) >> 2)
#define YRNUM(c, y) (DIVBY4(DAYS_PER_400YRS*(c)) + DIVBY4(DAYS_PER_4YRS*(y)))
#define DAYNUM(c,y,mon,d) (YRNUM((c), (y)) + mdays[mon] + (d))
#define EPOCH_DAYNUM DAYNUM(19, 69, 10, 1)
/* really January 1, 1970 */
#define MIN_DAYNUM -24856
/* December 13, 1901 */
#define MIN_DAYNUM -24856
/* December 13, 1901 */
#define MAX_DAYNUM 24854
/* January 18, 2038 */
#define MAX_DAYNUM 24854
/* January 18, 2038 */
/* definitions for squeezing values into "value" */
#define ABS_SIGNBIT 0200
#define VALMASK 0177
#define NEG(n) ((n)|ABS_SIGNBIT)
#define SIGNEDCHAR(c) ((c)&ABS_SIGNBIT? -((c)&VALMASK): (c))
#define FROMVAL(tp) (-SIGNEDCHAR((tp)->value) * 10)
/* uncompress */
#define TOVAL(tp, v) ((tp)->value = ((v) < 0? NEG((-(v))/10): (v)/10))
#define IsLeapYear(yr) ((yr%4) == 0)
char
nmdays
[]
=
{
0
,
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
};
/* days since start of year. mdays[0] is March, mdays[11] is February */
static
short
mdays
[]
=
{
0
,
31
,
61
,
92
,
122
,
153
,
184
,
214
,
245
,
275
,
306
,
337
};
/* exports */
static
int
dtok_numparsed
;
/*
* to keep this table reasonably small, we divide the lexval for TZ and DTZ
* entries by 10 and truncate the text field at MAXTOKLEN characters.
* the text field is not guaranteed to be NUL-terminated.
*/
static
datetkn
datetktbl
[]
=
{
/* text token lexval */
{
"acsst"
,
DTZ
,
63
},
/* Cent. Australia */
{
"acst"
,
TZ
,
57
},
/* Cent. Australia */
{
"adt"
,
DTZ
,
NEG
(
18
)},
/* Atlantic Daylight Time */
{
"aesst"
,
DTZ
,
66
},
/* E. Australia */
{
"aest"
,
TZ
,
60
},
/* Australia Eastern Std Time */
{
"ahst"
,
TZ
,
60
},
/* Alaska-Hawaii Std Time */
{
"am"
,
AMPM
,
AM
},
{
"apr"
,
MONTH
,
4
},
{
"april"
,
MONTH
,
4
},
{
"ast"
,
TZ
,
NEG
(
24
)},
/* Atlantic Std Time (Canada) */
{
"at"
,
PG_IGNORE
,
0
},
/* "at" (throwaway) */
{
"aug"
,
MONTH
,
8
},
{
"august"
,
MONTH
,
8
},
{
"awsst"
,
DTZ
,
54
},
/* W. Australia */
{
"awst"
,
TZ
,
48
},
/* W. Australia */
{
"bst"
,
TZ
,
6
},
/* British Summer Time */
{
"bt"
,
TZ
,
18
},
/* Baghdad Time */
{
"cadt"
,
DTZ
,
63
},
/* Central Australian DST */
{
"cast"
,
TZ
,
57
},
/* Central Australian ST */
{
"cat"
,
TZ
,
NEG
(
60
)},
/* Central Alaska Time */
{
"cct"
,
TZ
,
48
},
/* China Coast */
{
"cdt"
,
DTZ
,
NEG
(
30
)},
/* Central Daylight Time */
{
"cet"
,
TZ
,
6
},
/* Central European Time */
{
"cetdst"
,
DTZ
,
12
},
/* Central European Dayl.Time */
{
"cst"
,
TZ
,
NEG
(
36
)},
/* Central Standard Time */
{
"dec"
,
MONTH
,
12
},
{
"decemb"
,
MONTH
,
12
},
{
"dnt"
,
TZ
,
6
},
/* Dansk Normal Tid */
{
"dst"
,
PG_IGNORE
,
0
},
{
"east"
,
TZ
,
NEG
(
60
)},
/* East Australian Std Time */
{
"edt"
,
DTZ
,
NEG
(
24
)},
/* Eastern Daylight Time */
{
"eet"
,
TZ
,
12
},
/* East. Europe, USSR Zone 1 */
{
"eetdst"
,
DTZ
,
18
},
/* Eastern Europe */
{
"est"
,
TZ
,
NEG
(
30
)},
/* Eastern Standard Time */
{
"feb"
,
MONTH
,
2
},
{
"februa"
,
MONTH
,
2
},
{
"fri"
,
PG_IGNORE
,
5
},
{
"friday"
,
PG_IGNORE
,
5
},
{
"fst"
,
TZ
,
6
},
/* French Summer Time */
{
"fwt"
,
DTZ
,
12
},
/* French Winter Time */
{
"gmt"
,
TZ
,
0
},
/* Greenwish Mean Time */
{
"gst"
,
TZ
,
60
},
/* Guam Std Time, USSR Zone 9 */
{
"hdt"
,
DTZ
,
NEG
(
54
)},
/* Hawaii/Alaska */
{
"hmt"
,
DTZ
,
18
},
/* Hellas ? ? */
{
"hst"
,
TZ
,
NEG
(
60
)},
/* Hawaii Std Time */
{
"idle"
,
TZ
,
72
},
/* Intl. Date Line, East */
{
"idlw"
,
TZ
,
NEG
(
72
)},
/* Intl. Date Line, West */
{
"ist"
,
TZ
,
12
},
/* Israel */
{
"it"
,
TZ
,
22
},
/* Iran Time */
{
"jan"
,
MONTH
,
1
},
{
"januar"
,
MONTH
,
1
},
{
"jst"
,
TZ
,
54
},
/* Japan Std Time,USSR Zone 8 */
{
"jt"
,
TZ
,
45
},
/* Java Time */
{
"jul"
,
MONTH
,
7
},
{
"july"
,
MONTH
,
7
},
{
"jun"
,
MONTH
,
6
},
{
"june"
,
MONTH
,
6
},
{
"kst"
,
TZ
,
54
},
/* Korea Standard Time */
{
"ligt"
,
TZ
,
60
},
/* From Melbourne, Australia */
{
"mar"
,
MONTH
,
3
},
{
"march"
,
MONTH
,
3
},
{
"may"
,
MONTH
,
5
},
{
"mdt"
,
DTZ
,
NEG
(
36
)},
/* Mountain Daylight Time */
{
"mest"
,
DTZ
,
12
},
/* Middle Europe Summer Time */
{
"met"
,
TZ
,
6
},
/* Middle Europe Time */
{
"metdst"
,
DTZ
,
12
},
/* Middle Europe Daylight Time*/
{
"mewt"
,
TZ
,
6
},
/* Middle Europe Winter Time */
{
"mez"
,
TZ
,
6
},
/* Middle Europe Zone */
{
"mon"
,
PG_IGNORE
,
1
},
{
"monday"
,
PG_IGNORE
,
1
},
{
"mst"
,
TZ
,
NEG
(
42
)},
/* Mountain Standard Time */
{
"mt"
,
TZ
,
51
},
/* Moluccas Time */
{
"ndt"
,
DTZ
,
NEG
(
15
)},
/* Nfld. Daylight Time */
{
"nft"
,
TZ
,
NEG
(
21
)},
/* Newfoundland Standard Time */
{
"nor"
,
TZ
,
6
},
/* Norway Standard Time */
{
"nov"
,
MONTH
,
11
},
{
"novemb"
,
MONTH
,
11
},
{
"nst"
,
TZ
,
NEG
(
21
)},
/* Nfld. Standard Time */
{
"nt"
,
TZ
,
NEG
(
66
)},
/* Nome Time */
{
"nzdt"
,
DTZ
,
78
},
/* New Zealand Daylight Time */
{
"nzst"
,
TZ
,
72
},
/* New Zealand Standard Time */
{
"nzt"
,
TZ
,
72
},
/* New Zealand Time */
{
"oct"
,
MONTH
,
10
},
{
"octobe"
,
MONTH
,
10
},
{
"on"
,
PG_IGNORE
,
0
},
/* "on" (throwaway) */
{
"pdt"
,
DTZ
,
NEG
(
42
)},
/* Pacific Daylight Time */
{
"pm"
,
AMPM
,
PM
},
{
"pst"
,
TZ
,
NEG
(
48
)},
/* Pacific Standard Time */
{
"sadt"
,
DTZ
,
63
},
/* S. Australian Dayl. Time */
{
"sast"
,
TZ
,
57
},
/* South Australian Std Time */
{
"sat"
,
PG_IGNORE
,
6
},
{
"saturd"
,
PG_IGNORE
,
6
},
{
"sep"
,
MONTH
,
9
},
{
"sept"
,
MONTH
,
9
},
{
"septem"
,
MONTH
,
9
},
{
"set"
,
TZ
,
NEG
(
6
)},
/* Seychelles Time ?? */
{
"sst"
,
DTZ
,
12
},
/* Swedish Summer Time */
{
"sun"
,
PG_IGNORE
,
0
},
{
"sunday"
,
PG_IGNORE
,
0
},
{
"swt"
,
TZ
,
6
},
/* Swedish Winter Time */
{
"thu"
,
PG_IGNORE
,
4
},
{
"thur"
,
PG_IGNORE
,
4
},
{
"thurs"
,
PG_IGNORE
,
4
},
{
"thursd"
,
PG_IGNORE
,
4
},
{
"tue"
,
PG_IGNORE
,
2
},
{
"tues"
,
PG_IGNORE
,
2
},
{
"tuesda"
,
PG_IGNORE
,
2
},
{
"ut"
,
TZ
,
0
},
{
"utc"
,
TZ
,
0
},
{
"wadt"
,
DTZ
,
48
},
/* West Australian DST */
{
"wast"
,
TZ
,
42
},
/* West Australian Std Time */
{
"wat"
,
TZ
,
NEG
(
6
)},
/* West Africa Time */
{
"wdt"
,
DTZ
,
54
},
/* West Australian DST */
{
"wed"
,
PG_IGNORE
,
3
},
{
"wednes"
,
PG_IGNORE
,
3
},
{
"weds"
,
PG_IGNORE
,
3
},
{
"wet"
,
TZ
,
0
},
/* Western Europe */
{
"wetdst"
,
DTZ
,
6
},
/* Western Europe */
{
"wst"
,
TZ
,
48
},
/* West Australian Std Time */
{
"ydt"
,
DTZ
,
NEG
(
48
)},
/* Yukon Daylight Time */
{
"yst"
,
TZ
,
NEG
(
54
)},
/* Yukon Standard Time */
{
"zp4"
,
TZ
,
NEG
(
24
)},
/* GMT +4 hours. */
{
"zp5"
,
TZ
,
NEG
(
30
)},
/* GMT +5 hours. */
{
"zp6"
,
TZ
,
NEG
(
36
)},
/* GMT +6 hours. */
};
static
unsigned
int
szdatetktbl
=
sizeof
datetktbl
/
sizeof
datetktbl
[
0
];
/*
/*
* parse and convert absolute date in timestr (the normal interface)
* parse and convert absolute date in timestr (the normal interface)
*
*
* Returns the number of seconds since epoch (January 1 1970 GMT)
* Returns the number of seconds since epoch (January 1 1970 GMT)
*/
*/
AbsoluteTime
nabstimein
(
char
*
timestr
)
{
int
tz
=
0
;
struct
tm
date
;
if
(
!
timestr
)
return
INVALID_ABSTIME
;
while
(
ISSPACE
(
*
timestr
))
++
timestr
;
if
(
!
strcasecmp
(
timestr
,
"epoch"
))
#ifndef USE_POSIX_TIME
return
EPOCH_ABSTIME
;
long
int
timezone
;
if
(
!
strcasecmp
(
timestr
,
"now"
))
long
int
daylight
;
return
GetCurrentTransactionStartTime
();
#endif
if
(
!
strcasecmp
(
timestr
,
"current"
))
return
CURRENT_ABSTIME
;
if
(
!
strcasecmp
(
timestr
,
"infinity"
))
return
NOEND_ABSTIME
;
if
(
!
strcasecmp
(
timestr
,
"-infinity"
))
return
NOSTART_ABSTIME
;
if
(
prsabsdate
(
timestr
,
&
date
,
&
tz
)
<
0
)
return
INVALID_ABSTIME
;
return
dateconv
(
&
date
,
tz
);
}
/*
AbsoluteTime
* just parse the absolute date in timestr and get back a broken-out date.
GetCurrentAbsoluteTime
(
void
)
*/
int
prsabsdate
(
char
*
timestr
,
struct
tm
*
tm
,
int
*
tzp
)
/* - minutes west */
{
{
register
int
nf
;
time_t
now
;
char
*
fields
[
MAXDATEFIELDS
];
static
char
delims
[]
=
"-
\t\n
/,"
;
nf
=
split
(
timestr
,
fields
,
MAXDATEFIELDS
,
delims
+
1
);
if
(
nf
>
MAXDATEFIELDS
)
return
-
1
;
if
(
tryabsdate
(
fields
,
nf
,
tm
,
tzp
)
<
0
)
{
register
char
*
p
=
timestr
;
/*
* could be a DEC-date; glue it all back together, split it
* with dash as a delimiter and try again. Yes, this is a
* hack, but so are DEC-dates.
*/
while
(
--
nf
>
0
)
{
while
(
*
p
++
!=
'\0'
)
;
p
[
-
1
]
=
' '
;
}
nf
=
split
(
timestr
,
fields
,
MAXDATEFIELDS
,
delims
);
if
(
nf
>
MAXDATEFIELDS
)
return
-
1
;
if
(
tryabsdate
(
fields
,
nf
,
tm
,
tzp
)
<
0
)
return
-
1
;
}
return
0
;
}
/*
#ifdef USE_POSIX_TIME
* try to parse pre-split timestr as an absolute date
now
=
time
(
NULL
);
*/
int
tryabsdate
(
char
*
fields
[],
int
nf
,
struct
tm
*
tm
,
int
*
tzp
)
{
register
int
i
;
register
datetkn
*
tp
;
register
long
flg
=
0
,
ty
;
int
mer
=
HR24
,
bigval
=
-
1
;
#ifndef USE_POSIX_TIME
struct
timeb
now
;
/* the old V7-ism */
(
void
)
ftime
(
&
now
);
*
tzp
=
now
.
timezone
;
#else
/* USE_POSIX_TIME */
#if defined(HAVE_TZSET) && defined(HAVE_INT_TIMEZONE)
#if defined(HAVE_TZSET) && defined(HAVE_INT_TIMEZONE)
tzset
();
tzset
();
#ifndef win32
*
tzp
=
timezone
/
60
;
/* this is an X/Open-ism */
#else
*
tzp
=
_timezone
/
60
;
/* this is an X/Open-ism */
#endif
/* win32 */
#else
/* !HAVE_TZSET */
#else
/* !HAVE_TZSET */
time_t
now
=
time
((
time_t
*
)
NULL
);
struct
tm
*
tmnow
=
localtime
(
&
now
);
struct
tm
*
tmnow
=
localtime
(
&
now
);
*
tzp
=
-
tmnow
->
tm_gmtoff
/
60
;
/* tm_gmtoff is Sun/DEC-ism */
timezone
=
-
tmnow
->
tm_gmtoff
;
/* tm_gmtoff is Sun/DEC-ism */
daylight
=
(
tmnow
->
tm_isdst
>
0
);
#endif
#endif
#else
/* ! USE_POSIX_TIME */
struct
timeb
tbnow
;
/* the old V7-ism */
(
void
)
ftime
(
&
tbnow
);
now
=
tbnow
.
time
;
timezone
=
tbnow
.
timezone
*
60
;
daylight
=
(
tbnow
.
dstflag
!=
0
);
#endif
#endif
tm
->
tm_mday
=
tm
->
tm_mon
=
tm
->
tm_year
=
-
1
;
/* mandatory */
return
((
AbsoluteTime
)
now
);
tm
->
tm_hour
=
tm
->
tm_min
=
tm
->
tm_sec
=
0
;
}
/* GetCurrentAbsoluteTime() */
tm
->
tm_isdst
=
-
1
;
/* assume we don't know. */
dtok_numparsed
=
0
;
for
(
i
=
0
;
i
<
nf
;
i
++
)
{
if
(
fields
[
i
][
0
]
==
'\0'
)
continue
;
tp
=
datetoktype
(
fields
[
i
],
&
bigval
);
ty
=
(
1L
<<
tp
->
type
)
&
~
(
1L
<<
PG_IGNORE
);
if
(
flg
&
ty
)
return
-
1
;
/* repeated type */
flg
|=
ty
;
switch
(
tp
->
type
)
{
case
YEAR
:
tm
->
tm_year
=
bigval
;
break
;
case
DAY
:
tm
->
tm_mday
=
bigval
;
break
;
case
MONTH
:
tm
->
tm_mon
=
tp
->
value
;
break
;
case
TIME
:
if
(
parsetime
(
fields
[
i
],
tm
)
<
0
)
return
-
1
;
break
;
case
DTZ
:
tm
->
tm_isdst
++
;
/* FALLTHROUGH */
case
TZ
:
*
tzp
=
FROMVAL
(
tp
);
break
;
case
PG_IGNORE
:
break
;
case
AMPM
:
mer
=
tp
->
value
;
break
;
default:
return
-
1
;
/* bad token type: CANTHAPPEN */
}
}
if
(
tm
->
tm_year
==
-
1
||
tm
->
tm_mon
==
-
1
||
tm
->
tm_mday
==
-
1
)
return
-
1
;
/* missing component */
if
(
mer
==
PM
)
tm
->
tm_hour
+=
12
;
return
0
;
}
/* return -1 on failure */
void
int
GetCurrentTime
(
struct
tm
*
tm
)
parsetime
(
char
*
time
,
struct
tm
*
tm
)
{
{
register
char
c
;
time_t
now
;
register
int
x
;
struct
tm
*
tt
;
tm
->
tm_sec
=
0
;
GOBBLE_NUM
(
time
,
c
,
x
,
&
tm
->
tm_hour
);
if
(
c
!=
':'
)
return
-
1
;
/* only hour; too short */
GOBBLE_NUM
(
time
,
c
,
x
,
&
tm
->
tm_min
);
if
(
c
!=
':'
)
return
0
;
/* no seconds; okay */
GOBBLE_NUM
(
time
,
c
,
x
,
&
tm
->
tm_sec
);
/* this may be considered too strict. garbage at end of time? */
return
(
c
==
'\0'
||
ISSPACE
(
c
)
?
0
:
-
1
);
}
now
=
GetCurrentTransactionStartTime
();
tt
=
gmtime
(
&
now
);
/*
tm
->
tm_year
=
tt
->
tm_year
+
1900
;
* split - divide a string into fields, like awk split()
tm
->
tm_mon
=
tt
->
tm_mon
+
1
;
tm
->
tm_mday
=
tt
->
tm_mday
;
tm
->
tm_hour
=
tt
->
tm_hour
;
tm
->
tm_min
=
tt
->
tm_min
;
tm
->
tm_sec
=
tt
->
tm_sec
;
tm
->
tm_isdst
=
tt
->
tm_isdst
;
return
;
}
/* GetCurrentTime() */
/* nabstimein()
* Decode date/time string and return abstime.
*/
*/
int
/* number of fields, including overflow */
AbsoluteTime
split
(
char
*
string
,
nabstimein
(
char
*
str
)
char
*
fields
[],
/* list is not NULL-terminated */
int
nfields
,
/* number of entries available in fields[] */
char
*
sep
)
/* "" white, "c" single char, "ab" [ab]+ */
{
{
register
char
*
p
=
string
;
int
sec
;
register
char
c
;
/* latest character */
double
fsec
;
register
char
sepc
=
sep
[
0
];
int
day
,
tz
=
0
;
register
char
sepc2
;
struct
tm
date
,
*
tm
=
&
date
;
register
int
fn
;
register
char
**
fp
=
fields
;
register
char
*
sepp
;
register
int
trimtrail
;
/* white space */
if
(
sepc
==
'\0'
)
{
while
((
c
=
*
p
++
)
==
' '
||
c
==
'\t'
)
continue
;
p
--
;
trimtrail
=
1
;
sep
=
"
\t
"
;
/* note, code below knows this is 2 long */
sepc
=
' '
;
}
else
trimtrail
=
0
;
sepc2
=
sep
[
1
];
/* now we can safely pick this up */
/* catch empties */
if
(
*
p
==
'\0'
)
return
(
0
);
/* single separator */
if
(
sepc2
==
'\0'
)
{
fn
=
nfields
;
for
(;;)
{
*
fp
++
=
p
;
fn
--
;
if
(
fn
==
0
)
break
;
while
((
c
=
*
p
++
)
!=
sepc
)
if
(
c
==
'\0'
)
return
(
nfields
-
fn
);
*
(
p
-
1
)
=
'\0'
;
}
/* we have overflowed the fields vector -- just count them */
fn
=
nfields
;
for
(;;)
{
while
((
c
=
*
p
++
)
!=
sepc
)
if
(
c
==
'\0'
)
return
(
fn
);
fn
++
;
}
/* not reached */
}
/* two separators */
char
*
field
[
MAXDATEFIELDS
];
if
(
sep
[
2
]
==
'\0'
)
{
char
lowstr
[
MAXDATELEN
+
1
];
fn
=
nfields
;
int
dtype
;
for
(;;)
{
int
nf
,
ftype
[
MAXDATEFIELDS
];
*
fp
++
=
p
;
fn
--
;
while
((
c
=
*
p
++
)
!=
sepc
&&
c
!=
sepc2
)
if
(
c
==
'\0'
)
{
if
(
trimtrail
&&
**
(
fp
-
1
)
==
'\0'
)
fn
++
;
return
(
nfields
-
fn
);
}
if
(
fn
==
0
)
break
;
*
(
p
-
1
)
=
'\0'
;
while
((
c
=
*
p
++
)
==
sepc
||
c
==
sepc2
)
continue
;
p
--
;
}
/* we have overflowed the fields vector -- just count them */
fn
=
nfields
;
while
(
c
!=
'\0'
)
{
while
((
c
=
*
p
++
)
==
sepc
||
c
==
sepc2
)
continue
;
p
--
;
fn
++
;
while
((
c
=
*
p
++
)
!=
'\0'
&&
c
!=
sepc
&&
c
!=
sepc2
)
continue
;
}
/* might have to trim trailing white space */
if
(
trimtrail
)
{
p
--
;
while
((
c
=
*--
p
)
==
sepc
||
c
==
sepc2
)
continue
;
p
++
;
if
(
*
p
!=
'\0'
)
{
if
(
fn
==
nfields
+
1
)
*
p
=
'\0'
;
fn
--
;
}
}
return
(
fn
);
}
/* n separators */
if
(
!
PointerIsValid
(
str
))
fn
=
0
;
elog
(
WARN
,
"Bad (null) abstime external representation"
,
NULL
);
for
(;;)
{
if
(
fn
<
nfields
)
if
(
strlen
(
str
)
>
MAXDATELEN
)
*
fp
++
=
p
;
elog
(
WARN
,
"Bad (length) abstime external representation '%s'"
,
str
);
fn
++
;
for
(;;)
{
if
((
ParseDateTime
(
str
,
lowstr
,
field
,
ftype
,
MAXDATEFIELDS
,
&
nf
)
!=
0
)
c
=
*
p
++
;
||
(
DecodeDateTime
(
field
,
ftype
,
nf
,
&
dtype
,
tm
,
&
fsec
,
&
tz
)
!=
0
))
if
(
c
==
'\0'
)
elog
(
WARN
,
"Bad abstime external representation '%s'"
,
str
);
return
(
fn
);
sepp
=
sep
;
#ifdef DATEDEBUG
while
((
sepc
=
*
sepp
++
)
!=
'\0'
&&
sepc
!=
c
)
printf
(
"nabstimein- %d fields are type %d (DTK_DATE=%d)
\n
"
,
nf
,
dtype
,
DTK_DATE
);
continue
;
#endif
if
(
sepc
!=
'\0'
)
/* it was a separator */
break
;
switch
(
dtype
)
{
}
case
DTK_DATE
:
if
(
fn
<
nfields
)
#if FALSE
*
(
p
-
1
)
=
'\0'
;
return
(
dateconv
(
&
date
,
tz
));
for
(;;)
{
#endif
c
=
*
p
++
;
/* validate, before going out of range on some members */
sepp
=
sep
;
if
(
tm
->
tm_year
<
1901
||
tm
->
tm_year
>
2038
while
((
sepc
=
*
sepp
++
)
!=
'\0'
&&
sepc
!=
c
)
||
tm
->
tm_mon
<
1
||
tm
->
tm_mon
>
12
continue
;
||
tm
->
tm_mday
<
1
||
tm
->
tm_mday
>
31
if
(
sepc
==
'\0'
)
/* it wasn't a separator */
||
tm
->
tm_hour
<
0
||
tm
->
tm_hour
>=
24
break
;
||
tm
->
tm_min
<
0
||
tm
->
tm_min
>
59
}
||
tm
->
tm_sec
<
0
||
tm
->
tm_sec
>
59
)
p
--
;
return
INVALID_ABSTIME
;
}
day
=
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
-
date2j
(
1970
,
1
,
1
));
/* check for time out of range */
if
((
day
<
MIN_DAYNUM
)
||
(
day
>
MAX_DAYNUM
))
return
INVALID_ABSTIME
;
/* convert to seconds */
sec
=
tm
->
tm_sec
+
tz
+
(
tm
->
tm_min
+
(
day
*
24
+
tm
->
tm_hour
)
*
60
)
*
60
;
/* check for overflow */
if
((
day
==
MAX_DAYNUM
&&
sec
<
0
)
||
(
day
==
MIN_DAYNUM
&&
sec
>
0
))
return
INVALID_ABSTIME
;
/* daylight correction */
if
(
tm
->
tm_isdst
<
0
)
{
/* unknown; find out */
tm
->
tm_isdst
=
(
daylight
>
0
);
};
if
(
tm
->
tm_isdst
>
0
)
sec
-=
60
*
60
;
/* check for reserved values (e.g. "current" on edge of usual range */
if
(
!
AbsoluteTimeIsReal
(
sec
))
return
INVALID_ABSTIME
;
return
sec
;
case
DTK_EPOCH
:
return
EPOCH_ABSTIME
;
case
DTK_CURRENT
:
return
CURRENT_ABSTIME
;
case
DTK_LATE
:
return
NOEND_ABSTIME
;
case
DTK_EARLY
:
return
NOSTART_ABSTIME
;
case
DTK_INVALID
:
return
INVALID_ABSTIME
;
default:
};
elog
(
WARN
,
"Bad abstime (internal coding error) '%s'"
,
str
);
return
INVALID_ABSTIME
;
}
/* nabstimein() */
/* not reached */
}
/*
/*
* Given an AbsoluteTime return the English text version of the date
* Given an AbsoluteTime return the English text version of the date
...
@@ -529,11 +209,11 @@ nabstimeout(AbsoluteTime time)
...
@@ -529,11 +209,11 @@ nabstimeout(AbsoluteTime time)
char
*
result
;
char
*
result
;
switch
(
time
)
{
switch
(
time
)
{
case
EPOCH_ABSTIME
:
(
void
)
strcpy
(
buf
,
"epoch"
);
break
;
case
EPOCH_ABSTIME
:
(
void
)
strcpy
(
buf
,
EPOCH
);
break
;
case
INVALID_ABSTIME
:
(
void
)
strcpy
(
buf
,
"Invalid Abstime"
);
break
;
case
INVALID_ABSTIME
:
(
void
)
strcpy
(
buf
,
INVALID
);
break
;
case
CURRENT_ABSTIME
:
(
void
)
strcpy
(
buf
,
"current"
);
break
;
case
CURRENT_ABSTIME
:
(
void
)
strcpy
(
buf
,
DCURRENT
);
break
;
case
NOEND_ABSTIME
:
(
void
)
strcpy
(
buf
,
"infinity"
);
break
;
case
NOEND_ABSTIME
:
(
void
)
strcpy
(
buf
,
LATE
);
break
;
case
NOSTART_ABSTIME
:
(
void
)
strcpy
(
buf
,
"-infinity"
);
break
;
case
NOSTART_ABSTIME
:
(
void
)
strcpy
(
buf
,
EARLY
);
break
;
default:
default:
/* hack -- localtime happens to work for negative times */
/* hack -- localtime happens to work for negative times */
(
void
)
strftime
(
buf
,
sizeof
(
buf
),
"%a %b %d %H:%M:%S %Y %Z"
,
(
void
)
strftime
(
buf
,
sizeof
(
buf
),
"%a %b %d %H:%M:%S %Y %Z"
,
...
@@ -545,24 +225,35 @@ nabstimeout(AbsoluteTime time)
...
@@ -545,24 +225,35 @@ nabstimeout(AbsoluteTime time)
return
result
;
return
result
;
}
}
/* turn a (struct tm) and a few variables into a time_t, with range checking */
/* turn a (struct tm) and a few variables into a time_t, with range checking */
AbsoluteTime
AbsoluteTime
dateconv
(
register
struct
tm
*
tm
,
int
zone
)
dateconv
(
register
struct
tm
*
tm
,
int
zone
)
{
{
tm
->
tm_wday
=
tm
->
tm_yday
=
0
;
tm
->
tm_wday
=
tm
->
tm_yday
=
0
;
#if FALSE
if
(
tm
->
tm_year
<
70
)
{
tm
->
tm_year
+=
2000
;
}
else
if
(
tm
->
tm_year
<
1000
)
{
tm
->
tm_year
+=
1900
;
};
#endif
/* validate, before going out of range on some members */
/* validate, before going out of range on some members */
if
(
tm
->
tm_year
<
0
||
tm
->
tm_mon
<
1
||
tm
->
tm_mon
>
12
||
if
(
tm
->
tm_year
<
1901
||
tm
->
tm_year
>
2038
tm
->
tm_mday
<
1
||
tm
->
tm_hour
<
0
||
tm
->
tm_hour
>=
24
||
||
tm
->
tm_mon
<
1
||
tm
->
tm_mon
>
12
tm
->
tm_min
<
0
||
tm
->
tm_min
>
59
||
||
tm
->
tm_mday
<
1
||
tm
->
tm_mday
>
31
tm
->
tm_sec
<
0
||
tm
->
tm_sec
>
59
)
||
tm
->
tm_hour
<
0
||
tm
->
tm_hour
>=
24
return
-
1
;
||
tm
->
tm_min
<
0
||
tm
->
tm_min
>
59
||
tm
->
tm_sec
<
0
||
tm
->
tm_sec
>
59
)
return
INVALID_ABSTIME
;
/*
/*
* zone should really be -zone, and tz should be set to tp->value, not
* zone should really be -zone, and tz should be set to tp->value, not
* -tp->value. Or the table could be fixed.
* -tp->value. Or the table could be fixed.
*/
*/
tm
->
tm_
min
+=
zone
;
/* mktime lets it be out of range */
tm
->
tm_
sec
+=
zone
;
/* mktime lets it be out of range */
/* convert to seconds */
/* convert to seconds */
return
qmktime
(
tm
);
return
qmktime
(
tm
);
...
@@ -575,182 +266,62 @@ dateconv(register struct tm *tm, int zone)
...
@@ -575,182 +266,62 @@ dateconv(register struct tm *tm, int zone)
* and tm_yday.
* and tm_yday.
*/
*/
time_t
time_t
qmktime
(
struct
tm
*
t
p
)
qmktime
(
struct
tm
*
t
m
)
{
{
register
int
mon
=
tp
->
tm_mon
;
time_t
sec
;
register
int
day
=
tp
->
tm_mday
,
year
=
tp
->
tm_year
;
register
time_t
daynum
;
time_t
secondnum
;
register
int
century
;
int
day
;
#if FALSE
/* If it was a 2 digit year */
/* If it was a 2 digit year */
if
(
year
<
100
)
if
(
tm
->
tm_year
<
100
)
year
+=
1900
;
tm
->
tm_year
+=
1900
;
#endif
/*
day
=
(
date2j
(
tm
->
tm_year
,
tm
->
tm_mon
,
tm
->
tm_mday
)
-
date2j
(
1970
,
1
,
1
));
* validate day against days-per-month table, with leap-year
* correction
*/
if
(
day
>
nmdays
[
mon
])
if
(
mon
!=
2
||
(
year
%
4
==
0
&&
((
year
%
100
!=
0
||
year
%
400
==
0
))
&&
day
>
29
))
return
-
1
;
/* day too large for month */
/* split year into century and year-of-century */
century
=
year
/
100
;
year
%=
100
;
/*
* We calculate the day number exactly, assuming the calendar has
* always had the current leap year rules. (The leap year rules are
* to compensate for the fact that the Earth's revolution around the
* Sun takes 365.2425 days). We first need to rotate months so March
* is 0, since we want the last month to have the reduced number of
* days.
*/
if
(
mon
>
2
)
mon
-=
3
;
else
{
mon
+=
9
;
if
(
year
==
0
)
{
century
--
;
year
=
99
;
}
else
--
year
;
}
daynum
=
-
EPOCH_DAYNUM
+
DAYNUM
(
century
,
year
,
mon
,
day
);
/* check for time out of range */
/* check for time out of range */
if
(
daynum
<
MIN_DAYNUM
||
daynum
>
MAX_DAYNUM
)
if
(
(
day
<
MIN_DAYNUM
)
||
(
day
>
MAX_DAYNUM
)
)
return
INVALID_ABSTIME
;
return
INVALID_ABSTIME
;
/* convert to seconds */
/* convert to seconds */
secondnum
=
sec
=
tm
->
tm_sec
+
(
tm
->
tm_min
+
(
day
*
24
+
tm
->
tm_hour
)
*
60
)
*
60
;
tp
->
tm_sec
+
(
tp
->
tm_min
+
(
daynum
*
24
+
tp
->
tm_hour
)
*
60
)
*
60
;
/* check for overflow */
/* check for overflow */
if
((
day
num
==
MAX_DAYNUM
&&
secondnum
<
0
)
||
if
((
day
==
MAX_DAYNUM
&&
sec
<
0
)
||
(
day
num
==
MIN_DAYNUM
&&
secondnum
>
0
))
(
day
==
MIN_DAYNUM
&&
sec
>
0
))
return
INVALID_ABSTIME
;
return
INVALID_ABSTIME
;
/* check for
"current", "infinity", "-infinity"
*/
/* check for
reserved values (e.g. "current" on edge of usual range
*/
if
(
!
AbsoluteTimeIsReal
(
sec
ondnum
))
if
(
!
AbsoluteTimeIsReal
(
sec
))
return
INVALID_ABSTIME
;
return
INVALID_ABSTIME
;
/* daylight correction */
/* daylight correction */
if
(
tp
->
tm_isdst
<
0
)
/* unknown; find out */
if
(
tm
->
tm_isdst
<
0
)
{
/* unknown; find out */
{
tm
->
tm_isdst
=
(
daylight
>
0
);
struct
tm
*
result
;
};
if
(
tm
->
tm_isdst
>
0
)
sec
-=
60
*
60
;
/* NT returns NULL for any time before 1/1/70 */
return
sec
;
result
=
localtime
(
&
secondnum
);
}
/* qmktime() */
if
(
result
==
NULL
)
return
INVALID_ABSTIME
;
else
tp
->
tm_isdst
=
result
->
tm_isdst
;
}
if
(
tp
->
tm_isdst
>
0
)
secondnum
-=
60
*
60
;
return
secondnum
;
}
datetkn
*
datetoktype
(
char
*
s
,
int
*
bigvalp
)
{
register
char
*
cp
=
s
;
register
char
c
=
*
cp
;
static
datetkn
t
;
register
datetkn
*
tp
=
&
t
;
if
(
isascii
(
c
)
&&
isdigit
(
c
))
{
register
int
len
=
strlen
(
cp
);
if
(
len
>
3
&&
(
cp
[
1
]
==
':'
||
cp
[
2
]
==
':'
))
tp
->
type
=
TIME
;
else
{
if
(
bigvalp
!=
NULL
)
/* won't fit in tp->value */
*
bigvalp
=
atoi
(
cp
);
if
(
len
==
4
)
tp
->
type
=
YEAR
;
else
if
(
++
dtok_numparsed
==
1
)
tp
->
type
=
DAY
;
else
tp
->
type
=
YEAR
;
}
}
else
if
(
c
==
'-'
||
c
==
'+'
)
{
register
int
val
=
atoi
(
cp
+
1
);
register
int
hr
=
val
/
100
;
register
int
min
=
val
%
100
;
val
=
hr
*
60
+
min
;
if
(
c
==
'-'
)
val
=
-
val
;
tp
->
type
=
TZ
;
TOVAL
(
tp
,
val
);
}
else
{
char
lowtoken
[
TOKMAXLEN
+
1
];
register
char
*
ltp
=
lowtoken
,
*
endltp
=
lowtoken
+
TOKMAXLEN
;
/* copy to lowtoken to avoid modifying s */
while
((
c
=
*
cp
++
)
!=
'\0'
&&
ltp
<
endltp
)
*
ltp
++
=
(
isascii
(
c
)
&&
isupper
(
c
)
?
tolower
(
c
)
:
c
);
*
ltp
=
'\0'
;
tp
=
datebsearch
(
lowtoken
,
datetktbl
,
szdatetktbl
);
if
(
tp
==
NULL
)
{
tp
=
&
t
;
tp
->
type
=
PG_IGNORE
;
}
}
return
tp
;
}
/*
* Binary search -- from Knuth (6.2.1) Algorithm B. Special case like this
* is WAY faster than the generic bsearch().
*/
datetkn
*
datebsearch
(
char
*
key
,
datetkn
*
base
,
unsigned
int
nel
)
{
register
datetkn
*
last
=
base
+
nel
-
1
,
*
position
;
register
int
result
;
while
(
last
>=
base
)
{
position
=
base
+
((
last
-
base
)
>>
1
);
result
=
key
[
0
]
-
position
->
token
[
0
];
if
(
result
==
0
)
{
result
=
strncmp
(
key
,
position
->
token
,
TOKMAXLEN
);
if
(
result
==
0
)
return
position
;
}
if
(
result
<
0
)
last
=
position
-
1
;
else
base
=
position
+
1
;
}
return
0
;
}
/*
/*
* AbsoluteTimeIsBefore -- true iff time1 is before time2.
* AbsoluteTimeIsBefore -- true iff time1 is before time2.
* AbsoluteTimeIsBefore -- true iff time1 is after time2.
*/
*/
bool
bool
AbsoluteTimeIsBefore
(
AbsoluteTime
time1
,
AbsoluteTime
time2
)
AbsoluteTimeIsBefore
(
AbsoluteTime
time1
,
AbsoluteTime
time2
)
{
{
AbsoluteTime
tm
=
GetCurrentTransactionStartTime
();
Assert
(
AbsoluteTimeIsValid
(
time1
));
Assert
(
AbsoluteTimeIsValid
(
time1
));
Assert
(
AbsoluteTimeIsValid
(
time2
));
Assert
(
AbsoluteTimeIsValid
(
time2
));
if
((
time1
==
CURRENT_ABSTIME
)
||
(
time2
==
CURRENT_ABSTIME
))
return
false
;
if
(
time1
==
CURRENT_ABSTIME
)
if
(
time1
==
CURRENT_ABSTIME
)
return
(
tm
<
time2
);
time1
=
GetCurrentTransactionStartTime
();
if
(
time2
==
CURRENT_ABSTIME
)
if
(
time2
==
CURRENT_ABSTIME
)
return
(
time1
<
tm
);
time2
=
GetCurrentTransactionStartTime
(
);
return
(
time1
<
time2
);
return
(
time1
<
time2
);
}
}
...
@@ -758,17 +329,14 @@ AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2)
...
@@ -758,17 +329,14 @@ AbsoluteTimeIsBefore(AbsoluteTime time1, AbsoluteTime time2)
bool
bool
AbsoluteTimeIsAfter
(
AbsoluteTime
time1
,
AbsoluteTime
time2
)
AbsoluteTimeIsAfter
(
AbsoluteTime
time1
,
AbsoluteTime
time2
)
{
{
AbsoluteTime
tm
=
GetCurrentTransactionStartTime
();
Assert
(
AbsoluteTimeIsValid
(
time1
));
Assert
(
AbsoluteTimeIsValid
(
time1
));
Assert
(
AbsoluteTimeIsValid
(
time2
));
Assert
(
AbsoluteTimeIsValid
(
time2
));
if
((
time1
==
CURRENT_ABSTIME
)
||
(
time2
==
CURRENT_ABSTIME
))
return
false
;
if
(
time1
==
CURRENT_ABSTIME
)
if
(
time1
==
CURRENT_ABSTIME
)
return
(
tm
>
time2
);
time1
=
GetCurrentTransactionStartTime
();
if
(
time2
==
CURRENT_ABSTIME
)
if
(
time2
==
CURRENT_ABSTIME
)
return
(
time1
>
tm
);
time2
=
GetCurrentTransactionStartTime
(
);
return
(
time1
>
time2
);
return
(
time1
>
time2
);
}
}
...
@@ -781,9 +349,8 @@ AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2)
...
@@ -781,9 +349,8 @@ AbsoluteTimeIsAfter(AbsoluteTime time1, AbsoluteTime time2)
* abstimegt - returns 1, iff t1 greater than t2
* abstimegt - returns 1, iff t1 greater than t2
* abstimele - returns 1, iff t1 less than or equal to t2
* abstimele - returns 1, iff t1 less than or equal to t2
* abstimege - returns 1, iff t1 greater than or equal to t2
* abstimege - returns 1, iff t1 greater than or equal to t2
*
*/
*/
int32
bool
abstimeeq
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimeeq
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -796,7 +363,7 @@ abstimeeq(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -796,7 +363,7 @@ abstimeeq(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
==
t2
);
return
(
t1
==
t2
);
}
}
int32
bool
abstimene
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimene
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -809,7 +376,7 @@ abstimene(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -809,7 +376,7 @@ abstimene(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
!=
t2
);
return
(
t1
!=
t2
);
}
}
int32
bool
abstimelt
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimelt
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -822,7 +389,7 @@ abstimelt(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -822,7 +389,7 @@ abstimelt(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
<
t2
);
return
(
t1
<
t2
);
}
}
int32
bool
abstimegt
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimegt
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -835,7 +402,7 @@ abstimegt(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -835,7 +402,7 @@ abstimegt(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
>
t2
);
return
(
t1
>
t2
);
}
}
int32
bool
abstimele
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimele
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -848,7 +415,7 @@ abstimele(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -848,7 +415,7 @@ abstimele(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
<=
t2
);
return
(
t1
<=
t2
);
}
}
int32
bool
abstimege
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
abstimege
(
AbsoluteTime
t1
,
AbsoluteTime
t2
)
{
{
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
if
(
t1
==
INVALID_ABSTIME
||
t2
==
INVALID_ABSTIME
)
...
@@ -860,5 +427,3 @@ abstimege(AbsoluteTime t1, AbsoluteTime t2)
...
@@ -860,5 +427,3 @@ abstimege(AbsoluteTime t1, AbsoluteTime t2)
return
(
t1
>=
t2
);
return
(
t1
>=
t2
);
}
}
src/backend/utils/adt/name.c
View file @
53d8be3b
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.
1.1.1 1996/07/09 06:22:04
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/name.c,v 1.
2 1997/03/14 23:20:43
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -74,49 +74,49 @@ char *nameout(NameData *s)
...
@@ -74,49 +74,49 @@ char *nameout(NameData *s)
* namege - returns 1 iff a <= b
* namege - returns 1 iff a <= b
*
*
*/
*/
int32
nameeq
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
nameeq
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
!
arg1
||
!
arg2
)
if
(
!
arg1
||
!
arg2
)
return
0
;
return
0
;
else
else
return
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
==
0
);
return
(
(
bool
)
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
==
0
);
}
}
int32
namene
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
namene
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
!=
0
);
return
(
(
bool
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
!=
0
)
);
}
}
int32
namelt
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
namelt
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
<
0
));
return
((
bool
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
<
0
));
}
}
int32
namele
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
namele
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
<=
0
));
return
((
bool
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
<=
0
));
}
}
int32
namegt
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
namegt
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
>
0
));
return
((
bool
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
>
0
));
}
}
int32
namege
(
NameData
*
arg1
,
NameData
*
arg2
)
bool
namege
(
NameData
*
arg1
,
NameData
*
arg2
)
{
{
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
>=
0
));
return
((
bool
)
(
strncmp
(
arg1
->
data
,
arg2
->
data
,
NAMEDATALEN
)
>=
0
));
}
}
...
...
src/backend/utils/adt/oid.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.
5 1997/03/12 21:09:15
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.
6 1997/03/14 23:20:52
scrappy Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -100,19 +100,19 @@ char *oidout(Oid o)
...
@@ -100,19 +100,19 @@ char *oidout(Oid o)
* PUBLIC ROUTINES *
* PUBLIC ROUTINES *
*****************************************************************************/
*****************************************************************************/
int32
oideq
(
Oid
arg1
,
Oid
arg2
)
bool
oideq
(
Oid
arg1
,
Oid
arg2
)
{
{
return
(
arg1
==
arg2
);
return
(
arg1
==
arg2
);
}
}
int32
oidne
(
Oid
arg1
,
Oid
arg2
)
bool
oidne
(
Oid
arg1
,
Oid
arg2
)
{
{
return
(
arg1
!=
arg2
);
return
(
arg1
!=
arg2
);
}
}
int32
oid8eq
(
Oid
arg1
[],
Oid
arg2
[])
bool
oid8eq
(
Oid
arg1
[],
Oid
arg2
[])
{
{
return
(
int32
)(
memcmp
(
arg1
,
arg2
,
8
*
sizeof
(
Oid
))
==
0
);
return
(
bool
)(
memcmp
(
arg1
,
arg2
,
8
*
sizeof
(
Oid
))
==
0
);
}
}
bool
oideqint4
(
Oid
arg1
,
int32
arg2
)
bool
oideqint4
(
Oid
arg1
,
int32
arg2
)
...
...
src/backend/utils/adt/varchar.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.
6 1996/11/10 03:03:20 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.
7 1997/03/14 23:21:01 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -180,13 +180,13 @@ bcTruelen(char *arg)
...
@@ -180,13 +180,13 @@ bcTruelen(char *arg)
return
(
i
+
1
);
return
(
i
+
1
);
}
}
int32
bool
bpchareq
(
char
*
arg1
,
char
*
arg2
)
bpchareq
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
...
@@ -196,13 +196,13 @@ bpchareq(char *arg1, char *arg2)
...
@@ -196,13 +196,13 @@ bpchareq(char *arg1, char *arg2)
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
==
0
);
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
==
0
);
}
}
int32
bool
bpcharne
(
char
*
arg1
,
char
*
arg2
)
bpcharne
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
...
@@ -212,14 +212,14 @@ bpcharne(char *arg1, char *arg2)
...
@@ -212,14 +212,14 @@ bpcharne(char *arg1, char *arg2)
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
!=
0
);
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
!=
0
);
}
}
int32
bool
bpcharlt
(
char
*
arg1
,
char
*
arg2
)
bpcharlt
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
...
@@ -230,32 +230,32 @@ bpcharlt(char *arg1, char *arg2)
...
@@ -230,32 +230,32 @@ bpcharlt(char *arg1, char *arg2)
return
(
cmp
<
0
);
return
(
cmp
<
0
);
}
}
int32
bool
bpcharle
(
char
*
arg1
,
char
*
arg2
)
bpcharle
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
if
(
0
==
cmp
)
if
(
0
==
cmp
)
return
(
int32
)(
len1
<=
len2
?
1
:
0
);
return
(
bool
)(
len1
<=
len2
?
1
:
0
);
else
else
return
(
int32
)(
cmp
<=
0
);
return
(
bool
)(
cmp
<=
0
);
}
}
int32
bool
bpchargt
(
char
*
arg1
,
char
*
arg2
)
bpchargt
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
...
@@ -266,22 +266,22 @@ bpchargt(char *arg1, char *arg2)
...
@@ -266,22 +266,22 @@ bpchargt(char *arg1, char *arg2)
return
(
cmp
>
0
);
return
(
cmp
>
0
);
}
}
int32
bool
bpcharge
(
char
*
arg1
,
char
*
arg2
)
bpcharge
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
bcTruelen
(
arg1
);
len1
=
bcTruelen
(
arg1
);
len2
=
bcTruelen
(
arg2
);
len2
=
bcTruelen
(
arg2
);
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
if
(
0
==
cmp
)
if
(
0
==
cmp
)
return
(
int32
)(
len1
>=
len2
?
1
:
0
);
return
(
bool
)(
len1
>=
len2
?
1
:
0
);
else
else
return
(
int32
)(
cmp
>=
0
);
return
(
bool
)(
cmp
>=
0
);
}
}
int32
int32
...
@@ -319,13 +319,13 @@ vcTruelen(char *arg)
...
@@ -319,13 +319,13 @@ vcTruelen(char *arg)
return
i
;
return
i
;
}
}
int32
bool
varchareq
(
char
*
arg1
,
char
*
arg2
)
varchareq
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
...
@@ -335,13 +335,13 @@ varchareq(char *arg1, char *arg2)
...
@@ -335,13 +335,13 @@ varchareq(char *arg1, char *arg2)
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
==
0
);
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
==
0
);
}
}
int32
bool
varcharne
(
char
*
arg1
,
char
*
arg2
)
varcharne
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
...
@@ -351,14 +351,14 @@ varcharne(char *arg1, char *arg2)
...
@@ -351,14 +351,14 @@ varcharne(char *arg1, char *arg2)
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
!=
0
);
return
(
strncmp
(
arg1
+
4
,
arg2
+
4
,
len1
)
!=
0
);
}
}
int32
bool
varcharlt
(
char
*
arg1
,
char
*
arg2
)
varcharlt
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
...
@@ -369,32 +369,32 @@ varcharlt(char *arg1, char *arg2)
...
@@ -369,32 +369,32 @@ varcharlt(char *arg1, char *arg2)
return
(
cmp
<
0
);
return
(
cmp
<
0
);
}
}
int32
bool
varcharle
(
char
*
arg1
,
char
*
arg2
)
varcharle
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
if
(
0
==
cmp
)
if
(
0
==
cmp
)
return
(
int32
)(
len1
<=
len2
?
1
:
0
);
return
(
bool
)(
len1
<=
len2
?
1
:
0
);
else
else
return
(
int32
)(
cmp
<=
0
);
return
(
bool
)(
cmp
<=
0
);
}
}
int32
bool
varchargt
(
char
*
arg1
,
char
*
arg2
)
varchargt
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
...
@@ -405,22 +405,22 @@ varchargt(char *arg1, char *arg2)
...
@@ -405,22 +405,22 @@ varchargt(char *arg1, char *arg2)
return
(
cmp
>
0
);
return
(
cmp
>
0
);
}
}
int32
bool
varcharge
(
char
*
arg1
,
char
*
arg2
)
varcharge
(
char
*
arg1
,
char
*
arg2
)
{
{
int
len1
,
len2
;
int
len1
,
len2
;
int
cmp
;
int
cmp
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
len1
=
vcTruelen
(
arg1
);
len1
=
vcTruelen
(
arg1
);
len2
=
vcTruelen
(
arg2
);
len2
=
vcTruelen
(
arg2
);
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
cmp
=
strncmp
(
arg1
+
4
,
arg2
+
4
,
Min
(
len1
,
len2
));
if
(
0
==
cmp
)
if
(
0
==
cmp
)
return
(
int32
)(
len1
>=
len2
?
1
:
0
);
return
(
bool
)(
len1
>=
len2
?
1
:
0
);
else
else
return
(
int32
)(
cmp
>=
0
);
return
(
bool
)(
cmp
>=
0
);
}
}
...
...
src/backend/utils/adt/varlena.c
View file @
53d8be3b
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.1
0 1997/01/16 03:53:51 vadim
Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.1
1 1997/03/14 23:21:12 scrappy
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -255,16 +255,16 @@ textcat(text* t1, text* t2)
...
@@ -255,16 +255,16 @@ textcat(text* t1, text* t2)
* texteq - returns 1 iff arguments are equal
* texteq - returns 1 iff arguments are equal
* textne - returns 1 iff arguments are not equal
* textne - returns 1 iff arguments are not equal
*/
*/
int32
bool
texteq
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
texteq
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
register
int
len
;
register
int
len
;
register
char
*
a1p
,
*
a2p
;
register
char
*
a1p
,
*
a2p
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
NULL
);
return
((
bool
)
NULL
);
if
((
len
=
arg1
->
vl_len
)
!=
arg2
->
vl_len
)
if
((
len
=
arg1
->
vl_len
)
!=
arg2
->
vl_len
)
return
((
int32
)
0
);
return
((
bool
)
0
);
a1p
=
arg1
->
vl_dat
;
a1p
=
arg1
->
vl_dat
;
a2p
=
arg2
->
vl_dat
;
a2p
=
arg2
->
vl_dat
;
/*
/*
...
@@ -275,17 +275,17 @@ texteq(struct varlena *arg1, struct varlena *arg2)
...
@@ -275,17 +275,17 @@ texteq(struct varlena *arg1, struct varlena *arg2)
len
-=
sizeof
(
int32
);
len
-=
sizeof
(
int32
);
while
(
len
--
!=
0
)
while
(
len
--
!=
0
)
if
(
*
a1p
++
!=
*
a2p
++
)
if
(
*
a1p
++
!=
*
a2p
++
)
return
((
int32
)
0
);
return
((
bool
)
0
);
return
((
int32
)
1
);
return
((
bool
)
1
);
}
}
int32
bool
textne
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
textne
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
return
((
int32
)
!
texteq
(
arg1
,
arg2
));
return
((
bool
)
!
texteq
(
arg1
,
arg2
));
}
}
int32
bool
text_lt
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
text_lt
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
int
len
;
int
len
;
...
@@ -295,7 +295,7 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
...
@@ -295,7 +295,7 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
char
*
a1p
,
*
a2p
;
char
*
a1p
,
*
a2p
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
a1p
=
(
unsigned
char
*
)
VARDATA
(
arg1
);
a1p
=
(
unsigned
char
*
)
VARDATA
(
arg1
);
a2p
=
(
unsigned
char
*
)
VARDATA
(
arg2
);
a2p
=
(
unsigned
char
*
)
VARDATA
(
arg2
);
...
@@ -311,12 +311,12 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
...
@@ -311,12 +311,12 @@ text_lt(struct varlena *arg1, struct varlena *arg2)
len
--
;
len
--
;
}
}
if
(
len
)
if
(
len
)
return
(
int32
)
(
*
a1p
<
*
a2p
);
return
(
bool
)
(
*
a1p
<
*
a2p
);
else
else
return
(
int32
)
(
arg1
->
vl_len
<
arg2
->
vl_len
);
return
(
bool
)
(
arg1
->
vl_len
<
arg2
->
vl_len
);
}
}
int32
bool
text_le
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
text_le
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
int
len
;
int
len
;
...
@@ -326,7 +326,7 @@ text_le(struct varlena *arg1, struct varlena *arg2)
...
@@ -326,7 +326,7 @@ text_le(struct varlena *arg1, struct varlena *arg2)
char
*
a1p
,
*
a2p
;
char
*
a1p
,
*
a2p
;
if
(
arg1
==
NULL
||
arg2
==
NULL
)
if
(
arg1
==
NULL
||
arg2
==
NULL
)
return
((
int32
)
0
);
return
((
bool
)
0
);
a1p
=
(
unsigned
char
*
)
VARDATA
(
arg1
);
a1p
=
(
unsigned
char
*
)
VARDATA
(
arg1
);
a2p
=
(
unsigned
char
*
)
VARDATA
(
arg2
);
a2p
=
(
unsigned
char
*
)
VARDATA
(
arg2
);
...
@@ -342,21 +342,21 @@ text_le(struct varlena *arg1, struct varlena *arg2)
...
@@ -342,21 +342,21 @@ text_le(struct varlena *arg1, struct varlena *arg2)
len
--
;
len
--
;
}
}
if
(
len
)
if
(
len
)
return
(
int32
)
(
*
a1p
<
*
a2p
);
return
(
bool
)
(
*
a1p
<
*
a2p
);
else
else
return
((
int32
)
VARSIZE
(
arg1
)
<=
VARSIZE
(
arg2
));
return
((
bool
)
VARSIZE
(
arg1
)
<=
VARSIZE
(
arg2
));
}
}
int32
bool
text_gt
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
text_gt
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
return
((
int32
)
!
text_le
(
arg1
,
arg2
));
return
((
bool
)
!
text_le
(
arg1
,
arg2
));
}
}
int32
bool
text_ge
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
text_ge
(
struct
varlena
*
arg1
,
struct
varlena
*
arg2
)
{
{
return
((
int32
)
!
text_lt
(
arg1
,
arg2
));
return
((
bool
)
!
text_lt
(
arg1
,
arg2
));
}
}
/*-------------------------------------------------------------
/*-------------------------------------------------------------
...
...
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