aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execAmi.c44
-rw-r--r--src/backend/optimizer/plan/createplan.c97
-rw-r--r--src/backend/optimizer/plan/setrefs.c13
-rw-r--r--src/backend/optimizer/util/pathnode.c15
-rw-r--r--src/include/executor/executor.h5
-rw-r--r--src/include/executor/nodeCustom.h6
-rw-r--r--src/include/nodes/execnodes.h49
-rw-r--r--src/include/nodes/plannodes.h44
-rw-r--r--src/include/nodes/relation.h38
-rw-r--r--src/include/optimizer/pathnode.h6
-rw-r--r--src/include/optimizer/planmain.h3
11 files changed, 164 insertions, 156 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index b14e08cd1af..643aaace3a9 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -381,11 +381,14 @@ ExecRestrPos(PlanState *node)
}
/*
- * ExecSupportsMarkRestore - does a plan type support mark/restore?
+ * ExecSupportsMarkRestore - does a Path support mark/restore?
+ *
+ * This is used during planning and so must accept a Path, not a Plan.
+ * We keep it here to be adjacent to the routines above, which also must
+ * know which plan types support mark/restore.
*
* XXX Ideally, all plan node types would support mark/restore, and this
* wouldn't be needed. For now, this had better match the routines above.
- * But note the test is on Plan nodetype, not PlanState nodetype.
*
* (However, since the only present use of mark/restore is in mergejoin,
* there is no need to support mark/restore in any plan type that is not
@@ -395,6 +398,11 @@ ExecRestrPos(PlanState *node)
bool
ExecSupportsMarkRestore(Path *pathnode)
{
+ /*
+ * For consistency with the routines above, we do not examine the nodeTag
+ * but rather the pathtype, which is the Plan node type the Path would
+ * produce.
+ */
switch (pathnode->pathtype)
{
case T_SeqScan:
@@ -406,27 +414,23 @@ ExecSupportsMarkRestore(Path *pathnode)
case T_Sort:
return true;
+ case T_CustomScan:
+ Assert(IsA(pathnode, CustomPath));
+ if (((CustomPath *) pathnode)->flags & CUSTOMPATH_SUPPORT_MARK_RESTORE)
+ return true;
+ return false;
+
case T_Result:
/*
- * T_Result only supports mark/restore if it has a child plan that
- * does, so we do not have enough information to give a really
- * correct answer. However, for current uses it's enough to
- * always say "false", because this routine is not asked about
- * gating Result plans, only base-case Results.
+ * Although Result supports mark/restore if it has a child plan
+ * that does, we presently come here only for ResultPath nodes,
+ * which represent Result plans without a child plan. So there is
+ * nothing to recurse to and we can just say "false".
*/
+ Assert(IsA(pathnode, ResultPath));
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;
}
@@ -491,10 +495,10 @@ ExecSupportsBackwardScan(Plan *node)
case T_CustomScan:
{
- uint32 flags = ((CustomScan *) node)->flags;
+ uint32 flags = ((CustomScan *) node)->flags;
- if (TargetListSupportsBackwardScan(node->targetlist) &&
- (flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) != 0)
+ if ((flags & CUSTOMPATH_SUPPORT_BACKWARD_SCAN) &&
+ TargetListSupportsBackwardScan(node->targetlist))
return true;
}
return false;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 0a85cd99061..e6bd4c326ca 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -78,8 +78,8 @@ static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_pa
static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
List *tlist, List *scan_clauses);
static Plan *create_customscan_plan(PlannerInfo *root,
- CustomPath *best_path,
- List *tlist, List *scan_clauses);
+ CustomPath *best_path,
+ List *tlist, List *scan_clauses);
static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path,
Plan *outer_plan, Plan *inner_plan);
static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path,
@@ -1083,52 +1083,6 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path)
return plan;
}
-/*
- * create_custom_plan
- *
- * Transform a CustomPath into a Plan.
- */
-static Plan *
-create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
- List *tlist, List *scan_clauses)
-{
- Plan *plan;
- RelOptInfo *rel = best_path->path.parent;
-
- /*
- * Right now, all we can support is CustomScan node which is associated
- * with a particular base relation to be scanned.
- */
- Assert(rel && rel->reloptkind == RELOPT_BASEREL);
-
- /*
- * Sort clauses into the best execution order, although custom-scan
- * provider can reorder them again.
- */
- scan_clauses = order_qual_clauses(root, scan_clauses);
-
- /*
- * Create a CustomScan (or its inheritance) node according to
- * the supplied CustomPath.
- */
- plan = best_path->methods->PlanCustomPath(root, rel, best_path, tlist,
- scan_clauses);
-
- /*
- * NOTE: unlike create_foreignscan_plan(), it is responsibility of
- * the custom plan provider to replace outer-relation variables
- * with nestloop params, because we cannot know how many expression
- * trees are held in the private fields.
- */
-
- /*
- * Copy cost data from Path to Plan; no need to make custom-plan
- * providers do this
- */
- copy_path_costsize(plan, &best_path->path);
-
- return plan;
-}
/*****************************************************************************
*
@@ -2063,6 +2017,53 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
return scan_plan;
}
+/*
+ * create_custom_plan
+ *
+ * Transform a CustomPath into a Plan.
+ */
+static Plan *
+create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
+ List *tlist, List *scan_clauses)
+{
+ Plan *plan;
+ RelOptInfo *rel = best_path->path.parent;
+
+ /*
+ * Right now, all we can support is CustomScan node which is associated
+ * with a particular base relation to be scanned.
+ */
+ Assert(rel && rel->reloptkind == RELOPT_BASEREL);
+
+ /*
+ * Sort clauses into the best execution order, although custom-scan
+ * provider can reorder them again.
+ */
+ scan_clauses = order_qual_clauses(root, scan_clauses);
+
+ /*
+ * Invoke custom plan provider to create the Plan node represented by the
+ * CustomPath.
+ */
+ plan = best_path->methods->PlanCustomPath(root, rel, best_path, tlist,
+ scan_clauses);
+
+ /*
+ * NOTE: unlike create_foreignscan_plan(), it is the responsibility of the
+ * custom plan provider to replace outer-relation variables with nestloop
+ * params, because we cannot know what expression trees may be held in
+ * private fields.
+ */
+
+ /*
+ * Copy cost data from Path to Plan; no need to make custom-plan providers
+ * do this
+ */
+ copy_path_costsize(plan, &best_path->path);
+
+ return plan;
+}
+
/*****************************************************************************
*
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index bbc68a05a6c..e42972750b9 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -587,12 +587,13 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
fix_scan_list(root, cscan->scan.plan.targetlist, rtoffset);
cscan->scan.plan.qual =
fix_scan_list(root, cscan->scan.plan.qual, rtoffset);
+
/*
- * The core implementation applies the routine to fixup
- * varno on the target-list and scan qualifier.
- * If custom-scan has additional expression nodes on its
- * private fields, it has to apply same fixup on them.
- * Otherwise, the custom-plan provider can skip this callback.
+ * The core implementation applies the routine to fixup varno
+ * on the target-list and scan qualifier. If custom-scan has
+ * additional expression nodes on its private fields, it has
+ * to apply same fixup on them. Otherwise, the custom-plan
+ * provider can skip this callback.
*/
if (cscan->methods->SetCustomScanRef)
cscan->methods->SetCustomScanRef(root, cscan, rtoffset);
@@ -1083,7 +1084,7 @@ copyVar(Var *var)
* We assume it's okay to update opcode info in-place. So this could possibly
* scribble on the planner's input data structures, but it's OK.
*/
-void
+static void
fix_expr_common(PlannerInfo *root, Node *node)
{
/* We assume callers won't call us on a NULL pointer */
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 6f1c6cfb2aa..121b9ff3e45 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -1929,10 +1929,10 @@ reparameterize_path(PlannerInfo *root, Path *path,
}
/*****************************************************************************
- * creation of custom-plan paths
+ * creation of custom-plan paths
*****************************************************************************/
-static List *custom_path_providers = NIL;
+static List *custom_path_providers = NIL;
/*
* register_custom_path_provider
@@ -1942,12 +1942,13 @@ static List *custom_path_providers = NIL;
* methods of scanning a relation.
*/
void
-register_custom_path_provider(CustomPathMethods *cpp_methods)
+register_custom_path_provider(const CustomPathMethods *cpp_methods)
{
- MemoryContext oldcxt;
+ MemoryContext oldcxt;
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
- custom_path_providers = lappend(custom_path_providers, cpp_methods);
+ custom_path_providers = lappend(custom_path_providers,
+ (void *) cpp_methods);
MemoryContextSwitchTo(oldcxt);
}
@@ -1963,9 +1964,9 @@ create_customscan_paths(PlannerInfo *root,
RelOptInfo *baserel,
RangeTblEntry *rte)
{
- ListCell *cell;
+ ListCell *cell;
- foreach (cell, custom_path_providers)
+ foreach(cell, custom_path_providers)
{
const CustomPathMethods *cpp_methods = lfirst(cell);
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index f1b65b4d050..ed3ae39b66d 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -16,7 +16,6 @@
#include "executor/execdesc.h"
#include "nodes/parsenodes.h"
-#include "nodes/relation.h"
#include "utils/lockwaitpolicy.h"
@@ -101,10 +100,12 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
/*
* prototypes from functions in execAmi.c
*/
+struct Path; /* avoid including relation.h here */
+
extern void ExecReScan(PlanState *node);
extern void ExecMarkPos(PlanState *node);
extern void ExecRestrPos(PlanState *node);
-extern bool ExecSupportsMarkRestore(Path *pathnode);
+extern bool ExecSupportsMarkRestore(struct Path *pathnode);
extern bool ExecSupportsBackwardScan(Plan *node);
extern bool ExecMaterializesOutput(NodeTag plantype);
diff --git a/src/include/executor/nodeCustom.h b/src/include/executor/nodeCustom.h
index 1736d48bfaf..e6f125544bc 100644
--- a/src/include/executor/nodeCustom.h
+++ b/src/include/executor/nodeCustom.h
@@ -11,14 +11,14 @@
*/
#ifndef NODECUSTOM_H
#define NODECUSTOM_H
-#include "nodes/plannodes.h"
+
#include "nodes/execnodes.h"
/*
* General executor code
*/
extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan,
- EState *estate, int eflags);
+ EState *estate, int eflags);
extern TupleTableSlot *ExecCustomScan(CustomScanState *node);
extern Node *MultiExecCustomScan(CustomScanState *node);
extern void ExecEndCustomScan(CustomScanState *node);
@@ -27,4 +27,4 @@ extern void ExecReScanCustomScan(CustomScanState *node);
extern void ExecCustomMarkPos(CustomScanState *node);
extern void ExecCustomRestrPos(CustomScanState *node);
-#endif /* NODECUSTOM_H */
+#endif /* NODECUSTOM_H */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 8c8c01f1cd2..40fb8243ab4 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -19,7 +19,6 @@
#include "executor/instrument.h"
#include "nodes/params.h"
#include "nodes/plannodes.h"
-#include "nodes/relation.h"
#include "utils/reltrigger.h"
#include "utils/sortsupport.h"
#include "utils/tuplestore.h"
@@ -1512,39 +1511,39 @@ typedef struct ForeignScanState
* CustomScan nodes are used to execute custom code within executor.
* ----------------
*/
-struct CustomExecMethods;
-struct ExplainState; /* to avoid to include explain.h here */
-
-typedef struct CustomScanState
-{
- ScanState ss;
- uint32 flags; /* mask of CUSTOMPATH_* flags defined in relation.h*/
- const struct CustomExecMethods *methods;
-} CustomScanState;
+struct ExplainState; /* avoid including explain.h here */
+struct CustomScanState;
typedef struct CustomExecMethods
{
- const char *CustomName;
+ const char *CustomName;
/* EXECUTOR methods */
- void (*BeginCustomScan)(CustomScanState *node,
- EState *estate,
- int eflags);
- TupleTableSlot *(*ExecCustomScan)(CustomScanState *node);
- void (*EndCustomScan)(CustomScanState *node);
- void (*ReScanCustomScan)(CustomScanState *node);
- void (*MarkPosCustomScan)(CustomScanState *node);
- void (*RestrPosCustomScan)(CustomScanState *node);
+ void (*BeginCustomScan) (struct CustomScanState *node,
+ EState *estate,
+ int eflags);
+ TupleTableSlot *(*ExecCustomScan) (struct CustomScanState *node);
+ void (*EndCustomScan) (struct CustomScanState *node);
+ void (*ReScanCustomScan) (struct CustomScanState *node);
+ void (*MarkPosCustomScan) (struct CustomScanState *node);
+ void (*RestrPosCustomScan) (struct CustomScanState *node);
/* EXPLAIN support */
- void (*ExplainCustomScan)(CustomScanState *node,
- List *ancestors,
- struct ExplainState *es);
- Node *(*GetSpecialCustomVar)(CustomScanState *node,
- Var *varnode,
- PlanState **child_ps);
+ void (*ExplainCustomScan) (struct CustomScanState *node,
+ List *ancestors,
+ struct ExplainState *es);
+ Node *(*GetSpecialCustomVar) (struct CustomScanState *node,
+ Var *varnode,
+ PlanState **child_ps);
} CustomExecMethods;
+typedef struct CustomScanState
+{
+ ScanState ss;
+ uint32 flags; /* mask of CUSTOMPATH_* flags, see relation.h */
+ const CustomExecMethods *methods;
+} CustomScanState;
+
/* ----------------------------------------------------------------
* Join State Information
* ----------------------------------------------------------------
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 9dbb91cb90d..dd300b1a191 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -18,7 +18,6 @@
#include "lib/stringinfo.h"
#include "nodes/bitmapset.h"
#include "nodes/primnodes.h"
-#include "nodes/relation.h"
#include "utils/lockwaitpolicy.h"
@@ -486,33 +485,36 @@ typedef struct ForeignScan
} ForeignScan;
/* ----------------
- * CustomScan node
+ * CustomScan node
* ----------------
*/
-struct CustomScanMethods;
-
-typedef struct CustomScan
-{
- Scan scan;
- uint32 flags; /* mask of CUSTOMPATH_* flags defined in relation.h */
- struct CustomScanMethods *methods;
-} CustomScan;
+struct PlannerInfo; /* avoid including relation.h here */
+struct CustomScan;
typedef struct CustomScanMethods
{
const char *CustomName;
- void (*SetCustomScanRef)(struct PlannerInfo *root,
- CustomScan *cscan,
- int rtoffset);
- void (*FinalizeCustomScan)(struct PlannerInfo *root,
- CustomScan *cscan,
- bool (*finalize_primnode)(),
- void *finalize_context);
- Node *(*CreateCustomScanState)(CustomScan *cscan);
- void (*TextOutCustomScan)(StringInfo str, const CustomScan *node);
- CustomScan *(*CopyCustomScan)(const CustomScan *from);
+
+ void (*SetCustomScanRef) (struct PlannerInfo *root,
+ struct CustomScan *cscan,
+ int rtoffset);
+ void (*FinalizeCustomScan) (struct PlannerInfo *root,
+ struct CustomScan *cscan,
+ bool (*finalize_primnode) (),
+ void *finalize_context);
+ Node *(*CreateCustomScanState) (struct CustomScan *cscan);
+ void (*TextOutCustomScan) (StringInfo str,
+ const struct CustomScan *node);
+ struct CustomScan *(*CopyCustomScan) (const struct CustomScan *from);
} CustomScanMethods;
+typedef struct CustomScan
+{
+ Scan scan;
+ uint32 flags; /* mask of CUSTOMPATH_* flags, see relation.h */
+ const CustomScanMethods *methods;
+} CustomScan;
+
/*
* ==========
* Join nodes
@@ -864,7 +866,7 @@ typedef struct PlanRowMark
Index prti; /* range table index of parent relation */
Index rowmarkId; /* unique identifier for resjunk columns */
RowMarkType markType; /* see enum above */
- LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED options */
+ LockWaitPolicy waitPolicy; /* NOWAIT and SKIP LOCKED options */
bool isParent; /* true if this is a "dummy" parent entry */
} PlanRowMark;
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 05cfbcd2aa1..7953bf7ed6c 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -897,34 +897,34 @@ typedef struct ForeignPath
* the structure declared here; providers are expected to make it the first
* element in a larger structure.
*/
-
-struct CustomPathMethods;
-struct Plan; /* not to include plannodes.h here */
+struct CustomPath;
#define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001
#define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002
-typedef struct CustomPath
-{
- Path path;
- uint32 flags;
- const struct CustomPathMethods *methods;
-} CustomPath;
-
typedef struct CustomPathMethods
{
const char *CustomName;
- void (*CreateCustomScanPath)(PlannerInfo *root,
- RelOptInfo *baserel,
- RangeTblEntry *rte);
- struct Plan *(*PlanCustomPath)(PlannerInfo *root,
- RelOptInfo *rel,
- CustomPath *best_path,
- List *tlist,
- List *clauses);
- void (*TextOutCustomPath)(StringInfo str, const CustomPath *node);
+
+ void (*CreateCustomScanPath) (PlannerInfo *root,
+ RelOptInfo *baserel,
+ RangeTblEntry *rte);
+ struct Plan *(*PlanCustomPath) (PlannerInfo *root,
+ RelOptInfo *rel,
+ struct CustomPath *best_path,
+ List *tlist,
+ List *clauses);
+ void (*TextOutCustomPath) (StringInfo str,
+ const struct CustomPath *node);
} CustomPathMethods;
+typedef struct CustomPath
+{
+ Path path;
+ uint32 flags; /* mask of CUSTOMPATH_* flags, see above */
+ const CustomPathMethods *methods;
+} CustomPath;
+
/*
* AppendPath represents an Append plan, ie, successive execution of
* several member plans.
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 2b67ae6187b..0f2882986c0 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -131,11 +131,11 @@ extern Path *reparameterize_path(PlannerInfo *root, Path *path,
/*
* Interface definition of custom-scan providers
*/
-extern void register_custom_path_provider(CustomPathMethods *cpp_methods);
+extern void register_custom_path_provider(const CustomPathMethods *cpp_methods);
extern void create_customscan_paths(PlannerInfo *root,
- RelOptInfo *baserel,
- RangeTblEntry *rte);
+ RelOptInfo *baserel,
+ RangeTblEntry *rte);
/*
* prototypes for relnode.c
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index c97c5777a07..d6dae8e738e 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -130,9 +130,8 @@ extern bool query_is_distinct_for(Query *query, List *colnos, List *opids);
* prototypes for plan/setrefs.c
*/
extern Plan *set_plan_references(PlannerInfo *root, Plan *plan);
-extern void fix_opfuncids(Node *node);
extern Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset);
-extern void fix_expr_common(PlannerInfo *root, Node *node);
+extern void fix_opfuncids(Node *node);
extern void set_opfuncid(OpExpr *opexpr);
extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
extern void record_plan_function_dependency(PlannerInfo *root, Oid funcid);