Hello,
There is a Y2038 bug in win32gettimeofday.c due to long being 32-bits on
Windows and the use of struct timeval.
int
gettimeofday(struct timeval *tp, void *tzp)
struct timeval is defined in winsock2.h and is needed by the Windows
select() call. The 64-bit values have to be narrowed to 32-bit values
for the struct timeval slots.
tp->tv_sec = (long) ((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC);
tp->tv_usec = (long) (((ularge.QuadPart - epoch) %
FILETIME_UNITS_PER_SEC) / FILETIME_UNITS_PER_USEC);
I set my system clock to be in 2038 you can see the "wrap-around" error
in the following test.
C:\pg99>date 01-19-2038
C:\pg99>bin\psql -d postgres -p 5454 -c "SELECT clock_timestamp(),
extract(epoch from clock_timestamp()), timeofday();"
clock_timestamp | extract | timeofday
-------------------------------+--------------------+-------------------------------------
1901-12-13 18:46:42.483928-06 | -2147469197.516072 | Fri Dec 13
18:46:42.484319 1901 CST
(1 row)
I then set it to a date before 2038 but still in the future and it
worked as expected.
C:\pg99>date 05-19-2035
C:\pg99>bin\psql -d postgres -p 5454 -c "SELECT clock_timestamp(),
extract(epoch from clock_timestamp()), timeofday();"
clock_timestamp | extract | timeofday
-------------------------------+-------------------+-------------------------------------
2035-05-19 02:15:09.119002-05 | 2063171709.119002 | Sat May 19
02:15:09.119315 2035 CDT
(1 row)
The struct timeval is unguarded in winsock2.h are we could just use the
guard to define our own.
We can create our own pg_timeval with a few helper conversion functions.
Obviously, there are a lot of places in the codebase where gettimeofday
is called. My question is whether we want to fix this now or wait with
crossed fingers that Microsoft fixes this in a timely manner?
If we choose to create our own timeval struct, should we convert to
struct timespec instead? If we want to move forward with either of
these for a Y2038 fix, I will be more than happy to create a patch for
whichever.
Bryan Green