CREATE DOMAIN name [ AS ] data_type
[ COLLATE collation ]
[ DEFAULT expression ]
- [ constraint [ ... ] ]
+ [ domain_constraint [ ... ] ]
+
where domain_constraint is:
[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }
-
+ id="sql-createdomain-notes">
Notes
The command CREATE DOMAIN conforms to the SQL
standard.
+
+ The syntax NOT NULL in this command is a
+
PostgreSQL extension. (A standard-conforming
+ way to write the same would be CHECK (VALUE IS NOT
+ NULL). However, per ,
+ such constraints are best avoided in practice anyway.) The
+ NULL constraint
is a
+
PostgreSQL extension (see also
+ linkend="sql-createtable-compatibility"/>).
+
%type generic_set set_rest set_rest_more generic_reset reset_rest
SetResetClause FunctionSetResetClause
-%type TableElement TypedTableElement ConstraintElem TableFuncElement
+%type TableElement TypedTableElement ConstraintElem DomainConstraintElem TableFuncElement
%type columnDef columnOptions optionalPeriodName
%type def_elem reloption_elem old_aggr_elem operator_def_elem
%type def_arg columnElem where_clause where_or_current_clause
%type col_name_keyword reserved_keyword
%type bare_label_keyword
-%type TableConstraint TableLikeClause
+%type DomainConstraint TableConstraint TableLikeClause
%type TableLikeOptionList TableLikeOption
%type column_compression opt_column_compression column_storage opt_column_storage
%type ColQualList
}
;
+/*
+ * DomainConstraint is separate from TableConstraint because the syntax for
+ * NOT NULL constraints is different. For table constraints, we need to
+ * accept a column name, but for domain constraints, we don't. (We could
+ * accept something like NOT NULL VALUE, but that seems weird.) CREATE DOMAIN
+ * (which uses ColQualList) has for a long time accepted NOT NULL without a
+ * column name, so it makes sense that ALTER DOMAIN (which uses
+ * DomainConstraint) does as well. None of these syntaxes are per SQL
+ * standard; we are just living with the bits of inconsistency that have built
+ * up over time.
+ */
+DomainConstraint:
+ CONSTRAINT name DomainConstraintElem
+ {
+ Constraint *n = castNode(Constraint, $3);
+
+ n->conname = $2;
+ n->location = @1;
+ $$ = (Node *) n;
+ }
+ | DomainConstraintElem { $$ = $1; }
+ ;
+
+DomainConstraintElem:
+ CHECK '(' a_expr ')' ConstraintAttributeSpec
+ {
+ Constraint *n = makeNode(Constraint);
+
+ n->contype = CONSTR_CHECK;
+ n->location = @1;
+ n->raw_expr = $3;
+ n->cooked_expr = NULL;
+ processCASbits($5, @5, "CHECK",
+ NULL, NULL, &n->skip_validation,
+ &n->is_no_inherit, yyscanner);
+ n->initially_valid = !n->skip_validation;
+ $$ = (Node *) n;
+ }
+ | NOT NULL_P ConstraintAttributeSpec
+ {
+ Constraint *n = makeNode(Constraint);
+
+ n->contype = CONSTR_NOTNULL;
+ n->location = @1;
+ n->keys = list_make1(makeString("value"));
+ /* no NOT VALID support yet */
+ processCASbits($3, @3, "NOT NULL",
+ NULL, NULL, NULL,
+ &n->is_no_inherit, yyscanner);
+ n->initially_valid = true;
+ $$ = (Node *) n;
+ }
+ ;
+
opt_no_inherit: NO INHERIT { $$ = true; }
| /* EMPTY */ { $$ = false; }
;
$$ = (Node *) n;
}
/* ALTER DOMAIN ADD CONSTRAINT ... */
- | ALTER DOMAIN_P any_name ADD_P TableConstraint
+ | ALTER DOMAIN_P any_name ADD_P DomainConstraint
{
AlterDomainStmt *n = makeNode(AlterDomainStmt);
else if (conForm->contypid)
{
/* conkey is null for domain not-null constraints */
- appendStringInfoString(&buf, "NOT NULL VALUE");
+ appendStringInfoString(&buf, "NOT NULL");
}
break;
}
" CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
" t.typdefault as \"%s\",\n"
" pg_catalog.array_to_string(ARRAY(\n"
- " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
+ " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid AND r.contype = 'c'\n"
" ), ' ') as \"%s\"",
gettext_noop("Schema"),
gettext_noop("Name"),
ERROR: column "col1" of table "domcontest" contains values that violate the new constraint
alter domain con add constraint t check (VALUE < 34);
alter domain con add check (VALUE > 0);
+\dD con
+ List of domains
+ Schema | Name | Type | Collation | Nullable | Default | Check
+--------+------+---------+-----------+----------+---------+--------------------------------------
+ public | con | integer | | | | CHECK (VALUE < 34) CHECK (VALUE > 0)
+(1 row)
+
insert into domcontest values (-5); -- fails
ERROR: value for domain con violates check constraint "con_check"
insert into domcontest values (42); -- fails
, col2 connotnull
);
insert into domconnotnulltest default values;
-alter domain connotnull add not null value; -- fails
+alter domain connotnull add not null; -- fails
ERROR: column "col1" of table "domconnotnulltest" contains null values
update domconnotnulltest set col1 = 5;
-alter domain connotnull add not null value; -- fails
+alter domain connotnull add not null; -- fails
ERROR: column "col2" of table "domconnotnulltest" contains null values
update domconnotnulltest set col2 = 6;
-alter domain connotnull add constraint constr1 not null value;
+alter domain connotnull add constraint constr1 not null;
select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n';
count
-------
1
(1 row)
-alter domain connotnull add constraint constr1bis not null value; -- redundant
+alter domain connotnull add constraint constr1bis not null; -- redundant
select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n';
count
-------
1
(1 row)
+\dD connotnull
+ List of domains
+ Schema | Name | Type | Collation | Nullable | Default | Check
+--------+------------+---------+-----------+----------+---------+-------
+ public | connotnull | integer | | not null | |
+(1 row)
+
update domconnotnulltest set col1 = null; -- fails
ERROR: domain connotnull does not allow null values
alter domain connotnull drop constraint constr1;
alter domain con add constraint t check (VALUE < 34);
alter domain con add check (VALUE > 0);
+\dD con
+
insert into domcontest values (-5); -- fails
insert into domcontest values (42); -- fails
insert into domcontest values (5);
);
insert into domconnotnulltest default values;
-alter domain connotnull add not null value; -- fails
+alter domain connotnull add not null; -- fails
update domconnotnulltest set col1 = 5;
-alter domain connotnull add not null value; -- fails
+alter domain connotnull add not null; -- fails
update domconnotnulltest set col2 = 6;
-alter domain connotnull add constraint constr1 not null value;
+alter domain connotnull add constraint constr1 not null;
select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n';
-alter domain connotnull add constraint constr1bis not null value; -- redundant
+alter domain connotnull add constraint constr1bis not null; -- redundant
select count(*) from pg_constraint where contypid = 'connotnull'::regtype and contype = 'n';
+\dD connotnull
+
update domconnotnulltest set col1 = null; -- fails
alter domain connotnull drop constraint constr1;