Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5fbd9d9

Browse files
committed
Merge branch 'REL9_5_STABLE' into PGPRO9_5
2 parentsf8c2ef3 +0ce0801 commit5fbd9d9

File tree

20 files changed

+276
-131
lines changed

20 files changed

+276
-131
lines changed

‎doc/src/sgml/catalogs.sgml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9770,6 +9770,13 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
97709770
</tgroup>
97719771
</table>
97729772

9773+
<para>
9774+
While most timezone abbreviations represent fixed offsets from UTC,
9775+
there are some that have historically varied in value
9776+
(see <xref linkend="datetime-config-files"> for more information).
9777+
In such cases this view presents their current meaning.
9778+
</para>
9779+
97739780
</sect1>
97749781

97759782
<sect1 id="view-pg-timezone-names">

‎doc/src/sgml/datetime.sgml

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,19 +384,38 @@
384384

385385
<para>
386386
A <replaceable>zone_abbreviation</replaceable> is just the abbreviation
387-
being defined. The <replaceable>offset</replaceable> is the equivalent
388-
offset in seconds from UTC, positive being east from Greenwich and
389-
negative being west. For example, -18000 would be five hours west
390-
of Greenwich, or North American east coast standard time. <literal>D</>
391-
indicates that the zone name represents local daylight-savings time rather
392-
than standard time. Alternatively, a <replaceable>time_zone_name</> can
393-
be given, in which case that time zone definition is consulted, and the
394-
abbreviation's meaning in that zone is used. This alternative is
395-
recommended only for abbreviations whose meaning has historically varied,
396-
as looking up the meaning is noticeably more expensive than just using
397-
a fixed integer value.
387+
being defined. An <replaceable>offset</replaceable> is an integer giving
388+
the equivalent offset in seconds from UTC, positive being east from
389+
Greenwich and negative being west. For example, -18000 would be five
390+
hours west of Greenwich, or North American east coast standard time.
391+
<literal>D</> indicates that the zone name represents local
392+
daylight-savings time rather than standard time.
398393
</para>
399394

395+
<para>
396+
Alternatively, a <replaceable>time_zone_name</> can be given, referencing
397+
a zone name defined in the IANA timezone database. The zone's definition
398+
is consulted to see whether the abbreviation is or has been in use in
399+
that zone, and if so, the appropriate meaning is used &mdash; that is,
400+
the meaning that was currently in use at the timestamp whose value is
401+
being determined, or the meaning in use immediately before that if it
402+
wasn't current at that time, or the oldest meaning if it was used only
403+
after that time. This behavior is essential for dealing with
404+
abbreviations whose meaning has historically varied. It is also allowed
405+
to define an abbreviation in terms of a zone name in which that
406+
abbreviation does not appear; then using the abbreviation is just
407+
equivalent to writing out the zone name.
408+
</para>
409+
410+
<tip>
411+
<para>
412+
Using a simple integer <replaceable>offset</replaceable> is preferred
413+
when defining an abbreviation whose offset from UTC has never changed,
414+
as such abbreviations are much cheaper to process than those that
415+
require consulting a time zone definition.
416+
</para>
417+
</tip>
418+
400419
<para>
401420
The <literal>@INCLUDE</> syntax allows inclusion of another file in the
402421
<filename>.../share/timezonesets/</> directory. Inclusion can be nested,

‎src/backend/access/gin/gindatapage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ typedef struct
8686
charaction;
8787

8888
ItemPointerData*modifieditems;
89-
intnmodifieditems;
89+
uint16nmodifieditems;
9090

