PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_depend.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_depend.c
4  * routines to support manipulation of the pg_depend relation
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  * src/backend/catalog/pg_depend.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/genam.h"
18 #include "access/heapam.h"
19 #include "access/htup_details.h"
20 #include "catalog/dependency.h"
21 #include "catalog/indexing.h"
22 #include "catalog/pg_constraint.h"
23 #include "catalog/pg_depend.h"
24 #include "catalog/pg_extension.h"
25 #include "commands/extension.h"
26 #include "miscadmin.h"
27 #include "utils/fmgroids.h"
28 #include "utils/lsyscache.h"
29 #include "utils/rel.h"
30 #include "utils/tqual.h"
31 
32 
33 static bool isObjectPinned(const ObjectAddress *object, Relation rel);
34 
35 
36 /*
37  * Record a dependency between 2 objects via their respective objectAddress.
38  * The first argument is the dependent object, the second the one it
39  * references.
40  *
41  * This simply creates an entry in pg_depend, without any other processing.
42  */
43 void
45  const ObjectAddress *referenced,
46  DependencyType behavior)
47 {
48  recordMultipleDependencies(depender, referenced, 1, behavior);
49 }
50 
51 /*
52  * Record multiple dependencies (of the same kind) for a single dependent
53  * object. This has a little less overhead than recording each separately.
54  */
55 void
57  const ObjectAddress *referenced,
58  int nreferenced,
59  DependencyType behavior)
60 {
61  Relation dependDesc;
62  CatalogIndexState indstate;
63  HeapTuple tup;
64  int i;
65  bool nulls[Natts_pg_depend];
67 
68  if (nreferenced <= 0)
69  return; /* nothing to do */
70 
71  /*
72  * During bootstrap, do nothing since pg_depend may not exist yet. initdb
73  * will fill in appropriate pg_depend entries after bootstrap.
74  */
76  return;
77 
79 
80  /* Don't open indexes unless we need to make an update */
81  indstate = NULL;
82 
83  memset(nulls, false, sizeof(nulls));
84 
85  for (i = 0; i < nreferenced; i++, referenced++)
86  {
87  /*
88  * If the referenced object is pinned by the system, there's no real
89  * need to record dependencies on it. This saves lots of space in
90  * pg_depend, so it's worth the time taken to check.
91  */
92  if (!isObjectPinned(referenced, dependDesc))
93  {
94  /*
95  * Record the Dependency. Note we don't bother to check for
96  * duplicate dependencies; there's no harm in them.
97  */
98  values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
99  values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
100  values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
101 
102  values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
103  values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
104  values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
105 
106  values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
107 
108  tup = heap_form_tuple(dependDesc->rd_att, values, nulls);
109 
110  /* fetch index info only when we know we need it */
111  if (indstate == NULL)
112  indstate = CatalogOpenIndexes(dependDesc);
113 
114  CatalogTupleInsertWithInfo(dependDesc, tup, indstate);
115 
116  heap_freetuple(tup);
117  }
118  }
119 
120  if (indstate != NULL)
121  CatalogCloseIndexes(indstate);
122 
123  heap_close(dependDesc, RowExclusiveLock);
124 }
125 
126 /*
127  * If we are executing a CREATE EXTENSION operation, mark the given object
128  * as being a member of the extension. Otherwise, do nothing.
129  *
130  * This must be called during creation of any user-definable object type
131  * that could be a member of an extension.
132  *
133  * If isReplace is true, the object already existed (or might have already
134  * existed), so we must check for a pre-existing extension membership entry.
135  * Passing false is a guarantee that the object is newly created, and so
136  * could not already be a member of any extension.
137  */
138 void
140  bool isReplace)
141 {
142  /* Only whole objects can be extension members */
143  Assert(object->objectSubId == 0);
144 
145  if (creating_extension)
146  {
147  ObjectAddress extension;
148 
149  /* Only need to check for existing membership if isReplace */
150  if (isReplace)
151  {
152  Oid oldext;
153 
154  oldext = getExtensionOfObject(object->classId, object->objectId);
155  if (OidIsValid(oldext))
156  {
157  /* If already a member of this extension, nothing to do */
158  if (oldext == CurrentExtensionObject)
159  return;
160  /* Already a member of some other extension, so reject */
161  ereport(ERROR,
162  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
163  errmsg("%s is already a member of extension \"%s\"",
164  getObjectDescription(object),
165  get_extension_name(oldext))));
166  }
167  }
168 
169  /* OK, record it as a member of CurrentExtensionObject */
170  extension.classId = ExtensionRelationId;
171  extension.objectId = CurrentExtensionObject;
172  extension.objectSubId = 0;
173 
174  recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION);
175  }
176 }
177 
178 /*
179  * deleteDependencyRecordsFor -- delete all records with given depender
180  * classId/objectId. Returns the number of records deleted.
181  *
182  * This is used when redefining an existing object. Links leading to the
183  * object do not change, and links leading from it will be recreated
184  * (possibly with some differences from before).
185  *
186  * If skipExtensionDeps is true, we do not delete any dependencies that
187  * show that the given object is a member of an extension. This avoids
188  * needing a lot of extra logic to fetch and recreate that dependency.
189  */
190 long
192  bool skipExtensionDeps)
193 {
194  long count = 0;
195  Relation depRel;
196  ScanKeyData key[2];
197  SysScanDesc scan;
198  HeapTuple tup;
199 
201 
202  ScanKeyInit(&key[0],
204  BTEqualStrategyNumber, F_OIDEQ,
205  ObjectIdGetDatum(classId));
206  ScanKeyInit(&key[1],
208  BTEqualStrategyNumber, F_OIDEQ,
209  ObjectIdGetDatum(objectId));
210 
211  scan = systable_beginscan(depRel, DependDependerIndexId, true,
212  NULL, 2, key);
213 
214  while (HeapTupleIsValid(tup = systable_getnext(scan)))
215  {
216  if (skipExtensionDeps &&
217  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
218  continue;
219 
220  CatalogTupleDelete(depRel, &tup->t_self);
221  count++;
222  }
223 
224  systable_endscan(scan);
225 
226  heap_close(depRel, RowExclusiveLock);
227 
228  return count;
229 }
230 
231 /*
232  * deleteDependencyRecordsForClass -- delete all records with given depender
233  * classId/objectId, dependee classId, and deptype.
234  * Returns the number of records deleted.
235  *
236  * This is a variant of deleteDependencyRecordsFor, useful when revoking
237  * an object property that is expressed by a dependency record (such as
238  * extension membership).
239  */
240 long
242  Oid refclassId, char deptype)
243 {
244  long count = 0;
245  Relation depRel;
246  ScanKeyData key[2];
247  SysScanDesc scan;
248  HeapTuple tup;
249 
251 
252  ScanKeyInit(&key[0],
254  BTEqualStrategyNumber, F_OIDEQ,
255  ObjectIdGetDatum(classId));
256  ScanKeyInit(&key[1],
258  BTEqualStrategyNumber, F_OIDEQ,
259  ObjectIdGetDatum(objectId));
260 
261  scan = systable_beginscan(depRel, DependDependerIndexId, true,
262  NULL, 2, key);
263 
264  while (HeapTupleIsValid(tup = systable_getnext(scan)))
265  {
266  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
267 
268  if (depform->refclassid == refclassId && depform->deptype == deptype)
269  {
270  CatalogTupleDelete(depRel, &tup->t_self);
271  count++;
272  }
273  }
274 
275  systable_endscan(scan);
276 
277  heap_close(depRel, RowExclusiveLock);
278 
279  return count;
280 }
281 
282 /*
283  * Adjust dependency record(s) to point to a different object of the same type
284  *
285  * classId/objectId specify the referencing object.
286  * refClassId/oldRefObjectId specify the old referenced object.
287  * newRefObjectId is the new referenced object (must be of class refClassId).
288  *
289  * Note the lack of objsubid parameters. If there are subobject references
290  * they will all be readjusted.
291  *
292  * Returns the number of records updated.
293  */
294 long
295 changeDependencyFor(Oid classId, Oid objectId,
296  Oid refClassId, Oid oldRefObjectId,
297  Oid newRefObjectId)
298 {
299  long count = 0;
300  Relation depRel;
301  ScanKeyData key[2];
302  SysScanDesc scan;
303  HeapTuple tup;
304  ObjectAddress objAddr;
305  bool newIsPinned;
306 
308 
309  /*
310  * If oldRefObjectId is pinned, there won't be any dependency entries on
311  * it --- we can't cope in that case. (This isn't really worth expending
312  * code to fix, in current usage; it just means you can't rename stuff out
313  * of pg_catalog, which would likely be a bad move anyway.)
314  */
315  objAddr.classId = refClassId;
316  objAddr.objectId = oldRefObjectId;
317  objAddr.objectSubId = 0;
318 
319  if (isObjectPinned(&objAddr, depRel))
320  ereport(ERROR,
321  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
322  errmsg("cannot remove dependency on %s because it is a system object",
323  getObjectDescription(&objAddr))));
324 
325  /*
326  * We can handle adding a dependency on something pinned, though, since
327  * that just means deleting the dependency entry.
328  */
329  objAddr.objectId = newRefObjectId;
330 
331  newIsPinned = isObjectPinned(&objAddr, depRel);
332 
333  /* Now search for dependency records */
334  ScanKeyInit(&key[0],
336  BTEqualStrategyNumber, F_OIDEQ,
337  ObjectIdGetDatum(classId));
338  ScanKeyInit(&key[1],
340  BTEqualStrategyNumber, F_OIDEQ,
341  ObjectIdGetDatum(objectId));
342 
343  scan = systable_beginscan(depRel, DependDependerIndexId, true,
344  NULL, 2, key);
345 
346  while (HeapTupleIsValid((tup = systable_getnext(scan))))
347  {
348  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
349 
350  if (depform->refclassid == refClassId &&
351  depform->refobjid == oldRefObjectId)
352  {
353  if (newIsPinned)
354  CatalogTupleDelete(depRel, &tup->t_self);
355  else
356  {
357  /* make a modifiable copy */
358  tup = heap_copytuple(tup);
359  depform = (Form_pg_depend) GETSTRUCT(tup);
360 
361  depform->refobjid = newRefObjectId;
362 
363  CatalogTupleUpdate(depRel, &tup->t_self, tup);
364 
365  heap_freetuple(tup);
366  }
367 
368  count++;
369  }
370  }
371 
372  systable_endscan(scan);
373 
374  heap_close(depRel, RowExclusiveLock);
375 
376  return count;
377 }
378 
379 /*
380  * isObjectPinned()
381  *
382  * Test if an object is required for basic database functionality.
383  * Caller must already have opened pg_depend.
384  *
385  * The passed subId, if any, is ignored; we assume that only whole objects
386  * are pinned (and that this implies pinning their components).
387  */
388 static bool
390 {
391  bool ret = false;
392  SysScanDesc scan;
393  HeapTuple tup;
394  ScanKeyData key[2];
395 
396  ScanKeyInit(&key[0],
398  BTEqualStrategyNumber, F_OIDEQ,
399  ObjectIdGetDatum(object->classId));
400 
401  ScanKeyInit(&key[1],
403  BTEqualStrategyNumber, F_OIDEQ,
404  ObjectIdGetDatum(object->objectId));
405 
406  scan = systable_beginscan(rel, DependReferenceIndexId, true,
407  NULL, 2, key);
408 
409  /*
410  * Since we won't generate additional pg_depend entries for pinned
411  * objects, there can be at most one entry referencing a pinned object.
412  * Hence, it's sufficient to look at the first returned tuple; we don't
413  * need to loop.
414  */
415  tup = systable_getnext(scan);
416  if (HeapTupleIsValid(tup))
417  {
418  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
419 
420  if (foundDep->deptype == DEPENDENCY_PIN)
421  ret = true;
422  }
423 
424  systable_endscan(scan);
425 
426  return ret;
427 }
428 
429 
430 /*
431  * Various special-purpose lookups and manipulations of pg_depend.
432  */
433 
434 
435 /*
436  * Find the extension containing the specified object, if any
437  *
438  * Returns the OID of the extension, or InvalidOid if the object does not
439  * belong to any extension.
440  *
441  * Extension membership is marked by an EXTENSION dependency from the object
442  * to the extension. Note that the result will be indeterminate if pg_depend
443  * contains links from this object to more than one extension ... but that
444  * should never happen.
445  */
446 Oid
447 getExtensionOfObject(Oid classId, Oid objectId)
448 {
450  Relation depRel;
451  ScanKeyData key[2];
452  SysScanDesc scan;
453  HeapTuple tup;
454 
456 
457  ScanKeyInit(&key[0],
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(classId));
461  ScanKeyInit(&key[1],
463  BTEqualStrategyNumber, F_OIDEQ,
464  ObjectIdGetDatum(objectId));
465 
466  scan = systable_beginscan(depRel, DependDependerIndexId, true,
467  NULL, 2, key);
468 
469  while (HeapTupleIsValid((tup = systable_getnext(scan))))
470  {
471  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
472 
473  if (depform->refclassid == ExtensionRelationId &&
474  depform->deptype == DEPENDENCY_EXTENSION)
475  {
476  result = depform->refobjid;
477  break; /* no need to keep scanning */
478  }
479  }
480 
481  systable_endscan(scan);
482 
483  heap_close(depRel, AccessShareLock);
484 
485  return result;
486 }
487 
488 /*
489  * Detect whether a sequence is marked as "owned" by a column
490  *
491  * An ownership marker is an AUTO or INTERNAL dependency from the sequence to the
492  * column. If we find one, store the identity of the owning column
493  * into *tableId and *colId and return TRUE; else return FALSE.
494  *
495  * Note: if there's more than one such pg_depend entry then you get
496  * a random one of them returned into the out parameters. This should
497  * not happen, though.
498  */
499 bool
500 sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId)
501 {
502  bool ret = false;
503  Relation depRel;
504  ScanKeyData key[2];
505  SysScanDesc scan;
506  HeapTuple tup;
507 
509 
510  ScanKeyInit(&key[0],
512  BTEqualStrategyNumber, F_OIDEQ,
514  ScanKeyInit(&key[1],
516  BTEqualStrategyNumber, F_OIDEQ,
517  ObjectIdGetDatum(seqId));
518 
519  scan = systable_beginscan(depRel, DependDependerIndexId, true,
520  NULL, 2, key);
521 
522  while (HeapTupleIsValid((tup = systable_getnext(scan))))
523  {
524  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
525 
526  if (depform->refclassid == RelationRelationId &&
527  depform->deptype == deptype)
528  {
529  *tableId = depform->refobjid;
530  *colId = depform->refobjsubid;
531  ret = true;
532  break; /* no need to keep scanning */
533  }
534  }
535 
536  systable_endscan(scan);
537 
538  heap_close(depRel, AccessShareLock);
539 
540  return ret;
541 }
542 
543 /*
544  * Collect a list of OIDs of all sequences owned by the specified relation,
545  * and column if specified.
546  */
547 List *
549 {
550  List *result = NIL;
551  Relation depRel;
552  ScanKeyData key[3];
553  SysScanDesc scan;
554  HeapTuple tup;
555 
557 
558  ScanKeyInit(&key[0],
560  BTEqualStrategyNumber, F_OIDEQ,
562  ScanKeyInit(&key[1],
564  BTEqualStrategyNumber, F_OIDEQ,
565  ObjectIdGetDatum(relid));
566  if (attnum)
567  ScanKeyInit(&key[2],
569  BTEqualStrategyNumber, F_INT4EQ,
570  Int32GetDatum(attnum));
571 
572  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
573  NULL, attnum ? 3 : 2, key);
574 
575  while (HeapTupleIsValid(tup = systable_getnext(scan)))
576  {
577  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
578 
579  /*
580  * We assume any auto or internal dependency of a sequence on a column
581  * must be what we are looking for. (We need the relkind test because
582  * indexes can also have auto dependencies on columns.)
583  */
584  if (deprec->classid == RelationRelationId &&
585  deprec->objsubid == 0 &&
586  deprec->refobjsubid != 0 &&
587  (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
588  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
589  {
590  result = lappend_oid(result, deprec->objid);
591  }
592  }
593 
594  systable_endscan(scan);
595 
596  heap_close(depRel, AccessShareLock);
597 
598  return result;
599 }
600 
601 /*
602  * Get owned sequence, error if not exactly one.
603  */
604 Oid
606 {
607  List *seqlist = getOwnedSequences(relid, attnum);
608 
609  if (list_length(seqlist) > 1)
610  elog(ERROR, "more than one owned sequence found");
611  else if (list_length(seqlist) < 1)
612  elog(ERROR, "no owned sequence found");
613 
614  return linitial_oid(seqlist);
615 }
616 
617 /*
618  * get_constraint_index
619  * Given the OID of a unique or primary-key constraint, return the
620  * OID of the underlying unique index.
621  *
622  * Return InvalidOid if the index couldn't be found; this suggests the
623  * given OID is bogus, but we leave it to caller to decide what to do.
624  */
625 Oid
627 {
628  Oid indexId = InvalidOid;
629  Relation depRel;
630  ScanKeyData key[3];
631  SysScanDesc scan;
632  HeapTuple tup;
633 
634  /* Search the dependency table for the dependent index */
636 
637  ScanKeyInit(&key[0],
639  BTEqualStrategyNumber, F_OIDEQ,
641  ScanKeyInit(&key[1],
643  BTEqualStrategyNumber, F_OIDEQ,
644  ObjectIdGetDatum(constraintId));
645  ScanKeyInit(&key[2],
647  BTEqualStrategyNumber, F_INT4EQ,
648  Int32GetDatum(0));
649 
650  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
651  NULL, 3, key);
652 
653  while (HeapTupleIsValid(tup = systable_getnext(scan)))
654  {
655  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
656 
657  /*
658  * We assume any internal dependency of an index on the constraint
659  * must be what we are looking for. (The relkind test is just
660  * paranoia; there shouldn't be any such dependencies otherwise.)
661  */
662  if (deprec->classid == RelationRelationId &&
663  deprec->objsubid == 0 &&
664  deprec->deptype == DEPENDENCY_INTERNAL &&
665  get_rel_relkind(deprec->objid) == RELKIND_INDEX)
666  {
667  indexId = deprec->objid;
668  break;
669  }
670  }
671 
672  systable_endscan(scan);
673  heap_close(depRel, AccessShareLock);
674 
675  return indexId;
676 }
677 
678 /*
679  * get_index_constraint
680  * Given the OID of an index, return the OID of the owning unique or
681  * primary-key constraint, or InvalidOid if no such constraint.
682  */
683 Oid
685 {
686  Oid constraintId = InvalidOid;
687  Relation depRel;
688  ScanKeyData key[3];
689  SysScanDesc scan;
690  HeapTuple tup;
691 
692  /* Search the dependency table for the index */
694 
695  ScanKeyInit(&key[0],
697  BTEqualStrategyNumber, F_OIDEQ,
699  ScanKeyInit(&key[1],
701  BTEqualStrategyNumber, F_OIDEQ,
702  ObjectIdGetDatum(indexId));
703  ScanKeyInit(&key[2],
705  BTEqualStrategyNumber, F_INT4EQ,
706  Int32GetDatum(0));
707 
708  scan = systable_beginscan(depRel, DependDependerIndexId, true,
709  NULL, 3, key);
710 
711  while (HeapTupleIsValid(tup = systable_getnext(scan)))
712  {
713  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
714 
715  /*
716  * We assume any internal dependency on a constraint must be what we
717  * are looking for.
718  */
719  if (deprec->refclassid == ConstraintRelationId &&
720  deprec->refobjsubid == 0 &&
721  deprec->deptype == DEPENDENCY_INTERNAL)
722  {
723  constraintId = deprec->refobjid;
724  break;
725  }
726  }
727 
728  systable_endscan(scan);
729  heap_close(depRel, AccessShareLock);
730 
731  return constraintId;
732 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:611
Oid CurrentExtensionObject
Definition: extension.c:68
#define NIL
Definition: pg_list.h:69
DependencyType
Definition: dependency.h:73
#define Anum_pg_depend_refobjid
Definition: pg_depend.h:72
Oid getOwnedSequence(Oid relid, AttrNumber attnum)
Definition: pg_depend.c:605
#define Anum_pg_depend_refobjsubid
Definition: pg_depend.h:73
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:447
#define Anum_pg_depend_refclassid
Definition: pg_depend.h:71
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId)
Definition: pg_depend.c:500
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
#define DependReferenceIndexId
Definition: indexing.h:147
char * get_extension_name(Oid ext_oid)
Definition: extension.c:180
#define DependDependerIndexId
Definition: indexing.h:145
#define DependRelationId
Definition: pg_depend.h:29
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:191
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
return result
Definition: formatting.c:1633
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:695
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
unsigned int Oid
Definition: postgres_ext.h:31
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
#define OidIsValid(objectId)
Definition: c.h:538
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define Anum_pg_depend_objsubid
Definition: pg_depend.h:70
char * getObjectDescription(const ObjectAddress *object)
signed int int32
Definition: c.h:256
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:389
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define Natts_pg_depend
Definition: pg_depend.h:67
#define RowExclusiveLock
Definition: lockdefs.h:38
Oid get_index_constraint(Oid indexId)
Definition: pg_depend.c:684
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:61
#define ereport(elevel, rest)
Definition: elog.h:122
List * getOwnedSequences(Oid relid, AttrNumber attnum)
Definition: pg_depend.c:548
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
TupleDesc rd_att
Definition: rel.h:115
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:241
#define InvalidOid
Definition: postgres_ext.h:36
bool creating_extension
Definition: extension.c:67
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:676
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:139
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
#define linitial_oid(l)
Definition: pg_list.h:113
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
static int list_length(const List *l)
Definition: pg_list.h:89
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:368
#define Int32GetDatum(X)
Definition: postgres.h:485
int errmsg(const char *fmt,...)
Definition: elog.c:797
long changeDependencyFor(Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
Definition: pg_depend.c:295
int i
#define RELKIND_INDEX
Definition: pg_class.h:161
#define Anum_pg_depend_deptype
Definition: pg_depend.h:74
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid get_constraint_index(Oid constraintId)
Definition: pg_depend.c:626
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define Anum_pg_depend_classid
Definition: pg_depend.h:68
#define elog
Definition: elog.h:219
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:186
#define ExtensionRelationId
Definition: pg_extension.h:29
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
Definition: pg_list.h:45
int16 AttrNumber
Definition: attnum.h:21
#define Anum_pg_depend_objid
Definition: pg_depend.h:69
#define BTEqualStrategyNumber
Definition: stratnum.h:31