hi.

https://coverage.postgresql.org/src/backend/commands/typecmds.c.gcov.html
show DefineDomain has poor coverage tests.
so I added a more extensive regression test.

also
create domain d_fail as int4 constraint cc GENERATED ALWAYS AS (2) STORED;
ERROR:  unrecognized constraint subtype: 4

This kind of error message is not helpful. so I changed it to
ERROR:  generated columns are not supported on domains

create domain d_int as int4;
ALTER DOMAIN d_int ADD constraint cc check(value > 1) no inherit not valid;
should fail.
so I made it fail.

typedef struct AlterDomainStmt
{
    NodeTag        type;
    char        subtype;
    List       *typeName;        /* domain to work on */
    char       *name;            /* column or constraint name to act on */
    Node       *def;            /* definition of default or constraint */
    DropBehavior behavior;        /* RESTRICT or CASCADE for DROP cases */
    bool        missing_ok;        /* skip error if missing? */
} AlterDomainStmt;
we only have one `Node       *def; ` in AlterDomainStmt
unlike CreateDomainStmt, have `List       *constraints;`

so I guess we have to allow the following ALTER DOMAIN queries.
even though the corresponding CREATE DOMAIN stmt would fail.

create domain d_int as int4;
ALTER DOMAIN d_int ADD constraint cc1 check(value > 1) INITIALLY IMMEDIATE; --ok
ALTER DOMAIN d_int ADD constraint cc2 check(value > 1) NOT DEFERRABLE; --ok
ALTER DOMAIN d_int ADD constraint cc3 check(value > 1) NOT DEFERRABLE
not valid; --ok
ALTER DOMAIN d_int ADD constraint cc4 check(value > 1) INITIALLY
IMMEDIATE not valid; --ok

looking at pg_constraint, for the above queries, column {condeferrable
| condeferred | convalidated} all set properly.


i didn't found a way to trigger
errmsg("exclusion constraints not possible for domains")));
From 35d9ce7318b259281d1c8cf347dc0594e9ac62ba Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Mon, 11 Nov 2024 16:49:34 +0800
Subject: [PATCH v1 1/1] add more CREATE|ALTER DOMAIN tests

also AlterDomainAddConstraint, DefineDomain refactoring
---
 src/backend/commands/typecmds.c      | 20 ++++++-
 src/test/regress/expected/domain.out | 84 ++++++++++++++++++++++++++++
 src/test/regress/sql/domain.sql      | 37 ++++++++++++
 3 files changed, 140 insertions(+), 1 deletion(-)

diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 859e2191f0..8c602ca63e 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1011,6 +1011,16 @@ DefineDomain(CreateDomainStmt *stmt)
 						 errmsg("specifying constraint deferrability not supported for domains")));
 				break;
 
+			case CONSTR_IDENTITY:
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("identity columns are not supported on domains")));
+				break;
+			case CONSTR_GENERATED:
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("generated columns are not supported on domains")));
+				break;
 			default:
 				elog(ERROR, "unrecognized constraint subtype: %d",
 					 (int) constr->contype);
@@ -2934,8 +2944,16 @@ AlterDomainAddConstraint(List *names, Node *newConstraint,
 	switch (constr->contype)
 	{
 		case CONSTR_CHECK:
+			if (constr->is_no_inherit)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+						 errmsg("check constraints for domains cannot be marked NO INHERIT")));
+			break;
 		case CONSTR_NOTNULL:
-			/* processed below */
+			if (constr->is_no_inherit)
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+						 errmsg("NOT NULL constraints for domains cannot be marked NO INHERIT")));
 			break;
 
 		case CONSTR_UNIQUE:
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index f65b66345a..f4131c2696 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -87,6 +87,90 @@ drop domain domainvarchar restrict;
 drop domain domainnumeric restrict;
 drop domain domainint4 restrict;
 drop domain domaintext;