9191
/*
9292
* The following fields represent the items in this segment. If 'items' is

‎src/backend/access/transam/xlog.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4980,7 +4980,8 @@ readRecoveryCommandFile(void)
49804980
rtli= (TimeLineID)strtoul(item->value,NULL,0);
49814981
if (errno==EINVAL||errno==ERANGE)
49824982
ereport(FATAL,
4983-
(errmsg("recovery_target_timeline is not a valid number: \"%s\"",
4983+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4984+
errmsg("recovery_target_timeline is not a valid number: \"%s\"",
49844985
item->value)));
49854986
}
49864987
if (rtli)
@@ -4996,7 +4997,8 @@ readRecoveryCommandFile(void)
49964997
recoveryTargetXid= (TransactionId)strtoul(item->value,NULL,0);
49974998
if (errno==EINVAL||errno==ERANGE)
49984999
ereport(FATAL,
4999-
(errmsg("recovery_target_xid is not a valid number: \"%s\"",
5000+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5001+
errmsg("recovery_target_xid is not a valid number: \"%s\"",
50005002
item->value)));
50015003
ereport(DEBUG2,
50025004
(errmsg_internal("recovery_target_xid = %u",
@@ -5111,7 +5113,8 @@ readRecoveryCommandFile(void)
51115113
}
51125114
else
51135115
ereport(FATAL,
5114-
(errmsg("unrecognized recovery parameter \"%s\"",
5116+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5117+
errmsg("unrecognized recovery parameter \"%s\"",
51155118
item->name)));
51165119
}
51175120

@@ -5130,7 +5133,8 @@ readRecoveryCommandFile(void)
51305133
{
51315134
if (recoveryRestoreCommand==NULL)
51325135
ereport(FATAL,
5133-
(errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled",
5136+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5137+
errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled",
51345138
RECOVERY_COMMAND_FILE)));
51355139
}
51365140

@@ -5144,6 +5148,15 @@ readRecoveryCommandFile(void)
51445148
!EnableHotStandby)
51455149
recoveryTargetAction=RECOVERY_TARGET_ACTION_SHUTDOWN;
51465150

5151+
/*
5152+
* We don't support standby_mode in standalone backends; that requires
5153+
* other processes such as the WAL receiver to be alive.
5154+
*/
5155+
if (StandbyModeRequested&& !IsUnderPostmaster)
5156+
ereport(FATAL,
5157+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5158+
errmsg("standby mode is not supported by single-user servers")));
5159+
51475160
/* Enable fetching from archive recovery area */
51485161
ArchiveRecoveryRequested= true;
51495162

@@ -5160,7 +5173,8 @@ readRecoveryCommandFile(void)
51605173
/* Timeline 1 does not have a history file, all else should */
51615174
if (rtli!=1&& !existsTimeLineHistory(rtli))
51625175
ereport(FATAL,
5163-
(errmsg("recovery target timeline %u does not exist",
5176+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5177+
errmsg("recovery target timeline %u does not exist",
51645178
rtli)));
51655179
recoveryTargetTLI=rtli;
51665180
recoveryTargetIsLatest= false;

‎src/backend/utils/adt/datetime.c

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ static void AdjustFractDays(double frac, struct pg_tm * tm, fsec_t *fsec,
5252
intscale);
5353
staticintDetermineTimeZoneOffsetInternal(structpg_tm*tm,pg_tz*tzp,
5454
pg_time_t*tp);
55-
staticintDetermineTimeZoneAbbrevOffsetInternal(pg_time_tt,constchar*abbr,
56-
pg_tz*tzp,int*isdst);
55+
staticboolDetermineTimeZoneAbbrevOffsetInternal(pg_time_tt,
56+
constchar*abbr,pg_tz*tzp,
57+
int*offset,int*isdst);
5758
staticpg_tz*FetchDynamicTimeZone(TimeZoneAbbrevTable*tbl,constdatetkn*tp);
5859

5960

@@ -1620,19 +1621,40 @@ DetermineTimeZoneOffsetInternal(struct pg_tm * tm, pg_tz *tzp, pg_time_t *tp)
16201621
* This differs from the behavior of DetermineTimeZoneOffset() in that a
16211622
* standard-time or daylight-time abbreviation forces use of the corresponding
16221623
* GMT offset even when the zone was then in DS or standard time respectively.
1624+
* (However, that happens only if we can match the given abbreviation to some
1625+
* abbreviation that appears in the IANA timezone data. Otherwise, we fall
1626+
* back to doing DetermineTimeZoneOffset().)
16231627
*/
16241628
int
16251629
DetermineTimeZoneAbbrevOffset(structpg_tm*tm,constchar*abbr,pg_tz*tzp)
16261630
{
16271631
pg_time_tt;
1632+
intzone_offset;
1633+
intabbr_offset;
1634+
intabbr_isdst;
16281635

16291636
/*
16301637
* Compute the UTC time we want to probe at. (In event of overflow, we'll
16311638
* probe at the epoch, which is a bit random but probably doesn't matter.)
16321639
*/
1633-
(void)DetermineTimeZoneOffsetInternal(tm,tzp,&t);
1640+
zone_offset=DetermineTimeZoneOffsetInternal(tm,tzp,&t);
16341641

1635-
returnDetermineTimeZoneAbbrevOffsetInternal(t,abbr,tzp,&tm->tm_isdst);
1642+
/*
1643+
* Try to match the abbreviation to something in the zone definition.
1644+
*/
1645+
if (DetermineTimeZoneAbbrevOffsetInternal(t,abbr,tzp,
1646+
&abbr_offset,&abbr_isdst))
1647+
{
1648+
/* Success, so use the abbrev-specific answers. */
1649+
tm->tm_isdst=abbr_isdst;
1650+
returnabbr_offset;
1651+
}
1652+
1653+
/*
1654+
* No match, so use the answers we already got from
1655+
* DetermineTimeZoneOffsetInternal.
1656+
*/
1657+
returnzone_offset;
16361658
}
16371659

16381660

@@ -1646,19 +1668,41 @@ DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr,
16461668
pg_tz*tzp,int*isdst)
16471669
{
16481670
pg_time_tt=timestamptz_to_time_t(ts);
1671+
intzone_offset;
1672+
intabbr_offset;
1673+
inttz;
1674+
structpg_tmtm;
1675+
fsec_tfsec;
16491676

1650-
returnDetermineTimeZoneAbbrevOffsetInternal(t,abbr,tzp,isdst);
1677+
/*
1678+
* If the abbrev matches anything in the zone data, this is pretty easy.
1679+
*/
1680+
if (DetermineTimeZoneAbbrevOffsetInternal(t,abbr,tzp,
1681+
&abbr_offset,isdst))
1682+
returnabbr_offset;
1683+
1684+
/*
1685+
* Else, break down the timestamp so we can use DetermineTimeZoneOffset.
1686+
*/
1687+
if (timestamp2tm(ts,&tz,&tm,&fsec,NULL,tzp)!=0)
1688+
ereport(ERROR,
1689+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1690+
errmsg("timestamp out of range")));
1691+
1692+
zone_offset=DetermineTimeZoneOffset(&tm,tzp);
1693+
*isdst=tm.tm_isdst;
1694+
returnzone_offset;
16511695
}
16521696

