mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Fix make_timestamp[tz] to accept negative years as meaning BC.
Previously we threw an error. But make_date already allowed the case, so it is inconsistent as well as unhelpful for make_timestamp not to. Both functions continue to reject year zero. Code and test fixes by Peter Eisentraut, doc changes by me Discussion: https://postgr.es/m/13c0992c-f15a-a0ca-d839-91d3efd965d9@2ndquadrant.com
This commit is contained in:
parent
a6b1f5365d
commit
a094c8ff53
@ -8939,6 +8939,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Create date from year, month and day fields
|
Create date from year, month and day fields
|
||||||
|
(negative years signify BC)
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<literal>make_date(2013, 7, 15)</literal>
|
<literal>make_date(2013, 7, 15)</literal>
|
||||||
@ -9004,6 +9005,7 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Create timestamp from year, month, day, hour, minute and seconds fields
|
Create timestamp from year, month, day, hour, minute and seconds fields
|
||||||
|
(negative years signify BC)
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<literal>make_timestamp(2013, 7, 15, 8, 15, 23.5)</literal>
|
<literal>make_timestamp(2013, 7, 15, 8, 15, 23.5)</literal>
|
||||||
@ -9027,12 +9029,18 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Create timestamp with time zone from year, month, day, hour, minute
|
Create timestamp with time zone from year, month, day, hour, minute
|
||||||
and seconds fields; if <parameter>timezone</parameter> is not
|
and seconds fields (negative years signify BC).
|
||||||
specified, the current time zone is used
|
If <parameter>timezone</parameter> is not
|
||||||
|
specified, the current time zone is used; the examples assume the
|
||||||
|
session time zone is <literal>Europe/London</literal>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
<literal>make_timestamptz(2013, 7, 15, 8, 15, 23.5)</literal>
|
<literal>make_timestamptz(2013, 7, 15, 8, 15, 23.5)</literal>
|
||||||
<returnvalue>2013-07-15 08:15:23.5+01</returnvalue>
|
<returnvalue>2013-07-15 08:15:23.5+01</returnvalue>
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
<literal>make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York')</literal>
|
||||||
|
<returnvalue>2013-07-15 13:15:23.5+01</returnvalue>
|
||||||
</para></entry>
|
</para></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -556,17 +556,21 @@ make_timestamp_internal(int year, int month, int day,
|
|||||||
TimeOffset date;
|
TimeOffset date;
|
||||||
TimeOffset time;
|
TimeOffset time;
|
||||||
int dterr;
|
int dterr;
|
||||||
|
bool bc = false;
|
||||||
Timestamp result;
|
Timestamp result;
|
||||||
|
|
||||||
tm.tm_year = year;
|
tm.tm_year = year;
|
||||||
tm.tm_mon = month;
|
tm.tm_mon = month;
|
||||||
tm.tm_mday = day;
|
tm.tm_mday = day;
|
||||||
|
|
||||||
/*
|
/* Handle negative years as BC */
|
||||||
* Note: we'll reject zero or negative year values. Perhaps negatives
|
if (tm.tm_year < 0)
|
||||||
* should be allowed to represent BC years?
|
{
|
||||||
*/
|
bc = true;
|
||||||
dterr = ValidateDate(DTK_DATE_M, false, false, false, &tm);
|
tm.tm_year = -tm.tm_year;
|
||||||
|
}
|
||||||
|
|
||||||
|
dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
|
||||||
|
|
||||||
if (dterr != 0)
|
if (dterr != 0)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
@ -1607,6 +1607,8 @@ select make_time(8, 20, 0.0);
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- should fail
|
-- should fail
|
||||||
|
select make_date(0, 7, 15);
|
||||||
|
ERROR: date field value out of range: 0-07-15
|
||||||
select make_date(2013, 2, 30);
|
select make_date(2013, 2, 30);
|
||||||
ERROR: date field value out of range: 2013-02-30
|
ERROR: date field value out of range: 2013-02-30
|
||||||
select make_date(2013, 13, 1);
|
select make_date(2013, 13, 1);
|
||||||
|
@ -1704,9 +1704,18 @@ SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff
|
|||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- timestamp numeric fields constructor
|
-- timestamp numeric fields constructor
|
||||||
SELECT make_timestamp(2014,12,28,6,30,45.887);
|
SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887);
|
||||||
make_timestamp
|
make_timestamp
|
||||||
------------------------------
|
------------------------------
|
||||||
Sun Dec 28 06:30:45.887 2014
|
Sun Dec 28 06:30:45.887 2014
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT make_timestamp(-44, 3, 15, 12, 30, 15);
|
||||||
|
make_timestamp
|
||||||
|
-----------------------------
|
||||||
|
Fri Mar 15 12:30:15 0044 BC
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- should fail
|
||||||
|
select make_timestamp(0, 7, 15, 12, 30, 15);
|
||||||
|
ERROR: date field value out of range: 0-07-15
|
||||||
|
@ -378,6 +378,7 @@ select make_date(2013, 7, 15);
|
|||||||
select make_date(-44, 3, 15);
|
select make_date(-44, 3, 15);
|
||||||
select make_time(8, 20, 0.0);
|
select make_time(8, 20, 0.0);
|
||||||
-- should fail
|
-- should fail
|
||||||
|
select make_date(0, 7, 15);
|
||||||
select make_date(2013, 2, 30);
|
select make_date(2013, 2, 30);
|
||||||
select make_date(2013, 13, 1);
|
select make_date(2013, 13, 1);
|
||||||
select make_date(2013, 11, -1);
|
select make_date(2013, 11, -1);
|
||||||
|
@ -240,4 +240,7 @@ SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff
|
|||||||
) d(d);
|
) d(d);
|
||||||
|
|
||||||
-- timestamp numeric fields constructor
|
-- timestamp numeric fields constructor
|
||||||
SELECT make_timestamp(2014,12,28,6,30,45.887);
|
SELECT make_timestamp(2014, 12, 28, 6, 30, 45.887);
|
||||||
|
SELECT make_timestamp(-44, 3, 15, 12, 30, 15);
|
||||||
|
-- should fail
|
||||||
|
select make_timestamp(0, 7, 15, 12, 30, 15);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user