mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Fix bogus grammar for a CREATE CONSTRAINT TRIGGER error
If certain constraint characteristic clauses (NO INHERIT, NOT VALID, NOT ENFORCED) are given to CREATE CONSTRAINT TRIGGER, the resulting error message is ERROR: TRIGGER constraints cannot be marked NO INHERIT which is a bit silly, because these aren't "constraints of type TRIGGER". Hardcode a better error message to prevent it. This is a cosmetic fix for quite a fringe problem with no known complaints from users, so no backpatch. While at it, silently accept ENFORCED if given. Author: Amul Sul <sulamul@gmail.com> Reviewed-by: jian he <jian.universality@gmail.com> Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/CAAJ_b97hd-jMTS7AjgU6TDBCzDx_KyuKxG+K-DtYmOieg+giyQ@mail.gmail.com Discussion: https://postgr.es/m/CACJufxHSp2puxP=q8ZtUGL1F+heapnzqFBZy5ZNGUjUgwjBqTQ@mail.gmail.com
This commit is contained in:
@ -29,7 +29,7 @@ PostgreSQL documentation
|
|||||||
CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <replaceable class="parameter">name</replaceable> { BEFORE | AFTER | INSTEAD OF } { <replaceable class="parameter">event</replaceable> [ OR ... ] }
|
CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <replaceable class="parameter">name</replaceable> { BEFORE | AFTER | INSTEAD OF } { <replaceable class="parameter">event</replaceable> [ OR ... ] }
|
||||||
ON <replaceable class="parameter">table_name</replaceable>
|
ON <replaceable class="parameter">table_name</replaceable>
|
||||||
[ FROM <replaceable class="parameter">referenced_table_name</replaceable> ]
|
[ FROM <replaceable class="parameter">referenced_table_name</replaceable> ]
|
||||||
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
|
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] [ ENFORCED ]
|
||||||
[ REFERENCING { { OLD | NEW } TABLE [ AS ] <replaceable class="parameter">transition_relation_name</replaceable> } [ ... ] ]
|
[ REFERENCING { { OLD | NEW } TABLE [ AS ] <replaceable class="parameter">transition_relation_name</replaceable> } [ ... ] ]
|
||||||
[ FOR [ EACH ] { ROW | STATEMENT } ]
|
[ FOR [ EACH ] { ROW | STATEMENT } ]
|
||||||
[ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
|
[ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
|
||||||
@ -321,6 +321,13 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>ENFORCED</literal></term>
|
||||||
|
<listitem>
|
||||||
|
This is a noise word. Constraint triggers are always enforced.
|
||||||
|
</listitem>
|
||||||
|
</varlistitem>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><literal>REFERENCING</literal></term>
|
<term><literal>REFERENCING</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -6041,6 +6041,26 @@ CreateTrigStmt:
|
|||||||
EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
|
EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
|
||||||
{
|
{
|
||||||
CreateTrigStmt *n = makeNode(CreateTrigStmt);
|
CreateTrigStmt *n = makeNode(CreateTrigStmt);
|
||||||
|
bool dummy;
|
||||||
|
|
||||||
|
if (($11 & CAS_NOT_VALID) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("constraint triggers cannot be marked %s",
|
||||||
|
"NOT VALID"),
|
||||||
|
parser_errposition(@11));
|
||||||
|
if (($11 & CAS_NO_INHERIT) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("constraint triggers cannot be marked %s",
|
||||||
|
"NO INHERIT"),
|
||||||
|
parser_errposition(@11));
|
||||||
|
if (($11 & CAS_NOT_ENFORCED) != 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("constraint triggers cannot be marked %s",
|
||||||
|
"NOT ENFORCED"),
|
||||||
|
parser_errposition(@11));
|
||||||
|
|
||||||
n->replace = $2;
|
n->replace = $2;
|
||||||
if (n->replace) /* not supported, see CreateTrigger */
|
if (n->replace) /* not supported, see CreateTrigger */
|
||||||
@ -6060,7 +6080,7 @@ CreateTrigStmt:
|
|||||||
n->whenClause = $15;
|
n->whenClause = $15;
|
||||||
n->transitionRels = NIL;
|
n->transitionRels = NIL;
|
||||||
processCASbits($11, @11, "TRIGGER",
|
processCASbits($11, @11, "TRIGGER",
|
||||||
&n->deferrable, &n->initdeferred, NULL,
|
&n->deferrable, &n->initdeferred, &dummy,
|
||||||
NULL, NULL, yyscanner);
|
NULL, NULL, yyscanner);
|
||||||
n->constrrel = $10;
|
n->constrrel = $10;
|
||||||
$$ = (Node *) n;
|
$$ = (Node *) n;
|
||||||
|
@ -2280,6 +2280,27 @@ select * from parted;
|
|||||||
drop table parted;
|
drop table parted;
|
||||||
drop function parted_trigfunc();
|
drop function parted_trigfunc();
|
||||||
--
|
--
|
||||||
|
-- Constraint triggers
|
||||||
|
--
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo not valid
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
ERROR: constraint triggers cannot be marked NOT VALID
|
||||||
|
LINE 2: after insert on foo not valid
|
||||||
|
^
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo no inherit
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
ERROR: constraint triggers cannot be marked NO INHERIT
|
||||||
|
LINE 2: after insert on foo no inherit
|
||||||
|
^
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo not enforced
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
ERROR: constraint triggers cannot be marked NOT ENFORCED
|
||||||
|
LINE 2: after insert on foo not enforced
|
||||||
|
^
|
||||||
|
--
|
||||||
-- Constraint triggers and partitioned tables
|
-- Constraint triggers and partitioned tables
|
||||||
create table parted_constr_ancestor (a int, b text)
|
create table parted_constr_ancestor (a int, b text)
|
||||||
partition by range (b);
|
partition by range (b);
|
||||||
@ -2294,7 +2315,7 @@ create constraint trigger parted_trig after insert on parted_constr_ancestor
|
|||||||
deferrable
|
deferrable
|
||||||
for each row execute procedure trigger_notice_ab();
|
for each row execute procedure trigger_notice_ab();
|
||||||
create constraint trigger parted_trig_two after insert on parted_constr
|
create constraint trigger parted_trig_two after insert on parted_constr
|
||||||
deferrable initially deferred
|
deferrable initially deferred enforced
|
||||||
for each row when (bark(new.b) AND new.a % 2 = 1)
|
for each row when (bark(new.b) AND new.a % 2 = 1)
|
||||||
execute procedure trigger_notice_ab();
|
execute procedure trigger_notice_ab();
|
||||||
-- The immediate constraint is fired immediately; the WHEN clause of the
|
-- The immediate constraint is fired immediately; the WHEN clause of the
|
||||||
|
@ -1576,6 +1576,19 @@ select * from parted;
|
|||||||
drop table parted;
|
drop table parted;
|
||||||
drop function parted_trigfunc();
|
drop function parted_trigfunc();
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Constraint triggers
|
||||||
|
--
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo not valid
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo no inherit
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
create constraint trigger crtr
|
||||||
|
after insert on foo not enforced
|
||||||
|
for each row execute procedure foo ();
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Constraint triggers and partitioned tables
|
-- Constraint triggers and partitioned tables
|
||||||
create table parted_constr_ancestor (a int, b text)
|
create table parted_constr_ancestor (a int, b text)
|
||||||
@ -1591,7 +1604,7 @@ create constraint trigger parted_trig after insert on parted_constr_ancestor
|
|||||||
deferrable
|
deferrable
|
||||||
for each row execute procedure trigger_notice_ab();
|
for each row execute procedure trigger_notice_ab();
|
||||||
create constraint trigger parted_trig_two after insert on parted_constr
|
create constraint trigger parted_trig_two after insert on parted_constr
|
||||||
deferrable initially deferred
|
deferrable initially deferred enforced
|
||||||
for each row when (bark(new.b) AND new.a % 2 = 1)
|
for each row when (bark(new.b) AND new.a % 2 = 1)
|
||||||
execute procedure trigger_notice_ab();
|
execute procedure trigger_notice_ab();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user