PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
comment.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/indexing.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_description.h"
#include "catalog/pg_shdescription.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/rel.h"
#include "utils/tqual.h"
Include dependency graph for comment.c:

Go to the source code of this file.

Functions

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

Function Documentation

ObjectAddress CommentObject ( CommentStmt stmt)

Definition at line 40 of file comment.c.

References check_object_ownership(), ObjectAddress::classId, CommentStmt::comment, CreateComments(), CreateSharedComments(), ereport, errcode(), errmsg(), ERROR, get_database_oid(), get_object_address(), GetUserId(), InvalidObjectAddress, NoLock, NULL, CommentStmt::object, OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_ROLE, OBJECT_TABLESPACE, ObjectAddress::objectId, ObjectAddress::objectSubId, CommentStmt::objtype, OidIsValid, RelationData::rd_rel, relation_close(), RelationGetRelationName, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_VIEW, ShareUpdateExclusiveLock, strVal, and WARNING.

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

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((Value *) 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  ereport(ERROR,
99  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
100  errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
101  RelationGetRelationName(relation))));
102  break;
103  default:
104  break;
105  }
106 
107  /*
108  * Databases, tablespaces, and roles are cluster-wide objects, so any
109  * comments on those objects are recorded in the shared pg_shdescription
110  * catalog. Comments on all other objects are recorded in pg_description.
111  */
112  if (stmt->objtype == OBJECT_DATABASE || stmt->objtype == OBJECT_TABLESPACE
113  || stmt->objtype == OBJECT_ROLE)
114  CreateSharedComments(address.objectId, address.classId, stmt->comment);
115  else
116  CreateComments(address.objectId, address.classId, address.objectSubId,
117  stmt->comment);
118 
119  /*
120  * If get_object_address() opened the relation for us, we close it to keep
121  * the reference count correct - but we retain any locks acquired by
122  * get_object_address() until commit time, to guard against concurrent
123  * activity.
124  */
125  if (relation != NULL)
126  relation_close(relation, NoLock);
127 
128  return address;
129 }
ObjectType objtype
Definition: parsenodes.h:2544
Oid GetUserId(void)
Definition: miscinit.c:283
#define RELKIND_MATVIEW
Definition: pg_class.h:165
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
Definition: comment.c:141
char * comment
Definition: parsenodes.h:2546
void CreateSharedComments(Oid oid, Oid classoid, char *comment)
Definition: comment.c:236
Node * object
Definition: parsenodes.h:2545
Form_pg_class rd_rel
Definition: rel.h:114
#define OidIsValid(objectId)
Definition: c.h:538
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:166
#define ERROR
Definition: elog.h:43
#define NoLock
Definition: lockdefs.h:34
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define RELKIND_FOREIGN_TABLE
Definition: pg_class.h:167
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
Oid get_database_oid(const char *dbname, bool missing_ok)
Definition: dbcommands.c:2001
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define NULL
Definition: c.h:229
Definition: value.h:42
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
const ObjectAddress InvalidObjectAddress
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
#define RELKIND_RELATION
Definition: pg_class.h:160
void CreateComments ( Oid  oid,
Oid  classoid,
int32  subid,
char *  comment 
)

Definition at line 141 of file comment.c.

References Anum_pg_description_classoid, Anum_pg_description_description, Anum_pg_description_objoid, Anum_pg_description_objsubid, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), CStringGetTextDatum, DescriptionObjIndexId, DescriptionRelationId, heap_close, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), heap_open(), i, Int32GetDatum, Natts_pg_description, NoLock, NULL, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, and values.

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

142 {
143  Relation description;
144  ScanKeyData skey[3];
145  SysScanDesc sd;
146  HeapTuple oldtuple;
147  HeapTuple newtuple = NULL;
149  bool nulls[Natts_pg_description];
150  bool replaces[Natts_pg_description];
151  int i;
152 
153  /* Reduce empty-string to NULL case */
154  if (comment != NULL && strlen(comment) == 0)
155  comment = NULL;
156 
157  /* Prepare to form or update a tuple, if necessary */
158  if (comment != NULL)
159  {
160  for (i = 0; i < Natts_pg_description; i++)
161  {
162  nulls[i] = false;
163  replaces[i] = true;
164  }
165  values[Anum_pg_description_objoid - 1] = ObjectIdGetDatum(oid);
166  values[Anum_pg_description_classoid - 1] = ObjectIdGetDatum(classoid);
167  values[Anum_pg_description_objsubid - 1] = Int32GetDatum(subid);
169  }
170 
171  /* Use the index to search for a matching old tuple */
172 
173  ScanKeyInit(&skey[0],
175  BTEqualStrategyNumber, F_OIDEQ,
176  ObjectIdGetDatum(oid));
177  ScanKeyInit(&skey[1],
179  BTEqualStrategyNumber, F_OIDEQ,
180  ObjectIdGetDatum(classoid));
181  ScanKeyInit(&skey[2],
183  BTEqualStrategyNumber, F_INT4EQ,
184  Int32GetDatum(subid));
185 
187 
188  sd = systable_beginscan(description, DescriptionObjIndexId, true,
189  NULL, 3, skey);
190 
191  while ((oldtuple = systable_getnext(sd)) != NULL)
192  {
193  /* Found the old tuple, so delete or update it */
194 
195  if (comment == NULL)
196  CatalogTupleDelete(description, &oldtuple->t_self);
197  else
198  {
199  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(description), values,
200  nulls, replaces);
201  CatalogTupleUpdate(description, &oldtuple->t_self, newtuple);
202  }
203 
204  break; /* Assume there can be only one match */
205  }
206 
207  systable_endscan(sd);
208 
209  /* If we didn't find an old tuple, insert a new one */
210 
211  if (newtuple == NULL && comment != NULL)
212  {
213  newtuple = heap_form_tuple(RelationGetDescr(description),
214  values, nulls);
215  CatalogTupleInsert(description, newtuple);
216  }
217 
218  if (newtuple != NULL)
219  heap_freetuple(newtuple);
220 
221  /* Done */
222 
223  heap_close(description, NoLock);
224 }
#define Anum_pg_description_classoid
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define RelationGetDescr(relation)
Definition: rel.h:429
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_description_objoid
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
#define Natts_pg_description
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_description_description
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_description_objsubid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:229
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define DescriptionRelationId
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:485
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:91
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define DescriptionObjIndexId
Definition: indexing.h:150
void CreateSharedComments ( Oid  oid,
Oid  classoid,
char *  comment 
)

