diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c
index 94cc59d..ba8a8be 100644
--- a/src/backend/executor/execGrouping.c
+++ b/src/backend/executor/execGrouping.c
@@ -314,7 +314,7 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx,
 	hashtable->in_hash_funcs = NULL;
 	hashtable->cur_eq_funcs = NULL;
 
-	hashtable->hashtab = tuplehash_create(tablecxt, nbuckets);
+	hashtable->hashtab = tuplehash_create(tablecxt, nbuckets, NULL);
 	hashtable->hashtab->private_data = hashtable;
 
 	return hashtable;
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index 826fead..ea79de7 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -244,7 +244,7 @@ tbm_create_pagetable(TIDBitmap *tbm)
 	Assert(tbm->status != TBM_HASH);
 	Assert(tbm->pagetable == NULL);
 
-	tbm->pagetable = pagetable_create(tbm->mcxt, 128);
+	tbm->pagetable = pagetable_create(tbm->mcxt, 128, NULL);
 
 	/* If entry1 is valid, push it into the hashtable */
 	if (tbm->status == TBM_ONE_PAGE)
diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h
index 12aedbc..2328413 100644
--- a/src/include/lib/simplehash.h
+++ b/src/include/lib/simplehash.h
@@ -66,6 +66,7 @@
 #define SH_STATUS_EMPTY SH_MAKE_NAME(EMPTY)
 #define SH_STATUS_IN_USE SH_MAKE_NAME(IN_USE)
 #define SH_ITERATOR SH_MAKE_NAME(iterator)
+#define SH_ALLOCATOR SH_MAKE_NAME(alloc)
 
 /* function declarations */
 #define SH_CREATE SH_MAKE_NAME(create)
@@ -90,6 +91,22 @@
 /* generate forward declarations necessary to use the hash table */
 #ifdef SH_DECLARE
 
+/* Memory allocator function pointers */
+typedef void *(*HashAlloc) (Size size, void *args);
+typedef void (*HashFree) (void *pointer, void *args);
+
+typedef struct SH_ALLOCATOR
+{
+	/* Allocation function */
+	void 	*(*HashAlloc) (Size size, void *args);
+
+	/* Free function*/
+	void 	 (*HashFree) (void *pointer, void *args);
+
+	/* Arguments */
+	void 	*args;
+} SH_ALLOCATOR;
+
 /* type definitions */
 typedef struct SH_TYPE
 {
@@ -112,6 +129,9 @@ typedef struct SH_TYPE
 	/* hash buckets */
 	SH_ELEMENT_TYPE *data;
 
+	/* hash allocator */
+	SH_ALLOCATOR	*alloc;
+
 	/* memory context to use for allocations */
 	MemoryContext ctx;
 
@@ -133,7 +153,8 @@ typedef struct SH_ITERATOR
 } SH_ITERATOR;
 
 /* externally visible function prototypes */
-SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements);
+SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements,
+						SH_ALLOCATOR *alloc);
 SH_SCOPE void SH_DESTROY(SH_TYPE *tb);
 SH_SCOPE void SH_GROW(SH_TYPE *tb, uint32 newsize);
 SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE *tb, SH_KEY_TYPE key, bool *found);
@@ -281,7 +302,7 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry)
  * allocating required memory in the passed-in context.
  */
 SH_SCOPE SH_TYPE *
-SH_CREATE(MemoryContext ctx, uint32 nelements)
+SH_CREATE(MemoryContext ctx, uint32 nelements, SH_ALLOCATOR *alloc)
 {
 	SH_TYPE    *tb;
 	uint64		size;
@@ -294,7 +315,17 @@ SH_CREATE(MemoryContext ctx, uint32 nelements)
 
 	SH_COMPUTE_PARAMETERS(tb, size);
 
-	tb->data = MemoryContextAllocExtended(tb->ctx,
+	tb->alloc = alloc;
+
+	/*
+	 * If allocation handle is passed then use allocation function from the
+	 * handle otherwise use standard allocator.
+	 */
+	if (tb->alloc != NULL)
+		tb->data = tb->alloc->HashAlloc(sizeof(SH_ELEMENT_TYPE) * tb->size,
+										tb->alloc->args);
+	else
+		tb->data = MemoryContextAllocExtended(tb->ctx,
 										  sizeof(SH_ELEMENT_TYPE) * tb->size,
 										  MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
 
@@ -333,8 +364,16 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
 	/* compute parameters for new table */
 	SH_COMPUTE_PARAMETERS(tb, newsize);
 
-	tb->data = MemoryContextAllocExtended(
-								 tb->ctx, sizeof(SH_ELEMENT_TYPE) * tb->size,
+	/*
+	 * If allocation handle is valid then use allocation function from the
+	 * handle otherwise use standard allocator.
+	 */
+	if (tb->alloc != NULL)
+		tb->data = tb->alloc->HashAlloc(sizeof(SH_ELEMENT_TYPE) * tb->size,
+									tb->alloc->args);
+	else
+		tb->data = MemoryContextAllocExtended(tb->ctx,
+										  sizeof(SH_ELEMENT_TYPE) * tb->size,
 										  MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
 
 	newdata = tb->data;
@@ -421,7 +460,11 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
 		}
 	}
 
-	pfree(olddata);
+	if (tb->alloc == NULL)
+		pfree(olddata);
+	else
+		tb->alloc->HashFree(olddata, tb->alloc->args);
+
 }
 
 /*
