From: Alvaro Herrera Date: Tue, 5 Nov 2019 12:52:27 -0300 Subject: [PATCH] Fix deferred constraints on partitioned rels --- src/backend/commands/trigger.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 57c98912d5..5e302fee64 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -5362,6 +5362,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) Relation conrel; Relation tgrel; List *conoidlist = NIL; + List *pcl = NIL; List *tgoidlist = NIL; ListCell *lc; @@ -5440,7 +5441,18 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup); if (con->condeferrable) - conoidlist = lappend_oid(conoidlist, con->oid); + { + /* + * If we found it and it's deferrable, save it to one + * of the lists depending on whether it belongs to a + * partitioned table. + */ + if (get_rel_relkind(con->conrelid) == + RELKIND_PARTITIONED_TABLE) + pcl = lappend_oid(pcl, con->oid); + else + conoidlist = lappend_oid(conoidlist, con->oid); + } else if (stmt->deferred) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -5472,12 +5484,12 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) } /* - * Scan for any possible descendants of the constraints. We append - * whatever we find to the same list that we're scanning; this has the - * effect that we create new scans for those, too, so if there are - * further descendents, we'll also catch them. + * Scan for any possible descendants of constraints in partitioned + * tables. If we find any that are on further partitioned tables, + * append them to the list we're scanning. This ensures we process + * all descendant relations. */ - foreach(lc, conoidlist) + foreach(lc, pcl) { Oid parent = lfirst_oid(lc); ScanKeyData key; @@ -5495,7 +5507,10 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) { Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); - conoidlist = lappend_oid(conoidlist, con->oid); + if (get_rel_relkind(con->conrelid) == RELKIND_PARTITIONED_TABLE) + pcl = lappend_oid(pcl, con->oid); + else + conoidlist = lappend_oid(conoidlist, con->oid); } systable_endscan(scan); -- 2.20.1 --EeQfGwPcQSOJBaQU--