Rename the recently-added pg_timezonenames view to pg_timezone_abbrevs,

and create a new view pg_timezone_names that provides information about
the zones known in the 'zic' database.  Magnus Hagander, with some
additional work by Tom Lane.
This commit is contained in:
Tom Lane 2006-09-16 20:14:34 +00:00
parent 7ed5df437d
commit 5ff4f39c0e
9 changed files with 331 additions and 31 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.131 2006/09/16 00:30:11 momjian Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.132 2006/09/16 20:14:32 tgl Exp $ -->
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
@ -4564,10 +4564,15 @@
</row> </row>
<row> <row>
<entry><link linkend="view-pg-timezonenames"><structname>pg_timezonenames</structname></link></entry> <entry><link linkend="view-pg-timezone-abbrevs"><structname>pg_timezone_abbrevs</structname></link></entry>
<entry>time zone abbreviations</entry> <entry>time zone abbreviations</entry>
</row> </row>
<row>
<entry><link linkend="view-pg-timezone-names"><structname>pg_timezone_names</structname></link></entry>
<entry>time zone names</entry>
</row>
<row> <row>
<entry><link linkend="view-pg-user"><structname>pg_user</structname></link></entry> <entry><link linkend="view-pg-user"><structname>pg_user</structname></link></entry>
<entry>database users</entry> <entry>database users</entry>
@ -5884,22 +5889,74 @@
</sect1> </sect1>
<sect1 id="view-pg-timezonenames"> <sect1 id="view-pg-timezone-abbrevs">
<title><structname>pg_timezonenames</structname></title> <title><structname>pg_timezone_abbrevs</structname></title>
<indexterm zone="view-pg-timezonenames"> <indexterm zone="view-pg-timezone-abbrevs">
<primary>pg_timezonenames</primary> <primary>pg_timezone_abbrevs</primary>
</indexterm> </indexterm>
<para> <para>
The view <structname>pg_timezonenames</structname> provides a list The view <structname>pg_timezone_abbrevs</structname> provides a list
of time zone abbreviations that are currently recognized by the datetime of time zone abbreviations that are currently recognized by the datetime
input routines. The contents of this view change when the input routines. The contents of this view change when the
<xref linkend="guc-timezone-abbreviations"> run-time parameter is modified. <xref linkend="guc-timezone-abbreviations"> run-time parameter is modified.
</para> </para>
<table> <table>
<title><structname>pg_timezonenames</> Columns</title> <title><structname>pg_timezone_abbrevs</> Columns</title>
<tgroup cols=3>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry><structfield>abbrev</structfield></entry>
<entry><type>text</type></entry>
<entry>time zone abbreviation</entry>
</row>
<row>
<entry><structfield>utc_offset</structfield></entry>
<entry><type>interval</type></entry>
<entry>offset from UTC (positive means east of Greenwich)</entry>
</row>
<row>
<entry><structfield>is_dst</structfield></entry>
<entry><type>boolean</type></entry>
<entry>true if this is a daylight-savings abbreviation</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="view-pg-timezone-names">
<title><structname>pg_timezone_names</structname></title>
<indexterm zone="view-pg-timezone-names">
<primary>pg_timezone_names</primary>
</indexterm>
<para>
The view <structname>pg_timezone_names</structname> provides a list
of time zone names that are recognized by <command>SET TIMEZONE</>,
along with their associated abbreviations, UTC offsets,
and daylight-savings status.
Unlike the abbreviations shown in <link
linkend="view-pg-timezone-abbrevs"><structname>pg_timezone_abbrevs</structname></link>, many of these names imply a set of daylight-savings transition
date rules. Therefore, the associated information changes across local DST
boundaries. The displayed information is computed based on the current
value of <function>CURRENT_TIMESTAMP</>.
</para>
<table>
<title><structname>pg_timezone_names</> Columns</title>
<tgroup cols=3> <tgroup cols=3>
<thead> <thead>
@ -5913,6 +5970,11 @@
<row> <row>
<entry><structfield>name</structfield></entry> <entry><structfield>name</structfield></entry>
<entry><type>text</type></entry> <entry><type>text</type></entry>
<entry>time zone name</entry>
</row>
<row>
<entry><structfield>abbrev</structfield></entry>
<entry><type>text</type></entry>
<entry>time zone abbreviation</entry> <entry>time zone abbreviation</entry>
</row> </row>
<row> <row>
@ -5923,7 +5985,7 @@
<row> <row>
<entry><structfield>is_dst</structfield></entry> <entry><structfield>is_dst</structfield></entry>
<entry><type>boolean</type></entry> <entry><type>boolean</type></entry>
<entry>true if this is a daylight-savings zone</entry> <entry>true if currently observing daylight savings</entry>
</row> </row>
</tbody> </tbody>
</tgroup> </tgroup>

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 1996-2006, PostgreSQL Global Development Group * Copyright (c) 1996-2006, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.30 2006/08/19 01:36:24 tgl Exp $ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.31 2006/09/16 20:14:33 tgl Exp $
*/ */
CREATE VIEW pg_roles AS CREATE VIEW pg_roles AS
@ -186,10 +186,11 @@ CREATE RULE pg_settings_n AS
GRANT SELECT, UPDATE ON pg_settings TO PUBLIC; GRANT SELECT, UPDATE ON pg_settings TO PUBLIC;
CREATE VIEW pg_timezonenames AS CREATE VIEW pg_timezone_abbrevs AS
SELECT * SELECT * FROM pg_timezone_abbrevs();
FROM pg_timezonenames() AS T
(name text, utc_offset interval, is_dst boolean); CREATE VIEW pg_timezone_names AS
SELECT * FROM pg_timezone_names();
-- Statistics views -- Statistics views

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.170 2006/09/04 01:26:27 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.171 2006/09/16 20:14:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -3839,21 +3839,21 @@ InstallTimeZoneAbbrevs(tzEntry *abbrevs, int n)
/* /*
* This set-returning function reads all the available time zone abbreviations * This set-returning function reads all the available time zone abbreviations
* and returns a set of (name, utc_offset, is_dst). * and returns a set of (abbrev, utc_offset, is_dst).
*/ */
Datum Datum
pg_timezonenames(PG_FUNCTION_ARGS) pg_timezone_abbrevs(PG_FUNCTION_ARGS)
{ {
FuncCallContext *funcctx; FuncCallContext *funcctx;
int *pindex; int *pindex;
Datum result; Datum result;
Interval *resInterval;
HeapTuple tuple; HeapTuple tuple;
Datum values[3]; Datum values[3];
bool nulls[3]; bool nulls[3];
char buffer[TOKMAXLEN + 1]; char buffer[TOKMAXLEN + 1];
unsigned char *p; unsigned char *p;
struct pg_tm tm; struct pg_tm tm;
Interval *resInterval;
/* stuff done only on the first call of the function */ /* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL()) if (SRF_IS_FIRSTCALL())
@ -3876,11 +3876,11 @@ pg_timezonenames(PG_FUNCTION_ARGS)
funcctx->user_fctx = (void *) pindex; funcctx->user_fctx = (void *) pindex;
/* /*
* build tupdesc for result tuples. This must match the * build tupdesc for result tuples. This must match this function's
* definition of the pg_timezonenames view in system_views.sql * pg_proc entry!
*/ */
tupdesc = CreateTemplateTupleDesc(3, false); tupdesc = CreateTemplateTupleDesc(3, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TupleDescInitEntry(tupdesc, (AttrNumber) 1, "abbrev",
TEXTOID, -1, 0); TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset", TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset",
INTERVALOID, -1, 0); INTERVALOID, -1, 0);
@ -3928,3 +3928,114 @@ pg_timezonenames(PG_FUNCTION_ARGS)
SRF_RETURN_NEXT(funcctx, result); SRF_RETURN_NEXT(funcctx, result);
} }
/*
* This set-returning function reads all the available full time zones
* and returns a set of (name, abbrev, utc_offset, is_dst).
*/
Datum
pg_timezone_names(PG_FUNCTION_ARGS)
{
MemoryContext oldcontext;
FuncCallContext *funcctx;
pg_tzenum *tzenum;
pg_tz *tz;
Datum result;
HeapTuple tuple;
Datum values[4];
bool nulls[4];
int tzoff;
struct pg_tm tm;
fsec_t fsec;
char *tzn;
Interval *resInterval;
struct pg_tm itm;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
/* create a function context for cross-call persistence */
funcctx = SRF_FIRSTCALL_INIT();
/*
* switch to memory context appropriate for multiple function
* calls
*/
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
/* initialize timezone scanning code */
tzenum = pg_tzenumerate_start();
funcctx->user_fctx = (void *) tzenum;
/*
* build tupdesc for result tuples. This must match this function's
* pg_proc entry!
*/
tupdesc = CreateTemplateTupleDesc(4, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "abbrev",
TEXTOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "utc_offset",
INTERVALOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "is_dst",
BOOLOID, -1, 0);
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
MemoryContextSwitchTo(oldcontext);
}
/* stuff done on every call of the function */
funcctx = SRF_PERCALL_SETUP();
tzenum = (pg_tzenum *) funcctx->user_fctx;
/* search for another zone to display */
for (;;)
{
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
tz = pg_tzenumerate_next(tzenum);
MemoryContextSwitchTo(oldcontext);
if (!tz)
{
pg_tzenumerate_end(tzenum);
funcctx->user_fctx = NULL;
SRF_RETURN_DONE(funcctx);
}
/* Convert now() to local time in this zone */
if (timestamp2tm(GetCurrentTransactionStartTimestamp(),
&tzoff, &tm, &fsec, &tzn, tz) != 0)
continue; /* ignore if conversion fails */
/* Ignore zic's rather silly "Factory" time zone */
if (tzn && strcmp(tzn, "Local time zone must be set--see zic manual page") == 0)
continue;
/* Found a displayable zone */
break;
}
MemSet(nulls, 0, sizeof(nulls));
values[0] = DirectFunctionCall1(textin,
CStringGetDatum(pg_get_timezone_name(tz)));
values[1] = DirectFunctionCall1(textin,
CStringGetDatum(tzn ? tzn : ""));
MemSet(&itm, 0, sizeof(struct pg_tm));
itm.tm_sec = -tzoff;
resInterval = (Interval *) palloc(sizeof(Interval));
tm2interval(&itm, 0, resInterval);
values[2] = IntervalPGetDatum(resInterval);
values[3] = BoolGetDatum(tm.tm_isdst > 0);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
result = HeapTupleGetDatum(tuple);
SRF_RETURN_NEXT(funcctx, result);
}

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.356 2006/09/14 22:05:06 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.357 2006/09/16 20:14:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200609141 #define CATALOG_VERSION_NO 200609161
#endif #endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.424 2006/09/14 22:05:06 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.425 2006/09/16 20:14:33 tgl Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
@ -3791,7 +3791,9 @@ DATA(insert OID = 2510 ( pg_prepared_statement PGNSP PGUID 12 f f t t s 0 2249
DESCR("get the prepared statements for this session"); DESCR("get the prepared statements for this session");
DATA(insert OID = 2511 ( pg_cursor PGNSP PGUID 12 f f t t s 0 2249 "" _null_ _null_ _null_ pg_cursor - _null_ )); DATA(insert OID = 2511 ( pg_cursor PGNSP PGUID 12 f f t t s 0 2249 "" _null_ _null_ _null_ pg_cursor - _null_ ));
DESCR("get the open cursors for this session"); DESCR("get the open cursors for this session");
DATA(insert OID = 2599 ( pg_timezonenames PGNSP PGUID 12 f f t t s 0 2249 "" _null_ _null_ _null_ pg_timezonenames - _null_ )); DATA(insert OID = 2599 ( pg_timezone_abbrevs PGNSP PGUID 12 f f t t s 0 2249 "" "{25,1186,16}" "{o,o,o}" "{abbrev,utc_offset,is_dst}" pg_timezone_abbrevs - _null_ ));
DESCR("get the available time zone abbreviations");
DATA(insert OID = 2856 ( pg_timezone_names PGNSP PGUID 12 f f t t s 0 2249 "" "{25,25,1186,16}" "{o,o,o,o}" "{name,abbrev,utc_offset,is_dst}" pg_timezone_names - _null_ ));
DESCR("get the available time zone names"); DESCR("get the available time zone names");
/* non-persistent series generator */ /* non-persistent series generator */

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/include/pgtime.h,v 1.12 2006/03/05 15:58:53 momjian Exp $ * $PostgreSQL: pgsql/src/include/pgtime.h,v 1.13 2006/09/16 20:14:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -38,6 +38,7 @@ struct pg_tm
}; };
typedef struct pg_tz pg_tz; typedef struct pg_tz pg_tz;
typedef struct pg_tzenum pg_tzenum;
extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz); extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz);
extern struct pg_tm *pg_gmtime(const pg_time_t *timep); extern struct pg_tm *pg_gmtime(const pg_time_t *timep);
@ -56,6 +57,10 @@ extern pg_tz *pg_tzset(const char *tzname);
extern bool tz_acceptable(pg_tz *tz); extern bool tz_acceptable(pg_tz *tz);
extern const char *pg_get_timezone_name(pg_tz *tz); extern const char *pg_get_timezone_name(pg_tz *tz);
extern pg_tzenum *pg_tzenumerate_start(void);
extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir);
extern void pg_tzenumerate_end(pg_tzenum *dir);
extern pg_tz *global_timezone; extern pg_tz *global_timezone;
/* Maximum length of a timezone name (not including trailing null) */ /* Maximum length of a timezone name (not including trailing null) */

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.60 2006/07/25 03:51:22 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.61 2006/09/16 20:14:33 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -303,6 +303,7 @@ extern int j2day(int jd);
extern bool CheckDateTokenTables(void); extern bool CheckDateTokenTables(void);
extern void InstallTimeZoneAbbrevs(tzEntry *abbrevs, int n); extern void InstallTimeZoneAbbrevs(tzEntry *abbrevs, int n);
extern Datum pg_timezonenames(PG_FUNCTION_ARGS); extern Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS);
extern Datum pg_timezone_names(PG_FUNCTION_ARGS);
#endif /* DATETIME_H */ #endif /* DATETIME_H */

