PostgreSQL Source Code git master
pg_attrdef.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "access/table.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_attrdef.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for pg_attrdef.c:

Go to the source code of this file.

Functions

Oid StoreAttrDefault (Relation rel, AttrNumber attnum, Node *expr, bool is_internal)
 
void RemoveAttrDefault (Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal)
 
void RemoveAttrDefaultById (Oid attrdefId)
 
Oid GetAttrDefaultOid (Oid relid, AttrNumber attnum)
 
ObjectAddress GetAttrDefaultColumnAddress (Oid attrdefoid)
 

Function Documentation

◆ GetAttrDefaultColumnAddress()

ObjectAddress GetAttrDefaultColumnAddress ( Oid  attrdefoid)

Definition at line 321 of file pg_attrdef.c.

322{
324 Relation attrdef;
325 ScanKeyData skey[1];
326 SysScanDesc scan;
327 HeapTuple tup;
328
329 attrdef = table_open(AttrDefaultRelationId, AccessShareLock);
330 ScanKeyInit(&skey[0],
331 Anum_pg_attrdef_oid,
332 BTEqualStrategyNumber, F_OIDEQ,
333 ObjectIdGetDatum(attrdefoid));
334 scan = systable_beginscan(attrdef, AttrDefaultOidIndexId, true,
335 NULL, 1, skey);
336
337 if (HeapTupleIsValid(tup = systable_getnext(scan)))
338 {
340
341 result.classId = RelationRelationId;
342 result.objectId = atdform->adrelid;
343 result.objectSubId = atdform->adnum;
344 }
345
346 systable_endscan(scan);
348
349 return result;
350}
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:388
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
#define AccessShareLock
Definition: lockdefs.h:36
const ObjectAddress InvalidObjectAddress
FormData_pg_attrdef * Form_pg_attrdef
Definition: pg_attrdef.h:49
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, BTEqualStrategyNumber, ObjectAddress::classId, GETSTRUCT(), HeapTupleIsValid, InvalidObjectAddress, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by EventTriggerSQLDropAddObject(), getObjectDescription(), getObjectIdentityParts(), and RememberAllDependentForRebuilding().

◆ GetAttrDefaultOid()

Oid GetAttrDefaultOid ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 279 of file pg_attrdef.c.

280{
281 Oid result = InvalidOid;
282 Relation attrdef;
283 ScanKeyData keys[2];
284 SysScanDesc scan;
285 HeapTuple tup;
286
287 attrdef = table_open(AttrDefaultRelationId, AccessShareLock);
288 ScanKeyInit(&keys[0],
289 Anum_pg_attrdef_adrelid,
291 F_OIDEQ,
292 ObjectIdGetDatum(relid));
293 ScanKeyInit(&keys[1],
294 Anum_pg_attrdef_adnum,
296 F_INT2EQ,
298 scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
299 NULL, 2, keys);
300
301 if (HeapTupleIsValid(tup = systable_getnext(scan)))
302 {
304
305 result = atdform->oid;
306 }
307
308 systable_endscan(scan);
310
311 return result;
312}
int16 attnum
Definition: pg_attribute.h:74
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:182
#define InvalidOid
Definition: postgres_ext.h:37
unsigned int Oid
Definition: postgres_ext.h:32

References AccessShareLock, attnum, BTEqualStrategyNumber, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), InvalidOid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ATExecAlterColumnType(), ATExecDropExpression(), ATExecSetExpression(), and get_object_address_attrdef().

◆ RemoveAttrDefault()

void RemoveAttrDefault ( Oid  relid,
AttrNumber  attnum,
DropBehavior  behavior,
bool  complain,
bool  internal 
)

Definition at line 153 of file pg_attrdef.c.

155{
156 Relation attrdef_rel;
157 ScanKeyData scankeys[2];
158 SysScanDesc scan;
159 HeapTuple tuple;
160 bool found = false;
161
162 attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock);
163
164 ScanKeyInit(&scankeys[0],
165 Anum_pg_attrdef_adrelid,
166 BTEqualStrategyNumber, F_OIDEQ,
167 ObjectIdGetDatum(relid));
168 ScanKeyInit(&scankeys[1],
169 Anum_pg_attrdef_adnum,
170 BTEqualStrategyNumber, F_INT2EQ,
172
173 scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,
174 NULL, 2, scankeys);
175
176 /* There should be at most one matching tuple, but we loop anyway */
177 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
178 {
179 ObjectAddress object;
180 Form_pg_attrdef attrtuple = (Form_pg_attrdef) GETSTRUCT(tuple);
181
182 object.classId = AttrDefaultRelationId;
183 object.objectId = attrtuple->oid;
184 object.objectSubId = 0;
185
186 performDeletion(&object, behavior,
187 internal ? PERFORM_DELETION_INTERNAL : 0);
188
189 found = true;
190 }
191
192 systable_endscan(scan);
193 table_close(attrdef_rel, RowExclusiveLock);
194
195 if (complain && !found)
196 elog(ERROR, "could not find attrdef tuple for relation %u attnum %d",
197 relid, attnum);
198}
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition: dependency.c:274
#define PERFORM_DELETION_INTERNAL
Definition: dependency.h:92
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define RowExclusiveLock
Definition: lockdefs.h:38

