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

Commitf2b6bb4

Browse files
committed
Fix floating-point timestamp comparisons to not go nuts if NaN is
encountered; per bug report from Christian van der Leeden 8/7/03.Also, adjust larger/smaller routines (MAX/MIN) to share code withcomparisons for timestamp, interval, timetz.
1 parente060701 commitf2b6bb4

File tree

2 files changed

+67
-89
lines changed

2 files changed

+67
-89
lines changed

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.89 2003/08/04 02:40:04 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.90 2003/08/08 00:10:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1671,25 +1671,27 @@ timetz_larger(PG_FUNCTION_ARGS)
16711671
{
16721672
TimeTzADT*time1=PG_GETARG_TIMETZADT_P(0);
16731673
TimeTzADT*time2=PG_GETARG_TIMETZADT_P(1);
1674+
TimeTzADT*result;
16741675

1675-
if (DatumGetBool(DirectFunctionCall2(timetz_gt,
1676-
TimeTzADTPGetDatum(time1),
1677-
TimeTzADTPGetDatum(time2))))
1678-
PG_RETURN_TIMETZADT_P(time1);
1679-
PG_RETURN_TIMETZADT_P(time2);
1676+
if (timetz_cmp_internal(time1,time2)>0)
1677+
result=time1;
1678+
else
1679+
result=time2;
1680+
PG_RETURN_TIMETZADT_P(result);
16801681
}
16811682

16821683
Datum
16831684
timetz_smaller(PG_FUNCTION_ARGS)
16841685
{
16851686
TimeTzADT*time1=PG_GETARG_TIMETZADT_P(0);
16861687
TimeTzADT*time2=PG_GETARG_TIMETZADT_P(1);
1688+
TimeTzADT*result;
16871689

1688-
if (DatumGetBool(DirectFunctionCall2(timetz_lt,
1689-
TimeTzADTPGetDatum(time1),
1690-
TimeTzADTPGetDatum(time2))))
1691-
PG_RETURN_TIMETZADT_P(time1);
1692-
PG_RETURN_TIMETZADT_P(time2);
1690+
if (timetz_cmp_internal(time1,time2)<0)
1691+
result=time1;
1692+
else
1693+
result=time2;
1694+
PG_RETURN_TIMETZADT_P(result);
16931695
}
16941696

16951697
/* timetz_pl_interval()

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

Lines changed: 54 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.90 2003/08/04 02:40:05 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.91 2003/08/08 00:10:31 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -20,6 +20,10 @@
2020
#include<errno.h>
2121
#include<float.h>
2222
#include<limits.h>
23+
/* for finite() on Solaris */
24+
#ifdefHAVE_IEEEFP_H
25+
#include<ieeefp.h>
26+
#endif
2327

2428
#include"access/hash.h"
2529
#include"access/xact.h"
@@ -1290,14 +1294,47 @@ SetEpochTimestamp(void)
12901294
}/* SetEpochTimestamp() */
12911295

12921296
/*
1297+
* We are currently sharing some code between timestamp and timestamptz.
1298+
* The comparison functions are among them. - thomas 2001-09-25
1299+
*
12931300
*timestamp_relop - is timestamp1 relop timestamp2
12941301
*
12951302
*collate invalid timestamp at the end
12961303
*/
12971304
staticint
12981305
timestamp_cmp_internal(Timestampdt1,Timestampdt2)
12991306
{
1307+
#ifdefHAVE_INT64_TIMESTAMP
13001308
return ((dt1<dt2) ?-1 : ((dt1>dt2) ?1 :0));
1309+
#else
1310+
/*
1311+
* When using float representation, we have to be wary of NaNs.
1312+
*
1313+
* We consider all NANs to be equal and larger than any non-NAN. This
1314+
* is somewhat arbitrary; the important thing is to have a consistent
1315+
* sort order.
1316+
*/
1317+
if (isnan(dt1))
1318+
{
1319+
if (isnan(dt2))
1320+
return0;/* NAN = NAN */
1321+
else
1322+
return1;/* NAN > non-NAN */
1323+
}
1324+
elseif (isnan(dt2))
1325+
{
1326+
return-1;/* non-NAN < NAN */
1327+
}
1328+
else
1329+
{
1330+
if (dt1>dt2)
1331+
return1;
1332+
elseif (dt1<dt2)
1333+
return-1;
1334+
else
1335+
return0;
1336+
}
1337+
#endif
13011338
}
13021339

13031340
Datum
@@ -1610,18 +1647,18 @@ overlaps_timestamp(PG_FUNCTION_ARGS)
16101647
*"Arithmetic" operators on date/times.
16111648
*---------------------------------------------------------*/
16121649

