aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/catalog/dependency.c202
-rw-r--r--src/backend/catalog/index.c36
-rw-r--r--src/backend/catalog/pg_constraint.c25
-rw-r--r--src/backend/commands/indexcmds.c36
-rw-r--r--src/backend/commands/tablecmds.c24
-rw-r--r--src/backend/commands/trigger.c16
6 files changed, 250 insertions, 89 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 2c548958313..2048d71535b 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -99,9 +99,11 @@ typedef struct
#define DEPFLAG_NORMAL 0x0002 /* reached via normal dependency */
#define DEPFLAG_AUTO 0x0004 /* reached via auto dependency */
#define DEPFLAG_INTERNAL 0x0008 /* reached via internal dependency */
-#define DEPFLAG_EXTENSION 0x0010 /* reached via extension dependency */
-#define DEPFLAG_REVERSE 0x0020 /* reverse internal/extension link */
-#define DEPFLAG_SUBOBJECT 0x0040 /* subobject of another deletable object */
+#define DEPFLAG_PARTITION 0x0010 /* reached via partition dependency */
+#define DEPFLAG_EXTENSION 0x0020 /* reached via extension dependency */
+#define DEPFLAG_REVERSE 0x0040 /* reverse internal/extension link */
+#define DEPFLAG_IS_PART 0x0080 /* has a partition dependency */
+#define DEPFLAG_SUBOBJECT 0x0100 /* subobject of another deletable object */
/* expansible list of ObjectAddresses */
@@ -478,6 +480,8 @@ findDependentObjects(const ObjectAddress *object,
SysScanDesc scan;
HeapTuple tup;
ObjectAddress otherObject;
+ ObjectAddress owningObject;
+ ObjectAddress partitionObject;
ObjectAddressAndFlags *dependentObjects;
int numDependentObjects;
int maxDependentObjects;
@@ -547,6 +551,10 @@ findDependentObjects(const ObjectAddress *object,
scan = systable_beginscan(*depRel, DependDependerIndexId, true,
NULL, nkeys, key);
+ /* initialize variables that loop may fill */
+ memset(&owningObject, 0, sizeof(owningObject));
+ memset(&partitionObject, 0, sizeof(partitionObject));
+
while (HeapTupleIsValid(tup = systable_getnext(scan)))
{
Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
@@ -591,24 +599,26 @@ findDependentObjects(const ObjectAddress *object,
/* FALL THRU */
case DEPENDENCY_INTERNAL:
- case DEPENDENCY_INTERNAL_AUTO:
/*
* This object is part of the internal implementation of
* another object, or is part of the extension that is the
* other object. We have three cases:
*
- * 1. At the outermost recursion level, disallow the DROP. (We
- * just ereport here, rather than proceeding, since no other
- * dependencies are likely to be interesting.) However, if
- * the owning object is listed in pendingObjects, just release
- * the caller's lock and return; we'll eventually complete the
- * DROP when we reach that entry in the pending list.
+ * 1. At the outermost recursion level, we must disallow the
+ * DROP. However, if the owning object is listed in
+ * pendingObjects, just release the caller's lock and return;
+ * we'll eventually complete the DROP when we reach that entry
+ * in the pending list.
+ *
+ * Note: the above statement is true only if this pg_depend
+ * entry still exists by then; in principle, therefore, we
+ * could miss deleting an item the user told us to delete.
+ * However, no inconsistency can result: since we're at outer
+ * level, there is no object depending on this one.
*/
if (stack == NULL)
{
- char *otherObjDesc;
-
if (pendingObjects &&
object_address_present(&otherObject, pendingObjects))
{
@@ -617,14 +627,21 @@ findDependentObjects(const ObjectAddress *object,
ReleaseDeletionLock(object);
return;
}
- otherObjDesc = getObjectDescription(&otherObject);
- ereport(ERROR,
- (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
- errmsg("cannot drop %s because %s requires it",
- getObjectDescription(object),
- otherObjDesc),
- errhint("You can drop %s instead.",
- otherObjDesc)));
+
+ /*
+ * We postpone actually issuing the error message until
+ * after this loop, so that we can make the behavior
+ * independent of the ordering of pg_depend entries, at
+ * least if there's not more than one INTERNAL and one
+ * EXTENSION dependency. (If there's more, we'll complain
+ * about a random one of them.) Prefer to complain about
+ * EXTENSION, since that's generally a more important
+ * dependency.
+ */
+ if (!OidIsValid(owningObject.classId) ||
+ foundDep->deptype == DEPENDENCY_EXTENSION)
+ owningObject = otherObject;
+ break;
}
/*
@@ -643,14 +660,6 @@ findDependentObjects(const ObjectAddress *object,
* transform this deletion request into a delete of this
* owning object.
*
- * For INTERNAL_AUTO dependencies, we don't enforce this; in
- * other words, we don't follow the links back to the owning
- * object.
- */
- if (foundDep->deptype == DEPENDENCY_INTERNAL_AUTO)
- break;
-
- /*
* First, release caller's lock on this object and get
* deletion lock on the owning object. (We must release
* caller's lock to avoid deadlock against a concurrent
@@ -673,6 +682,13 @@ findDependentObjects(const ObjectAddress *object,
}
/*
+ * One way or the other, we're done with the scan; might as
+ * well close it down before recursing, to reduce peak
+ * resource consumption.
+ */
+ systable_endscan(scan);
+
+ /*
* Okay, recurse to the owning object instead of proceeding.
*
* We do not need to stack the current object; we want the
@@ -690,10 +706,66 @@ findDependentObjects(const ObjectAddress *object,
targetObjects,
pendingObjects,
depRel);
+
+ /*
+ * The current target object should have been added to
+ * targetObjects while processing the owning object; but it
+ * probably got only the flag bits associated with the
+ * dependency we're looking at. We need to add the objflags
+ * that were passed to this recursion level, too, else we may
+ * get a bogus failure in reportDependentObjects (if, for
+ * example, we were called due to a partition dependency).
+ *
+ * If somehow the current object didn't get scheduled for
+ * deletion, bleat. (That would imply that somebody deleted
+ * this dependency record before the recursion got to it.)
+ * Another idea would be to reacquire lock on the current
+ * object and resume trying to delete it, but it seems not
+ * worth dealing with the race conditions inherent in that.
+ */
+ if (!object_address_present_add_flags(object, objflags,
+ targetObjects))
+ elog(ERROR, "deletion of owning object %s failed to delete %s",
+ getObjectDescription(&otherObject),
+ getObjectDescription(object));
+
/* And we're done here. */
- systable_endscan(scan);
return;
+ case DEPENDENCY_PARTITION_PRI:
+
+ /*
+ * Remember that this object has a partition-type dependency.
+ * After the dependency scan, we'll complain if we didn't find
+ * a reason to delete one of its partition dependencies.
+ */
+ objflags |= DEPFLAG_IS_PART;
+
+ /*
+ * Also remember the primary partition owner, for error
+ * messages. If there are multiple primary owners (which
+ * there should not be), we'll report a random one of them.
+ */
+ partitionObject = otherObject;
+ break;
+
+ case DEPENDENCY_PARTITION_SEC:
+
+ /*
+ * Only use secondary partition owners in error messages if we
+ * find no primary owner (which probably shouldn't happen).
+ */
+ if (!(objflags & DEPFLAG_IS_PART))
+ partitionObject = otherObject;
+
+ /*
+ * Remember that this object has a partition-type dependency.
+ * After the dependency scan, we'll complain if we didn't find
+ * a reason to delete one of its partition dependencies.
+ */
+ objflags |= DEPFLAG_IS_PART;
+ break;
+
case DEPENDENCY_PIN:
/*
@@ -713,6 +785,28 @@ findDependentObjects(const ObjectAddress *object,
systable_endscan(scan);
/*
+ * If we found an INTERNAL or EXTENSION dependency when we're at outer
+ * level, complain about it now. If we also found a PARTITION dependency,
+ * we prefer to report the PARTITION dependency. This is arbitrary but
+ * seems to be more useful in practice.
+ */
+ if (OidIsValid(owningObject.classId))
+ {
+ char *otherObjDesc;
+
+ if (OidIsValid(partitionObject.classId))
+ otherObjDesc = getObjectDescription(&partitionObject);
+ else
+ otherObjDesc = getObjectDescription(&owningObject);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
+ errmsg("cannot drop %s because %s requires it",
+ getObjectDescription(object), otherObjDesc),
+ errhint("You can drop %s instead.", otherObjDesc)));
+ }
+
+ /*
* Next, identify all objects that directly depend on the current object.
* To ensure predictable deletion order, we collect them up in
* dependentObjects and sort the list before actually recursing. (The
@@ -789,10 +883,13 @@ findDependentObjects(const ObjectAddress *object,
case DEPENDENCY_AUTO_EXTENSION:
subflags = DEPFLAG_AUTO;
break;
- case DEPENDENCY_INTERNAL_AUTO:
case DEPENDENCY_INTERNAL:
subflags = DEPFLAG_INTERNAL;
break;
+ case DEPENDENCY_PARTITION_PRI:
+ case DEPENDENCY_PARTITION_SEC:
+ subflags = DEPFLAG_PARTITION;
+ break;
case DEPENDENCY_EXTENSION:
subflags = DEPFLAG_EXTENSION;
break;
@@ -868,10 +965,15 @@ findDependentObjects(const ObjectAddress *object,
/*
* Finally, we can add the target object to targetObjects. Be careful to
* include any flags that were passed back down to us from inner recursion
- * levels.
+ * levels. Record the "dependee" as being either the most important
+ * partition owner if there is one, else the object we recursed from, if
+ * any. (The logic in reportDependentObjects() is such that it can only
+ * need one of those objects.)
*/
extra.flags = mystack.flags;
- if (stack)
+ if (extra.flags & DEPFLAG_IS_PART)
+ extra.dependee = partitionObject;
+ else if (stack)
extra.dependee = *stack->object;
else
memset(&extra.dependee, 0, sizeof(extra.dependee));
@@ -906,8 +1008,37 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
int i;
/*
+ * If we need to delete any partition-dependent objects, make sure that
+ * we're deleting at least one of their partition dependencies, too. That
+ * can be detected by checking that we reached them by a PARTITION
+ * dependency at some point.
+ *
+ * We just report the first such object, as in most cases the only way to
+ * trigger this complaint is to explicitly try to delete one partition of
+ * a partitioned object.
+ */
+ for (i = 0; i < targetObjects->numrefs; i++)
+ {
+ const ObjectAddressExtra *extra = &targetObjects->extras[i];
+
+ if ((extra->flags & DEPFLAG_IS_PART) &&
+ !(extra->flags & DEPFLAG_PARTITION))
+ {
+ const ObjectAddress *object = &targetObjects->refs[i];
+ char *otherObjDesc = getObjectDescription(&extra->dependee);
+
+ ereport(ERROR,
+ (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
+ errmsg("cannot drop %s because %s requires it",
+ getObjectDescription(object), otherObjDesc),
+ errhint("You can drop %s instead.", otherObjDesc)));
+ }
+ }
+
+ /*
* If no error is to be thrown, and the msglevel is too low to be shown to
- * either client or server log, there's no need to do any of the work.
+ * either client or server log, there's no need to do any of the rest of
+ * the work.
*
* Note: this code doesn't know all there is to be known about elog
* levels, but it works for NOTICE and DEBUG2, which are the only values
@@ -951,11 +1082,12 @@ reportDependentObjects(const ObjectAddresses *targetObjects,
/*
* If, at any stage of the recursive search, we reached the object via
- * an AUTO, INTERNAL, or EXTENSION dependency, then it's okay to
- * delete it even in RESTRICT mode.
+ * an AUTO, INTERNAL, PARTITION, or EXTENSION dependency, then it's
+ * okay to delete it even in RESTRICT mode.
*/
if (extra->flags & (DEPFLAG_AUTO |
DEPFLAG_INTERNAL |
+ DEPFLAG_PARTITION |
DEPFLAG_EXTENSION))
{
/*
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index faf69568133..d16c3d0ea50 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1041,9 +1041,6 @@ index_create(Relation heapRelation,
else
{
bool have_simple_col = false;
- DependencyType deptype;
-
- deptype = OidIsValid(parentIndexRelid) ? DEPENDENCY_INTERNAL_AUTO : DEPENDENCY_AUTO;
/* Create auto dependencies on simply-referenced columns */
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
@@ -1054,7 +1051,7 @@ index_create(Relation heapRelation,
referenced.objectId = heapRelationId;
referenced.objectSubId = indexInfo->ii_IndexAttrNumbers[i];
- recordDependencyOn(&myself, &referenced, deptype);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
have_simple_col = true;
}
@@ -1072,18 +1069,29 @@ index_create(Relation heapRelation,
referenced.objectId = heapRelationId;
referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, deptype);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
}
}
- /* Store dependency on parent index, if any */
+ /*
+ * If this is an index partition, create partition dependencies on
+ * both the parent index and the table. (Note: these must be *in
+ * addition to*, not instead of, all other dependencies. Otherwise
+ * we'll be short some dependencies after DETACH PARTITION.)
+ */
if (OidIsValid(parentIndexRelid))
{
referenced.classId = RelationRelationId;
referenced.objectId = parentIndexRelid;
referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL_AUTO);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI);
+
+ referenced.classId = RelationRelationId;
+ referenced.objectId = heapRelationId;
+ referenced.objectSubId = 0;
+
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC);
}
/* Store dependency on collations */
@@ -1342,15 +1350,17 @@ index_constraint_create(Relation heapRelation,
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
/*
- * Also, if this is a constraint on a partition, mark it as depending on
- * the constraint in the parent.
+ * Also, if this is a constraint on a partition, give it partition-type
+ * dependencies on the parent constraint as well as the table.
*/
if (OidIsValid(parentConstraintId))
{
- ObjectAddress parentConstr;
-
- ObjectAddressSet(parentConstr, ConstraintRelationId, parentConstraintId);
- recordDependencyOn(&referenced, &parentConstr, DEPENDENCY_INTERNAL_AUTO);
+ ObjectAddressSet(myself, ConstraintRelationId, conOid);
+ ObjectAddressSet(referenced, ConstraintRelationId, parentConstraintId);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI);
+ ObjectAddressSet(referenced, RelationRelationId,
+ RelationGetRelid(heapRelation));
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC);
}
/*
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 698b493fc40..ad836e0d98e 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -760,13 +760,17 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
/*
* ConstraintSetParentConstraint
- * Set a partition's constraint as child of its parent table's
+ * Set a partition's constraint as child of its parent constraint,
+ * or remove the linkage if parentConstrId is InvalidOid.
*
* This updates the constraint's pg_constraint row to show it as inherited, and
- * add a dependency to the parent so that it cannot be removed on its own.
+ * adds PARTITION dependencies to prevent the constraint from being deleted
+ * on its own. Alternatively, reverse that.
*/
void
-ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId)
+ConstraintSetParentConstraint(Oid childConstrId,
+ Oid parentConstrId,
+ Oid childTableId)
{
Relation constrRel;
Form_pg_constraint constrForm;
@@ -795,10 +799,13 @@ ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId)
CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
- ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
ObjectAddressSet(depender, ConstraintRelationId, childConstrId);
- recordDependencyOn(&depender, &referenced, DEPENDENCY_INTERNAL_AUTO);
+ ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
+ recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI);
+
+ ObjectAddressSet(referenced, RelationRelationId, childTableId);
+ recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC);
}
else
{
@@ -809,10 +816,14 @@ ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId)
/* Make sure there's no further inheritance. */
Assert(constrForm->coninhcount == 0);
+ CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
+
deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
ConstraintRelationId,
- DEPENDENCY_INTERNAL_AUTO);
- CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
+ DEPENDENCY_PARTITION_PRI);
+ deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
+ RelationRelationId,
+ DEPENDENCY_PARTITION_SEC);
}
ReleaseSysCache(tuple);
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index bd85099c286..7352b9e341d 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -971,7 +971,8 @@ DefineIndex(Oid relationId,
IndexSetParentIndex(cldidx, indexRelationId);
if (createdConstraintId != InvalidOid)
ConstraintSetParentConstraint(cldConstrOid,
- createdConstraintId);
+ createdConstraintId,
+ childRelid);
if (!cldidx->rd_index->indisvalid)
invalidate_parent = true;
@@ -2622,35 +2623,34 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid)
if (fix_dependencies)
{
- ObjectAddress partIdx;
-
/*
- * Insert/delete pg_depend rows. If setting a parent, add an
- * INTERNAL_AUTO dependency to the parent index; if making standalone,
- * remove all existing rows and put back the regular dependency on the
- * table.
+ * Insert/delete pg_depend rows. If setting a parent, add PARTITION
+ * dependencies on the parent index and the table; if removing a
+ * parent, delete PARTITION dependencies.
*/
- ObjectAddressSet(partIdx, RelationRelationId, partRelid);
-
if (OidIsValid(parentOid))
{
+ ObjectAddress partIdx;
ObjectAddress parentIdx;
+ ObjectAddress partitionTbl;
+ ObjectAddressSet(partIdx, RelationRelationId, partRelid);
ObjectAddressSet(parentIdx, RelationRelationId, parentOid);
- recordDependencyOn(&partIdx, &parentIdx, DEPENDENCY_INTERNAL_AUTO);
+ ObjectAddressSet(partitionTbl, RelationRelationId,
+ partitionIdx->rd_index->indrelid);
+ recordDependencyOn(&partIdx, &parentIdx,
+ DEPENDENCY_PARTITION_PRI);
+ recordDependencyOn(&partIdx, &partitionTbl,
+ DEPENDENCY_PARTITION_SEC);
}
else
{
- ObjectAddress partitionTbl;
-
- ObjectAddressSet(partitionTbl, RelationRelationId,
- partitionIdx->rd_index->indrelid);
-
deleteDependencyRecordsForClass(RelationRelationId, partRelid,
RelationRelationId,
- DEPENDENCY_INTERNAL_AUTO);
-
- recordDependencyOn(&partIdx, &partitionTbl, DEPENDENCY_AUTO);
+ DEPENDENCY_PARTITION_PRI);
+ deleteDependencyRecordsForClass(RelationRelationId, partRelid,
+ RelationRelationId,
+ DEPENDENCY_PARTITION_SEC);
}
/* make our updates visible */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index b66d194b80d..715c6a221cf 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -7825,7 +7825,8 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
bool attach_it;
Oid constrOid;
ObjectAddress parentAddr,
- childAddr;
+ childAddr,
+ childTableAddr;
ListCell *cell;
int i;
@@ -7966,7 +7967,8 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
systable_endscan(scan);
table_close(trigrel, RowExclusiveLock);
- ConstraintSetParentConstraint(fk->conoid, parentConstrOid);
+ ConstraintSetParentConstraint(fk->conoid, parentConstrOid,
+ RelationGetRelid(partRel));
CommandCounterIncrement();
attach_it = true;
break;
@@ -8013,8 +8015,14 @@ CloneFkReferencing(Relation pg_constraint, Relation parentRel,
1, false, true);
subclone = lappend_oid(subclone, constrOid);
+ /* Set up partition dependencies for the new constraint */
ObjectAddressSet(childAddr, ConstraintRelationId, constrOid);
- recordDependencyOn(&childAddr, &parentAddr, DEPENDENCY_INTERNAL_AUTO);
+ recordDependencyOn(&childAddr, &parentAddr,
+ DEPENDENCY_PARTITION_PRI);
+ ObjectAddressSet(childTableAddr, RelationRelationId,
+ RelationGetRelid(partRel));
+ recordDependencyOn(&childAddr, &childTableAddr,
+ DEPENDENCY_PARTITION_SEC);
fkconstraint = makeNode(Constraint);
/* for now this is all we need */
@@ -14893,7 +14901,8 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel)
/* bingo. */
IndexSetParentIndex(attachrelIdxRels[i], idx);
if (OidIsValid(constraintOid))
- ConstraintSetParentConstraint(cldConstrOid, constraintOid);
+ ConstraintSetParentConstraint(cldConstrOid, constraintOid,
+ RelationGetRelid(attachrel));
update_relispartition(NULL, cldIdxId, true);
found = true;
break;
@@ -15151,7 +15160,7 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
constrOid = get_relation_idx_constraint_oid(RelationGetRelid(partRel),
idxid);
if (OidIsValid(constrOid))
- ConstraintSetParentConstraint(constrOid, InvalidOid);
+ ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid);
index_close(idx, NoLock);
}
@@ -15183,7 +15192,7 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
}
/* unset conparentid and adjust conislocal, coninhcount, etc. */
- ConstraintSetParentConstraint(fk->conoid, InvalidOid);
+ ConstraintSetParentConstraint(fk->conoid, InvalidOid, InvalidOid);
/*
* Make the action triggers on the referenced relation. When this was
@@ -15419,7 +15428,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
/* All good -- do it */
IndexSetParentIndex(partIdx, RelationGetRelid(parentIdx));
if (OidIsValid(constraintOid))
- ConstraintSetParentConstraint(cldConstrId, constraintOid);
+ ConstraintSetParentConstraint(cldConstrId, constraintOid,
+ RelationGetRelid(partTbl));
update_relispartition(NULL, partIdxId, true);
pfree(attmap);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 0b245a613e0..409bee24f89 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -1012,17 +1012,11 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* User CREATE TRIGGER, so place dependencies. We make trigger be
* auto-dropped if its relation is dropped or if the FK relation is
* dropped. (Auto drop is compatible with our pre-7.3 behavior.)
- *
- * Exception: if this trigger comes from a parent partitioned table,
- * then it's not separately drop-able, but goes away if the partition
- * does.
*/
referenced.classId = RelationRelationId;
referenced.objectId = RelationGetRelid(rel);
referenced.objectSubId = 0;
- recordDependencyOn(&myself, &referenced, OidIsValid(parentTriggerOid) ?
- DEPENDENCY_INTERNAL_AUTO :
- DEPENDENCY_AUTO);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
if (OidIsValid(constrrelid))
{
@@ -1046,11 +1040,15 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL);
}
- /* Depends on the parent trigger, if there is one. */
+ /*
+ * If it's a partition trigger, create the partition dependencies.
+ */
if (OidIsValid(parentTriggerOid))
{
ObjectAddressSet(referenced, TriggerRelationId, parentTriggerOid);
- recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL_AUTO);
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI);
+ ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(rel));
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC);
}
}