summaryrefslogtreecommitdiff
path: root/src/backend/catalog/pg_depend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/pg_depend.c')
-rw-r--r--src/backend/catalog/pg_depend.c153
1 files changed, 100 insertions, 53 deletions
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 5a297d4a27..99cdf5e7e6 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.21 2006/07/11 17:26:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_depend.c,v 1.22 2006/08/21 00:57:24 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -163,58 +163,6 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId)
}
/*
- * objectIsInternalDependency -- return whether the specified object
- * is listed as an internal dependency for some other object.
- *
- * This is used to implement DROP/REASSIGN OWNED. We cannot invoke
- * performDeletion blindly, because it may try to drop or modify an internal-
- * dependent object before the "main" object, so we need to skip the first
- * object and expect it to be automatically dropped when the main object is
- * dropped.
- */
-bool
-objectIsInternalDependency(Oid classId, Oid objectId)
-{
- Relation depRel;
- ScanKeyData key[2];
- SysScanDesc scan;
- HeapTuple tup;
- bool isdep = false;
-
- depRel = heap_open(DependRelationId, AccessShareLock);
-
- ScanKeyInit(&key[0],
- Anum_pg_depend_classid,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(classId));
- ScanKeyInit(&key[1],
- Anum_pg_depend_objid,
- BTEqualStrategyNumber, F_OIDEQ,
- ObjectIdGetDatum(objectId));
-
- scan = systable_beginscan(depRel, DependDependerIndexId, true,
- SnapshotNow, 2, key);
-
- while (HeapTupleIsValid(tup = systable_getnext(scan)))
- {
- Form_pg_depend depForm = (Form_pg_depend) GETSTRUCT(tup);
-
- if (depForm->deptype == DEPENDENCY_INTERNAL)
- {
- /* No need to keep scanning */
- isdep = true;
- break;
- }
- }
-
- systable_endscan(scan);
-
- heap_close(depRel, AccessShareLock);
-
- return isdep;
-}
-
-/*
* Adjust dependency record(s) to point to a different object of the same type
*
* classId/objectId specify the referencing object.
@@ -313,6 +261,105 @@ changeDependencyFor(Oid classId, Oid objectId,
}
/*
+ * Detect whether a sequence is marked as "owned" by a column
+ *
+ * An ownership marker is an AUTO dependency from the sequence to the
+ * column. If we find one, store the identity of the owning column
+ * into *tableId and *colId and return TRUE; else return FALSE.
+ *
+ * Note: if there's more than one such pg_depend entry then you get
+ * a random one of them returned into the out parameters. This should
+ * not happen, though.
+ */
+bool
+sequenceIsOwned(Oid seqId, Oid *tableId, int32 *colId)
+{
+ bool ret = false;
+ Relation depRel;
+ ScanKeyData key[2];
+ SysScanDesc scan;
+ HeapTuple tup;
+
+ depRel = heap_open(DependRelationId, AccessShareLock);
+
+ ScanKeyInit(&key[0],
+ Anum_pg_depend_classid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationRelationId));
+ ScanKeyInit(&key[1],
+ Anum_pg_depend_objid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(seqId));
+
+ scan = systable_beginscan(depRel, DependDependerIndexId, true,
+ SnapshotNow, 2, key);
+
+ while (HeapTupleIsValid((tup = systable_getnext(scan))))
+ {
+ Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
+
+ if (depform->refclassid == RelationRelationId &&
+ depform->deptype == DEPENDENCY_AUTO)
+ {
+ *tableId = depform->refobjid;
+ *colId = depform->refobjsubid;
+ ret = true;
+ break; /* no need to keep scanning */
+ }
+ }
+
+ systable_endscan(scan);
+
+ heap_close(depRel, AccessShareLock);
+
+ return ret;
+}
+
+/*
+ * Remove any existing "owned" markers for the specified sequence.
+ *
+ * Note: we don't provide a special function to install an "owned"
+ * marker; just use recordDependencyOn().
+ */
+void
+markSequenceUnowned(Oid seqId)
+{
+ Relation depRel;
+ ScanKeyData key[2];
+ SysScanDesc scan;
+ HeapTuple tup;
+
+ depRel = heap_open(DependRelationId, RowExclusiveLock);
+
+ ScanKeyInit(&key[0],
+ Anum_pg_depend_classid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(RelationRelationId));
+ ScanKeyInit(&key[1],
+ Anum_pg_depend_objid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(seqId));
+
+ scan = systable_beginscan(depRel, DependDependerIndexId, true,
+ SnapshotNow, 2, key);
+
+ while (HeapTupleIsValid((tup = systable_getnext(scan))))
+ {
+ Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
+
+ if (depform->refclassid == RelationRelationId &&
+ depform->deptype == DEPENDENCY_AUTO)
+ {
+ simple_heap_delete(depRel, &tup->t_self);
+ }
+ }
+
+ systable_endscan(scan);
+
+ heap_close(depRel, RowExclusiveLock);
+}
+
+/*
* isObjectPinned()
*
* Test if an object is required for basic database functionality.