|
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 | +#ifdef HAVE_INT64_TIMESTAMP |
| 1847 | + return hashint8(fcinfo); |
| 1848 | +#else |
| 1849 | + return hashfloat8(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 | + uint32 thash; |
| 2129 | + uint32 mhash; |
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 |
| - return hash_any((unsigned char *) key, |
2127 |
| - sizeof(key->time) + sizeof(key->day) + sizeof(key->month)); |
| 2137 | +#ifdef HAVE_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.
|
|
0 commit comments