aboutsummaryrefslogtreecommitdiff
path: root/src/include/executor/executor.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-02-27 13:43:29 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2011-02-27 13:44:12 -0500
commita874fe7b4c890d1fe3455215a83ca777867beadd (patch)
tree04b7870100a76bb79470abaf0f971550043590d7 /src/include/executor/executor.h
parent67a5e727c8655496013b007d2fb6137fcc244b18 (diff)
downloadpostgresql-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.h12
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);