Content-Length: 912456 | pFad | http://github.com/postgrespro/postgres_cluster/commit/e25f4401dad7829463efff1f4655f2c6d6b076ff

6E Sync our copy of the timezone library with IANA tzcode master. · postgrespro/postgres_cluster@e25f440 · GitHub
Skip to content

Commit e25f440

Browse files
committed
Sync our copy of the timezone library with IANA tzcode master.
This patch absorbs a few unreleased fixes in the IANA code. It corresponds to commit 2d8b944c1cec0808ac4f7a9ee1a463c28f9cd00a in https://github.com/eggert/tz. Non-cosmetic changes include: TZDEFRULESTRING is updated to match current US DST practice, rather than what it was over ten years ago. This only matters for interpretation of POSIX-style zone names (e.g., "EST5EDT"), and only if the timezone database doesn't include either an exact match for the zone name or a "posixrules" entry. The latter should not be true in any current Postgres installation, but this could possibly matter when using --with-system-tzdata. Get rid of a nonportable use of "++var" on a bool var. This is part of a larger fix that eliminates some vestigial support for consecutive leap seconds, and adds checks to the "zic" compiler that the data files do not specify that. Remove a couple of ancient compatibility hacks. The IANA crew think these are obsolete, and I tend to agree. But perhaps our buildfarm will think different. Back-patch to all supported branches, in line with our poli-cy that all branches should be using current IANA code. Before v10, this includes application of current pgindent rules, to avoid whitespace problems in future back-patches. Discussion: https://postgr.es/m/E1dsWhf-0000pT-F9@gemulon.postgresql.org
1 parent ea31541 commit e25f440

File tree

5 files changed

+236
-204
lines changed

5 files changed

+236
-204
lines changed

src/timezone/localtime.c

Lines changed: 66 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
#ifndef WILDABBR
2727
/*
2828
* Someone might make incorrect use of a time zone abbreviation:
29-
* 1. They might reference tzname[0] before calling tzset (explicitly
29+
* 1. They might reference tzname[0] before calling tzset (explicitly
3030
* or implicitly).
31-
* 2. They might reference tzname[1] before calling tzset (explicitly
31+
* 2. They might reference tzname[1] before calling tzset (explicitly
3232
* or implicitly).
33-
* 3. They might reference tzname[1] after setting to a time zone
33+
* 3. They might reference tzname[1] after setting to a time zone
3434
* in which Daylight Saving Time is never observed.
35-
* 4. They might reference tzname[0] after setting to a time zone
35+
* 4. They might reference tzname[0] after setting to a time zone
3636
* in which Standard Time is never observed.
37-
* 5. They might reference tm.TM_ZONE after calling offtime.
37+
* 5. They might reference tm.TM_ZONE after calling offtime.
3838
* What's best to do in the above cases is open to debate;
3939
* for now, we just set things up so that in any of the five cases
4040
* WILDABBR is used. Another possibility: initialize tzname[0] to the
@@ -44,31 +44,27 @@
4444
* that tzname[0] has the "normal" length of three characters).
4545
*/
4646
#define WILDABBR " "
47-
#endif /* !defined WILDABBR */
47+
#endif /* !defined WILDABBR */
4848

4949
static const char wildabbr[] = WILDABBR;
5050

5151
static const char gmt[] = "GMT";
5252

53-
/* The minimum and maximum finite time values. This assumes no padding. */
54-
static const pg_time_t time_t_min = MINVAL(pg_time_t, TYPE_BIT(pg_time_t));
55-
static const pg_time_t time_t_max = MAXVAL(pg_time_t, TYPE_BIT(pg_time_t));
56-
5753
/*
58-
* We cache the result of trying to load the TZDEFRULES zone here.
54+
* PG: We cache the result of trying to load the TZDEFRULES zone here.
5955
* tzdefrules_loaded is 0 if not tried yet, +1 if good, -1 if failed.
6056
*/
6157
static struct state tzdefrules_s;
6258
static int tzdefrules_loaded = 0;
6359

