mirror of
https://github.com/postgres/postgres.git
synced 2025-08-21 10:42:50 +03:00
Fix ALTER DOMAIN NOT NULL syntax
This addresses a few problems with commite5da0fe3c2
("Catalog domain not-null constraints"). In CREATE DOMAIN, a NOT NULL constraint looks like CREATE DOMAIN d1 AS int [ CONSTRAINT conname ] NOT NULL (Beforee5da0fe3c2
, the constraint name was accepted but ignored.) But in ALTER DOMAIN, a NOT NULL constraint looks like ALTER DOMAIN d1 ADD [ CONSTRAINT conname ] NOT NULL VALUE where VALUE is where for a table constraint the column name would be. (This works as ofe5da0fe3c2
. Beforee5da0fe3c2
, this syntax resulted in an internal error.) But for domains, this latter syntax is confusing and needlessly inconsistent between CREATE and ALTER. So this changes it to just ALTER DOMAIN d1 ADD [ CONSTRAINT conname ] NOT NULL (None of these syntaxes are per SQL standard; we are just living with the bits of inconsistency that have built up over time.) In passing, this also changes the psql \dD output to not show not-null constraints in the column "Check", since it's already shown in the column "Nullable". This has also been off sincee5da0fe3c2
. Reviewed-by: jian he <jian.universality@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/9ec24d7b-633d-463a-84c6-7acff769c9e8%40eisentraut.org
This commit is contained in:
@@ -524,7 +524,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
%type <vsetstmt> generic_set set_rest set_rest_more generic_reset reset_rest
|
||||
SetResetClause FunctionSetResetClause
|
||||
|
||||
%type <node> TableElement TypedTableElement ConstraintElem TableFuncElement
|
||||
%type <node> TableElement TypedTableElement ConstraintElem DomainConstraintElem TableFuncElement
|
||||
%type <node> columnDef columnOptions optionalPeriodName
|
||||
%type <defelt> def_elem reloption_elem old_aggr_elem operator_def_elem
|
||||
%type <node> def_arg columnElem where_clause where_or_current_clause
|
||||
@@ -596,7 +596,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
%type <keyword> col_name_keyword reserved_keyword
|
||||
%type <keyword> bare_label_keyword
|
||||
|
||||
%type <node> TableConstraint TableLikeClause
|
||||
%type <node> DomainConstraint TableConstraint TableLikeClause
|
||||
%type <ival> TableLikeOptionList TableLikeOption
|
||||
%type <str> column_compression opt_column_compression column_storage opt_column_storage
|
||||
%type <list> ColQualList
|
||||
@@ -4334,6 +4334,60 @@ ConstraintElem:
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* 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; }
|
||||
;
|
||||
@@ -11586,7 +11640,7 @@ AlterDomainStmt:
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
/* ALTER DOMAIN <domain> ADD CONSTRAINT ... */
|
||||
| ALTER DOMAIN_P any_name ADD_P TableConstraint
|
||||
| ALTER DOMAIN_P any_name ADD_P DomainConstraint
|
||||
{
|
||||
AlterDomainStmt *n = makeNode(AlterDomainStmt);
|
||||
|
||||
|
Reference in New Issue
Block a user