1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Sync our copy of the timezone library with IANA release tzcode2019b.

A large fraction of this diff is just due to upstream's somewhat
random decision to rename a bunch of internal variables and struct
fields.  However, there is an interesting new feature in zic:
it's grown a "-b slim" option that emits zone files without 32-bit
data and other backwards-compatibility hacks.  We should consider
whether we wish to enable that.
This commit is contained in:
Tom Lane
2019-07-17 18:26:23 -04:00
parent e0d13dc6fd
commit 59cea8f36b
5 changed files with 306 additions and 268 deletions

View File

@ -107,15 +107,15 @@ static bool typesequiv(struct state const *, int, int);
static struct pg_tm tm;
/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
static void
init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx)
{
s->tt_gmtoff = gmtoff;
s->tt_utoff = utoff;
s->tt_isdst = isdst;
s->tt_abbrind = abbrind;
s->tt_desigidx = desigidx;
s->tt_ttisstd = false;
s->tt_ttisgmt = false;
s->tt_ttisut = false;
}
static int32
@ -251,7 +251,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
for (stored = 4; stored <= 8; stored *= 2)
{
int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
int64 prevtr = 0;
int32 prevcorr = 0;
int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
@ -270,7 +270,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
&& (ttisstdcnt == typecnt || ttisstdcnt == 0)
&& (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
&& (ttisutcnt == typecnt || ttisutcnt == 0)))
return EINVAL;
if (nread
< (tzheadsize /* struct tzhead */
@ -280,7 +280,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
+ charcnt /* chars */
+ leapcnt * (stored + 4) /* lsinfos */
+ ttisstdcnt /* ttisstds */
+ ttisgmtcnt)) /* ttisgmts */
+ ttisutcnt)) /* ttisuts */
return EINVAL;
sp->leapcnt = leapcnt;
sp->timecnt = timecnt;
@ -332,19 +332,19 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
{
struct ttinfo *ttisp;
unsigned char isdst,
abbrind;
desigidx;
ttisp = &sp->ttis[i];
ttisp->tt_gmtoff = detzcode(p);
ttisp->tt_utoff = detzcode(p);
p += 4;
isdst = *p++;
if (!(isdst < 2))
return EINVAL;
ttisp->tt_isdst = isdst;
abbrind = *p++;
if (!(abbrind < sp->charcnt))
desigidx = *p++;
if (!(desigidx < sp->charcnt))
return EINVAL;
ttisp->tt_abbrind = abbrind;
ttisp->tt_desigidx = desigidx;
}
for (i = 0; i < sp->charcnt; ++i)
sp->chars[i] = *p++;
@ -398,13 +398,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
struct ttinfo *ttisp;
ttisp = &sp->ttis[i];
if (ttisgmtcnt == 0)
ttisp->tt_ttisgmt = false;
if (ttisutcnt == 0)
ttisp->tt_ttisut = false;
else
{
if (*p != true && *p != false)
return EINVAL;
ttisp->tt_ttisgmt = *p++;
ttisp->tt_ttisut = *p++;
}
}
@ -438,13 +438,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
for (i = 0; i < ts->typecnt; i++)
{
char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind;
char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx;
int j;
for (j = 0; j < charcnt; j++)
if (strcmp(sp->chars + j, tsabbr) == 0)
{
ts->ttis[i].tt_abbrind = j;
ts->ttis[i].tt_desigidx = j;
gotabbr++;
break;
}
@ -456,7 +456,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
{
strcpy(sp->chars + j, tsabbr);
charcnt = j + tsabbrlen + 1;
ts->ttis[i].tt_abbrind = j;
ts->ttis[i].tt_desigidx = j;
gotabbr++;
}
}
@ -614,12 +614,13 @@ typesequiv(const struct state *sp, int a, int b)
const struct ttinfo *ap = &sp->ttis[a];
const struct ttinfo *bp = &sp->ttis[b];
result = ap->tt_gmtoff == bp->tt_gmtoff &&
ap->tt_isdst == bp->tt_isdst &&
ap->tt_ttisstd == bp->tt_ttisstd &&
ap->tt_ttisgmt == bp->tt_ttisgmt &&
strcmp(&sp->chars[ap->tt_abbrind],
&sp->chars[bp->tt_abbrind]) == 0;
result = (ap->tt_utoff == bp->tt_utoff
&& ap->tt_isdst == bp->tt_isdst
&& ap->tt_ttisstd == bp->tt_ttisstd
&& ap->tt_ttisut == bp->tt_ttisut
&& (strcmp(&sp->chars[ap->tt_desigidx],
&sp->chars[bp->tt_desigidx])
== 0));
}
return result;
}
@ -1176,7 +1177,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
if (!sp->ttis[j].tt_isdst)
{
theirstdoffset =
-sp->ttis[j].tt_gmtoff;
-sp->ttis[j].tt_utoff;
break;
}
}
@ -1187,7 +1188,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
if (sp->ttis[j].tt_isdst)
{
theirdstoffset =
-sp->ttis[j].tt_gmtoff;
-sp->ttis[j].tt_utoff;
break;
}
}
@ -1206,7 +1207,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
{
j = sp->types[i];
sp->types[i] = sp->ttis[j].tt_isdst;
if (sp->ttis[j].tt_ttisgmt)
if (sp->ttis[j].tt_ttisut)
{
/* No adjustment to transition time */
}
@ -1234,7 +1235,7 @@ tzparse(const char *name, struct state *sp, bool lastditch)
theirstdoffset;
}
}
theiroffset = -sp->ttis[j].tt_gmtoff;
theiroffset = -sp->ttis[j].tt_utoff;
if (sp->ttis[j].tt_isdst)
theirdstoffset = theiroffset;
else
@ -1357,14 +1358,14 @@ localsub(struct state const *sp, pg_time_t const *timep,
/*
* To get (wrong) behavior that's compatible with System V Release 2.0
* you'd replace the statement below with t += ttisp->tt_gmtoff;
* you'd replace the statement below with t += ttisp->tt_utoff;
* timesub(&t, 0L, sp, tmp);
*/
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
result = timesub(&t, ttisp->tt_utoff, sp, tmp);
if (result)
{
result->tm_isdst = ttisp->tt_isdst;
result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_abbrind]);
result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_desigidx]);
}
return result;
}
@ -1647,7 +1648,7 @@ pg_next_dst_boundary(const pg_time_t *timep,
break;
}
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
return 0;
}
@ -1700,7 +1701,7 @@ pg_next_dst_boundary(const pg_time_t *timep,
/* No known transition > t, so use last known segment's type */
i = sp->types[sp->timecnt - 1];
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
return 0;
}
@ -1715,13 +1716,13 @@ pg_next_dst_boundary(const pg_time_t *timep,
break;
}
ttisp = &sp->ttis[i];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
*boundary = sp->ats[0];
/* And for "after", use the first segment's type */
i = sp->types[0];
ttisp = &sp->ttis[i];
*after_gmtoff = ttisp->tt_gmtoff;
*after_gmtoff = ttisp->tt_utoff;
*after_isdst = ttisp->tt_isdst;
return 1;
}
@ -1743,12 +1744,12 @@ pg_next_dst_boundary(const pg_time_t *timep,
}
j = sp->types[i - 1];
ttisp = &sp->ttis[j];
*before_gmtoff = ttisp->tt_gmtoff;
*before_gmtoff = ttisp->tt_utoff;
*before_isdst = ttisp->tt_isdst;
*boundary = sp->ats[i];
j = sp->types[i];
ttisp = &sp->ttis[j];
*after_gmtoff = ttisp->tt_gmtoff;
*after_gmtoff = ttisp->tt_utoff;
*after_isdst = ttisp->tt_isdst;
return 1;
}
@ -1832,9 +1833,9 @@ pg_interpret_timezone_abbrev(const char *abbrev,
for (i = cutoff - 1; i >= 0; i--)
{
ttisp = &sp->ttis[sp->types[i]];
if (ttisp->tt_abbrind == abbrind)
if (ttisp->tt_desigidx == abbrind)
{
*gmtoff = ttisp->tt_gmtoff;
*gmtoff = ttisp->tt_utoff;
*isdst = ttisp->tt_isdst;
return true;
}
@ -1846,9 +1847,9 @@ pg_interpret_timezone_abbrev(const char *abbrev,
for (i = cutoff; i < sp->timecnt; i++)
{
ttisp = &sp->ttis[sp->types[i]];
if (ttisp->tt_abbrind == abbrind)
if (ttisp->tt_desigidx == abbrind)
{
*gmtoff = ttisp->tt_gmtoff;
*gmtoff = ttisp->tt_utoff;
*isdst = ttisp->tt_isdst;
return true;
}
@ -1875,10 +1876,10 @@ pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
sp = &tz->state;
for (i = 1; i < sp->typecnt; i++)
{
if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff)
if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff)
return false;
}
*gmtoff = sp->ttis[0].tt_gmtoff;
*gmtoff = sp->ttis[0].tt_utoff;
return true;
}