16531697

16541698
/* DetermineTimeZoneAbbrevOffsetInternal()
16551699
*
16561700
* Workhorse for above two functions: work from a pg_time_t probe instant.
1657-
* DST statusis returned into *isdst.
1701+
*On success, return GMT offset andDST statusinto *offset and *isdst.
16581702
*/
1659-
staticint
1660-
DetermineTimeZoneAbbrevOffsetInternal(pg_time_tt,constchar*abbr,
1661-
pg_tz*tzp,int*isdst)
1703+
staticbool
1704+
DetermineTimeZoneAbbrevOffsetInternal(pg_time_tt,constchar*abbr,pg_tz*tzp,
1705+
int*offset,int*isdst)
16621706
{
16631707
charupabbr[TZ_STRLEN_MAX+1];
16641708
unsignedchar*p;
@@ -1670,18 +1714,17 @@ DetermineTimeZoneAbbrevOffsetInternal(pg_time_t t, const char *abbr,
16701714
*p=pg_toupper(*p);
16711715

16721716
/* Look up the abbrev's meaning at this time in this zone */
1673-
if (!pg_interpret_timezone_abbrev(upabbr,
1674-
&t,
1675-
&gmtoff,
1676-
isdst,
1677-
tzp))
1678-
ereport(ERROR,
1679-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1680-
errmsg("time zone abbreviation \"%s\" is not used in time zone \"%s\"",
1681-
abbr,pg_get_timezone_name(tzp))));
1682-
1683-
/* Change sign to agree with DetermineTimeZoneOffset() */
1684-
return (int)-gmtoff;
1717+
if (pg_interpret_timezone_abbrev(upabbr,
1718+
&t,
1719+
&gmtoff,
1720+
isdst,
1721+
tzp))
1722+
{
1723+
/* Change sign to agree with DetermineTimeZoneOffset() */
1724+
*offset= (int)-gmtoff;
1725+
return true;
1726+
}
1727+
return false;
16851728
}
16861729

16871730

‎src/bin/pg_basebackup/receivelog.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -516,26 +516,28 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
516516
if (!CheckServerVersionForStreaming(conn))
517517
return false;
518518

519+
/*
520+
* Decide whether we want to report the flush position. If we report
521+
* the flush position, the primary will know what WAL we'll
522+
* possibly re-request, and it can then remove older WAL safely.
523+
* We must always do that when we are using slots.
524+
*
525+
* Reporting the flush position makes one eligible as a synchronous
526+
* replica. People shouldn't include generic names in
527+
* synchronous_standby_names, but we've protected them against it so
528+
* far, so let's continue to do so unless specifically requested.
529+
*/
519530
if (replication_slot!=NULL)
520531
{
521-
/*
522-
* Report the flush position, so the primary can know what WAL we'll
523-
* possibly re-request, and remove older WAL safely.
524-
*
525-
* We only report it when a slot has explicitly been used, because
526-
* reporting the flush position makes one eligible as a synchronous
527-
* replica. People shouldn't include generic names in
528-
* synchronous_standby_names, but we've protected them against it so
529-
* far, so let's continue to do so in the situations when possible. If
530-
* they've got a slot, though, we need to report the flush position,
531-
* so that the master can remove WAL.
532-
*/
533532
reportFlushPosition= true;
534533
sprintf(slotcmd,"SLOT \"%s\" ",replication_slot);
535534
}
536535
else
537536
{
538-
reportFlushPosition= false;
537+
if (synchronous)
538+
reportFlushPosition= true;
539+
else
540+
reportFlushPosition= false;
539541
slotcmd[0]=0;
540542
}
541543

