diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-02-27 13:43:29 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-02-27 13:44:12 -0500 |
commit | a874fe7b4c890d1fe3455215a83ca777867beadd (patch) | |
tree | 04b7870100a76bb79470abaf0f971550043590d7 /src/include/executor/executor.h | |
parent | 67a5e727c8655496013b007d2fb6137fcc244b18 (diff) | |
download | postgresql-a874fe7b4c890d1fe3455215a83ca777867beadd.tar.gz postgresql-a874fe7b4c890d1fe3455215a83ca777867beadd.zip |
Refactor the executor's API to support data-modifying CTEs better.
The originally committed patch for modifying CTEs didn't interact well
with EXPLAIN, as noted by myself, and also had corner-case problems with
triggers, as noted by Dean Rasheed. Those problems show it is really not
practical for ExecutorEnd to call any user-defined code; so split the
cleanup duties out into a new function ExecutorFinish, which must be called
between the last ExecutorRun call and ExecutorEnd. Some Asserts have been
added to these functions to help verify correct usage.
It is no longer necessary for callers of the executor to call
AfterTriggerBeginQuery/AfterTriggerEndQuery for themselves, as this is now
done by ExecutorStart/ExecutorFinish respectively. If you really need to
suppress that and do it for yourself, pass EXEC_FLAG_SKIP_TRIGGERS to
ExecutorStart.
Also, refactor portal commit processing to allow for the possibility that
PortalDrop will invoke user-defined code. I think this is not actually
necessary just yet, since the portal-execution-strategy logic forces any
non-pure-SELECT query to be run to completion before we will consider
committing. But it seems like good future-proofing.
Diffstat (limited to 'src/include/executor/executor.h')
-rw-r--r-- | src/include/executor/executor.h | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 2ed54d0a5cc..3e9df936e51 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -44,11 +44,17 @@ * * MARK indicates that the plan node must support Mark/Restore calls. * When this is not passed, no Mark/Restore will occur. + * + * SKIP_TRIGGERS tells ExecutorStart/ExecutorFinish to skip calling + * AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily + * mean that the plan can't queue any AFTER triggers; just that the caller + * is responsible for there being a trigger context for them to be queued in. */ #define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */ #define EXEC_FLAG_REWIND 0x0002 /* need efficient rescan */ #define EXEC_FLAG_BACKWARD 0x0004 /* need backward scan */ #define EXEC_FLAG_MARK 0x0008 /* need mark/restore */ +#define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */ /* @@ -70,6 +76,10 @@ typedef void (*ExecutorRun_hook_type) (QueryDesc *queryDesc, long count); extern PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook; +/* Hook for plugins to get control in ExecutorFinish() */ +typedef void (*ExecutorFinish_hook_type) (QueryDesc *queryDesc); +extern PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook; + /* Hook for plugins to get control in ExecutorEnd() */ typedef void (*ExecutorEnd_hook_type) (QueryDesc *queryDesc); extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook; @@ -159,6 +169,8 @@ extern void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, long count); extern void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, long count); +extern void ExecutorFinish(QueryDesc *queryDesc); +extern void standard_ExecutorFinish(QueryDesc *queryDesc); extern void ExecutorEnd(QueryDesc *queryDesc); extern void standard_ExecutorEnd(QueryDesc *queryDesc); extern void ExecutorRewind(QueryDesc *queryDesc); |