summaryrefslogtreecommitdiff
path: root/src/backend/access/hash/hashfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/hash/hashfunc.c')
-rw-r--r--src/backend/access/hash/hashfunc.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index e6595de072..a82b8b32d5 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.35 2002/09/04 20:31:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.36 2003/06/22 22:04:54 tgl Exp $
*
* NOTES
* These functions are stored in pg_amproc. For each operator class
@@ -22,6 +22,7 @@
#include "access/hash.h"
+/* Note: this is used for both "char" and boolean datatypes */
Datum
hashchar(PG_FUNCTION_ARGS)
{
@@ -58,6 +59,14 @@ hashfloat4(PG_FUNCTION_ARGS)
{
float4 key = PG_GETARG_FLOAT4(0);
+ /*
+ * On IEEE-float machines, minus zero and zero have different bit patterns
+ * but should compare as equal. We must ensure that they have the same
+ * hash value, which is most easily done this way:
+ */
+ if (key == (float4) 0)
+ PG_RETURN_UINT32(0);
+
return hash_any((unsigned char *) &key, sizeof(key));
}
@@ -66,6 +75,14 @@ hashfloat8(PG_FUNCTION_ARGS)
{
float8 key = PG_GETARG_FLOAT8(0);
+ /*
+ * On IEEE-float machines, minus zero and zero have different bit patterns
+ * but should compare as equal. We must ensure that they have the same
+ * hash value, which is most easily done this way:
+ */
+ if (key == (float8) 0)
+ PG_RETURN_UINT32(0);
+
return hash_any((unsigned char *) &key, sizeof(key));
}
@@ -77,11 +94,6 @@ hashoidvector(PG_FUNCTION_ARGS)
return hash_any((unsigned char *) key, INDEX_MAX_KEYS * sizeof(Oid));
}
-/*
- * Note: hashint2vector currently can't be used as a user hash table
- * hash function, because it has no pg_proc entry. We only need it
- * for catcache indexing.
- */
Datum
hashint2vector(PG_FUNCTION_ARGS)
{
@@ -102,6 +114,26 @@ hashname(PG_FUNCTION_ARGS)
return hash_any((unsigned char *) key, keylen);
}
+Datum
+hashtext(PG_FUNCTION_ARGS)
+{
+ text *key = PG_GETARG_TEXT_P(0);
+ Datum result;
+
+ /*
+ * Note: this is currently identical in behavior to hashvarlena,
+ * but it seems likely that we may need to do something different
+ * in non-C locales. (See also hashbpchar, if so.)
+ */
+ result = hash_any((unsigned char *) VARDATA(key),
+ VARSIZE(key) - VARHDRSZ);
+
+ /* Avoid leaking memory for toasted inputs */
+ PG_FREE_IF_COPY(key, 0);
+
+ return result;
+}
+
/*
* hashvarlena() can be used for any varlena datatype in which there are
* no non-significant bits, ie, distinct bitpatterns never compare as equal.