OSDN Git Service

Fix sloppy usage of TRIGGER_FIRED_BEFORE/TRIGGER_FIRED_AFTER.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Oct 2010 17:27:31 +0000 (13:27 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 8 Oct 2010 17:27:31 +0000 (13:27 -0400)
Various places were testing TRIGGER_FIRED_BEFORE() where what they really
meant was !TRIGGER_FIRED_AFTER(), or vice versa.  This needs to be cleaned
up because there are about to be more than two possible states.

We might want to note this in the 9.1 release notes as something for
trigger authors to double-check.

For consistency's sake I also changed some places that assumed that
TRIGGER_FIRED_FOR_ROW and TRIGGER_FIRED_FOR_STATEMENT are necessarily
mutually exclusive; that's not in immediate danger of breaking, but
it's still sloppier than it should be.

Extracted from Dean Rasheed's patch for triggers on views.  I'm committing
this separately since it's an identifiable separate issue, and is the
only reason for the patch to touch most of these particular files.

contrib/spi/autoinc.c
contrib/spi/insert_username.c
contrib/spi/moddatetime.c
contrib/spi/refint.c
contrib/spi/timetravel.c
src/backend/utils/adt/tsvector_op.c
src/pl/plpgsql/src/pl_exec.c
src/pl/plpython/plpython.c
src/test/regress/regress.c

index 4552fc3..9b38493 100644 (file)
@@ -35,10 +35,10 @@ autoinc(PG_FUNCTION_ARGS)
        if (!CALLED_AS_TRIGGER(fcinfo))
                /* internal error */
                elog(ERROR, "not fired by trigger manager");
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "cannot process STATEMENT events");
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+               elog(ERROR, "must be fired for row");
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                /* internal error */
                elog(ERROR, "must be fired before event");
 
index da6764f..18a1334 100644 (file)
@@ -38,10 +38,10 @@ insert_username(PG_FUNCTION_ARGS)
        if (!CALLED_AS_TRIGGER(fcinfo))
                /* internal error */
                elog(ERROR, "insert_username: not fired by trigger manager");
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "insert_username: cannot process STATEMENT events");
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+               elog(ERROR, "insert_username: must be fired for row");
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                /* internal error */
                elog(ERROR, "insert_username: must be fired before event");
 
index e90c0b5..9a1addb 100644 (file)
@@ -43,17 +43,17 @@ moddatetime(PG_FUNCTION_ARGS)
                /* internal error */
                elog(ERROR, "moddatetime: not fired by trigger manager");
 
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "moddatetime: cannot process STATEMENT events");
+               elog(ERROR, "moddatetime: must be fired for row");
 
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                /* internal error */
                elog(ERROR, "moddatetime: must be fired before event");
 
        if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "moddatetime: must be fired before event");
+               elog(ERROR, "moddatetime: cannot process INSERT events");
        else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
                rettuple = trigdata->tg_newtuple;
        else
index cbd08d4..36f9ee4 100644 (file)
@@ -79,9 +79,9 @@ check_primary_key(PG_FUNCTION_ARGS)
                elog(ERROR, "check_primary_key: not fired by trigger manager");
 
        /* Should be called for ROW trigger */
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "check_primary_key: cannot process STATEMENT events");
+               elog(ERROR, "check_primary_key: must be fired for row");
 
        /* If INSERTion then must check Tuple to being inserted */
        if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
@@ -279,9 +279,9 @@ check_foreign_key(PG_FUNCTION_ARGS)
                elog(ERROR, "check_foreign_key: not fired by trigger manager");
 
        /* Should be called for ROW trigger */
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                /* internal error */
-               elog(ERROR, "check_foreign_key: cannot process STATEMENT events");
+               elog(ERROR, "check_foreign_key: must be fired for row");
 
        /* Not should be called for INSERT */
        if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
index 8bae313..1462124 100644 (file)
@@ -118,11 +118,11 @@ timetravel(PG_FUNCTION_ARGS)
                elog(ERROR, "timetravel: not fired by trigger manager");
 
        /* Should be called for ROW trigger */
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
-               elog(ERROR, "timetravel: cannot process STATEMENT events");
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
+               elog(ERROR, "timetravel: must be fired for row");
 
        /* Should be called BEFORE */
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                elog(ERROR, "timetravel: must be fired before event");
 
        /* INSERT ? */
index 399fee8..7695097 100644 (file)
@@ -1257,9 +1257,9 @@ tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
                elog(ERROR, "tsvector_update_trigger: not fired by trigger manager");
 
        trigdata = (TriggerData *) fcinfo->context;
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
-               elog(ERROR, "tsvector_update_trigger: can't process STATEMENT events");
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
+               elog(ERROR, "tsvector_update_trigger: must be fired for row");
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                elog(ERROR, "tsvector_update_trigger: must be fired BEFORE event");
 
        if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
index 6601320..e2b5f77 100644 (file)
@@ -526,7 +526,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
        rec_old->tupdesc = trigdata->tg_relation->rd_att;
        rec_old->freetupdesc = false;
 
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
        {
                /*
                 * Per-statement triggers don't use OLD/NEW variables
@@ -715,7 +715,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func,
         * attributes don't have the correct atttypmod's length. It's up to the
         * trigger's programmer to ensure that this doesn't happen. Jan
         */
-       if (estate.retisnull || TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+       if (estate.retisnull || !TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                rettup = NULL;
        else
        {
index 6e35637..4c53987 100644 (file)
@@ -841,7 +841,6 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
                Py_DECREF(plttableschema);
                pfree(stroid);
 
-
                if (TRIGGER_FIRED_BEFORE(tdata->tg_event))
                        pltwhen = PyString_FromString("BEFORE");
                else if (TRIGGER_FIRED_AFTER(tdata->tg_event))
index 8b0f9f1..8e4286a 100644 (file)
@@ -487,9 +487,9 @@ ttdummy(PG_FUNCTION_ARGS)
 
        if (!CALLED_AS_TRIGGER(fcinfo))
                elog(ERROR, "ttdummy: not fired by trigger manager");
-       if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
-               elog(ERROR, "ttdummy: cannot process STATEMENT events");
-       if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+       if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
+               elog(ERROR, "ttdummy: must be fired for row");
+       if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                elog(ERROR, "ttdummy: must be fired before event");
        if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
                elog(ERROR, "ttdummy: cannot process INSERT event");