mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-25 19:17:19 +02:00
Sync our copy of the timezone library with IANA release tzcode2018g.
This patch absorbs an upstream fix to "zic" for a recently-introduced bug that made it output data that some 32-bit clients couldn't read. Given the current source data, the bug only manifests in zones with leap seconds, which we don't generate, so that there's no actual change in our installed timezone data files from this. Still, in case somebody uses our copy of "zic" to do something else, it seems best to apply the fix promptly. Also, update the README's notes about converting upstream code to our conventions.
This commit is contained in:
parent
58c45fdaa8
commit
f107c33461
@ -55,7 +55,7 @@ match properly on the old version.
|
|||||||
Time Zone code
|
Time Zone code
|
||||||
==============
|
==============
|
||||||
|
|
||||||
The code in this directory is currently synced with tzcode release 2018f.
|
The code in this directory is currently synced with tzcode release 2018g.
|
||||||
There are many cosmetic (and not so cosmetic) differences from the
|
There are many cosmetic (and not so cosmetic) differences from the
|
||||||
original tzcode library, but diffs in the upstream version should usually
|
original tzcode library, but diffs in the upstream version should usually
|
||||||
be propagated to our version. Here are some notes about that.
|
be propagated to our version. Here are some notes about that.
|
||||||
@ -73,13 +73,18 @@ fixed that.)
|
|||||||
includes relying on configure's results rather than hand-hacked #defines,
|
includes relying on configure's results rather than hand-hacked #defines,
|
||||||
and not relying on <stdint.h> features that may not exist on old systems.
|
and not relying on <stdint.h> features that may not exist on old systems.
|
||||||
(In particular this means using Postgres' definitions of the int32 and
|
(In particular this means using Postgres' definitions of the int32 and
|
||||||
int64 typedefs, not int_fast32_t/int_fast64_t.)
|
int64 typedefs, not int_fast32_t/int_fast64_t. Likewise we use
|
||||||
|
PG_INT32_MIN/MAX not INT32_MIN/MAX.)
|
||||||
|
|
||||||
* Since Postgres is typically built on a system that has its own copy
|
* Since Postgres is typically built on a system that has its own copy
|
||||||
of the <time.h> functions, we must avoid conflicting with those. This
|
of the <time.h> functions, we must avoid conflicting with those. This
|
||||||
mandates renaming typedef time_t to pg_time_t, and similarly for most
|
mandates renaming typedef time_t to pg_time_t, and similarly for most
|
||||||
other exposed names.
|
other exposed names.
|
||||||
|
|
||||||
|
* zic.c's typedef "lineno" is renamed to "lineno_t", because having
|
||||||
|
"lineno" in our typedefs list would cause unfortunate pgindent behavior
|
||||||
|
in some other files where we have variables named that.
|
||||||
|
|
||||||
* We have exposed the tzload() and tzparse() internal functions, and
|
* We have exposed the tzload() and tzparse() internal functions, and
|
||||||
slightly modified the API of the former, in part because it now relies
|
slightly modified the API of the former, in part because it now relies
|
||||||
on our own pg_open_tzfile() rather than opening files for itself.
|
on our own pg_open_tzfile() rather than opening files for itself.
|
||||||
@ -108,8 +113,11 @@ to first run the tzcode source files through a sed filter like this:
|
|||||||
-e 's/\bregister[ \t]//g' \
|
-e 's/\bregister[ \t]//g' \
|
||||||
-e 's/int_fast32_t/int32/g' \
|
-e 's/int_fast32_t/int32/g' \
|
||||||
-e 's/int_fast64_t/int64/g' \
|
-e 's/int_fast64_t/int64/g' \
|
||||||
|
-e 's/INT32_MIN/PG_INT32_MIN/g' \
|
||||||
|
-e 's/INT32_MAX/PG_INT32_MAX/g' \
|
||||||
-e 's/struct[ \t]+tm\b/struct pg_tm/g' \
|
-e 's/struct[ \t]+tm\b/struct pg_tm/g' \
|
||||||
-e 's/\btime_t\b/pg_time_t/g' \
|
-e 's/\btime_t\b/pg_time_t/g' \
|
||||||
|
-e 's/lineno/lineno_t/g' \
|
||||||
|
|
||||||
and then run them through pgindent. (The first three sed patterns deal
|
and then run them through pgindent. (The first three sed patterns deal
|
||||||
with conversion of their block comment style to something pgindent
|
with conversion of their block comment style to something pgindent
|
||||||
|
@ -167,9 +167,11 @@ PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1};
|
|||||||
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
|
QTBUG-53071 <https://bugreports.qt.io/browse/QTBUG-53071>. This
|
||||||
workaround will no longer be needed when Qt 5.6.1 and earlier are
|
workaround will no longer be needed when Qt 5.6.1 and earlier are
|
||||||
obsolete, say in the year 2021. */
|
obsolete, say in the year 2021. */
|
||||||
|
#ifndef WORK_AROUND_QTBUG_53071
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
WORK_AROUND_QTBUG_53071 = true};
|
WORK_AROUND_QTBUG_53071 = true};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int charcnt;
|
static int charcnt;
|
||||||
static bool errors;
|
static bool errors;
|
||||||
@ -1912,12 +1914,6 @@ atcomp(const void *avp, const void *bvp)
|
|||||||
return (a < b) ? -1 : (a > b);
|
return (a < b) ? -1 : (a > b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
is32(const zic_t x)
|
|
||||||
{
|
|
||||||
return x == ((zic_t) ((int32) x));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
swaptypes(int i, int j)
|
swaptypes(int i, int j)
|
||||||
{
|
{
|
||||||
@ -1971,7 +1967,12 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
zic_t one = 1;
|
zic_t one = 1;
|
||||||
zic_t y2038_boundary = one << 31;
|
zic_t y2038_boundary = one << 31;
|
||||||
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
|
ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071;
|
||||||
zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1));
|
|
||||||
|
/*
|
||||||
|
* Allocate the ATS and TYPES arrays via a single malloc, as this is a bit
|
||||||
|
* faster.
|
||||||
|
*/
|
||||||
|
zic_t *ats = emalloc(MAXALIGN(size_product(nats, sizeof *ats + 1)));
|
||||||
void *typesptr = ats + nats;
|
void *typesptr = ats + nats;
|
||||||
unsigned char *types = typesptr;
|
unsigned char *types = typesptr;
|
||||||
|
|
||||||
@ -2029,20 +2030,6 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
types[i] = attypes[i].type;
|
types[i] = attypes[i].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
|
|
||||||
* inserting a no-op transition at time y2038_boundary - 1. This works
|
|
||||||
* only for timestamps before the boundary, which should be good enough in
|
|
||||||
* practice as QTBUG-53071 should be long-dead by 2038.
|
|
||||||
*/
|
|
||||||
if (WORK_AROUND_QTBUG_53071 && timecnt != 0
|
|
||||||
&& ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<'))
|
|
||||||
{
|
|
||||||
ats[timecnt] = y2038_boundary - 1;
|
|
||||||
types[timecnt] = types[timecnt - 1];
|
|
||||||
timecnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Correct for leap seconds.
|
* Correct for leap seconds.
|
||||||
*/
|
*/
|
||||||
@ -2057,6 +2044,23 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by
|
||||||
|
* inserting a no-op transition at time y2038_boundary - 1. This works
|
||||||
|
* only for timestamps before the boundary, which should be good enough in
|
||||||
|
* practice as QTBUG-53071 should be long-dead by 2038. Do this after
|
||||||
|
* correcting for leap seconds, as the idea is to insert a transition just
|
||||||
|
* before 32-bit pg_time_t rolls around, and this occurs at a slightly
|
||||||
|
* different moment if transitions are leap-second corrected.
|
||||||
|
*/
|
||||||
|
if (WORK_AROUND_QTBUG_53071 && timecnt != 0
|
||||||
|
&& ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<'))
|
||||||
|
{
|
||||||
|
ats[timecnt] = y2038_boundary - 1;
|
||||||
|
types[timecnt] = types[timecnt - 1];
|
||||||
|
timecnt++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out 32-bit-limited starts and counts.
|
* Figure out 32-bit-limited starts and counts.
|
||||||
*/
|
*/
|
||||||
@ -2064,25 +2068,24 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
timei32 = 0;
|
timei32 = 0;
|
||||||
leapcnt32 = leapcnt;
|
leapcnt32 = leapcnt;
|
||||||
leapi32 = 0;
|
leapi32 = 0;
|
||||||
while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
|
while (0 < timecnt32 && PG_INT32_MAX < ats[timecnt32 - 1])
|
||||||
--timecnt32;
|
--timecnt32;
|
||||||
while (timecnt32 > 0 && !is32(ats[timei32]))
|
while (1 < timecnt32 && ats[timei32] < PG_INT32_MIN
|
||||||
|
&& ats[timei32 + 1] <= PG_INT32_MIN)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Discard too-low transitions, except keep any last too-low
|
||||||
|
* transition if no transition is exactly at PG_INT32_MIN. The kept
|
||||||
|
* transition will be output as an PG_INT32_MIN "transition"
|
||||||
|
* appropriate for buggy 32-bit clients that do not use time type 0
|
||||||
|
* for timestamps before the first transition; see below.
|
||||||
|
*/
|
||||||
--timecnt32;
|
--timecnt32;
|
||||||
++timei32;
|
++timei32;
|
||||||
}
|
}
|
||||||
|
while (0 < leapcnt32 && PG_INT32_MAX < trans[leapcnt32 - 1])
|
||||||
/*
|
|
||||||
* Output an INT32_MIN "transition" if appropriate; see below.
|
|
||||||
*/
|
|
||||||
if (timei32 > 0 && ats[timei32] > PG_INT32_MIN)
|
|
||||||
{
|
|
||||||
--timei32;
|
|
||||||
++timecnt32;
|
|
||||||
}
|
|
||||||
while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
|
|
||||||
--leapcnt32;
|
--leapcnt32;
|
||||||
while (leapcnt32 > 0 && !is32(trans[leapi32]))
|
while (0 < leapcnt32 && trans[leapi32] < PG_INT32_MIN)
|
||||||
{
|
{
|
||||||
--leapcnt32;
|
--leapcnt32;
|
||||||
++leapi32;
|
++leapi32;
|
||||||
@ -2315,7 +2318,8 @@ writezone(const char *const name, const char *const string, char version,
|
|||||||
if (pass == 1)
|
if (pass == 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output an INT32_MIN "transition" if appropriate; see above.
|
* Output an PG_INT32_MIN "transition" if appropriate; see
|
||||||
|
* above.
|
||||||
*/
|
*/
|
||||||
puttzcode(((ats[i] < PG_INT32_MIN) ?
|
puttzcode(((ats[i] < PG_INT32_MIN) ?
|
||||||
PG_INT32_MIN : ats[i]), fp);
|
PG_INT32_MIN : ats[i]), fp);
|
||||||
|
Loading…
Reference in New Issue
Block a user