• Tom Lane's avatar
    Improve tzparse's handling of TZDEFRULES ("posixrules") zone data. · e7eb07f7
    Tom Lane authored
    In the IANA timezone code, tzparse() always tries to load the zone
    file named by TZDEFRULES ("posixrules").  Previously, we'd hacked
    that logic to skip the load in the "lastditch" code path, which we use
    only to initialize the default "GMT" zone during GUC initialization.
    That's critical for a couple of reasons: since we do not support leap
    seconds, we *must not* allow "GMT" to have leap seconds, and since this
    case runs before the GUC subsystem is fully alive, we'd really rather
    not take the risk of pg_open_tzfile throwing any errors.
    
    However, that still left the code reading TZDEFRULES on every other
    call, something we'd noticed to the extent of having added code to cache
    the result so it was only done once per process not a lot of times.
    Andres Freund complained about the static data space used up for the
    cache; but as long as the logic was like this, there was no point in
    trying to get rid of that space.
    
    We can improve matters by looking a bit more closely at what the IANA
    code actually needs the TZDEFRULES data for.  One thing it does is
    that if "posixrules" is a leap-second-aware zone, the leap-second
    behavior will be absorbed into every POSIX-style zone specification.
    However, that's a behavior we'd really prefer to do without, since
    for our purposes the end effect is to render every POSIX-style zone
    name unsupported.  Otherwise, the TZDEFRULES data is used only if
    the POSIX zone name specifies DST but doesn't include a transition
    date rule (e.g., "EST5EDT" rather than "EST5EDT,M3.2.0,M11.1.0").
    That is a minority case for our purposes --- in particular, it
    never happens when tzload() invokes tzparse() to interpret a
    transition date rule string found in a tzdata zone file.
    
    Hence, if we legislate that we're going to ignore leap-second data
    from "posixrules", we can postpone the TZDEFRULES load into the path
    where we actually need to substitute for a missing date rule string.
    That means it will never happen at all in common scenarios, making it
    reasonable to dynamically allocate the cache space when it does happen.
    Even when the data is already loaded, this saves some cycles in the
    common code path since we avoid a memcpy of 23KB or so.  And, IMO at
    least, this is a less ugly hack on the IANA logic than what we had
    before, since it's not messing with the lastditch-vs-regular code paths.
    
    Back-patch to all supported branches, not so much because this is a
    critical change as that I want to keep all our copies of the IANA
    timezone code in sync.
    
    Discussion: https://postgr.es/m/20181015200754.7y7zfuzsoux2c4ya@alap3.anarazel.de
    e7eb07f7
localtime.c 43.5 KB