From 7dac778561808267a064c0709e44a19057ab52f5 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Mon, 18 Jun 2001 16:14:44 +0000
Subject: [PATCH] Add GUC setting for Australian timezones.  Uses new GUC
 boolean callback functions to clear date cache.  Allow regression tests to
 pass when timezone set.

---
 doc/src/sgml/runtime.sgml                     | 13 ++++-
 src/backend/utils/adt/datetime.c              | 53 ++++++++++---------
 src/backend/utils/misc/guc.c                  | 17 ++++--
 src/backend/utils/misc/postgresql.conf.sample | 28 ++++------
 src/include/utils/datetime.h                  |  4 +-
 src/include/utils/guc.h                       |  3 +-
 .../expected/horology-no-DST-before-1970.out  |  2 +
 .../expected/horology-solaris-1947.out        |  2 +
 src/test/regress/expected/horology.out        |  2 +
 src/test/regress/expected/timestamp.out       |  2 +
 src/test/regress/sql/horology.sql             |  3 +-
 src/test/regress/sql/timestamp.sql            |  3 +-
 12 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index f5ed95be5d4..9ec23973fbe 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.67 2001/05/17 17:44:17 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.68 2001/06/18 16:14:43 momjian Exp $
 -->
 
 <Chapter Id="runtime">
@@ -1201,6 +1201,17 @@ dynamic_library_path = '/usr/local/lib:/home/my_project/lib:$libdir:$libdir/cont
       </listitem>
      </varlistentry>
 
+      <term>AUSTRALIAN_TIMEZONES (<type>bool</type>)</term>
+      <listitem>
+       <para>
+        If set to true, <literal>CST</literal>, <literal>EST</literal>,
+        and <literal>SAT</literal> are interpreted as Australian
+        timezones rather than as North American Central/Eastern
+        Timezones and Saturday. The default is false.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry>
       <indexterm>
        <primary>SSL</primary>
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 1a13aa4a4af..81a3d96b8aa 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.64 2001/05/03 22:53:07 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.65 2001/06/18 16:14:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include <limits.h>
 
 #include "miscadmin.h"
