|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.178 2007/06/15 20:56:50 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.179 2007/07/06 04:15:59 tgl Exp $ |
12 | 12 | * |
13 | 13 | *------------------------------------------------------------------------- |
14 | 14 | */ |
@@ -1839,6 +1839,17 @@ timestamp_cmp(PG_FUNCTION_ARGS) |
1839 | 1839 | PG_RETURN_INT32(timestamp_cmp_internal(dt1,dt2)); |
1840 | 1840 | } |
1841 | 1841 |
|
| 1842 | +Datum |
| 1843 | +timestamp_hash(PG_FUNCTION_ARGS) |
| 1844 | +{ |
| 1845 | +/* We can use either hashint8 or hashfloat8 directly */ |
| 1846 | +#ifdefHAVE_INT64_TIMESTAMP |
| 1847 | +returnhashint8(fcinfo); |
| 1848 | +#else |
| 1849 | +returnhashfloat8(fcinfo); |
| 1850 | +#endif |
| 1851 | +} |
| 1852 | + |
1842 | 1853 |
|
1843 | 1854 | /* |
1844 | 1855 | * Crosstype comparison functions for timestamp vs timestamptz |
@@ -2110,21 +2121,32 @@ interval_cmp(PG_FUNCTION_ARGS) |
2110 | 2121 | PG_RETURN_INT32(interval_cmp_internal(interval1,interval2)); |
2111 | 2122 | } |
2112 | 2123 |
|
2113 | | -/* |
2114 | | - * interval, being an unusual size, needs a specialized hash function. |
2115 | | - */ |
2116 | 2124 | Datum |
2117 | 2125 | interval_hash(PG_FUNCTION_ARGS) |
2118 | 2126 | { |
2119 | 2127 | Interval*key=PG_GETARG_INTERVAL_P(0); |
| 2128 | +uint32thash; |
| 2129 | +uint32mhash; |
2120 | 2130 |
|
2121 | 2131 | /* |
2122 | | - * Specify hash length as sizeof(double) + sizeof(int4), not as |
2123 | | - * sizeof(Interval), so that any garbage pad bytes in the structure won't |
2124 | | - * be included in the hash! |
| 2132 | + * To avoid any problems with padding bytes in the struct, |
| 2133 | + * we figure the field hashes separately and XOR them. This also |
| 2134 | + * provides a convenient framework for dealing with the fact that |
| 2135 | + * the time field might be either double or int64. |
2125 | 2136 | */ |
2126 | | -returnhash_any((unsignedchar*)key, |
2127 | | -sizeof(key->time)+sizeof(key->day)+sizeof(key->month)); |
| 2137 | +#ifdefHAVE_INT64_TIMESTAMP |
| 2138 | +thash=DatumGetUInt32(DirectFunctionCall1(hashint8, |
| 2139 | +Int64GetDatumFast(key->time))); |
| 2140 | +#else |
| 2141 | +thash=DatumGetUInt32(DirectFunctionCall1(hashfloat8, |
| 2142 | +Float8GetDatumFast(key->time))); |
| 2143 | +#endif |
| 2144 | +thash ^=DatumGetUInt32(hash_uint32(key->day)); |
| 2145 | +/* Shift so "k days" and "k months" don't hash to the same thing */ |
| 2146 | +mhash=DatumGetUInt32(hash_uint32(key->month)); |
| 2147 | +thash ^=mhash <<24; |
| 2148 | +thash ^=mhash >>8; |
| 2149 | +PG_RETURN_UINT32(thash); |
2128 | 2150 | } |
2129 | 2151 |
|
2130 | 2152 | /* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator. |
|