diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile index b83d496..806ce27 100644 --- a/src/backend/access/heap/Makefile +++ b/src/backend/access/heap/Makefile @@ -12,6 +12,7 @@ subdir = src/backend/access/heap top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o visibilitymap.o +OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o visibilitymap.o \ + heapfuncs.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/heap/heapfuncs.c b/src/backend/access/heap/heapfuncs.c new file mode 100644 index 0000000..6c3753b --- /dev/null +++ b/src/backend/access/heap/heapfuncs.c @@ -0,0 +1,81 @@ +/*------------------------------------------------------------------------- + * + * heapfuncs.c + * Functions for accessing the related heap page + * + * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/heap/heapfuncs.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/visibilitymap.h" +#include "funcapi.h" +#include "storage/freespace.h" +#include "storage/bufmgr.h" + +/* Functions for visibilitymap */ +extern Datum pg_is_all_visible(PG_FUNCTION_ARGS); +extern Datum pg_is_all_frozen(PG_FUNCTION_ARGS); + +static bool visibilitymap_test_internal(Oid relid, uint64 blkno, uint8); + +/* + * Return the page is all-visible or not, according to the visibility map. + */ +Datum +pg_is_all_visible(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + int64 blkno = PG_GETARG_INT64(1); + bool all_visible; + + all_visible = visibilitymap_test_internal(relid, blkno, VISIBILITYMAP_ALL_VISIBLE); + + PG_RETURN_BOOL(all_visible); +} + +/* + * Return the page is all-frozen or not, according to the visibility map. + */ +Datum +pg_is_all_frozen(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + int64 blkno = PG_GETARG_INT64(1); + bool all_frozen; + + all_frozen = visibilitymap_test_internal(relid, blkno, VISIBILITYMAP_ALL_FROZEN); + + PG_RETURN_BOOL(all_frozen); +} + +static bool +visibilitymap_test_internal(Oid relid, uint64 blkno, uint8 flag) +{ + + Relation rel; + Buffer vmbuffer = InvalidBuffer; + bool result; + + rel = relation_open(relid, AccessShareLock); + + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + + result = visibilitymap_test(rel, blkno, &vmbuffer, flag); + + if (BufferIsValid(vmbuffer)) + ReleaseBuffer(vmbuffer); + relation_close(rel, AccessShareLock); + + return result; +}