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

Improve EXPLAIN ANALYZE to show the time spent in each trigger when

executing a statement that fires triggers.  Formerly this time was
included in "Total runtime" but not otherwise accounted for.
As a side benefit, we avoid re-opening relations when firing non-deferred
AFTER triggers, because the trigger code can re-use the main executor's
ResultRelInfo data structure.
This commit is contained in:
Tom Lane
2005-03-25 21:58:00 +00:00
parent 08890b407e
commit adb1a6e95b
16 changed files with 403 additions and 143 deletions

View File

@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.243 2005/03/20 23:40:25 neilc Exp $
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.244 2005/03/25 21:57:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -39,6 +39,7 @@
#include "commands/trigger.h"
#include "executor/execdebug.h"
#include "executor/execdefs.h"
#include "executor/instrument.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
#include "optimizer/var.h"
@ -69,7 +70,8 @@ static void InitPlan(QueryDesc *queryDesc, bool explainOnly);
static void initResultRelInfo(ResultRelInfo *resultRelInfo,
Index resultRelationIndex,
List *rangeTable,
CmdType operation);
CmdType operation,
bool doInstrument);
static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate,
CmdType operation,
long numberTuples,
@ -508,7 +510,8 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
initResultRelInfo(resultRelInfo,
lfirst_int(l),
rangeTable,
operation);
operation,
estate->es_instrument);
resultRelInfo++;
}
}
@ -523,7 +526,8 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
initResultRelInfo(resultRelInfos,
parseTree->resultRelation,
rangeTable,
operation);
operation,
estate->es_instrument);
}
estate->es_result_relations = resultRelInfos;
@ -798,7 +802,8 @@ static void
initResultRelInfo(ResultRelInfo *resultRelInfo,
Index resultRelationIndex,
List *rangeTable,
CmdType operation)
CmdType operation,
bool doInstrument)
{
Oid resultRelationOid;
Relation resultRelationDesc;
@ -837,7 +842,22 @@ initResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo->ri_IndexRelationInfo = NULL;
/* make a copy so as not to depend on relcache info not changing... */
resultRelInfo->ri_TrigDesc = CopyTriggerDesc(resultRelationDesc->trigdesc);
resultRelInfo->ri_TrigFunctions = NULL;
if (resultRelInfo->ri_TrigDesc)
{
int n = resultRelInfo->ri_TrigDesc->numtriggers;
resultRelInfo->ri_TrigFunctions = (FmgrInfo *)
palloc0(n * sizeof(FmgrInfo));
if (doInstrument)
resultRelInfo->ri_TrigInstrument = InstrAlloc(n);
else
resultRelInfo->ri_TrigInstrument = NULL;
}
else
{
resultRelInfo->ri_TrigFunctions = NULL;
resultRelInfo->ri_TrigInstrument = NULL;
}
resultRelInfo->ri_ConstraintExprs = NULL;
resultRelInfo->ri_junkFilter = NULL;

View File

@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.46 2004/12/31 21:59:45 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.47 2005/03/25 21:57:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -252,7 +252,7 @@ ExecInitNode(Plan *node, EState *estate)
/* Set up instrumentation for this node if requested */
if (estate->es_instrument)
result->instrument = InstrAlloc();
result->instrument = InstrAlloc(1);
return result;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.92 2005/03/16 21:38:07 tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.93 2005/03/25 21:57:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -399,8 +399,8 @@ postquel_end(execution_state *es, SQLFunctionCachePtr fcache)
{
ActiveSnapshot = es->qd->snapshot;
AfterTriggerEndQuery(es->qd->estate);
ExecutorEnd(es->qd);
AfterTriggerEndQuery();
}
PG_CATCH();
{

View File

@ -7,7 +7,7 @@
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.10 2005/03/20 22:27:51 tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/instrument.c,v 1.11 2005/03/25 21:57:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -18,13 +18,13 @@
#include "executor/instrument.h"
/* Allocate new instrumentation structure */
/* Allocate new instrumentation structure(s) */
Instrumentation *
InstrAlloc(void)
InstrAlloc(int n)
{
Instrumentation *instr = palloc(sizeof(Instrumentation));
Instrumentation *instr = palloc0(n * sizeof(Instrumentation));
memset(instr, 0, sizeof(Instrumentation));
/* we don't need to do any initialization except zero 'em */
return instr;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.135 2005/03/16 21:38:08 tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.136 2005/03/25 21:57:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1546,10 +1546,10 @@ _SPI_pquery(QueryDesc *queryDesc, int tcount)
elog(ERROR, "consistency check on SPI tuple count failed");
}
ExecutorEnd(queryDesc);
/* Take care of any queued AFTER triggers */
AfterTriggerEndQuery();
AfterTriggerEndQuery(queryDesc->estate);
ExecutorEnd(queryDesc);
if (queryDesc->dest->mydest == SPI)
{