1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-14 18:42:34 +03:00

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.
This commit is contained in:
Tom Lane
2007-07-06 04:16:00 +00:00
parent ad9a99c24f
commit 7af3a6fc6f
9 changed files with 95 additions and 41 deletions

View File

@ -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.