aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2025-04-02 13:30:13 +0200
committerPeter Eisentraut <peter@eisentraut.org>2025-04-02 13:36:44 +0200
commiteec0040c4bcd650993bb058ebdf61ab94171fda4 (patch)
tree5b38744ff96722b149336728c50f0d973dc90bc8 /src/backend/parser/parse_utilcmd.c
parent327d987df1e72a9b146f312df0a5ed34ef148720 (diff)
downloadpostgresql-eec0040c4bcd650993bb058ebdf61ab94171fda4.tar.gz
postgresql-eec0040c4bcd650993bb058ebdf61ab94171fda4.zip
Add support for NOT ENFORCED in foreign key constraints
This expands the NOT ENFORCED constraint flag, previously only supported for CHECK constraints (commit ca87c415e2f), to foreign key constraints. Normally, when a foreign key constraint is created on a table, action and check triggers are added to maintain data integrity. With this patch, if a constraint is marked as NOT ENFORCED, integrity checks are no longer required, making these triggers unnecessary. Consequently, when creating a NOT ENFORCED foreign key constraint, triggers will not be created, and the constraint will be marked as NOT VALID. Similarly, if an existing foreign key constraint is changed to NOT ENFORCED, the associated triggers will be dropped, and the constraint will also be marked as NOT VALID. Conversely, if a NOT ENFORCED foreign key constraint is changed to ENFORCED, the necessary triggers will be created, and the will be changed to VALID by performing necessary validation. Since not-enforced foreign key constraints have no triggers, the shortcut used for example in psql and pg_dump to skip looking for foreign keys if the relation is known not to have triggers no longer applies. (It already didn't work for partitioned tables.) Author: Amul Sul <sulamul@gmail.com> Reviewed-by: Joel Jacobson <joel@compiler.org> Reviewed-by: Andrew Dunstan <andrew@dunslane.net> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: jian he <jian.universality@gmail.com> Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Isaac Morland <isaac.morland@gmail.com> Reviewed-by: Alexandra Wang <alexandra.wang.oss@gmail.com> Tested-by: Triveni N <triveni.n@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA@mail.gmail.com
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 9c1541e1fea..62015431fdf 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -2962,8 +2962,10 @@ transformFKConstraints(CreateStmtContext *cxt,
/*
* If CREATE TABLE or adding a column with NULL default, we can safely
- * skip validation of FK constraints, and nonetheless mark them valid.
- * (This will override any user-supplied NOT VALID flag.)
+ * skip validation of FK constraints, and mark them as valid based on the
+ * constraint enforcement flag, since NOT ENFORCED constraints must always
+ * be marked as NOT VALID. (This will override any user-supplied NOT VALID
+ * flag.)
*/
if (skipValidation)
{
@@ -2972,7 +2974,7 @@ transformFKConstraints(CreateStmtContext *cxt,
Constraint *constraint = (Constraint *) lfirst(fkclist);
constraint->skip_validation = true;
- constraint->initially_valid = true;
+ constraint->initially_valid = constraint->is_enforced;
}
}
@@ -3967,7 +3969,8 @@ transformConstraintAttrs(CreateStmtContext *cxt, List *constraintList)
case CONSTR_ATTR_ENFORCED:
if (lastprimarycon == NULL ||
- lastprimarycon->contype != CONSTR_CHECK)
+ (lastprimarycon->contype != CONSTR_CHECK &&
+ lastprimarycon->contype != CONSTR_FOREIGN))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced ENFORCED clause"),
@@ -3983,7 +3986,8 @@ transformConstraintAttrs(CreateStmtContext *cxt, List *constraintList)
case CONSTR_ATTR_NOT_ENFORCED:
if (lastprimarycon == NULL ||
- lastprimarycon->contype != CONSTR_CHECK)
+ (lastprimarycon->contype != CONSTR_CHECK &&
+ lastprimarycon->contype != CONSTR_FOREIGN))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("misplaced NOT ENFORCED clause"),