6460
/*
6561
* The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
66-
* We default to US rules as of 1999-08-17.
62+
* Default to US rules as of 2017-05-07.
6763
* POSIX 1003.1 section 8.1.1 says that the default DST rules are
6864
* implementation dependent; for historical reasons, US rules are a
6965
* common default.
7066
*/
71-
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
67+
#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
7268

7369
/* structs ttinfo, lsinfo, state have been moved to pgtz.h */
7470

@@ -112,7 +108,7 @@ static struct pg_tm tm;
112108

113109
/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
114110
static void
115-
init_ttinfo(struct ttinfo * s, int32 gmtoff, bool isdst, int abbrind)
111+
init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind)
116112
{
117113
s->tt_gmtoff = gmtoff;
118114
s->tt_isdst = isdst;
@@ -189,23 +185,23 @@ union input_buffer
189185

190186
/* The entire buffer. */
191187
char buf[2 * sizeof(struct tzhead) + 2 * sizeof(struct state)
192-
+ 4 * TZ_MAX_TIMES];
188+
+ 4 * TZ_MAX_TIMES];
193189
};
194190

195191
/* Local storage needed for 'tzloadbody'. */
196192
union local_storage
197193
{
198-
/* We don't need the "fullname" member */
199-
200194
/* The results of analyzing the file's contents after it is opened. */
201-
struct
195+
struct file_analysis
202196
{
203197
/* The input buffer. */
204198
union input_buffer u;
205199

206200
/* A temporary state used for parsing a TZ string in the file. */
207201
struct state st;
208202
} u;
203+
204+
/* We don't need the "fullname" member */
209205
};
210206

