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 */
2020#include <errno.h>
2121#include <float.h>
2222#include <limits.h>
23+ /* for finite() on Solaris */
24+ #ifdef HAVE_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 */
12971304static int
12981305timestamp_cmp_internal (Timestamp dt1 ,Timestamp dt2 )
12991306{
1307+ #ifdef HAVE_INT64_TIMESTAMP
13001308return ((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+ return 0 ;/* NAN = NAN */
1321+ else
1322+ return 1 ;/* NAN > non-NAN */
1323+ }
1324+ else if (isnan (dt2 ))
1325+ {
1326+ return -1 ;/* non-NAN < NAN */
1327+ }
1328+ else
1329+ {
1330+ if (dt1 > dt2 )
1331+ return 1 ;
1332+ else if (dt1 < dt2 )
1333+ return -1 ;
1334+ else
1335+ return 0 ;
1336+ }
1337+ #endif
13011338}
13021339
13031340Datum
@@ -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- */
16161650Datum
16171651timestamp_smaller (PG_FUNCTION_ARGS )
16181652{
16191653Timestamp dt1 = PG_GETARG_TIMESTAMP (0 );
16201654Timestamp dt2 = PG_GETARG_TIMESTAMP (1 );
16211655Timestamp result ;
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 ;
16251662PG_RETURN_TIMESTAMP (result );
16261663}
16271664
@@ -1632,8 +1669,10 @@ timestamp_larger(PG_FUNCTION_ARGS)
16321669Timestamp dt2 = PG_GETARG_TIMESTAMP (1 );
16331670Timestamp result ;
16341671
1635- result = ((dt2 > dt1 ) ?dt2 :dt1 );
1636-
1672+ if (timestamp_cmp_internal (dt1 ,dt2 )> 0 )
1673+ result = dt1 ;
1674+ else
1675+ result = dt2 ;
16371676PG_RETURN_TIMESTAMP (result );
16381677}
16391678
@@ -1846,42 +1885,11 @@ interval_smaller(PG_FUNCTION_ARGS)
18461885Interval * interval2 = PG_GETARG_INTERVAL_P (1 );
18471886Interval * result ;
18481887
1849- #ifdef HAVE_INT64_TIMESTAMP
1850- int64 span1 ,
1851- span2 ;
1852-
1853- #else
1854- double span1 ,
1855- span2 ;
1856- #endif
1857-
1858- result = (Interval * )palloc (sizeof (Interval ));
1859-
1860- span1 = interval1 -> time ;
1861- span2 = interval2 -> time ;
1862- #ifdef HAVE_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 ;
18791891else
1880- {
1881- result -> time = interval1 -> time ;
1882- result -> month = interval1 -> month ;
1883- }
1884-
1892+ result = interval2 ;
18851893PG_RETURN_INTERVAL_P (result );
18861894}
18871895
@@ -1892,42 +1900,10 @@ interval_larger(PG_FUNCTION_ARGS)
18921900Interval * interval2 = PG_GETARG_INTERVAL_P (1 );
18931901Interval * result ;
18941902
1895- #ifdef HAVE_INT64_TIMESTAMP
1896- int64 span1 ,
1897- span2 ;
1898-
1899- #else
1900- double span1 ,
1901- span2 ;
1902- #endif
1903-
1904- result = (Interval * )palloc (sizeof (Interval ));
1905-
1906- span1 = interval1 -> time ;
1907- span2 = interval2 -> time ;
1908- #ifdef HAVE_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 ;
19251905else
1926- {
1927- result -> time = interval1 -> time ;
1928- result -> month = interval1 -> month ;
1929- }
1930-
1906+ result = interval2 ;
19311907PG_RETURN_INTERVAL_P (result );
19321908}
19331909