From 596857043023738099d6d16f8edbe6b7353876c0 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 3 Oct 2014 14:48:11 -0400
Subject: [PATCH] Fix bogus logic for zic -P option.

The quick hack I added to zic to dump out currently-in-use timezone
abbreviations turns out to have a nasty bug: within each zone, it was
printing the last "struct ttinfo" to be *defined*, not necessarily the
last one in use.  This was mainly a problem in zones that had changed the
meaning of their zone abbreviation (to another GMT offset value) and later
changed it back.

As a result of this error, we'd missed out updating the tznames/ files
for some jurisdictions that have changed their zone abbreviations since
the tznames/ files were originally created.  I'll address the missing data
updates in a separate commit.
---
 src/timezone/zic.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index 2e389903230..13baf73d3c1 100644
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -1766,7 +1766,25 @@ writezone(const char *name, const char *string)
 			if (pass == 1)
 				puttzcode((long) ats[i], fp);
 			else
+			{
 				puttzcode64(ats[i], fp);
+
+				/* Print current timezone abbreviations if requested */
+				if (print_abbrevs &&
+					(ats[i] >= print_cutoff || i == thistimelim - 1))
+				{
+					unsigned char tm = typemap[types[i]];
+					char	   *thisabbrev = &thischars[indmap[abbrinds[tm]]];
+
+					/* filter out assorted junk entries */
+					if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
+						strcmp(thisabbrev, "zzz") != 0)
+						fprintf(stdout, "%s\t%ld%s\n",
+								thisabbrev,
+								gmtoffs[tm],
+								isdsts[tm] ? "\tD" : "");
+				}
+			}
 		for (i = thistimei; i < thistimelim; ++i)
 		{
 			unsigned char uc;
@@ -1783,21 +1801,6 @@ writezone(const char *name, const char *string)
 				puttzcode(gmtoffs[i], fp);
 				(void) putc(isdsts[i], fp);
 				(void) putc((unsigned char) indmap[abbrinds[i]], fp);
-
-				/* Print current timezone abbreviations if requested */
-				if (print_abbrevs && pass == 2 &&
-					(ats[i] >= print_cutoff || i == typecnt - 1))
-				{
-					char	   *thisabbrev = &thischars[indmap[abbrinds[i]]];
-
-					/* filter out assorted junk entries */
-					if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
-						strcmp(thisabbrev, "zzz") != 0)
-						fprintf(stdout, "%s\t%ld%s\n",
-								thisabbrev,
-								gmtoffs[i],
-								isdsts[i] ? "\tD" : "");
-				}
 			}
 		if (thischarcnt != 0)
 			(void) fwrite((void *) thischars,
-- 
GitLab