References attnum, BTEqualStrategyNumber, elog, ERROR, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), ObjectIdGetDatum(), PERFORM_DELETION_INTERNAL, performDeletion(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ATExecAlterColumnType(), ATExecColumnDefault(), ATExecCookedColumnDefault(), ATExecDropExpression(), and ATExecSetExpression().

◆ RemoveAttrDefaultById()

void RemoveAttrDefaultById ( Oid  attrdefId)

Definition at line 208 of file pg_attrdef.c.

209{
210 Relation attrdef_rel;
211 Relation attr_rel;
212 Relation myrel;
213 ScanKeyData scankeys[1];
214 SysScanDesc scan;
215 HeapTuple tuple;
216 Oid myrelid;
217 AttrNumber myattnum;
218
219 /* Grab an appropriate lock on the pg_attrdef relation */
220 attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock);
221
222 /* Find the pg_attrdef tuple */
223 ScanKeyInit(&scankeys[0],
224 Anum_pg_attrdef_oid,
225 BTEqualStrategyNumber, F_OIDEQ,
226 ObjectIdGetDatum(attrdefId));
227
228 scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndexId, true,
229 NULL, 1, scankeys);
230
231 tuple = systable_getnext(scan);
232 if (!HeapTupleIsValid(tuple))
233 elog(ERROR, "could not find tuple for attrdef %u", attrdefId);
234
235 myrelid = ((Form_pg_attrdef) GETSTRUCT(tuple))->adrelid;
236 myattnum = ((Form_pg_attrdef) GETSTRUCT(tuple))->adnum;
237
238 /* Get an exclusive lock on the relation owning the attribute */
239 myrel = relation_open(myrelid, AccessExclusiveLock);
240
241 /* Now we can delete the pg_attrdef row */
242 CatalogTupleDelete(attrdef_rel, &tuple->t_self);
243
244 systable_endscan(scan);
245 table_close(attrdef_rel, RowExclusiveLock);
246
247 /* Fix the pg_attribute row */
248 attr_rel = table_open(AttributeRelationId, RowExclusiveLock);
249
250 tuple = SearchSysCacheCopy2(ATTNUM,
251 ObjectIdGetDatum(myrelid),
252 Int16GetDatum(myattnum));
253 if (!HeapTupleIsValid(tuple)) /* shouldn't happen */
254 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
255 myattnum, myrelid);
256
257 ((Form_pg_attribute) GETSTRUCT(tuple))->atthasdef = false;
258
259 CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple);
260
261 /*
262 * Our update of the pg_attribute row will force a relcache rebuild, so
263 * there's nothing else to do here.
264 */
265 table_close(attr_rel, RowExclusiveLock);
266
267 /* Keep lock on attribute's rel until end of xact */
268 relation_close(myrel, NoLock);
269}
int16 AttrNumber
Definition: attnum.h:21
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition: indexing.c:365
#define NoLock
Definition: lockdefs.h:34
#define AccessExclusiveLock
Definition: lockdefs.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:202
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: relation.c:47
ItemPointerData t_self
Definition: htup.h:65
#define SearchSysCacheCopy2(cacheId, key1, key2)
Definition: syscache.h:93

References AccessExclusiveLock, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), elog, ERROR, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), NoLock, ObjectIdGetDatum(), relation_close(), relation_open(), RowExclusiveLock, ScanKeyInit(), SearchSysCacheCopy2, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by doDeletion().

◆ StoreAttrDefault()

Oid StoreAttrDefault ( Relation  rel,
AttrNumber  attnum,
Node expr,
bool  is_internal 
)

Definition at line 36 of file pg_attrdef.c.

