|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.197 2009/03/15 20:31:19 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.198 2009/04/04 04:53:25 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -2041,27 +2041,30 @@ timestamptz_cmp_timestamp(PG_FUNCTION_ARGS)
|
2041 | 2041 | *
|
2042 | 2042 | * collate invalid interval at the end
|
2043 | 2043 | */
|
2044 |
| -static int |
2045 |
| -interval_cmp_internal(Interval *interval1, Interval *interval2) |
| 2044 | +static inline TimeOffset |
| 2045 | +interval_cmp_value(const Interval *interval) |
2046 | 2046 | {
|
2047 |
| - TimeOffset span1, |
2048 |
| - span2; |
| 2047 | + TimeOffset span; |
2049 | 2048 |
|
2050 |
| - span1 = interval1->time; |
2051 |
| - span2 = interval2->time; |
| 2049 | + span = interval->time; |
2052 | 2050 |
|
2053 | 2051 | #ifdef HAVE_INT64_TIMESTAMP
|
2054 |
| - span1 += interval1->month * INT64CONST(30) * USECS_PER_DAY; |
2055 |
| - span1 += interval1->day * INT64CONST(24) * USECS_PER_HOUR; |
2056 |
| - span2 += interval2->month * INT64CONST(30) * USECS_PER_DAY; |
2057 |
| - span2 += interval2->day * INT64CONST(24) * USECS_PER_HOUR; |
| 2052 | + span += interval->month * INT64CONST(30) * USECS_PER_DAY; |
| 2053 | + span += interval->day * INT64CONST(24) * USECS_PER_HOUR; |
2058 | 2054 | #else
|
2059 |
| - span1 += interval1->month * ((double) DAYS_PER_MONTH * SECS_PER_DAY); |
2060 |
| - span1 += interval1->day * ((double) HOURS_PER_DAY * SECS_PER_HOUR); |
2061 |
| - span2 += interval2->month * ((double) DAYS_PER_MONTH * SECS_PER_DAY); |
2062 |
| - span2 += interval2->day * ((double) HOURS_PER_DAY * SECS_PER_HOUR); |
| 2055 | + span += interval->month * ((double) DAYS_PER_MONTH * SECS_PER_DAY); |
| 2056 | + span += interval->day * ((double) HOURS_PER_DAY * SECS_PER_HOUR); |
2063 | 2057 | #endif
|
2064 | 2058 |
|
| 2059 | + return span; |
| 2060 | +} |
| 2061 | + |
| 2062 | +static int |
| 2063 | +interval_cmp_internal(Interval *interval1, Interval *interval2) |
| 2064 | +{ |
| 2065 | + TimeOffset span1 = interval_cmp_value(interval1); |
| 2066 | + TimeOffset span2 = interval_cmp_value(interval2); |
| 2067 | + |
2065 | 2068 | return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);
|
2066 | 2069 | }
|
2067 | 2070 |
|
@@ -2128,32 +2131,24 @@ interval_cmp(PG_FUNCTION_ARGS)
|
2128 | 2131 | PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
|
2129 | 2132 | }
|
2130 | 2133 |
|
| 2134 | +/* |
| 2135 | + * Hashing for intervals |
| 2136 | + * |
| 2137 | + * We must produce equal hashvals for values that interval_cmp_internal() |
| 2138 | + * considers equal. So, compute the net span the same way it does, |
| 2139 | + * and then hash that, using either int64 or float8 hashing. |
| 2140 | + */ |
2131 | 2141 | Datum
|
2132 | 2142 | interval_hash(PG_FUNCTION_ARGS)
|
2133 | 2143 | {
|
2134 |
| - Interval *key = PG_GETARG_INTERVAL_P(0); |
2135 |
| - uint32 thash; |
2136 |
| - uint32 mhash; |
| 2144 | + Interval *interval = PG_GETARG_INTERVAL_P(0); |
| 2145 | + TimeOffset span = interval_cmp_value(interval); |
2137 | 2146 |
|
2138 |
| - /* |
2139 |
| - * To avoid any problems with padding bytes in the struct, we figure the |
2140 |
| - * field hashes separately and XOR them. This also provides a convenient |
2141 |
| - * framework for dealing with the fact that the time field might be either |
2142 |
| - * double or int64. |
2143 |
| - */ |
2144 | 2147 | #ifdef HAVE_INT64_TIMESTAMP
|
2145 |
| - thash = DatumGetUInt32(DirectFunctionCall1(hashint8, |
2146 |
| - Int64GetDatumFast(key->time))); |
| 2148 | + return DirectFunctionCall1(hashint8, Int64GetDatumFast(span)); |
2147 | 2149 | #else
|
2148 |
| - thash = DatumGetUInt32(DirectFunctionCall1(hashfloat8, |
2149 |
| - Float8GetDatumFast(key->time))); |
| 2150 | + return DirectFunctionCall1(hashfloat8, Float8GetDatumFast(span)); |
2150 | 2151 | #endif
|
2151 |
| - thash ^= DatumGetUInt32(hash_uint32(key->day)); |
2152 |
| - /* Shift so "k days" and "k months" don't hash to the same thing */ |
2153 |
| - mhash = DatumGetUInt32(hash_uint32(key->month)); |
2154 |
| - thash ^= mhash << 24; |
2155 |
| - thash ^= mhash >> 8; |
2156 |
| - PG_RETURN_UINT32(thash); |
2157 | 2152 | }
|
2158 | 2153 |
|
2159 | 2154 | /* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator.
|
|
0 commit comments