Definition at line 236 of file comment.c.

References Anum_pg_shdescription_classoid, Anum_pg_shdescription_description, Anum_pg_shdescription_objoid, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), CStringGetTextDatum, heap_close, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), heap_open(), i, Natts_pg_shdescription, NoLock, NULL, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedDescriptionObjIndexId, SharedDescriptionRelationId, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, and values.

Referenced by CommentObject().

237 {
238  Relation shdescription;
239  ScanKeyData skey[2];
240  SysScanDesc sd;
241  HeapTuple oldtuple;
242  HeapTuple newtuple = NULL;
244  bool nulls[Natts_pg_shdescription];
245  bool replaces[Natts_pg_shdescription];
246  int i;
247 
248  /* Reduce empty-string to NULL case */
249  if (comment != NULL && strlen(comment) == 0)
250  comment = NULL;
251 
252  /* Prepare to form or update a tuple, if necessary */
253  if (comment != NULL)
254  {
255  for (i = 0; i < Natts_pg_shdescription; i++)
256  {
257  nulls[i] = false;
258  replaces[i] = true;
259  }
261  values[Anum_pg_shdescription_classoid - 1] = ObjectIdGetDatum(classoid);
263  }
264 
265  /* Use the index to search for a matching old tuple */
266 
267  ScanKeyInit(&skey[0],
269  BTEqualStrategyNumber, F_OIDEQ,
270  ObjectIdGetDatum(oid));
271  ScanKeyInit(&skey[1],
273  BTEqualStrategyNumber, F_OIDEQ,
274  ObjectIdGetDatum(classoid));
275 
277 
278  sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true,
279  NULL, 2, skey);
280 
281  while ((oldtuple = systable_getnext(sd)) != NULL)
282  {
283  /* Found the old tuple, so delete or update it */
284 
285  if (comment == NULL)
286  CatalogTupleDelete(shdescription, &oldtuple->t_self);
287  else
288  {
289  newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(shdescription),
290  values, nulls, replaces);
291  CatalogTupleUpdate(shdescription, &oldtuple->t_self, newtuple);
292  }
293 
294  break; /* Assume there can be only one match */
295  }
296 
297  systable_endscan(sd);
298 
299  /* If we didn't find an old tuple, insert a new one */
300 
301  if (newtuple == NULL && comment != NULL)
302  {
303  newtuple = heap_form_tuple(RelationGetDescr(shdescription),
304  values, nulls);
305  CatalogTupleInsert(shdescription, newtuple);
306  }
307 
308  if (newtuple != NULL)
309  heap_freetuple(newtuple);
310 
311  /* Done */
312 
313  heap_close(shdescription, NoLock);
314 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define RelationGetDescr(relation)
Definition: rel.h:429
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:162
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define SharedDescriptionRelationId
#define Anum_pg_shdescription_classoid
#define Natts_pg_shdescription
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define Anum_pg_shdescription_description
#define SharedDescriptionObjIndexId
Definition: indexing.h:152
#define NULL
Definition: c.h:229
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define Anum_pg_shdescription_objoid
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:91
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:793
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void DeleteComments ( Oid  oid,
Oid  classoid,
int32  subid 
)

Definition at line 324 of file comment.c.

References Anum_pg_description_classoid, Anum_pg_description_objoid, Anum_pg_description_objsubid, BTEqualStrategyNumber, CatalogTupleDelete(), DescriptionObjIndexId, DescriptionRelationId, heap_close, heap_open(), Int32GetDatum, NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by deleteOneObject().

325 {
326  Relation description;
327  ScanKeyData skey[3];
328  int nkeys;
329  SysScanDesc sd;
330  HeapTuple oldtuple;
331 
332  /* Use the index to search for all matching old tuples */
333 
334  ScanKeyInit(&skey[0],
336  BTEqualStrategyNumber, F_OIDEQ,
337  ObjectIdGetDatum(oid));
338  ScanKeyInit(&skey[1],
340  BTEqualStrategyNumber, F_OIDEQ,
341  ObjectIdGetDatum(classoid));
342 
343  if (subid != 0)
344  {
345  ScanKeyInit(&skey[2],
347  BTEqualStrategyNumber, F_INT4EQ,
348  Int32GetDatum(subid));
349  nkeys = 3;
350  }
351  else
352  nkeys = 2;
353 
355 
356  sd = systable_beginscan(description, DescriptionObjIndexId, true,
357  NULL, nkeys, skey);
358 
359  while ((oldtuple = systable_getnext(sd)) != NULL)
360  CatalogTupleDelete(description, &oldtuple->t_self);
361 
362  /* Done */
363 
364  systable_endscan(sd);
365  heap_close(description, RowExclusiveLock);
366 }
#define Anum_pg_description_classoid
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_description_objoid
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Anum_pg_description_objsubid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:229
#define DescriptionRelationId
#define Int32GetDatum(X)
Definition: postgres.h:485
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define DescriptionObjIndexId
Definition: indexing.h:150
void DeleteSharedComments ( Oid  oid,
Oid  classoid 
)

Definition at line 372 of file comment.c.

References Anum_pg_shdescription_classoid, Anum_pg_shdescription_objoid, BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), NULL, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), SharedDescriptionObjIndexId, SharedDescriptionRelationId, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

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

373 {
374  Relation shdescription;
375  ScanKeyData skey[2];
376  SysScanDesc sd;
377  HeapTuple oldtuple;
378 
379  /* Use the index to search for all matching old tuples */
380 
381  ScanKeyInit(&skey[0],
383  BTEqualStrategyNumber, F_OIDEQ,
384  ObjectIdGetDatum(oid));
385  ScanKeyInit(&skey[1],
387  BTEqualStrategyNumber, F_OIDEQ,
388  ObjectIdGetDatum(classoid));
389 
391 
392  sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true,
393  NULL, 2, skey);
394 
395  while ((oldtuple = systable_getnext(sd)) != NULL)
396  CatalogTupleDelete(shdescription, &oldtuple->t_self);
397 
398  /* Done */
399 
400  systable_endscan(sd);
401  heap_close(shdescription, RowExclusiveLock);
402 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define SharedDescriptionRelationId
#define Anum_pg_shdescription_classoid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define SharedDescriptionObjIndexId
Definition: indexing.h:152
#define NULL
Definition: c.h:229
#define Anum_pg_shdescription_objoid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
char* GetComment ( Oid  oid,
Oid  classoid,
int32  subid 
)

Definition at line 408 of file comment.c.

References AccessShareLock, Anum_pg_description_classoid, Anum_pg_description_description, Anum_pg_description_objoid, Anum_pg_description_objsubid, BTEqualStrategyNumber, DescriptionObjIndexId, DescriptionRelationId, heap_close, heap_getattr, heap_open(), Int32GetDatum, NULL, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), TextDatumGetCString, and value.

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

409 {
410  Relation description;
411  ScanKeyData skey[3];
412  SysScanDesc sd;
413  TupleDesc tupdesc;
414  HeapTuple tuple;
415  char *comment;
416 
417  /* Use the index to search for a matching old tuple */
418 
419  ScanKeyInit(&skey[0],
421  BTEqualStrategyNumber, F_OIDEQ,
422  ObjectIdGetDatum(oid));
423  ScanKeyInit(&skey[1],
425  BTEqualStrategyNumber, F_OIDEQ,
426  ObjectIdGetDatum(classoid));
427  ScanKeyInit(&skey[2],
429  BTEqualStrategyNumber, F_INT4EQ,
430  Int32GetDatum(subid));
431 
433  tupdesc = RelationGetDescr(description);
434 
435  sd = systable_beginscan(description, DescriptionObjIndexId, true,
436  NULL, 3, skey);
437 
438  comment = NULL;
439  while ((tuple = systable_getnext(sd)) != NULL)
440  {
441  Datum value;
442  bool isnull;
443 
444  /* Found the tuple, get description field */
445  value = heap_getattr(tuple, Anum_pg_description_description, tupdesc, &isnull);
446  if (!isnull)
447  comment = TextDatumGetCString(value);
448  break; /* Assume there can be only one match */
449  }
450 
451  systable_endscan(sd);
452 
453  /* Done */
454  heap_close(description, AccessShareLock);
455 
456  return comment;
457 }
#define Anum_pg_description_classoid
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define RelationGetDescr(relation)
Definition: rel.h:429
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_description_objoid
static struct @114 value
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define Anum_pg_description_description
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
#define TextDatumGetCString(d)
Definition: builtins.h:92
uintptr_t Datum
Definition: postgres.h:372
#define Anum_pg_description_objsubid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define NULL
Definition: c.h:229
#define DescriptionRelationId
#define Int32GetDatum(X)
Definition: postgres.h:485
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define DescriptionObjIndexId
Definition: indexing.h:150