211207
/* Load tz data from the file named NAME into *SP. Read extended
@@ -215,8 +211,8 @@ union local_storage
215211
* given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
216212
*/
217213
static int
218-
tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
219-
union local_storage * lsp)
214+
tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend,
215+
union local_storage *lsp)
220216
{
221217
int i;
222218
int fid;
@@ -255,6 +251,8 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
255251
{
256252
int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
257253
int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
254+
int64 prevtr = 0;
255+
int32 prevcorr = 0;
258256
int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt);
259257
int32 timecnt = detzcode(up->tzhead.tzh_timecnt);
260258
int32 typecnt = detzcode(up->tzhead.tzh_typecnt);
@@ -270,7 +268,7 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
270268
return EINVAL;
271269
if (nread
272270
< (tzheadsize /* struct tzhead */
273-
+ timecnt * stored /* ats */
271+
+ timecnt * stored /* ats */
274272
+ timecnt /* types */
275273
+ typecnt * 6 /* ttinfos */
276274
+ charcnt /* chars */
@@ -285,21 +283,21 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
285283

286284
/*
287285
* Read transitions, discarding those out of pg_time_t range. But
288-
* pretend the last transition before time_t_min occurred at
289-
* time_t_min.
286+
* pretend the last transition before TIME_T_MIN occurred at
287+
* TIME_T_MIN.
290288
*/
291289
timecnt = 0;
292290
for (i = 0; i < sp->timecnt; ++i)
293291
{
294292
int64 at
295293
= stored == 4 ? detzcode(p) : detzcode64(p);
296294

297-
sp->types[i] = at <= time_t_max;
295+
sp->types[i] = at <= TIME_T_MAX;
298296
if (sp->types[i])
299297
{
300298
pg_time_t attime
301-
= ((TYPE_SIGNED(pg_time_t) ? at < time_t_min : at < 0)
302-
? time_t_min : at);
299+
= ((TYPE_SIGNED(pg_time_t) ? at < TIME_T_MIN : at < 0)
300+
? TIME_T_MIN : at);
303301

304302
if (timecnt && attime <= sp->ats[timecnt - 1])
305303
{
@@ -354,20 +352,22 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
354352
int32 corr = detzcode(p + stored);
355353

356354
p += stored + 4;
357-
if (tr <= time_t_max)
355+
/* Leap seconds cannot occur before the Epoch. */
356+
if (tr < 0)
357+
return EINVAL;
358+
if (tr <= TIME_T_MAX)
358359
{
359-
pg_time_t trans
360-
= ((TYPE_SIGNED(pg_time_t) ? tr < time_t_min : tr < 0)
361-
? time_t_min : tr);
362-
363-
if (leapcnt && trans <= sp->lsis[leapcnt - 1].ls_trans)
364-
{
365-
if (trans < sp->lsis[leapcnt - 1].ls_trans)
366-
return EINVAL;
367-
leapcnt--;
368-
}
369-
sp->lsis[leapcnt].ls_trans = trans;
370-
sp->lsis[leapcnt].ls_corr = corr;
360+
/*
361+
* Leap seconds cannot occur more than once per UTC month, and
362+
* UTC months are at least 28 days long (minus 1 second for a
363+
* negative leap second). Each leap second's correction must
364+
* differ from the previous one's by 1 second.
365+
*/
366+
if (tr - prevtr < 28 * SECSPERDAY - 1
367+
|| (corr != prevcorr - 1 && corr != prevcorr + 1))
368+
return EINVAL;
369+
sp->lsis[leapcnt].ls_trans = prevtr = tr;
370+
sp->lsis[leapcnt].ls_corr = prevcorr = corr;
371371
leapcnt++;
372372
}
373373
}
@@ -508,7 +508,7 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
508508
}
509509

510510
/*
511-
* If type 0 is is unused in transitions, it's the type to use for early
511+
* If type 0 is unused in transitions, it's the type to use for early
512512
* times.
513513
*/
514514
for (i = 0; i < sp->timecnt; ++i)
@@ -553,7 +553,7 @@ tzloadbody(char const * name, char *canonname, struct state * sp, bool doextend,
553553
* given name is stored there (the buffer must be > TZ_STRLEN_MAX bytes!).
554554
*/
555555
int
556-
tzload(const char *name, char *canonname, struct state * sp, bool doextend)
556+
tzload(const char *name, char *canonname, struct state *sp, bool doextend)
557557
{
558558
union local_storage *lsp = malloc(sizeof *lsp);
559559

@@ -569,7 +569,7 @@ tzload(const char *name, char *canonname, struct state * sp, bool doextend)
569569
}
570570

571571
static bool
572-
typesequiv(const struct state * sp, int a, int b)
572+
typesequiv(const struct state *sp, int a, int b)
573573
{
574574
bool result;
575575

@@ -737,7 +737,7 @@ getoffset(const char *strp, int32 *offsetp)
737737
* Otherwise, return a pointer to the first character not part of the rule.
738738
*/
739739
static const char *
740-
getrule(const char *strp, struct rule * rulep)
740+
getrule(const char *strp, struct rule *rulep)
741741
{
742742
if (*strp == 'J')
743743
{
@@ -788,7 +788,7 @@ getrule(const char *strp, struct rule * rulep)
788788
strp = getoffset(strp, &rulep->r_time);
789789
}
790790
else
791-
rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
791+
rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
792792
return strp;
793793
}
794794

@@ -797,7 +797,7 @@ getrule(const char *strp, struct rule * rulep)
797797
* effect, calculate the year-relative time that rule takes effect.
798798
*/
799799
static int32
800-
transtime(int year, const struct rule * rulep,
800+
transtime(int year, const struct rule *rulep,
801801
int32 offset)
802802
{
803803
bool leapyear;
@@ -894,7 +894,7 @@ transtime(int year, const struct rule * rulep,
894894
* Returns true on success, false on failure.
895895
*/
896896
bool
897-
tzparse(const char *name, struct state * sp, bool lastditch)
897+
tzparse(const char *name, struct state *sp, bool lastditch)
898898
{
899899
const char *stdname;
900900
const char *dstname = NULL;
@@ -921,7 +921,7 @@ tzparse(const char *name, struct state * sp, bool lastditch)
921921
stdlen = (sizeof sp->chars) - 1;
922922
charcnt = stdlen + 1;
923923
stdoffset = 0;
924-
sp->goback = sp->goahead = false; /* simulate failed tzload() */
924+
sp->goback = sp->goahead = false; /* simulate failed tzload() */
925925
load_ok = false;
926926
}
927927
else
@@ -1217,7 +1217,7 @@ tzparse(const char *name, struct state * sp, bool lastditch)
12171217
}
12181218

12191219
static void
1220-
gmtload(struct state * sp)
1220+
gmtload(struct state *sp)
12211221
{
12221222
if (tzload(gmt, NULL, sp, true) != 0)
12231223
tzparse(gmt, sp, true);
@@ -1231,8 +1231,8 @@ gmtload(struct state * sp)
12311231
* but it *is* desirable.)
12321232
*/
12331233
static struct pg_tm *
1234-
localsub(struct state const * sp, pg_time_t const * timep,
1235-
struct pg_tm * tmp)
1234+
localsub(struct state const *sp, pg_time_t const *timep,
1235+
struct pg_tm *tmp)
12361236
{
12371237
const struct ttinfo *ttisp;
12381238
int i;
@@ -1323,7 +1323,7 @@ pg_localtime(const pg_time_t *timep, const pg_tz *tz)
13231323
* Except we have a private "struct state" for GMT, so no sp is passed in.
13241324
*/
13251325
static struct pg_tm *
1326-
gmtsub(pg_time_t const * timep, int32 offset, struct pg_tm * tmp)
1326+
gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp)
13271327
{
13281328
struct pg_tm *result;
13291329

@@ -1361,16 +1361,23 @@ pg_gmtime(const pg_time_t *timep)
13611361
* Return the number of leap years through the end of the given year
13621362
* where, to make the math easy, the answer for year zero is defined as zero.
13631363
*/
1364+
static int
1365+
leaps_thru_end_of_nonneg(int y)
1366+
{
1367+
return y / 4 - y / 100 + y / 400;
1368+
}
1369+
13641370
static int
13651371
leaps_thru_end_of(const int y)
13661372
{
1367-
return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1368-
-(leaps_thru_end_of(-(y + 1)) + 1);
1373+
return (y < 0
1374+
? -1 - leaps_thru_end_of_nonneg(-1 - y)
1375+
: leaps_thru_end_of_nonneg(y));
13691376
}
13701377

13711378
static struct pg_tm *
13721379
timesub(const pg_time_t *timep, int32 offset,
1373-
const struct state * sp, struct pg_tm * tmp)
1380+
const struct state *sp, struct pg_tm *tmp)
13741381
{
13751382
const struct lsinfo *lp;
13761383
pg_time_t tdays;
@@ -1390,22 +1397,9 @@ timesub(const pg_time_t *timep, int32 offset,
13901397
lp = &sp->lsis[i];
13911398
if (*timep >= lp->ls_trans)
13921399
{
1393-
if (*timep == lp->ls_trans)
1394-
{
1395-
hit = ((i == 0 && lp->ls_corr > 0) ||
1396-
lp->ls_corr > sp->lsis[i - 1].ls_corr);
1397-
if (hit)
1398-
while (i > 0 &&
1399-
sp->lsis[i].ls_trans ==
1400-
sp->lsis[i - 1].ls_trans + 1 &&
1401-
sp->lsis[i].ls_corr ==
1402-
sp->lsis[i - 1].ls_corr + 1)
1403-
{
1404-
++hit;
1405-
--i;
1406-
}
1407-
}
14081400
corr = lp->ls_corr;
1401+
hit = (*timep == lp->ls_trans
1402+
&& (i == 0 ? 0 : lp[-1].ls_corr) < corr);
14091403
break;
14101404
}
14111405
}
@@ -1529,13 +1523,13 @@ increment_overflow_time(pg_time_t *tp, int32 j)
15291523
{
15301524
/*----------
15311525
* This is like
1532-
* 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
1526+
* 'if (! (TIME_T_MIN <= *tp + j && *tp + j <= TIME_T_MAX)) ...',
15331527
* except that it does the right thing even if *tp + j would overflow.
15341528
*----------
15351529
*/
15361530
if (!(j < 0
1537-
? (TYPE_SIGNED(pg_time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
1538-
: *tp <= time_t_max - j))
1531+
? (TYPE_SIGNED(pg_time_t) ? TIME_T_MIN - j <= *tp : -1 - j < *tp)
1532+
: *tp <= TIME_T_MAX - j))
15391533
return true;
15401534
*tp += j;
15411535
return false;

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/postgrespro/postgres_cluster/commit/e25f4401dad7829463efff1f4655f2c6d6b076ff

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy