From 986b0bd3fb45f5c691e5a7affcdd626c67801dbc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@alvh.no-ip.org>
Date: Mon, 10 Mar 2025 18:27:19 +0100
Subject: [PATCH v2 2/2] handle constraints on domains too

---
 src/backend/parser/gram.y            | 51 +++++++++++++++++++++++++---
 src/test/regress/expected/domain.out | 22 ++++++++++--
 src/test/regress/sql/domain.sql      |  8 ++++-
 3 files changed, 72 insertions(+), 9 deletions(-)

diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 50024aabbca..517f08fc7f5 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -4410,29 +4410,70 @@ DomainConstraintElem:
 			CHECK '(' a_expr ')' ConstraintAttributeSpec
 				{
 					Constraint *n = makeNode(Constraint);
+					CAS_flags seen;
 
 					n->contype = CONSTR_CHECK;
 					n->location = @1;
 					n->raw_expr = $3;
 					n->cooked_expr = NULL;
-					processCASbits($5, @5, "CHECK", /* FIXME */
+					processCASbits($5, @5, NULL,
 								   NULL, NULL, NULL, &n->skip_validation,
-								   &n->is_no_inherit, NULL, yyscanner);
+								   &n->is_no_inherit, &seen, yyscanner);
 					n->is_enforced = true;
+					if (seen.seen_deferrability)
+						ereport(ERROR,
+								errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+								errmsg("specifying constraint deferrability not supported for domains"),
+								parser_errposition(@5));
+					if (seen.seen_enforced)
+						ereport(ERROR,
+							   errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							   errmsg("specifying constraint enforceability not supported for domains"),
+							   parser_errposition(@5));
+					if (seen.seen_inherit)
+						ereport(ERROR,
+							   errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							   errmsg("CHECK constraints for domains cannot be marked %s",
+									  "INHERIT / NO INHERIT"),
+							   parser_errposition(@5));
+
 					n->initially_valid = !n->skip_validation;
 					$$ = (Node *) n;
 				}
 			| NOT NULL_P ConstraintAttributeSpec
 				{
 					Constraint *n = makeNode(Constraint);
+					CAS_flags seen;
 
 					n->contype = CONSTR_NOTNULL;
 					n->location = @1;
 					n->keys = list_make1(makeString("value"));
-					/* no NOT VALID, NO INHERIT support */
-					processCASbits($3, @3, "NOT NULL", /* FIXME */
+					/* no DEFERRABLE, NOT VALID, NO INHERIT support */
+					processCASbits($3, @3, NULL,
 								   NULL, NULL, NULL,
-								   NULL, NULL, NULL, yyscanner);
+								   NULL, NULL, &seen, yyscanner);
+					if (seen.seen_valid)
+						ereport(ERROR,
+								errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+								errmsg("not-null constraints on domains cannot be marked %s",
+									   "NOT VALID"),
+								parser_errposition(@3));
+					if (seen.seen_deferrability)
+						ereport(ERROR,
+								errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+								errmsg("specifying constraint deferrability not supported for domains"),
+								parser_errposition(@3));
+					if (seen.seen_enforced)
+						ereport(ERROR,
+							   errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							   errmsg("specifying constraint enforceability not supported for domains"),
+							   parser_errposition(@3));
+					if (seen.seen_inherit)
+						ereport(ERROR,
+							   errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							   errmsg("%s constraints on domains cannot be marked %s",
+									  "NOT NULL", "INHERIT / NOT INHERIT"),
+							   parser_errposition(@3));
 					n->initially_valid = true;
 					$$ = (Node *) n;
 				}
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index ba6f05eeb7d..bdb568a9d59 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -1361,15 +1361,31 @@ ERROR:  specifying constraint enforceability not supported for domains
 LINE 1: ...S int CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORC...
                                                              ^
 CREATE DOMAIN constraint_enforced_dom AS int;
--- XXX misleading error messages
 ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
-ERROR:  CHECK constraints cannot be marked ENFORCED
+ERROR:  specifying constraint enforceability not supported for domains
 LINE 1: ...om ADD CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
                                                               ^
 ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORCED;
-ERROR:  CHECK constraints cannot be marked NOT ENFORCED
+ERROR:  specifying constraint enforceability not supported for domains
 LINE 1: ...m ADD CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORC...
                                                              ^
+-- other constraint properties also disallowed
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) DEFERRABLE;
+ERROR:  specifying constraint deferrability not supported for domains
+LINE 1: ...m ADD CONSTRAINT the_constraint CHECK (value > 0) DEFERRABLE...
+                                                             ^
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NOT DEFERRABLE;
+ERROR:  specifying constraint deferrability not supported for domains
+LINE 1: ...m ADD CONSTRAINT the_constraint CHECK (value > 0) NOT DEFERR...
+                                                             ^
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) INITIALLY DEFERRED;
+ERROR:  specifying constraint deferrability not supported for domains
+LINE 1: ...m ADD CONSTRAINT the_constraint CHECK (value > 0) INITIALLY ...
+                                                             ^
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NO INHERIT;
+ERROR:  CHECK constraints for domains cannot be marked INHERIT / NO INHERIT
+LINE 1: ...m ADD CONSTRAINT the_constraint CHECK (value > 0) NO INHERIT...
+                                                             ^
 DROP DOMAIN constraint_enforced_dom;
 --
 -- Information schema
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index b752a63ab5f..c83c136398a 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -886,9 +886,15 @@ drop domain mytext cascade;
 CREATE DOMAIN constraint_enforced_dom AS int CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
 CREATE DOMAIN constraint_not_enforced_dom AS int CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORCED;
 CREATE DOMAIN constraint_enforced_dom AS int;
--- XXX misleading error messages
 ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) ENFORCED;
 ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NOT ENFORCED;
+
+-- other constraint properties also disallowed
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) DEFERRABLE;
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NOT DEFERRABLE;
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) INITIALLY DEFERRED;
+ALTER DOMAIN constraint_enforced_dom ADD CONSTRAINT the_constraint CHECK (value > 0) NO INHERIT;
+
 DROP DOMAIN constraint_enforced_dom;
 
 --
-- 
2.39.5