‎src/port/path.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ skip_drive(const char *path)
8686
bool
8787
has_drive_prefix(constchar*path)
8888
{
89+
#ifdefWIN32
8990
returnskip_drive(path)!=path;
91+
#else
92+
return false;
93+
#endif
9094
}
9195

9296
/*

‎src/test/regress/expected/timestamptz.out

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,3 +2538,38 @@ SELECT '2007-12-09 07:30:00 UTC'::timestamptz AT TIME ZONE 'VET';
25382538
Sun Dec 09 03:00:00 2007
25392539
(1 row)
25402540

2541+
--
2542+
-- Test that the pg_timezone_names and pg_timezone_abbrevs views are
2543+
-- more-or-less working. We can't test their contents in any great detail
2544+
-- without the outputs changing anytime IANA updates the underlying data,
2545+
-- but it seems reasonable to expect at least one entry per major meridian.
2546+
-- (At the time of writing, the actual counts are around 38 because of
2547+
-- zones using fractional GMT offsets, so this is a pretty loose test.)
2548+
--
2549+
select count(distinct utc_offset) >= 24 as ok from pg_timezone_names;
2550+
ok
2551+
----
2552+
t
2553+
(1 row)
2554+
2555+
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
2556+
ok
2557+
----
2558+
t
2559+
(1 row)
2560+
2561+
-- Let's check the non-default timezone abbreviation sets, too
2562+
set timezone_abbreviations = 'Australia';
2563+
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
2564+
ok
2565+
----
2566+
t
2567+
(1 row)
2568+
2569+
set timezone_abbreviations = 'India';
2570+
select count(distinct utc_offset) >= 24 as ok from pg_timezone_abbrevs;
2571+
ok
2572+
----
2573+
t
2574+
(1 row)
2575+

‎src/test/regress/sql/timestamptz.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,19 @@ SELECT '2007-12-09 07:00:00 UTC'::timestamptz AT TIME ZONE 'VET';
449449
SELECT'2007-12-09 07:00:01 UTC'::timestamptz ATTIME ZONE'VET';
450450
SELECT'2007-12-09 07:29:59 UTC'::timestamptz ATTIME ZONE'VET';
451451
SELECT'2007-12-09 07:30:00 UTC'::timestamptz ATTIME ZONE'VET';
452+
453+
--
454+
-- Test that the pg_timezone_names and pg_timezone_abbrevs views are
455+
-- more-or-less working. We can't test their contents in any great detail
456+
-- without the outputs changing anytime IANA updates the underlying data,
457+
-- but it seems reasonable to expect at least one entry per major meridian.
458+
-- (At the time of writing, the actual counts are around 38 because of
459+
-- zones using fractional GMT offsets, so this is a pretty loose test.)
460+
--
461+
selectcount(distinct utc_offset)>=24as okfrom pg_timezone_names;
462+
selectcount(distinct utc_offset)>=24as okfrom pg_timezone_abbrevs;
463+
-- Let's check the non-default timezone abbreviation sets, too
464+
set timezone_abbreviations='Australia';
465+
selectcount(distinct utc_offset)>=24as okfrom pg_timezone_abbrevs;
466+
set timezone_abbreviations='India';
467+
selectcount(distinct utc_offset)>=24as okfrom pg_timezone_abbrevs;

‎src/timezone/README

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ in the same commit. Usually, if a known abbreviation has changed meaning,
3434
the appropriate fix is to make it refer to a long-form zone name instead
3535
of a fixed GMT offset.
3636

37+
The core regression test suite does some simple validation of the zone
38+
data and abbreviations data (notably by checking that the pg_timezone_names
39+
and pg_timezone_abbrevs views don't throw errors). It's worth running it
40+
as a cross-check on proposed updates.
41+
3742
When there has been a new release of Windows (probably including Service
3843
Packs), the list of matching timezones need to be updated. Run the
3944
script in src/tools/win32tzlist.pl on a Windows machine running this new

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp