aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tid.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-12-30 15:40:04 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2018-12-30 15:40:04 -0500
commit0a6ea4001a9dff64e9ba66f68855a59a1bf69bc9 (patch)
tree7ab069dcd37ad075745f99b3e9d56b191c4cd19a /src/backend/utils/adt/tid.c
parentb5415e3c2187ab304390524f5ae66b4bd2c58279 (diff)
downloadpostgresql-0a6ea4001a9dff64e9ba66f68855a59a1bf69bc9.tar.gz
postgresql-0a6ea4001a9dff64e9ba66f68855a59a1bf69bc9.zip
Add a hash opclass for type "tid".
Up to now we've not worried much about joins where the join key is a relation's CTID column, reasoning that storing a table's CTIDs in some other table would be pretty useless. However, there are use-cases for this sort of query involving self-joins, so that argument doesn't really hold water. With larger relations, a merge or hash join is desirable. We had a btree opclass for type "tid", allowing merge joins on CTID, but no hash opclass so that hash joins weren't possible. Add the missing infrastructure. This also potentially enables hash aggregation on "tid", though the use-cases for that aren't too clear. Discussion: https://postgr.es/m/1853.1545453106@sss.pgh.pa.us
Diffstat (limited to 'src/backend/utils/adt/tid.c')
-rw-r--r--src/backend/utils/adt/tid.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 41d540b46ec..7b25947682e 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -20,6 +20,7 @@
#include <math.h>
#include <limits.h>
+#include "access/hash.h"
#include "access/heapam.h"
#include "access/sysattr.h"
#include "catalog/namespace.h"
@@ -239,6 +240,33 @@ tidsmaller(PG_FUNCTION_ARGS)
PG_RETURN_ITEMPOINTER(ItemPointerCompare(arg1, arg2) <= 0 ? arg1 : arg2);
}
+Datum
+hashtid(PG_FUNCTION_ARGS)
+{
+ ItemPointer key = PG_GETARG_ITEMPOINTER(0);
+
+ /*
+ * While you'll probably have a lot of trouble with a compiler that
+ * insists on appending pad space to struct ItemPointerData, we can at
+ * least make this code work, by not using sizeof(ItemPointerData).
+ * Instead rely on knowing the sizes of the component fields.
+ */
+ return hash_any((unsigned char *) key,
+ sizeof(BlockIdData) + sizeof(OffsetNumber));
+}
+
+Datum
+hashtidextended(PG_FUNCTION_ARGS)
+{
+ ItemPointer key = PG_GETARG_ITEMPOINTER(0);
+ uint64 seed = PG_GETARG_INT64(1);
+
+ /* As above */
+ return hash_any_extended((unsigned char *) key,
+ sizeof(BlockIdData) + sizeof(OffsetNumber),
+ seed);
+}
+
/*
* Functions to get latest tid of a specified tuple.