diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 1c2503f..029d3bc 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -21,12 +21,15 @@
 #include <limits.h>
 
 #include "access/heapam.h"
+#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "catalog/namespace.h"
 #include "catalog/pg_type.h"
+#include "funcapi.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
 #include "parser/parsetree.h"
+#include "storage/bufmgr.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/rel.h"
@@ -398,3 +401,73 @@ currtid_byrelname(PG_FUNCTION_ARGS)
 
 	PG_RETURN_ITEMPOINTER(result);
 }
+
+Datum
+pg_tuple_header(PG_FUNCTION_ARGS)
+{
+	Oid			reloid = PG_GETARG_OID(0);
+	ItemPointer tid = PG_GETARG_ITEMPOINTER(1);
+	Relation	rel;
+	AclResult	aclresult;
+	HeapTupleData tup;
+	Buffer		buf;
+	TupleDesc	tupdesc;
+	HeapTuple	result = NULL;
+	Datum		values[7];
+	bool		nulls[7];
+
+	/*
+	 * Attempt to open the relation.
+	 *
+	 * We use try_relation_open() here and throw our own error message because
+	 * relation_open() will elog() if the relation isn't found.
+	 */
+	rel = try_relation_open(reloid, AccessShareLock);
+	if (rel == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_UNDEFINED_TABLE),
+				 errmsg("relation with OID %u does not exist", reloid)));
+
+	/* Check permissions and relkind. */
+	aclresult = pg_class_aclcheck(reloid, GetUserId(), ACL_SELECT);
+	if (aclresult != ACLCHECK_OK)
+		aclcheck_error(aclresult, ACL_KIND_CLASS,
+					   RelationGetRelationName(rel));
+	if (rel->rd_rel->relkind != RELKIND_RELATION &&
+		rel->rd_rel->relkind != RELKIND_MATVIEW)
+		ereport(ERROR,
+				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+				 errmsg("\"%s\" is not a table or materialized view",
+					RelationGetRelationName(rel))));
+
+	/* Fetch the tuple. */
+	tup.t_self = *tid;
+	if (!heap_fetch(rel, GetActiveSnapshot(), &tup, &buf, false, NULL))
+	{
+		relation_close(rel, AccessShareLock);	
+		PG_RETURN_NULL();
+	}
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+
+	/* Fill in the values. */
+	values[0] = TransactionIdGetDatum(HeapTupleHeaderGetRawXmin(tup.t_data));
+	values[1] = TransactionIdGetDatum(HeapTupleHeaderGetRawXmax(tup.t_data));
+	values[2] = CommandIdGetDatum(HeapTupleHeaderGetRawCommandId(tup.t_data));
+	values[3] = ItemPointerGetDatum(&tup.t_data->t_ctid);
+	values[4] = Int32GetDatum((int32) tup.t_data->t_infomask);
+	values[5] = Int32GetDatum((int32) tup.t_data->t_infomask2);
+	values[6] = Int16GetDatum((int16) tup.t_data->t_hoff);
+
+	/* Build the tuple. */
+	memset(nulls, 0, sizeof(nulls));
+	result = heap_form_tuple(tupdesc, values, nulls);
+
+	/* Release resources. */
+	ReleaseBuffer(buf);
+	relation_close(rel, AccessShareLock);	
+
+	PG_RETURN_DATUM(HeapTupleGetDatum(result));
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0117500..d88898a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -1371,6 +1371,8 @@ DATA(insert OID = 2795 ( tidlarger		   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0
 DESCR("larger of two");
 DATA(insert OID = 2796 ( tidsmaller		   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 27 "27 27" _null_ _null_ _null_ _null_ tidsmaller _null_ _null_ _null_ ));
 DESCR("smaller of two");
+DATA(insert OID = 3195 ( pg_tuple_header   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2249 "2205 27" "{2205,27,28,28,29,27,23,23,21}" "{i,i,o,o,o,o,o,o,o}" "{tableoid,tid,xmin,xmax,cid,ctid,infomask,infomask2,hoff}" _null_ pg_tuple_header _null_ _null_ _null_ ));
+DESCR("tuple header fields");
 
 DATA(insert OID = 1296 (  timedate_pl	   PGNSP PGUID 14 1 0 0 0 f f f f t f i 2 0 1114 "1083 1082" _null_ _null_ _null_ _null_ "select ($2 + $1)" _null_ _null_ _null_ ));
 DATA(insert OID = 1297 (  datetimetz_pl    PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1184 "1082 1266" _null_ _null_ _null_ _null_ datetimetz_timestamptz _null_ _null_ _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 1bfd145..4d573d4 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -695,6 +695,7 @@ extern Datum tidlarger(PG_FUNCTION_ARGS);
 extern Datum tidsmaller(PG_FUNCTION_ARGS);
 extern Datum currtid_byreloid(PG_FUNCTION_ARGS);
 extern Datum currtid_byrelname(PG_FUNCTION_ARGS);
+extern Datum pg_tuple_header(PG_FUNCTION_ARGS);
 
 /* varchar.c */
 extern Datum bpcharin(PG_FUNCTION_ARGS);