View File

@ -1306,7 +1306,8 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name])); pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.schemaname, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.schemaname <> ALL (ARRAY['pg_catalog'::name, 'pg_toast'::name, 'information_schema'::name]));
pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text); pg_stats | SELECT n.nspname AS schemaname, c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE 1 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS most_common_vals, CASE 1 WHEN s.stakind1 THEN s.stanumbers1 WHEN s.stakind2 THEN s.stanumbers2 WHEN s.stakind3 THEN s.stanumbers3 WHEN s.stakind4 THEN s.stanumbers4 ELSE NULL::real[] END AS most_common_freqs, CASE 2 WHEN s.stakind1 THEN s.stavalues1 WHEN s.stakind2 THEN s.stavalues2 WHEN s.stakind3 THEN s.stavalues3 WHEN s.stakind4 THEN s.stavalues4 ELSE NULL::"unknown" END AS histogram_bounds, CASE 3 WHEN s.stakind1 THEN s.stanumbers1[1] WHEN s.stakind2 THEN s.stanumbers2[1] WHEN s.stakind3 THEN s.stanumbers3[1] WHEN s.stakind4 THEN s.stanumbers4[1] ELSE NULL::real END AS correlation FROM (((pg_statistic s JOIN pg_class c ON ((c.oid = s.starelid))) JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE has_table_privilege(c.oid, 'select'::text);
pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char"); pg_tables | SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, t.spcname AS "tablespace", c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM ((pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = c.reltablespace))) WHERE (c.relkind = 'r'::"char");
pg_timezonenames | SELECT t.name, t.utc_offset, t.is_dst FROM pg_timezonenames() t(name text, utc_offset interval, is_dst boolean); pg_timezone_abbrevs | SELECT pg_timezone_abbrevs.abbrev, pg_timezone_abbrevs.utc_offset, pg_timezone_abbrevs.is_dst FROM pg_timezone_abbrevs() pg_timezone_abbrevs(abbrev, utc_offset, is_dst);
pg_timezone_names | SELECT pg_timezone_names.name, pg_timezone_names.abbrev, pg_timezone_names.utc_offset, pg_timezone_names.is_dst FROM pg_timezone_names() pg_timezone_names(name, abbrev, utc_offset, is_dst);
pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow; pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;
pg_views | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char"); pg_views | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char");
rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1; rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1;
@ -1323,7 +1324,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color)))); shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath); street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
toyemp | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp; toyemp | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp;
(47 rows) (48 rows)
SELECT tablename, rulename, definition FROM pg_rules SELECT tablename, rulename, definition FROM pg_rules
ORDER BY tablename, rulename; ORDER BY tablename, rulename;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.44 2006/07/14 14:52:27 momjian Exp $ * $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.45 2006/09/16 20:14:34 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1136,3 +1136,120 @@ pg_timezone_initialize(void)
SetConfigOption("timezone", def_tz, PGC_POSTMASTER, PGC_S_ARGV); SetConfigOption("timezone", def_tz, PGC_POSTMASTER, PGC_S_ARGV);
} }
} }
/*
* Functions to enumerate available timezones
*
* Note that pg_tzenumerate_next() will return a pointer into the pg_tzenum
* structure, so the data is only valid up to the next call.
*
* All data is allocated using palloc in the current context.
*/
#define MAX_TZDIR_DEPTH 10
struct pg_tzenum {
int baselen;
int depth;
DIR *dirdesc[MAX_TZDIR_DEPTH];
char *dirname[MAX_TZDIR_DEPTH];
struct pg_tz tz;
};
/* typedef pg_tzenum is declared in pgtime.h */
pg_tzenum *
pg_tzenumerate_start(void)
{
pg_tzenum *ret = (pg_tzenum *) palloc0(sizeof(pg_tzenum));
char *startdir = pstrdup(pg_TZDIR());
ret->baselen = strlen(startdir) + 1;
ret->depth = 0;
ret->dirname[0] = startdir;
ret->dirdesc[0] = AllocateDir(startdir);
if (!ret->dirdesc[0])
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open directory \"%s\": %m", startdir)));
return ret;
}
void
pg_tzenumerate_end(pg_tzenum *dir)
{
while (dir->depth >= 0)
{
FreeDir(dir->dirdesc[dir->depth]);
pfree(dir->dirname[dir->depth]);
dir->depth--;
}
pfree(dir);
}
pg_tz *
pg_tzenumerate_next(pg_tzenum *dir)
{
while (dir->depth >= 0)
{
struct dirent *direntry;
char fullname[MAXPGPATH];
struct stat statbuf;
direntry = ReadDir(dir->dirdesc[dir->depth], dir->dirname[dir->depth]);
if (!direntry)
{
/* End of this directory */
FreeDir(dir->dirdesc[dir->depth]);
pfree(dir->dirname[dir->depth]);
dir->depth--;
continue;
}
if (direntry->d_name[0] == '.')
continue;
snprintf(fullname, MAXPGPATH, "%s/%s",
dir->dirname[dir->depth], direntry->d_name);
if (stat(fullname, &statbuf) != 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not stat \"%s\": %m", fullname)));
if (S_ISDIR(statbuf.st_mode))
{
/* Step into the subdirectory */
if (dir->depth >= MAX_TZDIR_DEPTH-1)
ereport(ERROR,
(errmsg("timezone directory stack overflow")));
dir->depth++;
dir->dirname[dir->depth] = pstrdup(fullname);
dir->dirdesc[dir->depth] = AllocateDir(fullname);
if (!dir->dirdesc[dir->depth])
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open directory \"%s\": %m",
fullname)));
/* Start over reading in the new directory */
continue;
}
/*
* Load this timezone using tzload() not pg_tzset(),
* so we don't fill the cache
*/
if (tzload(fullname + dir->baselen, &dir->tz.state) != 0)
{
/* Zone could not be loaded, ignore it */
continue;
}
/* Timezone loaded OK. */
strcpy(dir->tz.TZname, fullname + dir->baselen);
return &dir->tz;
}
/* Nothing more found */
return NULL;
}