diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/Makefile | 2 | ||||
-rw-r--r-- | src/backend/executor/execAmi.c | 38 | ||||
-rw-r--r-- | src/backend/executor/execProcnode.c | 14 | ||||
-rw-r--r-- | src/backend/executor/nodeCustom.c | 126 |
4 files changed, 177 insertions, 3 deletions
diff --git a/src/backend/executor/Makefile b/src/backend/executor/Makefile index 6081b56c086..af707b03751 100644 --- a/src/backend/executor/Makefile +++ b/src/backend/executor/Makefile @@ -16,7 +16,7 @@ OBJS = execAmi.o execCurrent.o execGrouping.o execJunk.o execMain.o \ execProcnode.o execQual.o execScan.o execTuples.o \ execUtils.o functions.o instrument.o nodeAppend.o nodeAgg.o \ nodeBitmapAnd.o nodeBitmapOr.o \ - nodeBitmapHeapscan.o nodeBitmapIndexscan.o nodeHash.o \ + nodeBitmapHeapscan.o nodeBitmapIndexscan.o nodeCustom.o nodeHash.o \ nodeHashjoin.o nodeIndexscan.o nodeIndexonlyscan.o \ nodeLimit.o nodeLockRows.o \ nodeMaterial.o nodeMergeAppend.o nodeMergejoin.o nodeModifyTable.o \ diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 640964c5b7c..b14e08cd1af 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -21,6 +21,7 @@ #include "executor/nodeBitmapIndexscan.h" #include "executor/nodeBitmapOr.h" #include "executor/nodeCtescan.h" +#include "executor/nodeCustom.h" #include "executor/nodeForeignscan.h" #include "executor/nodeFunctionscan.h" #include "executor/nodeGroup.h" @@ -49,6 +50,7 @@ #include "executor/nodeWindowAgg.h" #include "executor/nodeWorktablescan.h" #include "nodes/nodeFuncs.h" +#include "nodes/relation.h" #include "utils/rel.h" #include "utils/syscache.h" @@ -197,6 +199,10 @@ ExecReScan(PlanState *node) ExecReScanForeignScan((ForeignScanState *) node); break; + case T_CustomScanState: + ExecReScanCustomScan((CustomScanState *) node); + break; + case T_NestLoopState: ExecReScanNestLoop((NestLoopState *) node); break; @@ -291,6 +297,10 @@ ExecMarkPos(PlanState *node) ExecValuesMarkPos((ValuesScanState *) node); break; + case T_CustomScanState: + ExecCustomMarkPos((CustomScanState *) node); + break; + case T_MaterialState: ExecMaterialMarkPos((MaterialState *) node); break; @@ -348,6 +358,10 @@ ExecRestrPos(PlanState *node) ExecValuesRestrPos((ValuesScanState *) node); break; + case T_CustomScanState: + ExecCustomRestrPos((CustomScanState *) node); + break; + case T_MaterialState: ExecMaterialRestrPos((MaterialState *) node); break; @@ -379,9 +393,9 @@ ExecRestrPos(PlanState *node) * and valuesscan support is actually useless code at present.) */ bool -ExecSupportsMarkRestore(NodeTag plantype) +ExecSupportsMarkRestore(Path *pathnode) { - switch (plantype) + switch (pathnode->pathtype) { case T_SeqScan: case T_IndexScan: @@ -403,6 +417,16 @@ ExecSupportsMarkRestore(NodeTag plantype) */ return false; + case T_CustomScan: + { + CustomPath *cpath = (CustomPath *) pathnode; + + Assert(IsA(cpath, CustomPath)); + if (cpath->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE) + return true; + } + break; + default: break; } @@ -465,6 +489,16 @@ ExecSupportsBackwardScan(Plan *node) return ExecSupportsBackwardScan(((SubqueryScan *) node)->subplan) && TargetListSupportsBackwardScan(node->targetlist); + case T_CustomScan: + { + uint32 flags = ((CustomScan *) node)->flags; + + if (TargetListSupportsBackwardScan(node->targetlist) && + (flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) != 0) + return true; + } + return false; + case T_Material: case T_Sort: /* these don't evaluate tlist */ diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index c0189eb5a12..e27c0627bc4 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -85,6 +85,7 @@ #include "executor/nodeBitmapIndexscan.h" #include "executor/nodeBitmapOr.h" #include "executor/nodeCtescan.h" +#include "executor/nodeCustom.h" #include "executor/nodeForeignscan.h" #include "executor/nodeFunctionscan.h" #include "executor/nodeGroup.h" @@ -244,6 +245,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags) estate, eflags); break; + case T_CustomScan: + result = (PlanState *) ExecInitCustomScan((CustomScan *) node, + estate, eflags); + break; + /* * join nodes */ @@ -442,6 +448,10 @@ ExecProcNode(PlanState *node) result = ExecForeignScan((ForeignScanState *) node); break; + case T_CustomScanState: + result = ExecCustomScan((CustomScanState *) node); + break; + /* * join nodes */ @@ -678,6 +688,10 @@ ExecEndNode(PlanState *node) ExecEndForeignScan((ForeignScanState *) node); break; + case T_CustomScanState: + ExecEndCustomScan((CustomScanState *) node); + break; + /* * join nodes */ diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c new file mode 100644 index 00000000000..576b295a49a --- /dev/null +++ b/src/backend/executor/nodeCustom.c @@ -0,0 +1,126 @@ +/* ------------------------------------------------------------------------ + * + * nodeCustom.c + * Routines to handle execution of custom scan node + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * ------------------------------------------------------------------------ + */ +#include "postgres.h" + +#include "executor/executor.h" +#include "executor/nodeCustom.h" +#include "nodes/execnodes.h" +#include "nodes/plannodes.h" +#include "parser/parsetree.h" +#include "utils/hsearch.h" +#include "utils/memutils.h" +#include "utils/rel.h" + +CustomScanState * +ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) +{ + CustomScanState *css; + Relation scan_rel; + + /* populate a CustomScanState according to the CustomScan */ + css = (CustomScanState *) cscan->methods->CreateCustomScanState(cscan); + Assert(IsA(css, CustomScanState)); + + /* fill up fields of ScanState */ + css->ss.ps.plan = &cscan->scan.plan; + css->ss.ps.state = estate; + + /* create expression context for node */ + ExecAssignExprContext(estate, &css->ss.ps); + + /* initialize child expressions */ + css->ss.ps.targetlist = (List *) + ExecInitExpr((Expr *) cscan->scan.plan.targetlist, + (PlanState *) css); + css->ss.ps.qual = (List *) + ExecInitExpr((Expr *) cscan->scan.plan.qual, + (PlanState *) css); + + /* tuple table initialization */ + ExecInitScanTupleSlot(estate, &css->ss); + ExecInitResultTupleSlot(estate, &css->ss.ps); + + /* initialize scan relation */ + scan_rel = ExecOpenScanRelation(estate, cscan->scan.scanrelid, eflags); + css->ss.ss_currentRelation = scan_rel; + css->ss.ss_currentScanDesc = NULL; /* set by provider */ + ExecAssignScanType(&css->ss, RelationGetDescr(scan_rel)); + + css->ss.ps.ps_TupFromTlist = false; + + /* + * Initialize result tuple type and projection info. + */ + ExecAssignResultTypeFromTL(&css->ss.ps); + ExecAssignScanProjectionInfo(&css->ss); + + /* + * The callback of custom-scan provider applies the final initialization + * of the custom-scan-state node according to its logic. + */ + css->methods->BeginCustomScan(css, estate, eflags); + + return css; +} + +TupleTableSlot * +ExecCustomScan(CustomScanState *node) +{ + Assert(node->methods->ExecCustomScan != NULL); + return node->methods->ExecCustomScan(node); +} + +void +ExecEndCustomScan(CustomScanState *node) +{ + Assert(node->methods->EndCustomScan != NULL); + node->methods->EndCustomScan(node); + + /* Free the exprcontext */ + ExecFreeExprContext(&node->ss.ps); + + /* Clean out the tuple table */ + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ss_ScanTupleSlot) + ExecClearTuple(node->ss.ss_ScanTupleSlot); + + /* Close the heap relation */ + ExecCloseScanRelation(node->ss.ss_currentRelation); +} + +void +ExecReScanCustomScan(CustomScanState *node) +{ + Assert(node->methods->ReScanCustomScan != NULL); + node->methods->ReScanCustomScan(node); +} + +void +ExecCustomMarkPos(CustomScanState *node) +{ + if (!node->methods->MarkPosCustomScan) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("custom-scan \"%s\" does not support MarkPos", + node->methods->CustomName))); + node->methods->MarkPosCustomScan(node); +} + +void +ExecCustomRestrPos(CustomScanState *node) +{ + if (!node->methods->RestrPosCustomScan) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("custom-scan \"%s\" does not support MarkPos", + node->methods->CustomName))); + node->methods->RestrPosCustomScan(node); +} |