1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-27 23:21:58 +03:00

This patch implements FOR EACH STATEMENT triggers, per my email to

-hackers a couple days ago.

Notes/caveats:

        - added regression tests for the new functionality, all
          regression tests pass on my machine

        - added pg_dump support

        - updated PL/PgSQL to support per-statement triggers; didn't
          look at the other procedural languages.

        - there's (even) more code duplication in trigger.c than there
          was previously. Any suggestions on how to refactor the
          ExecXXXTriggers() functions to reuse more code would be
          welcome -- I took a brief look at it, but couldn't see an
          easy way to do it (there are several subtly-different
          versions of the code in question)

        - updated the documentation. I also took the liberty of
          removing a big chunk of duplicated syntax documentation in
          the Programmer's Guide on triggers, and moving that
          information to the CREATE TRIGGER reference page.

        - I also included some spelling fixes and similar small
          cleanups I noticed while making the changes. If you'd like
          me to split those into a separate patch, let me know.

Neil Conway
This commit is contained in:
Bruce Momjian
2002-11-23 03:59:09 +00:00
parent ea29b32758
commit 1b7f3cc02d
24 changed files with 702 additions and 411 deletions

View File

@ -13,7 +13,7 @@
*
* These three procedures are the external interfaces to the executor.
* In each case, the query descriptor and the execution state is required
* as arguments
* as arguments
*
* ExecutorStart() must be called at the beginning of any execution of any
* query plan and ExecutorEnd() should always be called at the end of
@ -27,7 +27,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.186 2002/11/13 00:44:08 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.187 2002/11/23 03:59:07 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -908,12 +908,12 @@ ExecutePlan(EState *estate,
ScanDirection direction,
DestReceiver *destfunc)
{
JunkFilter *junkfilter;
TupleTableSlot *slot;
ItemPointer tupleid = NULL;
ItemPointerData tuple_ctid;
long current_tuple_count;
TupleTableSlot *result;
JunkFilter *junkfilter;
TupleTableSlot *slot;
ItemPointer tupleid = NULL;
ItemPointerData tuple_ctid;
long current_tuple_count;
TupleTableSlot *result;
/*
* initialize local variables
@ -927,6 +927,24 @@ ExecutePlan(EState *estate,
*/
estate->es_direction = direction;
/*
* Process BEFORE EACH STATEMENT triggers
*/
switch (operation)
{
case CMD_UPDATE:
ExecBSUpdateTriggers(estate, estate->es_result_relation_info);
break;
case CMD_DELETE:
ExecBSDeleteTriggers(estate, estate->es_result_relation_info);
break;
case CMD_INSERT:
ExecBSInsertTriggers(estate, estate->es_result_relation_info);
break;
default:
/* do nothing */
}
/*
* Loop until we've processed the proper number of tuples from the
* plan.
@ -1124,6 +1142,24 @@ lnext: ;
break;
}
/*
* Process AFTER EACH STATEMENT triggers
*/
switch (operation)
{
case CMD_UPDATE:
ExecASUpdateTriggers(estate, estate->es_result_relation_info);
break;
case CMD_DELETE:
ExecASDeleteTriggers(estate, estate->es_result_relation_info);
break;
case CMD_INSERT:
ExecASInsertTriggers(estate, estate->es_result_relation_info);
break;
default:
/* do nothing */
}
/*
* here, result is either a slot containing a tuple in the case of a
* SELECT or NULL otherwise.
@ -1205,7 +1241,7 @@ ExecInsert(TupleTableSlot *slot,
/* BEFORE ROW INSERT Triggers */
if (resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
resultRelInfo->ri_TrigDesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)
{
HeapTuple newtuple;
@ -1256,8 +1292,7 @@ ExecInsert(TupleTableSlot *slot,
ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
/* AFTER ROW INSERT Triggers */
if (resultRelInfo->ri_TrigDesc)
ExecARInsertTriggers(estate, resultRelInfo, tuple);
ExecARInsertTriggers(estate, resultRelInfo, tuple);
}
/* ----------------------------------------------------------------
@ -1346,8 +1381,7 @@ ldelete:;
*/
/* AFTER ROW DELETE Triggers */
if (resultRelInfo->ri_TrigDesc)
ExecARDeleteTriggers(estate, resultRelInfo, tupleid);
ExecARDeleteTriggers(estate, resultRelInfo, tupleid);
}
/* ----------------------------------------------------------------
@ -1498,8 +1532,7 @@ lreplace:;
ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false);
/* AFTER ROW UPDATE Triggers */
if (resultRelInfo->ri_TrigDesc)
ExecARUpdateTriggers(estate, resultRelInfo, tupleid, tuple);
ExecARUpdateTriggers(estate, resultRelInfo, tupleid, tuple);
}
static char *