+#include "utils/guc.h"
 #include "utils/datetime.h"
 
 static int DecodeNumber(int flen, char *field,
@@ -36,7 +37,6 @@ static int	DecodeTimezone(char *str, int *tzp);
 static datetkn *datebsearch(char *key, datetkn *base, unsigned int nel);
 static int	DecodeDate(char *str, int fmask, int *tmask, struct tm * tm);
 
-#define USE_DATE_CACHE 1
 #define ROUND_ALL 0
 
 static int	DecodePosixTimezone(char *str, int *val);
@@ -117,11 +117,7 @@ static datetkn datetktbl[] = {
 	{"cdt", DTZ, NEG(30)},		/* Central Daylight Time */
 	{"cet", TZ, 6},				/* Central European Time */
 	{"cetdst", DTZ, 12},		/* Central European Dayl.Time */
-#if USE_AUSTRALIAN_RULES
-	{"cst", TZ, 63},			/* Australia Eastern Std Time */
-#else
 	{"cst", TZ, NEG(36)},		/* Central Standard Time */
-#endif
 	{DCURRENT, RESERV, DTK_CURRENT},	/* "current" is always now */
 	{"dec", MONTH, 12},
 	{"december", MONTH, 12},
@@ -134,11 +130,7 @@ static datetkn datetktbl[] = {
 	{"eet", TZ, 12},			/* East. Europe, USSR Zone 1 */
 	{"eetdst", DTZ, 18},		/* Eastern Europe */
 	{EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
-#if USE_AUSTRALIAN_RULES
-	{"est", TZ, 60},			/* Australia Eastern Std Time */
-#else
 	{"est", TZ, NEG(30)},		/* Eastern Standard Time */
-#endif
 	{"feb", MONTH, 2},
 	{"february", MONTH, 2},
 	{"fri", DOW, 5},
@@ -199,11 +191,7 @@ static datetkn datetktbl[] = {
 	{"pst", TZ, NEG(48)},		/* Pacific Standard Time */
 	{"sadt", DTZ, 63},			/* S. Australian Dayl. Time */
 	{"sast", TZ, 57},			/* South Australian Std Time */
-#if USE_AUSTRALIAN_RULES
-	{"sat", TZ, 57},
-#else
 	{"sat", DOW, 6},
-#endif
 	{"saturday", DOW, 6},
 	{"sep", MONTH, 9},
 	{"sept", MONTH, 9},
@@ -247,6 +235,16 @@ static datetkn datetktbl[] = {
 
 static unsigned int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0];
 
+/* Used for SET australian_timezones to override North American ones */
+static datetkn australian_datetktbl[] = {
+	{"cst", TZ, 63},			/* Australia Eastern Std Time */
+	{"est", TZ, 60},			/* Australia Eastern Std Time */
+	{"sat", TZ, 57},
+};
+
+static unsigned int australian_szdatetktbl = sizeof australian_datetktbl /
+											 sizeof australian_datetktbl[0];
+
 static datetkn deltatktbl[] = {
 /*		text			token	lexval */
 	{"@", IGNORE, 0},			/* postgres relative time prefix */
@@ -327,13 +325,10 @@ static datetkn deltatktbl[] = {
 
 static unsigned int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0];
 
-#if USE_DATE_CACHE
 datetkn    *datecache[MAXDATEFIELDS] = {NULL};
 
 datetkn    *deltacache[MAXDATEFIELDS] = {NULL};
 
-#endif
-
 
 /*
  * Calendar time to Julian date conversions.
@@ -1618,18 +1613,19 @@ DecodeSpecial(int field, char *lowtoken, int *val)
 	int			type;
 	datetkn    *tp;
 
-#if USE_DATE_CACHE
 	if ((datecache[field] != NULL)
 		&& (strncmp(lowtoken, datecache[field]->token, TOKMAXLEN) == 0))
 		tp = datecache[field];
 	else
 	{
-#endif
-		tp = datebsearch(lowtoken, datetktbl, szdatetktbl);
-#if USE_DATE_CACHE
+		tp = NULL;
+		if (Australian_timezones)
+			tp = datebsearch(lowtoken, australian_datetktbl,
+									   australian_szdatetktbl);
+		if (!tp)
+			tp = datebsearch(lowtoken, datetktbl, szdatetktbl);
 	}
 	datecache[field] = tp;
-#endif
 	if (tp == NULL)
 	{
 		type = IGNORE;
@@ -1937,18 +1933,14 @@ DecodeUnits(int field, char *lowtoken, int *val)
 	int			type;
 	datetkn    *tp;
 
-#if USE_DATE_CACHE
 	if ((deltacache[field] != NULL)
 		&& (strncmp(lowtoken, deltacache[field]->token, TOKMAXLEN) == 0))
 		tp = deltacache[field];
 	else
 	{
-#endif
 		tp = datebsearch(lowtoken, deltatktbl, szdeltatktbl);
-#if USE_DATE_CACHE
 	}
 	deltacache[field] = tp;
-#endif
 	if (tp == NULL)
 	{
 		type = IGNORE;
@@ -2455,3 +2447,12 @@ EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str)
 
 	return 0;
 }	/* EncodeTimeSpan() */
+
+
+void ClearDateCache(bool dummy)
+{
+	int i;
+
+	for (i=0; i < MAXDATEFIELDS; i++)
+		datecache[i] = NULL;
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 28b1eb0bd67..6dcaa177458 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4,7 +4,7 @@
  * Support for grand unified configuration scheme, including SET
  * command, configuration file, and command line options.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.38 2001/06/12 22:54:06 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.39 2001/06/18 16:14:43 momjian Exp $
  *
  * Copyright 2000 by PostgreSQL Global Development Group
  * Written by Peter Eisentraut <peter_e@gmx.net>.
@@ -33,6 +33,7 @@
 #include "parser/parse_expr.h"
 #include "storage/proc.h"
 #include "tcop/tcopprot.h"
+#include "utils/datetime.h"
 
 
 /* XXX these should be in other modules' header files */
@@ -69,6 +70,8 @@ bool		Show_btree_build_stats = false;
 
 bool		SQL_inheritance = true;
 
+bool		Australian_timezones = false;
+
 #ifndef PG_KRB_SRVTAB
 #define PG_KRB_SRVTAB ""
 #endif
@@ -229,6 +232,9 @@ static struct config_bool
 
 	{"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL},
 
+	{"australian_timezones", PGC_USERSET, &Australian_timezones,
+	false, ClearDateCache},
+
 	{"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL},
 
 	{NULL, 0, NULL, false, NULL}
@@ -327,8 +333,8 @@ static struct config_real
 	DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL},
 
 	{"geqo_selection_bias", PGC_USERSET, &Geqo_selection_bias,
-	 DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
-	 MAX_GEQO_SELECTION_BIAS, NULL, NULL},
+	DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS,
+	MAX_GEQO_SELECTION_BIAS, NULL, NULL},
 
 	{NULL, 0, NULL, 0.0, 0.0, 0.0, NULL, NULL}
 };
@@ -360,8 +366,8 @@ static struct config_string
 	"", NULL, NULL},
 
 	{"wal_sync_method", PGC_SIGHUP, &XLOG_sync_method,
-		XLOG_sync_method_default,
-	check_xlog_sync_method, assign_xlog_sync_method},
+	XLOG_sync_method_default, check_xlog_sync_method,
+	assign_xlog_sync_method},
 
 	{NULL, 0, NULL, NULL, NULL, NULL}
 };
@@ -956,6 +962,7 @@ _ShowOption(enum config_type opttype, struct config_generic *record)
 		case PGC_BOOL:
 			val = *((struct config_bool *) record)->variable ? "on" : "off";
 			break;
+
 		case PGC_INT:
 			snprintf(buffer, sizeof(buffer), "%d",
 					 *((struct config_int *) record)->variable);
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index a493eed21e8..a77666d9f44 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -84,24 +84,6 @@
 #geqo_random_seed = -1 # auto-compute seed
 
 
-#
-#	Inheritance
-#
-#sql_inheritance = true
-
-
-#
-#	Deadlock
-#
-#deadlock_timeout = 1000
-
-
-#
-#	Expression Depth Limitation
-#
-#max_expr_depth = 10000 # min 10
-
-
 #
 #	Write-ahead log (WAL)
 #
@@ -172,3 +154,13 @@
 #trace_lock_oidmin = 16384
 #trace_lock_table = 0
 #endif
+
+
+#
+#	Misc
+#
+#sql_inheritance = true
+#australian_timezones = false
+#deadlock_timeout = 1000
+#max_expr_depth = 10000 # min 10
+
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 5922d635dce..4f7e9c91108 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: datetime.h,v 1.18 2001/05/03 22:53:07 tgl Exp $
+ * $Id: datetime.h,v 1.19 2001/06/18 16:14:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -182,6 +182,7 @@ typedef struct
 	char		value;			/* this may be unsigned, alas */
 } datetkn;
 
+extern datetkn datetktbl[];
 
 /* TMODULO()
  * Macro to replace modf(), which is broken on some platforms.
@@ -264,6 +265,7 @@ extern int	EncodeTimeSpan(struct tm * tm, double fsec, int style, char *str);
 
 extern int	DecodeSpecial(int field, char *lowtoken, int *val);
 extern int	DecodeUnits(int field, char *lowtoken, int *val);
+extern void ClearDateCache(bool);
 
 extern int	j2day(int jd);
 
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index 08774128c14..8909320718c 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -4,7 +4,7 @@
  * External declarations pertaining to backend/utils/misc/guc.c and
  * backend/utils/misc/guc-file.l
  *
- * $Id: guc.h,v 1.8 2001/06/12 22:54:06 tgl Exp $
+ * $Id: guc.h,v 1.9 2001/06/18 16:14:43 momjian Exp $
  */
 #ifndef GUC_H
 #define GUC_H
@@ -70,5 +70,6 @@ extern bool Show_query_stats;
 extern bool Show_btree_build_stats;
 
 extern bool SQL_inheritance;
+extern bool Australian_timezones;
 
 #endif	 /* GUC_H */
diff --git a/src/test/regress/expected/horology-no-DST-before-1970.out b/src/test/regress/expected/horology-no-DST-before-1970.out
index 18ca744d785..f71b6a9821e 100644
--- a/src/test/regress/expected/horology-no-DST-before-1970.out
+++ b/src/test/regress/expected/horology-no-DST-before-1970.out
@@ -4,6 +4,8 @@
 --
 -- date, time arithmetic
 --
+-- needed so tests pass
+SET australian_timezones = 'off';
 SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time";
          Date + Time          
 ------------------------------
diff --git a/src/test/regress/expected/horology-solaris-1947.out b/src/test/regress/expected/horology-solaris-1947.out
index 451c6a6c765..99313d4cb4c 100644
--- a/src/test/regress/expected/horology-solaris-1947.out
+++ b/src/test/regress/expected/horology-solaris-1947.out
@@ -4,6 +4,8 @@
 --
 -- date, time arithmetic
 --
+-- needed so tests pass
+SET australian_timezones = 'off';
 SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time";
          Date + Time          
 ------------------------------
diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out
index dc16d58dea9..9e054d2209f 100644
--- a/src/test/regress/expected/horology.out
+++ b/src/test/regress/expected/horology.out
@@ -4,6 +4,8 @@
 --
 -- date, time arithmetic
 --
+-- needed so tests pass
+SET australian_timezones = 'off';
 SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time";
          Date + Time          
 ------------------------------
diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out
index 60d36735435..5bfaa459c70 100644
--- a/src/test/regress/expected/timestamp.out
+++ b/src/test/regress/expected/timestamp.out
@@ -4,6 +4,8 @@
 -- Shorthand values
 -- Not directly usable for regression testing since these are not constants.
 -- So, just try to test parser and hope for the best - thomas 97/04/26
+-- needed so tests pass
+SET australian_timezones = 'off';
 SELECT (timestamp 'today' = (timestamp 'yesterday' + interval '1 day')) as "True";
  True 
 ------
diff --git a/src/test/regress/sql/horology.sql b/src/test/regress/sql/horology.sql
index 2350064d839..8d228e0e4d8 100644
--- a/src/test/regress/sql/horology.sql
+++ b/src/test/regress/sql/horology.sql
@@ -1,10 +1,11 @@
 --
 -- HOROLOGY
 --
-
 --
 -- date, time arithmetic
 --
+-- needed so tests pass
+SET australian_timezones = 'off';
 
 SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time";
 
diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql
index 84c4fdbf6c3..49103dbe5ea 100644
--- a/src/test/regress/sql/timestamp.sql
+++ b/src/test/regress/sql/timestamp.sql
@@ -1,10 +1,11 @@
 --
 -- DATETIME
 --
-
 -- Shorthand values
 -- Not directly usable for regression testing since these are not constants.
 -- So, just try to test parser and hope for the best - thomas 97/04/26
+-- needed so tests pass
+SET australian_timezones = 'off';
 
 SELECT (timestamp 'today' = (timestamp 'yesterday' + interval '1 day')) as "True";
 SELECT (timestamp 'today' = (timestamp 'tomorrow' - interval '1 day')) as "True";
-- 
GitLab