Fix bogus grammar for a CREATE CONSTRAINT TRIGGER error · postgres/postgres@87251e1 · GitHub | Latest TMZ Celebrity News & Gossip | Watch TMZ Live
Skip to content

Commit 87251e1

Browse files
author
Álvaro Herrera
committed
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
1 parent 8ec04c8 commit 87251e1

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

doc/src/sgml/ref/create_trigger.sgml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ PostgreSQL documentation
2929
CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <replaceable class="parameter">name</replaceable> { BEFORE | AFTER | INSTEAD OF } { <replaceable class="parameter">event</replaceable> [ OR ... ] }
3030
ON <replaceable class="parameter">table_name</replaceable>
3131
[ FROM <replaceable class="parameter">referenced_table_name</replaceable> ]
32-
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
32+
[ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] [ ENFORCED ]
3333
[ REFERENCING { { OLD | NEW } TABLE [ AS ] <replaceable class="parameter">transition_relation_name</replaceable> } [ ... ] ]
3434
[ FOR [ EACH ] { ROW | STATEMENT } ]
3535
[ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
@@ -321,6 +321,13 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
321321
</listitem>
322322
</varlistentry>
323323

324+
<varlistentry>
325+
<term><literal>ENFORCED</literal></term>
326+
<listitem>
327+
This is a noise word. Constraint triggers are always enforced.
328+
</listitem>
329+
</varlistitem>
330+
324331
<varlistentry>
325332
<term><literal>REFERENCING</literal></term>
326333
<listitem>

src/backend/parser/gram.y

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6041,6 +6041,26 @@ CreateTrigStmt:
60416041
EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')'
60426042
{
60436043
CreateTrigStmt *n = makeNode(CreateTrigStmt);
6044+
bool dummy;
6045+
6046+
if (($11 & CAS_NOT_VALID) != 0)
6047+
ereport(ERROR,
6048+
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6049+
errmsg("constraint triggers cannot be marked %s",
6050+
"NOT VALID"),
6051+
parser_errposition(@11));
6052+
if (($11 & CAS_NO_INHERIT) != 0)
6053+
ereport(ERROR,
6054+
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6055+
errmsg("constraint triggers cannot be marked %s",
6056+
"NO INHERIT"),
6057+
parser_errposition(@11));
6058+
if (($11 & CAS_NOT_ENFORCED) != 0)
6059+
ereport(ERROR,
6060+
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6061+
errmsg("constraint triggers cannot be marked %s",
6062+
"NOT ENFORCED"),
6063+
parser_errposition(@11));
60446064

60456065
n->replace = $2;
60466066
if (n->replace) /* not supported, see CreateTrigger */
@@ -6060,7 +6080,7 @@ CreateTrigStmt:
60606080
n->whenClause = $15;
60616081
n->transitionRels = NIL;
60626082
processCASbits($11, @11, "TRIGGER",
6063-
&n->deferrable, &n->initdeferred, NULL,
6083+
&n->deferrable, &n->initdeferred, &dummy,
60646084
NULL, NULL, yyscanner);
60656085
n->constrrel = $10;
60666086
$$ = (Node *) n;

src/test/regress/expected/triggers.out

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2280,6 +2280,27 @@ select * from parted;
22802280
drop table parted;
22812281
drop function parted_trigfunc();
22822282
--
2283+
-- Constraint triggers
2284+
--
2285+
create constraint trigger crtr
2286+
after insert on foo not valid
2287+
for each row execute procedure foo ();
2288+
ERROR: constraint triggers cannot be marked NOT VALID
2289+
LINE 2: after insert on foo not valid
2290+
^
2291+
create constraint trigger crtr
2292+
after insert on foo no inherit
2293+
for each row execute procedure foo ();
2294+
ERROR: constraint triggers cannot be marked NO INHERIT
2295+
LINE 2: after insert on foo no inherit
2296+
^
2297+
create constraint trigger crtr
2298+
after insert on foo not enforced
2299+
for each row execute procedure foo ();
2300+
ERROR: constraint triggers cannot be marked NOT ENFORCED
2301+
LINE 2: after insert on foo not enforced
2302+
^
2303+
--
22832304
-- Constraint triggers and partitioned tables
22842305
create table parted_constr_ancestor (a int, b text)
22852306
partition by range (b);
@@ -2294,7 +2315,7 @@ create constraint trigger parted_trig after insert on parted_constr_ancestor
22942315
deferrable
22952316
for each row execute procedure trigger_notice_ab();
22962317
create constraint trigger parted_trig_two after insert on parted_constr
2297-
deferrable initially deferred
2318+
deferrable initially deferred enforced
22982319
for each row when (bark(new.b) AND new.a % 2 = 1)
22992320
execute procedure trigger_notice_ab();
23002321
-- The immediate constraint is fired immediately; the WHEN clause of the

src/test/regress/sql/triggers.sql

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,19 @@ select * from parted;
15761576
drop table parted;
15771577
drop function parted_trigfunc();
15781578

1579+
--
1580+
-- Constraint triggers
1581+
--
1582+
create constraint trigger crtr
1583+
after insert on foo not valid
1584+
for each row execute procedure foo ();
1585+
create constraint trigger crtr
1586+
after insert on foo no inherit
1587+
for each row execute procedure foo ();
1588+
create constraint trigger crtr
1589+
after insert on foo not enforced
1590+
for each row execute procedure foo ();
1591+
15791592
--
15801593
-- Constraint triggers and partitioned tables
15811594
create table parted_constr_ancestor (a int, b text)
@@ -1591,7 +1604,7 @@ create constraint trigger parted_trig after insert on parted_constr_ancestor
15911604
deferrable
15921605
for each row execute procedure trigger_notice_ab();
15931606
create constraint trigger parted_trig_two after insert on parted_constr
1594-
deferrable initially deferred
1607+
deferrable initially deferred enforced
15951608
for each row when (bark(new.b) AND new.a % 2 = 1)
15961609
execute procedure trigger_notice_ab();
15971610

0 commit comments

Comments
 (0)

TMZ Celebrity News – Breaking Stories, Videos & Gossip

Looking for the latest TMZ celebrity news? You've come to the right place. From shocking Hollywood scandals to exclusive videos, TMZ delivers it all in real time.

Whether it’s a red carpet slip-up, a viral paparazzi moment, or a legal drama involving your favorite stars, TMZ news is always first to break the story. Stay in the loop with daily updates, insider tips, and jaw-dropping photos.

🎥 Watch TMZ Live

TMZ Live brings you daily celebrity news and interviews straight from the TMZ newsroom. Don’t miss a beat—watch now and see what’s trending in Hollywood.