summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/date.c34
-rw-r--r--src/backend/utils/adt/timestamp.c40
2 files changed, 57 insertions, 17 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index a66680f4772..efc965ae4c3 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.133 2007/06/15 20:56:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.134 2007/07/06 04:15:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1198,6 +1198,17 @@ time_cmp(PG_FUNCTION_ARGS)
}
Datum
+time_hash(PG_FUNCTION_ARGS)
+{
+ /* We can use either hashint8 or hashfloat8 directly */
+#ifdef HAVE_INT64_TIMESTAMP
+ return hashint8(fcinfo);
+#else
+ return hashfloat8(fcinfo);
+#endif
+}
+
+Datum
time_larger(PG_FUNCTION_ARGS)
{
TimeADT time1 = PG_GETARG_TIMEADT(0);
@@ -1960,20 +1971,27 @@ timetz_cmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(timetz_cmp_internal(time1, time2));
}
-/*
- * timetz, being an unusual size, needs a specialized hash function.
- */
Datum
timetz_hash(PG_FUNCTION_ARGS)
{
TimeTzADT *key = PG_GETARG_TIMETZADT_P(0);
+ uint32 thash;
/*
- * Specify hash length as sizeof(double) + sizeof(int4), not as
- * sizeof(TimeTzADT), so that any garbage pad bytes in the structure won't
- * be included in the hash!
+ * To avoid any problems with padding bytes in the struct,
+ * we figure the field hashes separately and XOR them. This also
+ * provides a convenient framework for dealing with the fact that
+ * the time field might be either double or int64.
*/
- return hash_any((unsigned char *) key, sizeof(key->time) + sizeof(key->zone));
+#ifdef HAVE_INT64_TIMESTAMP
+ thash = DatumGetUInt32(DirectFunctionCall1(hashint8,
+ Int64GetDatumFast(key->time)));
+#else
+ thash = DatumGetUInt32(DirectFunctionCall1(hashfloat8,
+ Float8GetDatumFast(key->time)));
+#endif
+ thash ^= DatumGetUInt32(hash_uint32(key->zone));
+ PG_RETURN_UINT32(thash);
}
Datum
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index d2019351168..04eaa81140d 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.178 2007/06/15 20:56:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.179 2007/07/06 04:15:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1839,6 +1839,17 @@ timestamp_cmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));
}
+Datum
+timestamp_hash(PG_FUNCTION_ARGS)
+{
+ /* We can use either hashint8 or hashfloat8 directly */
+#ifdef HAVE_INT64_TIMESTAMP
+ return hashint8(fcinfo);
+#else
+ return hashfloat8(fcinfo);
+#endif
+}
+
/*
* Crosstype comparison functions for timestamp vs timestamptz
@@ -2110,21 +2121,32 @@ interval_cmp(PG_FUNCTION_ARGS)
PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
}
-/*
- * interval, being an unusual size, needs a specialized hash function.
- */
Datum
interval_hash(PG_FUNCTION_ARGS)
{
Interval *key = PG_GETARG_INTERVAL_P(0);
+ uint32 thash;
+ uint32 mhash;
/*
- * Specify hash length as sizeof(double) + sizeof(int4), not as
- * sizeof(Interval), so that any garbage pad bytes in the structure won't
- * be included in the hash!
+ * To avoid any problems with padding bytes in the struct,
+ * we figure the field hashes separately and XOR them. This also
+ * provides a convenient framework for dealing with the fact that
+ * the time field might be either double or int64.
*/
- return hash_any((unsigned char *) key,
- sizeof(key->time) + sizeof(key->day) + sizeof(key->month));
+#ifdef HAVE_INT64_TIMESTAMP
+ thash = DatumGetUInt32(DirectFunctionCall1(hashint8,
+ Int64GetDatumFast(key->time)));
+#else
+ thash = DatumGetUInt32(DirectFunctionCall1(hashfloat8,
+ Float8GetDatumFast(key->time)));
+#endif
+ thash ^= DatumGetUInt32(hash_uint32(key->day));
+ /* Shift so "k days" and "k months" don't hash to the same thing */
+ mhash = DatumGetUInt32(hash_uint32(key->month));
+ thash ^= mhash << 24;
+ thash ^= mhash >> 8;
+ PG_RETURN_UINT32(thash);
}
/* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator.