PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
comment.h File Reference
Include dependency graph for comment.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ObjectAddress CommentObject (CommentStmt *stmt)
 
void DeleteComments (Oid oid, Oid classoid, int32 subid)
 
void CreateComments (Oid oid, Oid classoid, int32 subid, const char *comment)
 
void DeleteSharedComments (Oid oid, Oid classoid)
 
void CreateSharedComments (Oid oid, Oid classoid, const char *comment)
 
char * GetComment (Oid oid, Oid classoid, int32 subid)
 

Function Documentation

◆ CommentObject()

ObjectAddress CommentObject ( CommentStmt stmt)

Definition at line 40 of file comment.c.

41{
42 Relation relation;
44
45 /*
46 * When loading a dump, we may see a COMMENT ON DATABASE for the old name
47 * of the database. Erroring out would prevent pg_restore from completing
48 * (which is really pg_restore's fault, but for now we will work around
49 * the problem here). Consensus is that the best fix is to treat wrong
50 * database name as a WARNING not an ERROR; hence, the following special
51 * case.
52 */
53 if (stmt->objtype == OBJECT_DATABASE)
54 {
55 char *database = strVal(stmt->object);
56
57 if (!OidIsValid(get_database_oid(database, true)))
58 {
60 (errcode(ERRCODE_UNDEFINED_DATABASE),
61 errmsg("database \"%s\" does not exist", database)));
62 return address;
63 }
64 }
65
66 /*
67 * Translate the parser representation that identifies this object into an
68 * ObjectAddress. get_object_address() will throw an error if the object
69 * does not exist, and will also acquire a lock on the target to guard
70 * against concurrent DROP operations.
71 */
72 address = get_object_address(stmt->objtype, stmt->object,
73 &relation, ShareUpdateExclusiveLock, false);
74
75 /* Require ownership of the target object. */
76 check_object_ownership(GetUserId(), stmt->objtype, address,
77 stmt->object, relation);
78
79 /* Perform other integrity checks as needed. */
80 switch (stmt->objtype)
81 {
82 case OBJECT_COLUMN:
83
84 /*
85 * Allow comments only on columns of tables, views, materialized
86 * views, composite types, and foreign tables (which are the only
87 * relkinds for which pg_dump will dump per-column comments). In
88 * particular we wish to disallow comments on index columns,
89 * because the naming of an index's columns may change across PG
90 * versions, so dumping per-column comments could create reload
91 * failures.
92 */
93 if (relation->rd_rel->relkind != RELKIND_RELATION &&
94 relation->rd_rel->relkind != RELKIND_VIEW &&
95 relation->rd_rel->relkind != RELKIND_MATVIEW &&
96 relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
97 relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
98 relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
100 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
101 errmsg("cannot set comment on relation \"%s\"",
102 RelationGetRelationName(relation)),
103 errdetail_relkind_not_supported(relation->rd_rel->relkind)));
104 break;
105 default:
106 break;
107 }
108
109 /*
110 * Databases, tablespaces, and roles are cluster-wide objects, so any
111 * comments on those objects are recorded in the shared pg_shdescription
112 * catalog. Comments on all other objects are recorded in pg_description.
113 */
114 if (stmt->objtype == OBJECT_DATABASE || stmt->objtype == OBJECT_TABLESPACE
115 || stmt->objtype == OBJECT_ROLE)
116 CreateSharedComments(address.objectId, address.classId, stmt->comment);
117 else
118 CreateComments(address.objectId, address.classId, address.objectSubId,
119 stmt->comment);
120
121 /*
122 * If get_object_address() opened the relation for us, we close it to keep
123 * the reference count correct - but we retain any locks acquired by
124 * get_object_address() until commit time, to guard against concurrent
125 * activity.
126 */
127 if (relation != NULL)
128 relation_close(relation, NoLock);
129
130 return address;
131}
#define OidIsValid(objectId)
Definition: c.h:729
void CreateSharedComments(Oid oid, Oid classoid, const char *comment)
Definition: comment.c:238
void CreateComments(Oid oid, Oid classoid, int32 subid, const char *comment)
Definition: comment.c:143
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:3140
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define WARNING
Definition: elog.h:36
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define stmt
Definition: indent_codes.h:59
#define NoLock
Definition: lockdefs.h:34
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
Oid GetUserId(void)
Definition: miscinit.c:517
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
const ObjectAddress InvalidObjectAddress
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
@ OBJECT_COLUMN
Definition: parsenodes.h:2274
@ OBJECT_TABLESPACE
Definition: parsenodes.h:2310
@ OBJECT_ROLE
Definition: parsenodes.h:2301
@ OBJECT_DATABASE
Definition: parsenodes.h:2277
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
#define RelationGetRelationName(relation)
Definition: rel.h:539
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Form_pg_class rd_rel
Definition: rel.h:111
#define strVal(v)
Definition: value.h:82

References check_object_ownership(), ObjectAddress::classId, CreateComments(), CreateSharedComments(), ereport, errcode(), errdetail_relkind_not_supported(), errmsg(), ERROR, get_database_oid(), get_object_address(), GetUserId(), InvalidObjectAddress, NoLock, OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_ROLE, OBJECT_TABLESPACE, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, RelationData::rd_rel, relation_close(), RelationGetRelationName, ShareUpdateExclusiveLock, stmt, strVal, and WARNING.

Referenced by ATExecCmd(), ProcessUtilitySlow(), and standard_ProcessUtility().

◆ CreateComments()

void CreateComments ( Oid  oid,
Oid  classoid,
int32  subid,
const char *  comment 
)

Definition at line 143 of file comment.c.

144{
146 ScanKeyData skey[3];
147 SysScanDesc sd;
148 HeapTuple oldtuple;
149 HeapTuple newtuple = NULL;
150 Datum values[Natts_pg_description];
151 bool nulls[Natts_pg_description];
152 bool replaces[Natts_pg_description];
153 int i;
154
155 /* Reduce empty-string to NULL case */
156 if (comment != NULL && strlen(comment) == 0)
157 comment = NULL;
158
159 /* Prepare to form or update a tuple, if necessary */
160 if (comment != NULL)
161 {
162 for (i = 0; i < Natts_pg_description; i++)
163 {
164 nulls[i] = false;
165 replaces[i] = true;
166 }
167 values[Anum_pg_description_objoid - 1] = ObjectIdGetDatum(oid);
168 values[Anum_pg_description_classoid - 1] = ObjectIdGetDatum(classoid);
169 values[Anum_pg_description_objsubid - 1] = Int32GetDatum(subid);
170 values[Anum_pg_description_description - 1] = CStringGetTextDatum(comment);
171 }
172
173 /* Use the index to search for a matching old tuple */
174
175 ScanKeyInit(&skey[0],
176 Anum_pg_description_objoid,
177 BTEqualStrategyNumber, F_OIDEQ,
178 ObjectIdGetDatum(oid));
179 ScanKeyInit(&skey[1],
180 Anum_pg_description_classoid,
181 BTEqualStrategyNumber, F_OIDEQ,
182 ObjectIdGetDatum(classoid));
183 ScanKeyInit(&skey[2],
184 Anum_pg_description_objsubid,
185 BTEqualStrategyNumber, F_INT4EQ,
186 Int32GetDatum(subid));
187
188 description = table_open(DescriptionRelationId, RowExclusiveLock);
189
190 sd = systable_beginscan(description, DescriptionObjIndexId, true,
191 NULL, 3, skey);
192
193 while ((oldtuple = systable_getnext(sd)) != NULL)
194 {
195 /* Found the old tuple, so delete or update it */
196
197 if (comment == NULL)
199 else
200 {
202 nulls, replaces);
203 CatalogTupleUpdate(description, &oldtuple->t_self, newtuple);
204 }
205
206 break; /* Assume there can be only one match */
207 }
208
210
211 /* If we didn't find an old tuple, insert a new one */
212
213 if (newtuple == NULL && comment != NULL)
214 {
216 values, nulls);
218 }
219
220 if (newtuple != NULL)
221 heap_freetuple(newtuple);
222
223 /* Done */
224
226}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define CStringGetTextDatum(s)
Definition: builtins.h:97
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:606
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:513
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
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
#define comment
Definition: indent_codes.h:49
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
int i
Definition: isn.c:72
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:64
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define RelationGetDescr(relation)
Definition: rel.h:531
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
ItemPointerData t_self
Definition: htup.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
const char * description

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), comment, CStringGetTextDatum, description, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), i, Int32GetDatum(), NoLock, ObjectIdGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), and values.

Referenced by CommentObject(), CreateExtensionInternal(), CreateStatistics(), DefineIndex(), and pg_import_system_collations().

◆ CreateSharedComments()

void CreateSharedComments ( Oid  oid,
Oid  classoid,
const char *  comment 
)

Definition at line 238 of file comment.c.

239{
240 Relation shdescription;
241 ScanKeyData skey[2];
242 SysScanDesc sd;
243 HeapTuple oldtuple;
244 HeapTuple newtuple = NULL;
245 Datum values[Natts_pg_shdescription];
246 bool nulls[Natts_pg_shdescription];
247 bool replaces[Natts_pg_shdescription];
248 int i;
249
250 /* Reduce empty-string to NULL case */
251 if (comment != NULL && strlen(comment) == 0)
252 comment = NULL;
253
254 /* Prepare to form or update a tuple, if necessary */
255 if (comment != NULL)
256 {
257 for (i = 0; i < Natts_pg_shdescription; i++)
258 {
259 nulls[i] = false;
260 replaces[i] = true;
261 }
262 values[Anum_pg_shdescription_objoid - 1] = ObjectIdGetDatum(oid);
263 values[Anum_pg_shdescription_classoid - 1] = ObjectIdGetDatum(classoid);
264 values[Anum_pg_shdescription_description - 1] = CStringGetTextDatum(comment);
265 }
266
267 /* Use the index to search for a matching old tuple */
268
269 ScanKeyInit(&skey[0],
270 Anum_pg_shdescription_objoid,
271 BTEqualStrategyNumber, F_OIDEQ,
272 ObjectIdGetDatum(oid));
273 ScanKeyInit(&skey[1],
274 Anum_pg_shdescription_classoid,
275 BTEqualStrategyNumber, F_OIDEQ,
276 ObjectIdGetDatum(classoid));
277
278 shdescription = table_open(SharedDescriptionRelationId, RowExclusiveLock);
279
280 sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true,
281 NULL, 2, skey);
282
283 while ((oldtuple = systable_getnext(sd)) != NULL)
284 {
285 /* Found the old tuple, so delete or update it */
286
287 if (comment == NULL)
288 CatalogTupleDelete(shdescription, &oldtuple->t_self);
289 else
290 {
291 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(shdescription),
292 values, nulls, replaces);
293 CatalogTupleUpdate(shdescription, &oldtuple->t_self, newtuple);
294 }
295
296 break; /* Assume there can be only one match */
297 }
298
300
301 /* If we didn't find an old tuple, insert a new one */
302
303 if (newtuple == NULL && comment != NULL)
304 {
305 newtuple = heap_form_tuple(RelationGetDescr(shdescription),
306 values, nulls);
307 CatalogTupleInsert(shdescription, newtuple);
308 }
309
310 if (newtuple != NULL)
311 heap_freetuple(newtuple);
312
313 /* Done */
314
315 table_close(shdescription, NoLock);
316}

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), comment, CStringGetTextDatum, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), i, NoLock, ObjectIdGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), and values.

Referenced by CommentObject().

◆ DeleteComments()

void DeleteComments ( Oid  oid,
Oid  classoid,
int32  subid 
)

Definition at line 326 of file comment.c.

