From: Andres Freund Date: Mon, 21 Jan 2019 18:14:09 +0000 (-0800) Subject: Introduce access/{table.h, relation.h}, for generic functions from heapam.h. X-Git-Tag: REL_12_BETA1~905 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4b21acf522d751ba5b6679df391d5121b6c4a35f;p=postgresql Introduce access/{table.h, relation.h}, for generic functions from heapam.h. access/heapam contains functions that are very storage specific (say heap_insert() and a lot of lower level functions), and fairly generic infrastructure like relation_open(), heap_open() etc. In the upcoming pluggable storage work we're introducing a layer between table accesses in general and heapam, to allow for different storage methods. For a bit cleaner separation it thus seems advantageous to move generic functions like the aforementioned to their own headers. access/relation.h will contain relation_open() etc, and access/table.h will contain table_open() (formerly known as heap_open()). I've decided for table.h not to include relation.h, but we might change that at a later stage. relation.h already exists in another directory, but the other plausible name (rel.h) also conflicts. It'd be nice if there were a non-conflicting name, but nobody came up with a suggestion. It's possible that the appropriate way to address the naming conflict would be to rename nodes/relation.h, which isn't particularly well named. To avoid breaking a lot of extensions that just use heap_open() etc, table.h has macros mapping the old names to the new ones, and heapam.h includes relation, table.h. That also allows to keep the bulk renaming of existing callers in a separate commit. Author: Andres Freund Discussion: https://postgr.es/m/20190111000539.xbv7s6w7ilcvm7dp@alap3.anarazel.de --- diff --git a/src/backend/access/Makefile b/src/backend/access/Makefile index bd93a6a8d1..0880e0a8bb 100644 --- a/src/backend/access/Makefile +++ b/src/backend/access/Makefile @@ -9,6 +9,6 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global SUBDIRS = brin common gin gist hash heap index nbtree rmgrdesc spgist \ - tablesample transam + table tablesample transam include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/common/Makefile b/src/backend/access/common/Makefile index f130b6e350..d469504337 100644 --- a/src/backend/access/common/Makefile +++ b/src/backend/access/common/Makefile @@ -13,6 +13,6 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = bufmask.o heaptuple.o indextuple.o printsimple.o printtup.o \ - reloptions.o scankey.o session.o tupconvert.o tupdesc.o + relation.o reloptions.o scankey.o session.o tupconvert.o tupdesc.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/common/relation.c b/src/backend/access/common/relation.c new file mode 100644 index 0000000000..beec34f126 --- /dev/null +++ b/src/backend/access/common/relation.c @@ -0,0 +1,217 @@ +/*------------------------------------------------------------------------- + * + * relation.c + * Generic relation related routines. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/common/relation.c + * + * NOTES + * This file contains relation_ routines that implement access to relations + * (tables, indexes, etc). Support that's specific to subtypes of relations + * should go into their respective files, not here. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/relation.h" +#include "access/xact.h" +#include "catalog/namespace.h" +#include "miscadmin.h" +#include "pgstat.h" +#include "storage/lmgr.h" +#include "utils/inval.h" +#include "utils/syscache.h" + + +/* ---------------- + * relation_open - open any relation by relation OID + * + * If lockmode is not "NoLock", the specified kind of lock is + * obtained on the relation. (Generally, NoLock should only be + * used if the caller knows it has some appropriate lock on the + * relation already.) + * + * An error is raised if the relation does not exist. + * + * NB: a "relation" is anything with a pg_class entry. The caller is + * expected to check whether the relkind is something it can handle. + * ---------------- + */ +Relation +relation_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* Get the lock before trying to open the relcache entry */ + if (lockmode != NoLock) + LockRelationOid(relationId, lockmode); + + /* The relcache does all the real work... */ + r = RelationIdGetRelation(relationId); + + if (!RelationIsValid(r)) + elog(ERROR, "could not open relation with OID %u", relationId); + + /* + * If we didn't get the lock ourselves, assert that caller holds one, + * except in bootstrap mode where no locks are used. + */ + Assert(lockmode != NoLock || + IsBootstrapProcessingMode() || + CheckRelationLockedByMe(r, AccessShareLock, true)); + + /* Make note that we've accessed a temporary relation */ + if (RelationUsesLocalBuffers(r)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; + + pgstat_initstats(r); + + return r; +} + +/* ---------------- + * try_relation_open - open any relation by relation OID + * + * Same as relation_open, except return NULL instead of failing + * if the relation does not exist. + * ---------------- + */ +Relation +try_relation_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* Get the lock first */ + if (lockmode != NoLock) + LockRelationOid(relationId, lockmode); + + /* + * Now that we have the lock, probe to see if the relation really exists + * or not. + */ + if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relationId))) + { + /* Release useless lock */ + if (lockmode != NoLock) + UnlockRelationOid(relationId, lockmode); + + return NULL; + } + + /* Should be safe to do a relcache load */ + r = RelationIdGetRelation(relationId); + + if (!RelationIsValid(r)) + elog(ERROR, "could not open relation with OID %u", relationId); + + /* If we didn't get the lock ourselves, assert that caller holds one */ + Assert(lockmode != NoLock || + CheckRelationLockedByMe(r, AccessShareLock, true)); + + /* Make note that we've accessed a temporary relation */ + if (RelationUsesLocalBuffers(r)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; + + pgstat_initstats(r); + + return r; +} + +/* ---------------- + * relation_openrv - open any relation specified by a RangeVar + * + * Same as relation_open, but the relation is specified by a RangeVar. + * ---------------- + */ +Relation +relation_openrv(const RangeVar *relation, LOCKMODE lockmode) +{ + Oid relOid; + + /* + * Check for shared-cache-inval messages before trying to open the + * relation. This is needed even if we already hold a lock on the + * relation, because GRANT/REVOKE are executed without taking any lock on + * the target relation, and we want to be sure we see current ACL + * information. We can skip this if asked for NoLock, on the assumption + * that such a call is not the first one in the current command, and so we + * should be reasonably up-to-date already. (XXX this all could stand to + * be redesigned, but for the moment we'll keep doing this like it's been + * done historically.) + */ + if (lockmode != NoLock) + AcceptInvalidationMessages(); + + /* Look up and lock the appropriate relation using namespace search */ + relOid = RangeVarGetRelid(relation, lockmode, false); + + /* Let relation_open do the rest */ + return relation_open(relOid, NoLock); +} + +/* ---------------- + * relation_openrv_extended - open any relation specified by a RangeVar + * + * Same as relation_openrv, but with an additional missing_ok argument + * allowing a NULL return rather than an error if the relation is not + * found. (Note that some other causes, such as permissions problems, + * will still result in an ereport.) + * ---------------- + */ +Relation +relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok) +{ + Oid relOid; + + /* + * Check for shared-cache-inval messages before trying to open the + * relation. See comments in relation_openrv(). + */ + if (lockmode != NoLock) + AcceptInvalidationMessages(); + + /* Look up and lock the appropriate relation using namespace search */ + relOid = RangeVarGetRelid(relation, lockmode, missing_ok); + + /* Return NULL on not-found */ + if (!OidIsValid(relOid)) + return NULL; + + /* Let relation_open do the rest */ + return relation_open(relOid, NoLock); +} + +/* ---------------- + * relation_close - close any relation + * + * If lockmode is not "NoLock", we then release the specified lock. + * + * Note that it is often sensible to hold a lock beyond relation_close; + * in that case, the lock is released automatically at xact end. + * ---------------- + */ +void +relation_close(Relation relation, LOCKMODE lockmode) +{ + LockRelId relid = relation->rd_lockInfo.lockRelId; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* The relcache does the real work... */ + RelationClose(relation); + + if (lockmode != NoLock) + UnlockRelationId(&relid, lockmode); +} diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index b6fe3a92f0..6c33aefd85 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -12,12 +12,6 @@ * * * INTERFACE ROUTINES - * relation_open - open any relation by relation OID - * relation_openrv - open any relation specified by a RangeVar - * relation_close - close any relation - * heap_open - open a heap relation by relation OID - * heap_openrv - open a heap relation specified by a RangeVar - * heap_close - (now just a macro for relation_close) * heap_beginscan - begin relation scan * heap_rescan - restart a relation scan * heap_endscan - end relation scan @@ -56,7 +50,6 @@ #include "access/xloginsert.h" #include "access/xlogutils.h" #include "catalog/catalog.h" -#include "catalog/namespace.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" @@ -73,7 +66,6 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/snapmgr.h" -#include "utils/syscache.h" #include "utils/tqual.h" @@ -1103,287 +1095,6 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, * ---------------------------------------------------------------- */ -/* ---------------- - * relation_open - open any relation by relation OID - * - * If lockmode is not "NoLock", the specified kind of lock is - * obtained on the relation. (Generally, NoLock should only be - * used if the caller knows it has some appropriate lock on the - * relation already.) - * - * An error is raised if the relation does not exist. - * - * NB: a "relation" is anything with a pg_class entry. The caller is - * expected to check whether the relkind is something it can handle. - * ---------------- - */ -Relation -relation_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* Get the lock before trying to open the relcache entry */ - if (lockmode != NoLock) - LockRelationOid(relationId, lockmode); - - /* The relcache does all the real work... */ - r = RelationIdGetRelation(relationId); - - if (!RelationIsValid(r)) - elog(ERROR, "could not open relation with OID %u", relationId); - - /* - * If we didn't get the lock ourselves, assert that caller holds one, - * except in bootstrap mode where no locks are used. - */ - Assert(lockmode != NoLock || - IsBootstrapProcessingMode() || - CheckRelationLockedByMe(r, AccessShareLock, true)); - - /* Make note that we've accessed a temporary relation */ - if (RelationUsesLocalBuffers(r)) - MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; - - pgstat_initstats(r); - - return r; -} - -/* ---------------- - * try_relation_open - open any relation by relation OID - * - * Same as relation_open, except return NULL instead of failing - * if the relation does not exist. - * ---------------- - */ -Relation -try_relation_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* Get the lock first */ - if (lockmode != NoLock) - LockRelationOid(relationId, lockmode); - - /* - * Now that we have the lock, probe to see if the relation really exists - * or not. - */ - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relationId))) - { - /* Release useless lock */ - if (lockmode != NoLock) - UnlockRelationOid(relationId, lockmode); - - return NULL; - } - - /* Should be safe to do a relcache load */ - r = RelationIdGetRelation(relationId); - - if (!RelationIsValid(r)) - elog(ERROR, "could not open relation with OID %u", relationId); - - /* If we didn't get the lock ourselves, assert that caller holds one */ - Assert(lockmode != NoLock || - CheckRelationLockedByMe(r, AccessShareLock, true)); - - /* Make note that we've accessed a temporary relation */ - if (RelationUsesLocalBuffers(r)) - MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; - - pgstat_initstats(r); - - return r; -} - -/* ---------------- - * relation_openrv - open any relation specified by a RangeVar - * - * Same as relation_open, but the relation is specified by a RangeVar. - * ---------------- - */ -Relation -relation_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Oid relOid; - - /* - * Check for shared-cache-inval messages before trying to open the - * relation. This is needed even if we already hold a lock on the - * relation, because GRANT/REVOKE are executed without taking any lock on - * the target relation, and we want to be sure we see current ACL - * information. We can skip this if asked for NoLock, on the assumption - * that such a call is not the first one in the current command, and so we - * should be reasonably up-to-date already. (XXX this all could stand to - * be redesigned, but for the moment we'll keep doing this like it's been - * done historically.) - */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); - - /* Look up and lock the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, lockmode, false); - - /* Let relation_open do the rest */ - return relation_open(relOid, NoLock); -} - -/* ---------------- - * relation_openrv_extended - open any relation specified by a RangeVar - * - * Same as relation_openrv, but with an additional missing_ok argument - * allowing a NULL return rather than an error if the relation is not - * found. (Note that some other causes, such as permissions problems, - * will still result in an ereport.) - * ---------------- - */ -Relation -relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, - bool missing_ok) -{ - Oid relOid; - - /* - * Check for shared-cache-inval messages before trying to open the - * relation. See comments in relation_openrv(). - */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); - - /* Look up and lock the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, lockmode, missing_ok); - - /* Return NULL on not-found */ - if (!OidIsValid(relOid)) - return NULL; - - /* Let relation_open do the rest */ - return relation_open(relOid, NoLock); -} - -/* ---------------- - * relation_close - close any relation - * - * If lockmode is not "NoLock", we then release the specified lock. - * - * Note that it is often sensible to hold a lock beyond relation_close; - * in that case, the lock is released automatically at xact end. - * ---------------- - */ -void -relation_close(Relation relation, LOCKMODE lockmode) -{ - LockRelId relid = relation->rd_lockInfo.lockRelId; - - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* The relcache does the real work... */ - RelationClose(relation); - - if (lockmode != NoLock) - UnlockRelationId(&relid, lockmode); -} - - -/* ---------------- - * heap_open - open a heap relation by relation OID - * - * This is essentially relation_open plus check that the relation - * is not an index nor a composite type. (The caller should also - * check that it's not a view or foreign table before assuming it has - * storage.) - * ---------------- - */ -Relation -heap_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - r = relation_open(relationId, lockmode); - - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - -/* ---------------- - * heap_openrv - open a heap relation specified - * by a RangeVar node - * - * As above, but relation is specified by a RangeVar. - * ---------------- - */ -Relation -heap_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Relation r; - - r = relation_openrv(relation, lockmode); - - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - -/* ---------------- - * heap_openrv_extended - open a heap relation specified - * by a RangeVar node - * - * As above, but optionally return NULL instead of failing for - * relation-not-found. - * ---------------- - */ -Relation -heap_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, - bool missing_ok) -{ - Relation r; - - r = relation_openrv_extended(relation, lockmode, missing_ok); - - if (r) - { - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - } - - return r; -} - /* ---------------- * heap_beginscan - begin relation scan diff --git a/src/backend/access/table/Makefile b/src/backend/access/table/Makefile new file mode 100644 index 0000000000..ac1de5a52b --- /dev/null +++ b/src/backend/access/table/Makefile @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for access/table +# +# IDENTIFICATION +# src/backend/access/table/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/access/table +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = table.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c new file mode 100644 index 0000000000..a51c06ce2e --- /dev/null +++ b/src/backend/access/table/table.c @@ -0,0 +1,136 @@ +/*------------------------------------------------------------------------- + * + * table.c + * Generic routines for table related code. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/table/table.c + * + * + * NOTES + * This file contains table_ routines that implement access to tables (in + * contrast to other relation types like indexes) that are independent of + * individual table access methods. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/relation.h" +#include "access/table.h" +#include "storage/lmgr.h" + + +/* ---------------- + * table_open - open a table relation by relation OID + * + * This is essentially relation_open plus check that the relation + * is not an index nor a composite type. (The caller should also + * check that it's not a view or foreign table before assuming it has + * storage.) + * ---------------- + */ +Relation +table_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + r = relation_open(relationId, lockmode); + + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + + return r; +} + +/* ---------------- + * table_openrv - open a table relation specified + * by a RangeVar node + * + * As above, but relation is specified by a RangeVar. + * ---------------- + */ +Relation +table_openrv(const RangeVar *relation, LOCKMODE lockmode) +{ + Relation r; + + r = relation_openrv(relation, lockmode); + + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + + return r; +} + +/* ---------------- + * table_openrv_extended - open a table relation specified + * by a RangeVar node + * + * As above, but optionally return NULL instead of failing for + * relation-not-found. + * ---------------- + */ +Relation +table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok) +{ + Relation r; + + r = relation_openrv_extended(relation, lockmode, missing_ok); + + if (r) + { + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + } + + return r; +} + +/* ---------------- + * table_close - close a table + * + * If lockmode is not "NoLock", we then release the specified lock. + * + * Note that it is often sensible to hold a lock beyond relation_close; + * in that case, the lock is released automatically at xact end. + * ---------------- + */ +void +table_close(Relation relation, LOCKMODE lockmode) +{ + relation_close(relation, lockmode); +} diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 4b78150330..6a2489ede3 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -14,8 +14,10 @@ #ifndef HEAPAM_H #define HEAPAM_H +#include "access/relation.h" /* for backward compatibility */ #include "access/sdir.h" #include "access/skey.h" +#include "access/table.h" /* for backward compatibility */ #include "nodes/lockoptions.h" #include "nodes/primnodes.h" #include "storage/bufpage.h" @@ -67,20 +69,6 @@ typedef struct HeapUpdateFailureData * ---------------- */ -/* in heap/heapam.c */ -extern Relation relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation relation_openrv_extended(const RangeVar *relation, - LOCKMODE lockmode, bool missing_ok); -extern void relation_close(Relation relation, LOCKMODE lockmode); - -extern Relation heap_open(Oid relationId, LOCKMODE lockmode); -extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation heap_openrv_extended(const RangeVar *relation, - LOCKMODE lockmode, bool missing_ok); - -#define heap_close(r,l) relation_close(r,l) /* struct definitions appear in relscan.h */ typedef struct HeapScanDescData *HeapScanDesc; diff --git a/src/include/access/relation.h b/src/include/access/relation.h new file mode 100644 index 0000000000..d2c019e69f --- /dev/null +++ b/src/include/access/relation.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * relation.h + * Generic relation related routines. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/relation.h + * + *------------------------------------------------------------------------- + */ +#ifndef ACCESS_RELATION_H +#define ACCESS_RELATION_H + +#include "nodes/primnodes.h" +#include "utils/relcache.h" +#include "storage/lockdefs.h" + + +extern Relation relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation relation_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern void relation_close(Relation relation, LOCKMODE lockmode); + +#endif /* ACCESS_RELATION_H */ diff --git a/src/include/access/table.h b/src/include/access/table.h new file mode 100644 index 0000000000..453f4dd6a1 --- /dev/null +++ b/src/include/access/table.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * table.h + * Generic routines for table related code. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/table.h + * + *------------------------------------------------------------------------- + */ +#ifndef TABLE_H +#define TABLE_H + +#include "nodes/primnodes.h" +#include "utils/relcache.h" +#include "storage/lockdefs.h" + + +extern Relation table_open(Oid relationId, LOCKMODE lockmode); +extern Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation table_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern void table_close(Relation relation, LOCKMODE lockmode); + +/* + * heap_ used to be the prefix for these routines, and a lot of code will just + * continue to work without adaptions after the introduction of pluggable + * storage, therefore just map these names. + */ +#define heap_open(r, l) table_open(r, l) +#define heap_openrv(r, l) table_openrv(r, l) +#define heap_openrv_extended(r, l, m) table_openrv_extended(r, l, m) +#define heap_close(r, l) table_close(r, l) + +#endif /* TABLE_H */