Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ea57e53

Browse files
committed
Remove support for timezone "posixrules" file.
The IANA tzcode library has a feature to read a time zone file named "posixrules" and apply the daylight-savings transition dates and times therein, when it is given a POSIX-style time zone specification that lacks an explicit transition rule. However, there's a problem with that code: it doesn't work for dates past the Y2038 time_t rollover. (Effectively, all times beyond that point are treated as standard time.) The IANA crew regard this feature as legacy, so their plan is to remove it not fix it. The time frame in which that will happen is unclear, but presumably it'll happen well before 2038. Moreover, effective with the next IANA data update (probably this fall), the recommended default will be to not install a "posixrules" file in the first place. The time frame in which tzdata packagers might adopt that suggestion is likewise unclear, but at least some platforms will probably do it in the next year or so. While we could ignore that recommendation so far as PG-supplied tzdata trees are concerned, builds using --with-system-tzdata will be subject to whatever the platform's tzdata packager decides to do. Thus, whether or not we do anything, some increasing fraction of Postgres users will be exposed to the behavior observed when there is no "posixrules" file; and if we do nothing, we'll have essentially no control over the timing of that change. The best thing to do to ameliorate the uncertainty seems to be to proactively remove the posixrules-reading feature. If we do that in a scheduled release then at least we can release-note the behavioral change, rather than having users be surprised by it after a routine tzdata update. The change in question is fairly minor anyway: to be affected, you have to be using a POSIX-style timezone spec, it has to not have an explicit rule, and it has to not be one of the four traditional continental-USA zone names (EST5EDT, CST6CDT, MST7MDT, or PST8PDT), as those are special-cased. Since the default "posixrules" file provides USA DST rules, the number of people who are likely to find such a zone spec useful is probably quite small. Moreover, the fallback behavior with no explicit rule and no "posixrules" file is to apply current USA rules, so the only thing that really breaks is the DST transitions in years before 2007 (and you get the countervailing fix that transitions after 2038 will be applied). Now, some installations might have replaced the "posixrules" file, allowing e.g. EU rules to be applied to a POSIX-style timezone spec. That won't work anymore. But it's not exactly clear why this solution would be preferable to using a regular named zone. In any case, given the Y2038 issue, we need to be pushing users to stop depending on this. Back-patch into v13; it hasn't been released yet, so it seems OK to change its behavior. (Personally I think we ought to back-patch further, but I've been outvoted.) Discussion: https://postgr.es/m/1390.1562258309@sss.pgh.pa.us Discussion: https://postgr.es/m/20200621211855.6211-1-eggert@cs.ucla.edu
1 parent c410af0 commit ea57e53

File tree

5 files changed

+18
-89
lines changed

5 files changed

+18
-89
lines changed

doc/src/sgml/datetime.sgml

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -718,33 +718,12 @@
718718
<para>
719719
If a daylight-savings abbreviation is given but the
720720
transition <replaceable>rule</replaceable> field is omitted,
721-
<productname>PostgreSQL</productname> attempts to determine the
722-
transition times by consulting the <filename>posixrules</filename> file
723-
in the IANA time zone database. This file has the same format as a
724-
full time zone entry, but only its transition timing rules are used,
725-
not its UTC offsets. Typically, this file has the same contents as the
726-
<literal>US/Eastern</literal> file, so that POSIX-style time zone
727-
specifications follow USA daylight-savings rules. If needed, you can
728-
adjust this behavior by replacing the <filename>posixrules</filename>
729-
file.
730-
</para>
731-
732-
<note>
733-
<para>
734-
The facility to consult a <filename>posixrules</filename> file has
735-
been deprecated by IANA, and it is likely to go away in the future.
736-
One bug in this feature, which is unlikely to be fixed before it
737-
disappears, is that it fails to apply DST rules to dates after 2038.
738-
</para>
739-
</note>
740-
741-
<para>
742-
If the <filename>posixrules</filename> file is not present,
743721
the fallback behavior is to use the
744722
rule <literal>M3.2.0,M11.1.0</literal>, which corresponds to USA
745723
practice as of 2020 (that is, spring forward on the second Sunday of
746724
March, fall back on the first Sunday of November, both transitions
747-
occurring at 2AM prevailing time).
725+
occurring at 2AM prevailing time). Note that this rule does not
726+
give correct USA transition dates for years before 2007.
748727
</para>
749728

750729
<para>
@@ -765,8 +744,7 @@
765744
because (for historical reasons) there are files by those names in the
766745
IANA time zone database. The practical implication of this is that
767746
these zone names will produce valid historical USA daylight-savings
768-
transitions, even when a plain POSIX specification would not due to
769-
lack of a suitable <filename>posixrules</filename> file.
747+
transitions, even when a plain POSIX specification would not.
770748
</para>
771749

772750
<para>

src/timezone/Makefile

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ ZICOBJS = \
2929
# we now distribute the timezone data as a single file
3030
TZDATAFILES = $(srcdir)/data/tzdata.zi
3131

32-
# which zone should determine the DST rules (not the specific UTC offset!)
33-
# for POSIX-style timezone specs
34-
POSIXRULES = US/Eastern
35-
3632
# any custom options you might want to pass to zic while installing data files
3733
ZIC_OPTIONS =
3834

@@ -60,13 +56,13 @@ zic: $(ZICOBJS) | submake-libpgport
6056