+--error case.
+create table t1(a int primary key);
+create domain d_fail as int4 constraint cc references t1;
+ERROR:  foreign key constraints not possible for domains
+create domain d_fail as int4 not null no inherit;
+ERROR:  not-null constraints for domains cannot be marked NO INHERIT
+create domain d_fail as int4 not null null;
+ERROR:  conflicting NULL/NOT NULL constraints
+create domain d_fail as int4 not null default 3 default 3;
+ERROR:  multiple default expressions
+create domain d_fail as int4 unique;
+ERROR:  unique constraints not possible for domains
+create domain d_fail as int4 PRIMARY key;
+ERROR:  primary key constraints not possible for domains
+create domain d_fail as int4 constraint cc generated by default as identity;
+ERROR:  identity columns are not supported on domains
+create domain d_fail as int4 constraint cc GENERATED ALWAYS AS (2) STORED;
+ERROR:  generated columns are not supported on domains
+create domain d_fail as int4 constraint cc check (value > 1) INITIALLY DEFERRED;
+ERROR:  specifying constraint deferrability not supported for domains
+create domain d_fail as int4 constraint cc check(values > 1) no inherit;
+ERROR:  check constraints for domains cannot be marked NO INHERIT
+create domain d_fail as int4 constraint cc check(values > 1) DEFERRABLE INITIALLY DEFERRED ;
+ERROR:  specifying constraint deferrability not supported for domains
+create domain d_fail as int4 constraint cc check(values > 1) DEFERRABLE NOT DEFERRABLE ;
+ERROR:  specifying constraint deferrability not supported for domains
+create domain d_fail as int4 constraint cc check(values > 1) INITIALLY IMMEDIATE;
+ERROR:  specifying constraint deferrability not supported for domains
+create domain d_fail as int4 constraint cc exclude (values > 1) INITIALLY IMMEDIATE;
+ERROR:  syntax error at or near "exclude"
+LINE 1: create domain d_fail as int4 constraint cc exclude (values >...
+                                                   ^
+create domain d_int as int4;
+ALTER DOMAIN d_int ADD constraint ne not null no inherit;
+ERROR:  NOT NULL constraints cannot be marked NO INHERIT
+LINE 1: ALTER DOMAIN d_int ADD constraint ne not null no inherit;
+                                                      ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY DEFERRED;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY ...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) no inherit;
+ERROR:  check constraints for domains cannot be marked NO INHERIT
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE INITIALLY DEFERRED;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERRABLE;
+ERROR:  conflicting constraint properties
+LINE 1: ...int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERR...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc1 check(value > 1) INITIALLY IMMEDIATE; --ok
+ALTER DOMAIN d_int ADD constraint cc2 check(value > 1) NOT DEFERRABLE; --ok
+--with not valid
+ALTER DOMAIN d_int ADD constraint ne not null no inherit not valid;
+ERROR:  NOT NULL constraints cannot be marked NOT VALID
+LINE 1: ALTER DOMAIN d_int ADD constraint ne not null no inherit not...
+                                                      ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE not valid;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY DEFERRED not valid;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY ...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) no inherit not valid;
+ERROR:  check constraints for domains cannot be marked NO INHERIT
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE INITIALLY DEFERRED not valid;
+ERROR:  CHECK constraints cannot be marked DEFERRABLE
+LINE 1: ...R DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERRABLE not valid;
+ERROR:  conflicting constraint properties
+LINE 1: ...int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERR...
+                                                             ^
+ALTER DOMAIN d_int ADD constraint cc3 check(value > 1) NOT DEFERRABLE not valid; --ok
+ALTER DOMAIN d_int ADD constraint cc4 check(value > 1) INITIALLY IMMEDIATE not valid; --ok
+DROP DOMAIN d_int;
+DROP TABLE t1;
 -- Test non-error-throwing input
 create domain positiveint int4 check(value > 0);
 create domain weirdfloat float8 check((1 / value) < 10);
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index b5a70ee8be..60ed54df19 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -68,6 +68,43 @@ drop domain domainnumeric restrict;
 drop domain domainint4 restrict;
 drop domain domaintext;
 
+--error case.
+create table t1(a int primary key);
+create domain d_fail as int4 constraint cc references t1;
+create domain d_fail as int4 not null no inherit;
+create domain d_fail as int4 not null null;
+create domain d_fail as int4 not null default 3 default 3;
+create domain d_fail as int4 unique;
+create domain d_fail as int4 PRIMARY key;
+create domain d_fail as int4 constraint cc generated by default as identity;
+create domain d_fail as int4 constraint cc GENERATED ALWAYS AS (2) STORED;
+create domain d_fail as int4 constraint cc check (value > 1) INITIALLY DEFERRED;
+create domain d_fail as int4 constraint cc check(values > 1) no inherit;
+create domain d_fail as int4 constraint cc check(values > 1) DEFERRABLE INITIALLY DEFERRED ;
+create domain d_fail as int4 constraint cc check(values > 1) DEFERRABLE NOT DEFERRABLE ;
+create domain d_fail as int4 constraint cc check(values > 1) INITIALLY IMMEDIATE;
+create domain d_fail as int4 constraint cc exclude (values > 1) INITIALLY IMMEDIATE;
+
+create domain d_int as int4;
+ALTER DOMAIN d_int ADD constraint ne not null no inherit;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY DEFERRED;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) no inherit;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE INITIALLY DEFERRED;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERRABLE;
+ALTER DOMAIN d_int ADD constraint cc1 check(value > 1) INITIALLY IMMEDIATE; --ok
+ALTER DOMAIN d_int ADD constraint cc2 check(value > 1) NOT DEFERRABLE; --ok
+--with not valid
+ALTER DOMAIN d_int ADD constraint ne not null no inherit not valid;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE not valid;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) INITIALLY DEFERRED not valid;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) no inherit not valid;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE INITIALLY DEFERRED not valid;
+ALTER DOMAIN d_int ADD constraint cc check(value > 1) DEFERRABLE NOT DEFERRABLE not valid;
+ALTER DOMAIN d_int ADD constraint cc3 check(value > 1) NOT DEFERRABLE not valid; --ok
+ALTER DOMAIN d_int ADD constraint cc4 check(value > 1) INITIALLY IMMEDIATE not valid; --ok
+DROP DOMAIN d_int;
+DROP TABLE t1;
 
 -- Test non-error-throwing input
 
-- 
2.34.1

Reply via email to