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 | */ |
38 | Relation |
39 | table_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 | */ |
67 | Relation |
68 | table_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 | */ |
97 | Relation |
98 | table_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 | */ |
132 | void |
133 | table_close(Relation relation, LOCKMODE lockmode) |
134 | { |
135 | relation_close(relation, lockmode); |
136 | } |
137 | |