8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.170 2006/09/04 01:26:27 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.171 2006/09/16 20:14:33 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -3839,21 +3839,21 @@ InstallTimeZoneAbbrevs(tzEntry *abbrevs, int n)
3839
3839
3840
3840
/*
3841
3841
* This set-returning function reads all the available time zone abbreviations
3842
- * and returns a set of (name , utc_offset, is_dst).
3842
+ * and returns a set of (abbrev , utc_offset, is_dst).
3843
3843
*/
3844
3844
Datum
3845
- pg_timezonenames (PG_FUNCTION_ARGS )
3845
+ pg_timezone_abbrevs (PG_FUNCTION_ARGS )
3846
3846
{
3847
3847
FuncCallContext * funcctx ;
3848
3848
int * pindex ;
3849
3849
Datum result ;
3850
- Interval * resInterval ;
3851
3850
HeapTuple tuple ;
3852
3851
Datum values [3 ];
3853
3852
bool nulls [3 ];
3854
3853
char buffer [TOKMAXLEN + 1 ];
3855
3854
unsigned char * p ;
3856
3855
struct pg_tm tm ;
3856
+ Interval * resInterval ;
3857
3857
3858
3858
/* stuff done only on the first call of the function */
3859
3859
if (SRF_IS_FIRSTCALL ())
@@ -3876,11 +3876,11 @@ pg_timezonenames(PG_FUNCTION_ARGS)
3876
3876
funcctx -> user_fctx = (void * ) pindex ;
3877
3877
3878
3878
/*
3879
- * build tupdesc for result tuples. This must match the
3880
- * definition of the pg_timezonenames view in system_views.sql
3879
+ * build tupdesc for result tuples. This must match this function's
3880
+ * pg_proc entry!
3881
3881
*/
3882
3882
tupdesc = CreateTemplateTupleDesc (3 , false);
3883
- TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "name " ,
3883
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "abbrev " ,
3884
3884
TEXTOID , -1 , 0 );
3885
3885
TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "utc_offset" ,
3886
3886
INTERVALOID , -1 , 0 );
@@ -3928,3 +3928,114 @@ pg_timezonenames(PG_FUNCTION_ARGS)
3928
3928
3929
3929
SRF_RETURN_NEXT (funcctx , result );
3930
3930
}
3931
+
3932
+ /*
3933
+ * This set-returning function reads all the available full time zones
3934
+ * and returns a set of (name, abbrev, utc_offset, is_dst).
3935
+ */
3936
+ Datum
3937
+ pg_timezone_names (PG_FUNCTION_ARGS )
3938
+ {
3939
+ MemoryContext oldcontext ;
3940
+ FuncCallContext * funcctx ;
3941
+ pg_tzenum * tzenum ;
3942
+ pg_tz * tz ;
3943
+ Datum result ;
3944
+ HeapTuple tuple ;
3945
+ Datum values [4 ];
3946
+ bool nulls [4 ];
3947
+ int tzoff ;
3948
+ struct pg_tm tm ;
3949
+ fsec_t fsec ;
3950
+ char * tzn ;
3951
+ Interval * resInterval ;
3952
+ struct pg_tm itm ;
3953
+
3954
+ /* stuff done only on the first call of the function */
3955
+ if (SRF_IS_FIRSTCALL ())
3956
+ {
3957
+ TupleDesc tupdesc ;
3958
+
3959
+ /* create a function context for cross-call persistence */
3960
+ funcctx = SRF_FIRSTCALL_INIT ();
3961
+
3962
+ /*
3963
+ * switch to memory context appropriate for multiple function
3964
+ * calls
3965
+ */
3966
+ oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
3967
+
3968
+ /* initialize timezone scanning code */
3969
+ tzenum = pg_tzenumerate_start ();
3970
+ funcctx -> user_fctx = (void * ) tzenum ;
3971
+
3972
+ /*
3973
+ * build tupdesc for result tuples. This must match this function's
3974
+ * pg_proc entry!
3975
+ */
3976
+ tupdesc = CreateTemplateTupleDesc (4 , false);
3977
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 1 , "name" ,
3978
+ TEXTOID , -1 , 0 );
3979
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 2 , "abbrev" ,
3980
+ TEXTOID , -1 , 0 );
3981
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 3 , "utc_offset" ,
3982
+ INTERVALOID , -1 , 0 );
3983
+ TupleDescInitEntry (tupdesc , (AttrNumber ) 4 , "is_dst" ,
3984
+ BOOLOID , -1 , 0 );
3985
+
3986
+ funcctx -> tuple_desc = BlessTupleDesc (tupdesc );
3987
+ MemoryContextSwitchTo (oldcontext );
3988
+ }
3989
+
3990
+ /* stuff done on every call of the function */
3991
+ funcctx = SRF_PERCALL_SETUP ();
3992
+ tzenum = (pg_tzenum * ) funcctx -> user_fctx ;
3993
+
3994
+ /* search for another zone to display */
3995
+ for (;;)
3996
+ {
3997
+ oldcontext = MemoryContextSwitchTo (funcctx -> multi_call_memory_ctx );
3998
+ tz = pg_tzenumerate_next (tzenum );
3999
+ MemoryContextSwitchTo (oldcontext );
4000
+
4001
+ if (!tz )
4002
+ {
4003
+ pg_tzenumerate_end (tzenum );
4004
+ funcctx -> user_fctx = NULL ;
4005
+ SRF_RETURN_DONE (funcctx );
4006
+ }
4007
+
4008
+ /* Convert now() to local time in this zone */
4009
+ if (timestamp2tm (GetCurrentTransactionStartTimestamp (),
4010
+ & tzoff , & tm , & fsec , & tzn , tz ) != 0 )
4011
+ continue ; /* ignore if conversion fails */
4012
+
4013
+ /* Ignore zic's rather silly "Factory" time zone */
4014
+ if (tzn && strcmp (tzn , "Local time zone must be set--see zic manual page" ) == 0 )
4015
+ continue ;
4016
+
4017
+ /* Found a displayable zone */
4018
+ break ;
4019
+ }
4020
+
4021
+ MemSet (nulls , 0 , sizeof (nulls ));
4022
+
4023
+ values [0 ] = DirectFunctionCall1 (textin ,
4024
+ CStringGetDatum (pg_get_timezone_name (tz )));
4025
+
4026
+ values [1 ] = DirectFunctionCall1 (textin ,
4027
+ CStringGetDatum (tzn ? tzn : "" ));
4028
+
4029
+ MemSet (& itm , 0 , sizeof (struct pg_tm ));
4030
+ itm .tm_sec = - tzoff ;
4031
+ resInterval = (Interval * ) palloc (sizeof (Interval ));
4032
+ tm2interval (& itm , 0 , resInterval );
4033
+ values [2 ] = IntervalPGetDatum (resInterval );
4034
+
4035
+ values [3 ] = BoolGetDatum (tm .tm_isdst > 0 );
4036
+
4037
+ tuple = heap_form_tuple (funcctx -> tuple_desc , values , nulls );
4038
+ result = HeapTupleGetDatum (tuple );
4039
+
4040
+ SRF_RETURN_NEXT (funcctx , result );
4041
+ }
0 commit comments