1/*-------------------------------------------------------------------------
2 *
3 * table.c
4 * Generic routines for table related code.
5 *
6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/access/table/table.c
12 *
13 *
14 * NOTES
15 * This file contains table_ routines that implement access to tables (in
16 * contrast to other relation types like indexes) that are independent of
17 * individual table access methods.
18 *
19 *-------------------------------------------------------------------------
20 */
21
22#include "postgres.h"
23
24#include "access/relation.h"
25#include "access/table.h"
26#include "storage/lmgr.h"
27
28
29/* ----------------
30 * table_open - open a table relation by relation OID
31 *
32 * This is essentially relation_open plus check that the relation
33 * is not an index nor a composite type. (The caller should also
34 * check that it's not a view or foreign table before assuming it has
35 * storage.)
36 * ----------------
37 */
38Relation
39table_open(Oid relationId, LOCKMODE lockmode)
40{
41 Relation r;
42
43 r = relation_open(relationId, lockmode);
44
45 if (r->rd_rel->relkind == RELKIND_INDEX ||
46 r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
47 ereport(ERROR,
48 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
49 errmsg("\"%s\" is an index",
50 RelationGetRelationName(r))));
51 else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
52 ereport(ERROR,
53 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
54 errmsg("\"%s\" is a composite type",
55 RelationGetRelationName(r))));
56
57 return r;
58}
59
60/* ----------------
61 * table_openrv - open a table relation specified
62 * by a RangeVar node
63 *
64 * As above, but relation is specified by a RangeVar.
65 * ----------------
66 */
67Relation
68table_openrv(const RangeVar *relation, LOCKMODE lockmode)
69{
70 Relation r;
71
72 r = relation_openrv(relation, lockmode);
73
74 if (r->rd_rel->relkind == RELKIND_INDEX ||
75 r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
76 ereport(ERROR,
77 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
78 errmsg("\"%s\" is an index",
79 RelationGetRelationName(r))));
80 else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
81 ereport(ERROR,
82 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
83 errmsg("\"%s\" is a composite type",
84 RelationGetRelationName(r))));
85
86 return r;
87}
88
89/* ----------------
90 * table_openrv_extended - open a table relation specified
91 * by a RangeVar node
92 *
93 * As above, but optionally return NULL instead of failing for
94 * relation-not-found.
95 * ----------------
96 */
97Relation
98table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode,
99 bool missing_ok)
100{
101 Relation r;
102
103 r = relation_openrv_extended(relation, lockmode, missing_ok);
104
105 if (r)
106 {
107 if (r->rd_rel->relkind == RELKIND_INDEX ||
108 r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX)
109 ereport(ERROR,
110 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
111 errmsg("\"%s\" is an index",
112 RelationGetRelationName(r))));
113 else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
114 ereport(ERROR,
115 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
116 errmsg("\"%s\" is a composite type",
117 RelationGetRelationName(r))));
118 }
119
120 return r;
121}
122
123/* ----------------
124 * table_close - close a table
125 *
126 * If lockmode is not "NoLock", we then release the specified lock.
127 *
128 * Note that it is often sensible to hold a lock beyond relation_close;
129 * in that case, the lock is released automatically at xact end.
130 * ----------------
131 */
132void
133table_close(Relation relation, LOCKMODE lockmode)
134{
135 relation_close(relation, lockmode);
136}
137