Index: src/backend/executor/execMain.c =================================================================== --- src/backend/executor/execMain.c (HEAD) +++ src/backend/executor/execMain.c (working copy) @@ -67,14 +67,12 @@ struct evalPlanQual *free; /* list of free PlanQual plans */ } evalPlanQual; +/* Hook for plugins to get control in ExecutorRun() */ +executor_hook_type executor_hook = NULL; + /* decls for local routines only used within this module */ static void InitPlan(QueryDesc *queryDesc, int eflags); static void ExecEndPlan(PlanState *planstate, EState *estate); -static TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate, - CmdType operation, - long numberTuples, - ScanDirection direction, - DestReceiver *dest); static void ExecSelect(TupleTableSlot *slot, DestReceiver *dest, EState *estate); static void ExecInsert(TupleTableSlot *slot, ItemPointer tupleid, @@ -262,6 +260,8 @@ */ if (ScanDirectionIsNoMovement(direction)) result = NULL; + else if (executor_hook) + result = executor_hook(queryDesc, direction, count); else result = ExecutePlan(estate, queryDesc->planstate, @@ -1182,7 +1182,7 @@ * user can see it * ---------------------------------------------------------------- */ -static TupleTableSlot * +TupleTableSlot * ExecutePlan(EState *estate, PlanState *planstate, CmdType operation, Index: src/backend/nodes/copyfuncs.c =================================================================== --- src/backend/nodes/copyfuncs.c (HEAD) +++ src/backend/nodes/copyfuncs.c (working copy) @@ -85,6 +85,7 @@ COPY_NODE_FIELD(rowMarks); COPY_NODE_FIELD(relationOids); COPY_SCALAR_FIELD(nParamExec); + COPY_SCALAR_FIELD(tag); return newnode; } Index: src/backend/nodes/outfuncs.c =================================================================== --- src/backend/nodes/outfuncs.c (HEAD) +++ src/backend/nodes/outfuncs.c (working copy) @@ -252,6 +252,7 @@ WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(relationOids); WRITE_INT_FIELD(nParamExec); + WRITE_INT_FIELD(tag); } /* Index: src/include/executor/executor.h =================================================================== --- src/include/executor/executor.h (HEAD) +++ src/include/executor/executor.h (working copy) @@ -138,6 +138,11 @@ ScanDirection direction, long count); extern void ExecutorEnd(QueryDesc *queryDesc); extern void ExecutorRewind(QueryDesc *queryDesc); +extern TupleTableSlot *ExecutePlan(EState *estate, PlanState *planstate, + CmdType operation, + long numberTuples, + ScanDirection direction, + DestReceiver *dest); extern void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, @@ -152,6 +157,11 @@ extern PlanState *ExecGetActivePlanTree(QueryDesc *queryDesc); extern DestReceiver *CreateIntoRelDestReceiver(void); +/* Hook for plugins to get control in ExecutorRun() */ +typedef TupleTableSlot *(*executor_hook_type) (QueryDesc *queryDesc, + ScanDirection direction, long count); +extern PGDLLIMPORT executor_hook_type executor_hook; + /* * prototypes from functions in execProcnode.c */ Index: src/include/nodes/plannodes.h =================================================================== --- src/include/nodes/plannodes.h (HEAD) +++ src/include/nodes/plannodes.h (working copy) @@ -73,6 +73,8 @@ List *relationOids; /* OIDs of relations the plan depends on */ int nParamExec; /* number of PARAM_EXEC Params used */ + + uint32 tag; /* plan tag */ } PlannedStmt; /* macro for fetching the Plan associated with a SubPlan node */