6157
install: all installdirs
6258
ifeq (,$(with_system_tzdata))
63-
$(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' -b slim $(ZIC_OPTIONS) $(TZDATAFILES)
59+
$(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -b slim $(ZIC_OPTIONS) $(TZDATAFILES)
6460
endif
6561
$(MAKE) -C tznames $@
6662

6763
abbrevs.txt: zic $(TZDATAFILES)
6864
mkdir junkdir
69-
$(ZIC) -P -d junkdir -p '$(POSIXRULES)' $(TZDATAFILES) | LANG=C sort | uniq >abbrevs.txt
65+
$(ZIC) -P -d junkdir $(TZDATAFILES) | LANG=C sort | uniq >abbrevs.txt
7066
rm -rf junkdir
7167

7268
installdirs:

src/timezone/README

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,7 @@ in some other files where we have variables named that.
9393
slightly modified the API of the former, in part because it now relies
9494
on our own pg_open_tzfile() rather than opening files for itself.
9595

96-
* tzparse() is adjusted to avoid loading the TZDEFRULES zone unless
97-
really necessary, and to ignore any leap-second data it may supply.
98-
We also cache the result of loading the TZDEFRULES zone, so that
99-
that's not repeated more than once per process.
96+
* tzparse() is adjusted to never try to load the TZDEFRULES zone.
10097

10198
* There's a fair amount of code we don't need and have removed,
10299
including all the nonstandard optional APIs. We have also added

src/timezone/localtime.c

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,7 @@ static const char wildabbr[] = WILDABBR;
5353
static const char gmt[] = "GMT";
5454

5555
/*
56-
* PG: We cache the result of trying to load the TZDEFRULES zone here.
57-
* tzdefrules_loaded is 0 if not tried yet, +1 if good, -1 if failed.
58-
*/
59-
static struct state *tzdefrules_s = NULL;
60-
static int tzdefrules_loaded = 0;
61-
62-
/*
63-
* The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
56+
* The DST rules to use if a POSIX TZ string has no rules.
6457
* Default to US rules as of 2017-05-07.
6558
* POSIX does not specify the default DST rules;
6659
* for historical reasons, US rules are a common default.
@@ -986,14 +979,15 @@ tzparse(const char *name, struct state *sp, bool lastditch)
986979
return false;
987980

988981
/*
989-
* The IANA code always tries tzload(TZDEFRULES) here. We do not want to
990-
* do that; it would be bad news in the lastditch case, where we can't
991-
* assume pg_open_tzfile() is sane yet. Moreover, the only reason to do
992-
* it unconditionally is to absorb the TZDEFRULES zone's leap second info,
993-
* which we don't want to do anyway. Without that, we only need to load
994-
* TZDEFRULES if the zone name specifies DST but doesn't incorporate a
995-
* POSIX-style transition date rule, which is not a common case.
982+
* The IANA code always tries to tzload(TZDEFRULES) here. We do not want
983+
* to do that; it would be bad news in the lastditch case, where we can't
984+
* assume pg_open_tzfile() is sane yet. Moreover, if we did load it and
985+
* it contains leap-second-dependent info, that would cause problems too.
986+
* Finally, IANA has deprecated the TZDEFRULES feature, so it presumably
987+
* will die at some point. Desupporting it now seems like good
988+
* future-proofing.
996989
*/
990+
load_ok = false;
997991
sp->goback = sp->goahead = false; /* simulate failed tzload() */
998992
sp->leapcnt = 0; /* intentionally assume no leap seconds */
999993

@@ -1027,38 +1021,8 @@ tzparse(const char *name, struct state *sp, bool lastditch)
10271021
}
10281022
else
10291023
dstoffset = stdoffset - SECSPERHOUR;
1030-
if (*name == '\0')
1031-
{
1032-
/*
1033-
* The POSIX zone name does not provide a transition-date rule.
1034-
* Here we must load the TZDEFRULES zone, if possible, to serve as
1035-
* source data for the transition dates. Unlike the IANA code, we
1036-
* try to cache the data so it's only loaded once.
1037-
*/
1038-
if (tzdefrules_loaded == 0)
1039-
{
1040-
/* Allocate on first use */
1041-
if (tzdefrules_s == NULL)
1042-
tzdefrules_s = (struct state *) malloc(sizeof(struct state));
1043-
if (tzdefrules_s != NULL)
1044-
{
1045-
if (tzload(TZDEFRULES, NULL, tzdefrules_s, false) == 0)
1046-
tzdefrules_loaded = 1;
1047-
else
1048-
tzdefrules_loaded = -1;
1049-
/* In any case, we ignore leap-second data from the file */
1050-
tzdefrules_s->leapcnt = 0;
1051-
}
1052-
}
1053-
load_ok = (tzdefrules_loaded > 0);
1054-
if (load_ok)
1055-
memcpy(sp, tzdefrules_s, sizeof(struct state));
1056-
else
1057-
{
1058-
/* If we can't load TZDEFRULES, fall back to hard-wired rule */
1059-
name = TZDEFRULESTRING;
1060-
}
1061-
}
1024+
if (*name == '\0' && !load_ok)
1025+
name = TZDEFRULESTRING;
10621026
if (*name == ',' || *name == ';')
10631027
{
10641028
struct rule start;

src/tools/msvc/Install.pm

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,16 +366,10 @@ sub GenerateTimezoneFiles
366366
|| die "Could not find TZDATAFILES line in timezone makefile\n";
367367
my @tzfiles = split /\s+/, $1;
368368

369-
$mf =~ /^POSIXRULES\s*:?=\s*(.*)$/m
370-
|| die "Could not find POSIXRULES line in timezone makefile\n";
371-
my $posixrules = $1;
372-
$posixrules =~ s/\s+//g;
373-
374369
print "Generating timezone files...";
375370

376371
my @args = (
377-
"$conf/zic/zic", '-d', "$target/share/timezone", '-p',
378-
"$posixrules", '-b', 'slim');
372+
"$conf/zic/zic", '-d', "$target/share/timezone", '-b', 'slim');
379373
foreach (@tzfiles)
380374
{
381375
my $tzfile = $_;

0 commit comments

Comments
 (0)