summaryrefslogtreecommitdiff
path: root/src/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces')
-rw-r--r--src/interfaces/ecpg/pgtypeslib/dt.h28
-rw-r--r--src/interfaces/ecpg/pgtypeslib/timestamp.c6
2 files changed, 24 insertions, 10 deletions
diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h
index 145e2b7c4fb..c0c3ac19016 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt.h
+++ b/src/interfaces/ecpg/pgtypeslib/dt.h
@@ -287,22 +287,32 @@ do { \
*/
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
-/* Julian date support for date2j() and j2date()
- *
- * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy
- * about the maximum, since it's far enough out to not be especially
- * interesting.
+/*
+ * Julian date support --- see comments in backend's timestamp.h.
*/
#define JULIAN_MINYEAR (-4713)
#define JULIAN_MINMONTH (11)
#define JULIAN_MINDAY (24)
#define JULIAN_MAXYEAR (5874898)
+#define JULIAN_MAXMONTH (6)
+#define JULIAN_MAXDAY (3)
+
+#define IS_VALID_JULIAN(y,m,d) \
+ (((y) > JULIAN_MINYEAR || \
+ ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \
+ ((y) < JULIAN_MAXYEAR || \
+ ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH))))
+
+#ifdef HAVE_INT64_TIMESTAMP
+#define MIN_TIMESTAMP INT64CONST(-211813488000000000)
+#define END_TIMESTAMP INT64CONST(9223371331200000000)
+#else
+#define MIN_TIMESTAMP (-211813488000.0)
+#define END_TIMESTAMP 185330760393600.0
+#endif
-#define IS_VALID_JULIAN(y,m,d) ((((y) > JULIAN_MINYEAR) \
- || (((y) == JULIAN_MINYEAR) && (((m) > JULIAN_MINMONTH) \
- || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
- && ((y) < JULIAN_MAXYEAR))
+#define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP)
#define UTIME_MINYEAR (1901)
#define UTIME_MINMONTH (12)
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c
index cf1fed2c00b..f746a90f8b1 100644
--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c
+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c
@@ -61,7 +61,7 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result)
time;
#endif
- /* Julian day routines are not correct for negative Julian days */
+ /* Prevent overflow in Julian-day routines */
if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday))
return -1;
@@ -83,6 +83,10 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result)
if (tzp != NULL)
*result = dt2local(*result, -(*tzp));
+ /* final range check catches just-out-of-range timestamps */
+ if (!IS_VALID_TIMESTAMP(*result))
+ return -1;
+
return 0;
} /* tm2timestamp() */