1613-
/* We are currently sharing some code between timestamp and timestamptz.
1614-
* The comparison functions are among them. - thomas 2001-09-25
1615-
*/
16161650
Datum
16171651
timestamp_smaller(PG_FUNCTION_ARGS)
16181652
{
16191653
Timestampdt1=PG_GETARG_TIMESTAMP(0);
16201654
Timestampdt2=PG_GETARG_TIMESTAMP(1);
16211655
Timestampresult;
16221656

1623-
result= ((dt2<dt1) ?dt2 :dt1);
1624-
1657+
/* use timestamp_cmp_internal to be sure this agrees with comparisons */
1658+
if (timestamp_cmp_internal(dt1,dt2)<0)
1659+
result=dt1;
1660+
else
1661+
result=dt2;
16251662
PG_RETURN_TIMESTAMP(result);
16261663
}
16271664

@@ -1632,8 +1669,10 @@ timestamp_larger(PG_FUNCTION_ARGS)
16321669
Timestampdt2=PG_GETARG_TIMESTAMP(1);
16331670
Timestampresult;
16341671

1635-
result= ((dt2>dt1) ?dt2 :dt1);
1636-
1672+
if (timestamp_cmp_internal(dt1,dt2)>0)
1673+
result=dt1;
1674+
else
1675+
result=dt2;
16371676
PG_RETURN_TIMESTAMP(result);
16381677
}
16391678

@@ -1846,42 +1885,11 @@ interval_smaller(PG_FUNCTION_ARGS)
18461885
Interval*interval2=PG_GETARG_INTERVAL_P(1);
18471886
Interval*result;
18481887

1849-
#ifdefHAVE_INT64_TIMESTAMP
1850-
int64span1,
1851-
span2;
1852-
1853-
#else
1854-
doublespan1,
1855-
span2;
1856-
#endif
1857-
1858-
result= (Interval*)palloc(sizeof(Interval));
1859-
1860-
span1=interval1->time;
1861-
span2=interval2->time;
1862-
#ifdefHAVE_INT64_TIMESTAMP
1863-
if (interval1->month!=0)
1864-
span1+= ((interval1->month*INT64CONST(30)*INT64CONST(86400000000)));
1865-
if (interval2->month!=0)
1866-
span2+= ((interval2->month*INT64CONST(30)*INT64CONST(86400000000)));
1867-
#else
1868-
if (interval1->month!=0)
1869-
span1+= (interval1->month* (30.0*86400));
1870-
if (interval2->month!=0)
1871-
span2+= (interval2->month* (30.0*86400));
1872-
#endif
1873-
1874-
if (span2<span1)
1875-
{
1876-
result->time=interval2->time;
1877-
result->month=interval2->month;
1878-
}
1888+
/* use interval_cmp_internal to be sure this agrees with comparisons */
1889+
if (interval_cmp_internal(interval1,interval2)<0)
1890+
result=interval1;
18791891
else
1880-
{
1881-
result->time=interval1->time;
1882-
result->month=interval1->month;
1883-
}
1884-
1892+
result=interval2;
18851893
PG_RETURN_INTERVAL_P(result);
18861894
}
18871895

@@ -1892,42 +1900,10 @@ interval_larger(PG_FUNCTION_ARGS)
18921900
Interval*interval2=PG_GETARG_INTERVAL_P(1);
18931901
Interval*result;
18941902

1895-
#ifdefHAVE_INT64_TIMESTAMP
1896-
int64span1,
1897-
span2;
1898-
1899-
#else
1900-
doublespan1,
1901-
span2;
1902-
#endif
1903-
1904-
result= (Interval*)palloc(sizeof(Interval));
1905-
1906-
span1=interval1->time;
1907-
span2=interval2->time;
1908-
#ifdefHAVE_INT64_TIMESTAMP
1909-
if (interval1->month!=0)
1910-
span1+= ((interval1->month*INT64CONST(30)*INT64CONST(86400000000)));
1911-
if (interval2->month!=0)
1912-
span2+= ((interval2->month*INT64CONST(30)*INT64CONST(86400000000)));
1913-
#else
1914-
if (interval1->month!=0)
1915-
span1+= (interval1->month* (30.0*86400));
1916-
if (interval2->month!=0)
1917-
span2+= (interval2->month* (30.0*86400));
1918-
#endif
1919-
1920-
if (span2>span1)
1921-
{
1922-
result->time=interval2->time;
1923-
result->month=interval2->month;
1924-
}
1903+
if (interval_cmp_internal(interval1,interval2)>0)
1904+
result=interval1;
19251905
else
1926-
{
1927-
result->time=interval1->time;
1928-
result->month=interval1->month;
1929-
}
1930-
1906+
result=interval2;
19311907
PG_RETURN_INTERVAL_P(result);
19321908
}
19331909

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp