1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Fire non-deferred AFTER triggers immediately upon query completion,

rather than when returning to the idle loop.  This makes no particular
difference for interactively-issued queries, but it makes a big difference
for queries issued within functions: trigger execution now occurs before
the calling function is allowed to proceed.  This responds to numerous
complaints about nonintuitive behavior of foreign key checking, such as
http://archives.postgresql.org/pgsql-bugs/2004-09/msg00020.php, and
appears to be required by the SQL99 spec.
Also take the opportunity to simplify the data structures used for the
pending-trigger list, rename them for more clarity, and squeeze out a
bit of space.
This commit is contained in:
Tom Lane
2004-09-10 18:40:09 +00:00
parent 856d1faac1
commit b339d1fff6
17 changed files with 967 additions and 631 deletions

View File

@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.85 2004/08/29 05:06:49 momjian Exp $
* $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.86 2004/09/10 18:40:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "commands/trigger.h"
#include "executor/executor.h"
#include "miscadmin.h"
#include "tcop/tcopprot.h"
@ -136,6 +137,11 @@ ProcessQuery(Query *parsetree,
*/
queryDesc = CreateQueryDesc(parsetree, plan, dest, params, false);
/*
* Set up to collect AFTER triggers
*/
AfterTriggerBeginQuery();
/*
* Call ExecStart to prepare the plan for execution
*/
@ -185,6 +191,9 @@ ProcessQuery(Query *parsetree,
*/
ExecutorEnd(queryDesc);
/* And take care of any queued AFTER triggers */
AfterTriggerEndQuery();
FreeQueryDesc(queryDesc);
}
@ -290,6 +299,13 @@ PortalStart(Portal portal, ParamListInfo params)
params,
false);
/*
* We do *not* call AfterTriggerBeginQuery() here. We
* assume that a SELECT cannot queue any triggers. It
* would be messy to support triggers since the execution
* of the portal may be interleaved with other queries.
*/
/*
* Call ExecStart to prepare the plan for execution
*/
@ -1144,8 +1160,8 @@ DoPortalRunFetch(Portal portal,
return PortalRunSelect(portal, false, 1L, dest);
}
else
/* count == 0 */
{
/* count == 0 */
/* Rewind to start, return zero rows */
DoPortalRewind(portal);
return PortalRunSelect(portal, true, 0L, dest);
@ -1173,8 +1189,8 @@ DoPortalRunFetch(Portal portal,
return PortalRunSelect(portal, false, 1L, dest);
}
else
/* count == 0 */
{
/* count == 0 */
/* Same as FETCH FORWARD 0, so fall out of switch */
fdirection = FETCH_FORWARD;
}