327{
329 ScanKeyData skey[3];
330 int nkeys;
331 SysScanDesc sd;
332 HeapTuple oldtuple;
333
334 /* Use the index to search for all matching old tuples */
335
336 ScanKeyInit(&skey[0],
337 Anum_pg_description_objoid,
338 BTEqualStrategyNumber, F_OIDEQ,
339 ObjectIdGetDatum(oid));
340 ScanKeyInit(&skey[1],
341 Anum_pg_description_classoid,
342 BTEqualStrategyNumber, F_OIDEQ,
343 ObjectIdGetDatum(classoid));
344
345 if (subid != 0)
346 {
347 ScanKeyInit(&skey[2],
348 Anum_pg_description_objsubid,
349 BTEqualStrategyNumber, F_INT4EQ,
350 Int32GetDatum(subid));
351 nkeys = 3;
352 }
353 else
354 nkeys = 2;
355
356 description = table_open(DescriptionRelationId, RowExclusiveLock);
357
358 sd = systable_beginscan(description, DescriptionObjIndexId, true,
359 NULL, nkeys, skey);
360
361 while ((oldtuple = systable_getnext(sd)) != NULL)
363
364 /* Done */
365
368}

References BTEqualStrategyNumber, CatalogTupleDelete(), description, Int32GetDatum(), ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by deleteOneObject().

◆ DeleteSharedComments()

void DeleteSharedComments ( Oid  oid,
Oid  classoid 
)

Definition at line 374 of file comment.c.

375{
376 Relation shdescription;
377 ScanKeyData skey[2];
378 SysScanDesc sd;
379 HeapTuple oldtuple;
380
381 /* Use the index to search for all matching old tuples */
382
383 ScanKeyInit(&skey[0],
384 Anum_pg_shdescription_objoid,
385 BTEqualStrategyNumber, F_OIDEQ,
386 ObjectIdGetDatum(oid));
387 ScanKeyInit(&skey[1],
388 Anum_pg_shdescription_classoid,
389 BTEqualStrategyNumber, F_OIDEQ,
390 ObjectIdGetDatum(classoid));
391
392 shdescription = table_open(SharedDescriptionRelationId, RowExclusiveLock);
393
394 sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true,
395 NULL, 2, skey);
396
397 while ((oldtuple = systable_getnext(sd)) != NULL)
398 CatalogTupleDelete(shdescription, &oldtuple->t_self);
399
400 /* Done */
401
403 table_close(shdescription, RowExclusiveLock);
404}

References BTEqualStrategyNumber, CatalogTupleDelete(), ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by dropdb(), DropRole(), and DropTableSpace().

◆ GetComment()

char * GetComment ( Oid  oid,
Oid  classoid,
int32  subid 
)

Definition at line 410 of file comment.c.

411{
413 ScanKeyData skey[3];
414 SysScanDesc sd;
415 TupleDesc tupdesc;
416 HeapTuple tuple;
417 char *comment;
418
419 /* Use the index to search for a matching old tuple */
420
421 ScanKeyInit(&skey[0],
422 Anum_pg_description_objoid,
423 BTEqualStrategyNumber, F_OIDEQ,
424 ObjectIdGetDatum(oid));
425 ScanKeyInit(&skey[1],
426 Anum_pg_description_classoid,
427 BTEqualStrategyNumber, F_OIDEQ,
428 ObjectIdGetDatum(classoid));
429 ScanKeyInit(&skey[2],
430 Anum_pg_description_objsubid,
431 BTEqualStrategyNumber, F_INT4EQ,
432 Int32GetDatum(subid));
433
434 description = table_open(DescriptionRelationId, AccessShareLock);
435 tupdesc = RelationGetDescr(description);
436
437 sd = systable_beginscan(description, DescriptionObjIndexId, true,
438 NULL, 3, skey);
439
440 comment = NULL;
441 while ((tuple = systable_getnext(sd)) != NULL)
442 {
443 Datum value;
444 bool isnull;
445
446 /* Found the tuple, get description field */
447 value = heap_getattr(tuple, Anum_pg_description_description, tupdesc, &isnull);
448 if (!isnull)
450 break; /* Assume there can be only one match */
451 }
452
454
455 /* Done */
457
458 return comment;
459}
#define TextDatumGetCString(d)
Definition: builtins.h:98
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
static struct @161 value
#define AccessShareLock
Definition: lockdefs.h:36

References AccessShareLock, BTEqualStrategyNumber, comment, description, heap_getattr(), Int32GetDatum(), ObjectIdGetDatum(), RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TextDatumGetCString, and value.

Referenced by ATPostAlterTypeParse(), expandTableLikeClause(), RebuildConstraintComment(), and transformTableLikeClause().