38{
39 char *adbin;
40 Relation adrel;
41 HeapTuple tuple;
42 Datum values[Natts_pg_attrdef];
43 static bool nulls[Natts_pg_attrdef] = {false, false, false, false};
44 Relation attrrel;
45 HeapTuple atttup;
46 Form_pg_attribute attStruct;
47 Datum valuesAtt[Natts_pg_attribute] = {0};
48 bool nullsAtt[Natts_pg_attribute] = {0};
49 bool replacesAtt[Natts_pg_attribute] = {0};
50 char attgenerated;
51 Oid attrdefOid;
52 ObjectAddress colobject,
53 defobject;
54
55 adrel = table_open(AttrDefaultRelationId, RowExclusiveLock);
56
57 /*
58 * Flatten expression to string form for storage.
59 */
60 adbin = nodeToString(expr);
61
62 /*
63 * Make the pg_attrdef entry.
64 */
65 attrdefOid = GetNewOidWithIndex(adrel, AttrDefaultOidIndexId,
66 Anum_pg_attrdef_oid);
67 values[Anum_pg_attrdef_oid - 1] = ObjectIdGetDatum(attrdefOid);
68 values[Anum_pg_attrdef_adrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
69 values[Anum_pg_attrdef_adnum - 1] = Int16GetDatum(attnum);
70 values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
71
72 tuple = heap_form_tuple(adrel->rd_att, values, nulls);
73 CatalogTupleInsert(adrel, tuple);
74
75 defobject.classId = AttrDefaultRelationId;
76 defobject.objectId = attrdefOid;
77 defobject.objectSubId = 0;
78
80
81 /* now can free some of the stuff allocated above */
82 pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
83 heap_freetuple(tuple);
84 pfree(adbin);
85
86 /*
87 * Update the pg_attribute entry for the column to show that a default
88 * exists.
89 */
90 attrrel = table_open(AttributeRelationId, RowExclusiveLock);
91 atttup = SearchSysCacheCopy2(ATTNUM,
94 if (!HeapTupleIsValid(atttup))
95 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
97 attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
98 attgenerated = attStruct->attgenerated;
99
100 valuesAtt[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(true);
101 replacesAtt[Anum_pg_attribute_atthasdef - 1] = true;
102
103 atttup = heap_modify_tuple(atttup, RelationGetDescr(attrrel),
104 valuesAtt, nullsAtt, replacesAtt);
105
106 CatalogTupleUpdate(attrrel, &atttup->t_self, atttup);
107
109 heap_freetuple(atttup);
110
111 /*
112 * Make a dependency so that the pg_attrdef entry goes away if the column
113 * (or whole table) is deleted. In the case of a generated column, make
114 * it an internal dependency to prevent the default expression from being
115 * deleted separately.
116 */
117 colobject.classId = RelationRelationId;
118 colobject.objectId = RelationGetRelid(rel);
119 colobject.objectSubId = attnum;
120
121 recordDependencyOn(&defobject, &colobject,
122 attgenerated ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
123
124 /*
125 * Record dependencies on objects used in the expression, too.
126 */
129 DEPENDENCY_NORMAL, false);
130
131 /*
132 * Post creation hook for attribute defaults.
133 *
134 * XXX. ALTER TABLE ALTER COLUMN SET/DROP DEFAULT is implemented with a
135 * couple of deletion/creation of the attribute's default entry, so the
136 * callee should check existence of an older version of this entry if it
137 * needs to distinguish.
138 */
139 InvokeObjectPostCreateHookArg(AttrDefaultRelationId,
140 RelationGetRelid(rel), attnum, is_internal);
141
142 return attrdefOid;
143}
static Datum values[MAXATTR]
Definition: bootstrap.c:153
#define CStringGetTextDatum(s)
Definition: builtins.h:97
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:448
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
Definition: dependency.c:1629
@ DEPENDENCY_AUTO
Definition: dependency.h:34
@ DEPENDENCY_INTERNAL
Definition: dependency.h:35
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition: heaptuple.c:1210
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1435
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
void pfree(void *pointer)
Definition: mcxt.c:1594
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:175
char * nodeToString(const void *obj)
Definition: outfuncs.c:802
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:45
static Datum BoolGetDatum(bool X)
Definition: postgres.h:112
uint64_t Datum
Definition: postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:322
#define RelationGetRelid(relation)
Definition: rel.h:515
#define RelationGetDescr(relation)
Definition: rel.h:541
TupleDesc rd_att
Definition: rel.h:112

References attnum, BoolGetDatum(), CatalogTupleInsert(), CatalogTupleUpdate(), ObjectAddress::classId, CStringGetTextDatum, DatumGetPointer(), DEPENDENCY_AUTO, DEPENDENCY_INTERNAL, DEPENDENCY_NORMAL, elog, ERROR, GetNewOidWithIndex(), GETSTRUCT(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, Int16GetDatum(), InvokeObjectPostCreateHookArg, nodeToString(), ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, pfree(), RelationData::rd_att, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RelationGetRelid, RowExclusiveLock, SearchSysCacheCopy2, HeapTupleData::t_self, table_close(), table_open(), and values.

Referenced by AddRelationNewConstraints(), ATExecAlterColumnType(), ATExecCookedColumnDefault(), and StoreConstraints().