From 7af3a6fc6f9e2486df37eeac0d61addba09a3551 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 6 Jul 2007 04:16:00 +0000 Subject: Fix up hash functions for datetime datatypes so that they don't take unwarranted liberties with int8 vs float8 values for these types. Specifically, be sure to apply either hashint8 or hashfloat8 depending on HAVE_INT64_TIMESTAMP. Per my gripe of even date. --- src/backend/utils/adt/date.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'src/backend/utils/adt/date.c') 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 $ * *------------------------------------------------------------------------- */ @@ -1197,6 +1197,17 @@ time_cmp(PG_FUNCTION_ARGS) PG_RETURN_INT32(0); } +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) { @@ -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 -- cgit v1.2.3