Re: Australian timezone configure option - Mailing list pgsql-patches
| From | Bruce Momjian |
|---|---|
| Subject | Re: Australian timezone configure option |
| Date | |
| Msg-id | 200106120354.f5C3s0402765@candle.pha.pa.us Whole thread Raw |
| In response to | Australian timezone configure option (Chris Dunlop <chris@onthe.net.au>) |
| Responses |
Re: Australian timezone configure option
Re: Australian timezone configure option Re: Australian timezone configure option |
| List | pgsql-patches |
> Hi,
>
> Being in Australia, it's always been a minor pain building the support
> for Australian timezone rules by defining USE_AUSTRALIAN_RULES to the
> compiler. Not to mention the not inconsiderable pain involved in pawing
> through the code and documentation trying to work out why the timezones
> were wrong in the first place.
OK, this patch makes Australian_timezones a GUC option. It can be set
anytime in psql. The code uses a static variable to check if the GUC
setting has changed and adjust the C struct accordingly. I have also
added code to allow the regression tests to pass even if postgresql.conf
has australian_timezones defined.
test=> select datetime('2001-01-01 00:00:00 EST');
timestamp
------------------------
2001-01-01 00:00:00-05
(1 row)
test=> set australian_timezones = true;
SET VARIABLE
test=> select datetime('2001-01-01 00:00:00 EST');
timestamp
------------------------
2000-12-31 09:00:00-05
(1 row)
test=> reset all;
RESET VARIABLE
test=> select datetime('2001-01-01 00:00:00 EST');
timestamp
------------------------
2001-01-01 00:00:00-05
(1 row)
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Index: src/backend/utils/adt/datetime.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/adt/datetime.c,v
retrieving revision 1.64
diff -c -r1.64 datetime.c
*** src/backend/utils/adt/datetime.c 2001/05/03 22:53:07 1.64
--- src/backend/utils/adt/datetime.c 2001/06/12 03:52:10
***************
*** 22,27 ****
--- 22,28 ----
#include <limits.h>
#include "miscadmin.h"
+ #include "utils/guc.h"
#include "utils/datetime.h"
static int DecodeNumber(int flen, char *field,
***************
*** 35,40 ****
--- 36,42 ----
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);
+ static void CheckAustralianTimezones(int field);
#define USE_DATE_CACHE 1
#define ROUND_ALL 0
***************
*** 85,91 ****
* entries by 10 and truncate the text field at MAXTOKLEN characters.
* the text field is not guaranteed to be NULL-terminated.
*/
! static datetkn datetktbl[] = {
/* text token lexval */
{EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */
{"acsst", DTZ, 63}, /* Cent. Australia */
--- 87,93 ----
* entries by 10 and truncate the text field at MAXTOKLEN characters.
* the text field is not guaranteed to be NULL-terminated.
*/
! datetkn datetktbl[] = {
/* text token lexval */
{EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */
{"acsst", DTZ, 63}, /* Cent. Australia */
***************
*** 117,127 ****
{"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},
--- 119,125 ----
{"cdt", DTZ, NEG(30)}, /* Central Daylight Time */
{"cet", TZ, 6}, /* Central European Time */
{"cetdst", DTZ, 12}, /* Central European Dayl.Time */
! {"cst", TZ, NEG(36)}, /* Central Standard Time, may be Australian */
{DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */
{"dec", MONTH, 12},
{"december", MONTH, 12},
***************
*** 134,144 ****
{"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},
--- 132,138 ----
{"eet", TZ, 12}, /* East. Europe, USSR Zone 1 */
{"eetdst", DTZ, 18}, /* Eastern Europe */
{EPOCH, RESERV, DTK_EPOCH}, /* "epoch" reserved for system epoch time */
! {"est", TZ, NEG(30)}, /* Eastern Standard Time, may be Australian */
{"feb", MONTH, 2},
{"february", MONTH, 2},
{"fri", DOW, 5},
***************
*** 199,209 ****
{"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},
--- 193,199 ----
{"pst", TZ, NEG(48)}, /* Pacific Standard Time */
{"sadt", DTZ, 63}, /* S. Australian Dayl. Time */
{"sast", TZ, 57}, /* South Australian Std Time */
! {"sat", DOW, 6}, /* may be changed to Australian */
{"saturday", DOW, 6},
{"sep", MONTH, 9},
{"sept", MONTH, 9},
***************
*** 1618,1623 ****
--- 1608,1615 ----
int type;
datetkn *tp;
+ CheckAustralianTimezones(field);
+
#if USE_DATE_CACHE
if ((datecache[field] != NULL)
&& (strncmp(lowtoken, datecache[field]->token, TOKMAXLEN) == 0))
***************
*** 2455,2457 ****
--- 2447,2495 ----
return 0;
} /* EncodeTimeSpan() */
+
+
+ static void CheckAustralianTimezones(int field)
+ {
+ datetkn *tp;
+ int prev_Australian_timezones = false; /* structure preloaded as false */
+
+ if (Australian_timezones != prev_Australian_timezones)
+ {
+ #if USE_DATE_CACHE
+ datecache[field] = NULL;
+ #endif
+ /* CST */
+ tp = datebsearch("cst", datetktbl, szdatetktbl);
+ Assert(tp);
+ tp->type = TZ;
+ if (!Australian_timezones)
+ tp->value = NEG(36); /* Central Standard Time */
+ else
+ tp->value = 63; /* Australia Eastern Std Time */
+
+ /* EST */
+ tp = datebsearch("est", datetktbl, szdatetktbl);
+ Assert(tp);
+ tp->type = TZ;
+ if (!Australian_timezones)
+ tp->value = NEG(30); /* Eastern Standard Time */
+ else
+ tp->value = 60; /* Australia Eastern Std Time */
+
+ /* SAT */
+ tp = datebsearch("sat", datetktbl, szdatetktbl);
+ Assert(tp);
+ if (!Australian_timezones)
+ {
+ tp->type = DOW;
+ tp->value = 6;
+ }
+ else
+ {
+ tp->type = TZ;
+ tp->value = 57;
+ }
+ prev_Australian_timezones = Australian_timezones;
+ }
+ }
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.37
diff -c -r1.37 guc.c
*** src/backend/utils/misc/guc.c 2001/06/07 04:50:57 1.37
--- src/backend/utils/misc/guc.c 2001/06/12 03:52:11
***************
*** 71,76 ****
--- 71,78 ----
bool SQL_inheritance = true;
+ bool Australian_timezones = false;
+
#ifndef PG_KRB_SRVTAB
#define PG_KRB_SRVTAB ""
#endif
***************
*** 222,227 ****
--- 224,230 ----
{"show_source_port", PGC_SIGHUP, &ShowPortNumber, false},
{"sql_inheritance", PGC_USERSET, &SQL_inheritance, true},
+ {"australian_timezones", PGC_USERSET, &Australian_timezones, false},
{"fixbtree", PGC_POSTMASTER, &FixBTree, true},
***************
*** 880,885 ****
--- 883,889 ----
case PGC_BOOL:
val = *((struct config_bool *) record)->variable ? "on" : "off";
break;
+
case PGC_INT:
snprintf(buffer, 256, "%d", *((struct config_int *) record)->variable);
val = buffer;
***************
*** 955,961 ****
elog(FATAL, "out of memory");
}
else
! /* no equal sign in string */
{
*name = strdup(string);
if (!*name)
--- 959,965 ----
elog(FATAL, "out of memory");
}
else
! /* no equal sign in string */
{
*name = strdup(string);
if (!*name)
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.11
diff -c -r1.11 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample 2001/05/07 23:32:55 1.11
--- src/backend/utils/misc/postgresql.conf.sample 2001/06/12 03:52:11
***************
*** 172,174 ****
--- 172,180 ----
#trace_lock_oidmin = 16384
#trace_lock_table = 0
#endif
+
+
+ #
+ # Lock Tracing
+ #
+ #australian_timezones = false
Index: src/include/utils/datetime.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/utils/datetime.h,v
retrieving revision 1.18
diff -c -r1.18 datetime.h
*** src/include/utils/datetime.h 2001/05/03 22:53:07 1.18
--- src/include/utils/datetime.h 2001/06/12 03:52:12
***************
*** 182,187 ****
--- 182,188 ----
char value; /* this may be unsigned, alas */
} datetkn;
+ extern datetkn datetktbl[];
/* TMODULO()
* Macro to replace modf(), which is broken on some platforms.
Index: src/include/utils/guc.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.7
diff -c -r1.7 guc.h
*** src/include/utils/guc.h 2001/06/07 04:50:57 1.7
--- src/include/utils/guc.h 2001/06/12 03:52:12
***************
*** 68,72 ****
--- 68,73 ----
extern bool Show_btree_build_stats;
extern bool SQL_inheritance;
+ extern bool Australian_timezones;
#endif /* GUC_H */
Index: src/test/regress/expected/horology-no-DST-before-1970.out
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/expected/horology-no-DST-before-1970.out,v
retrieving revision 1.12
diff -c -r1.12 horology-no-DST-before-1970.out
*** src/test/regress/expected/horology-no-DST-before-1970.out 2001/04/06 05:50:25 1.12
--- src/test/regress/expected/horology-no-DST-before-1970.out 2001/06/12 03:52:16
***************
*** 4,9 ****
--- 4,11 ----
--
-- 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
------------------------------
Index: src/test/regress/expected/horology-solaris-1947.out
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/expected/horology-solaris-1947.out,v
retrieving revision 1.10
diff -c -r1.10 horology-solaris-1947.out
*** src/test/regress/expected/horology-solaris-1947.out 2001/04/06 05:50:25 1.10
--- src/test/regress/expected/horology-solaris-1947.out 2001/06/12 03:52:17
***************
*** 4,9 ****
--- 4,11 ----
--
-- 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
------------------------------
Index: src/test/regress/expected/horology.out
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/expected/horology.out,v
retrieving revision 1.23
diff -c -r1.23 horology.out
*** src/test/regress/expected/horology.out 2001/04/06 05:50:25 1.23
--- src/test/regress/expected/horology.out 2001/06/12 03:52:19
***************
*** 4,9 ****
--- 4,11 ----
--
-- 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
------------------------------
Index: src/test/regress/expected/timestamp.out
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/expected/timestamp.out,v
retrieving revision 1.12
diff -c -r1.12 timestamp.out
*** src/test/regress/expected/timestamp.out 2001/05/03 19:00:37 1.12
--- src/test/regress/expected/timestamp.out 2001/06/12 03:52:19
***************
*** 4,9 ****
--- 4,11 ----
-- 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
------
Index: src/test/regress/sql/horology.sql
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/sql/horology.sql,v
retrieving revision 1.14
diff -c -r1.14 horology.sql
*** src/test/regress/sql/horology.sql 2001/04/06 05:50:29 1.14
--- src/test/regress/sql/horology.sql 2001/06/12 03:52:19
***************
*** 1,10 ****
--
-- HOROLOGY
--
-
--
-- date, time arithmetic
--
SELECT date '1981-02-03' + time '04:05:06' AS "Date + Time";
--- 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";
Index: src/test/regress/sql/timestamp.sql
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/test/regress/sql/timestamp.sql,v
retrieving revision 1.7
diff -c -r1.7 timestamp.sql
*** src/test/regress/sql/timestamp.sql 2000/11/25 05:00:33 1.7
--- src/test/regress/sql/timestamp.sql 2001/06/12 03:52:20
***************
*** 1,10 ****
--
-- 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
SELECT (timestamp 'today' = (timestamp 'yesterday' + interval '1 day')) as "True";
SELECT (timestamp 'today' = (timestamp 'tomorrow' - interval '1 day')) as "True";
--- 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";
pgsql-patches by date: