--- /dev/null
+
+
+
+
Writing A Custom Scan Provider
+
+
+ handler for
+
+
+
PostgreSQL> supports a set of experimental facilities which
+ are intended to allow extension modules to add new scan types to the system.
+ Unlike a foreign data wrapper>, which is only
+ responsible for knowing how to scan its own foreign tables, a custom scan
+ provider can provide an alternative method of scanning any relation in the
+ system. Typically, the motivation for writing a custom scan provider will
+ be to allow the use of some optimization not supported by the core
+ system, such as caching or some form of hardware acceleration. This chapter
+ outlines how to write a new custom scan provider.
+
+
+ Implementing a new type of custom scan is a three-step process. First,
+ during planning, it is necessary to generate access paths representing a
+ scan using the proposed strategy. Second, if one of those access paths
+ is selected by the planner as the optimal strategy for scanning a
+ particular relation, the access path must be converted to a plan.
+ Finally, it must be possible to execute the plan and generate the same
+ results that would have been generated for any other access path targeting
+ the same relation.
+
+
+
+
Implementing Custom Paths
+
+ A custom scan provider will typically add paths by setting the following
+ hook, which is called after the core code has generated what it believes
+ to be the complete and correct set of access paths for the relation.
+typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
+ RelOptInfo *rel,
+ Index rti,
+ RangeTblEntry *rte);
+extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
+
+
+
+ Although this hook function can be used to examine, modify, or remove
+ paths generated by the core system, a custom scan provider will typically
+ confine itself to generating CustomPath> objects and adding
+ them to rel> using add_path>. The custom scan
+ provider is responsible for initializing the CustomPath>
+ object, which is declared like this:
+typedef struct CustomPath
+{
+ Path path;
+ uint32 flags;
+ List *custom_private;
+ const CustomPathMethods *methods;
+} CustomPath;
+
+
+
+ path> must be initialized as for any other path, including
+ the row-count estimate, start and total cost, and sort ordering provided
+ by this path. flags> is a bitmask, which should include
+ CUSTOMPATH_SUPPORT_BACKWARD_SCAN> if the custom path can support
+ a backward scan and CUSTOMPATH_SUPPORT_MARK_RESTORE> if it
+ can support mark and restore. Both capabilities are optional.
+ custom_private> can be used to store the custom path's
+ private data. Private data should be stored in a form that can be handled
+ by nodeToString>, so that debugging routines which attempt to
+ print the custom path will work as designed. methods> must
+ point to a (usually statically allocated) object implementing the required
+ custom path methods, of which there are currently only two, as further
+ detailed below.
+
+
+
+
Custom Path Callbacks
+
+Plan *(*PlanCustomPath) (PlannerInfo *root,
+ RelOptInfo *rel,
+ CustomPath *best_path,
+ List *tlist,
+ List *clauses);
+
+ Convert a custom path to a finished plan. The return value will generally
+ be a CustomScan> object, which the callback must allocate and
+ initialize. See for more details.
+
+
+void (*TextOutCustomPath) (StringInfo str,
+ const CustomPath *node);
+
+ Generate additional output when nodeToString> is invoked on
+ this custom path. This callback is optional. Since
+ nodeToString> will automatically dump all fields in the
+ structure that it can see, including custom_private>, this
+ is only useful if the CustomPath> is actually embedded in a
+ larger struct containing additional fields.
+
+
+
+
+
+
Implementing Custom Plans
+
+ A custom scan is represented in a finished plan tree using the following
+ structure:
+typedef struct CustomScan
+{
+ Scan scan;
+ uint32 flags;
+ List *custom_exprs;
+ List *custom_private;
+ const CustomScanMethods *methods;
+} CustomScan;
+
+
+
+ scan> must be initialized as for any other scan, including
+ estimated costs, target lists, qualifications, and so on.
+ flags> is a bitmask with the same meaning as in
+ CustomPath>. custom_exprs> should be used to
+ store expression trees that will need to be fixed up by
+ setrefs.c> and subselect.c>, while
+ custom_private> should be used to store other private data that
+ is only used by the custom scan provider itself. Plan trees must be able
+ to be duplicated using copyObject>, so all the data stored
+ within these two fields must consist of nodes that function can handle.
+ methods> must point to a (usually statically allocated)
+ object implementing the required custom scan methods, which are further
+ detailed below.
+
+
+
+
Custom Scan Callbacks
+Node *(*CreateCustomScanState) (CustomScan *cscan);
+
+ Allocate a CustomScanState> for this
+ CustomScan>. The actual allocation will often be larger than
+ required for an ordinary CustomScanState>, because many
+ scan types will wish to embed that as the first field of a large structure.
+ The value returned must have the node tag and methods>
+ set appropriately, but the other fields need not be initialized at this
+ stage; after ExecInitCustomScan> performs basic initialization,
+ the BeginCustomScan> callback will be invoked to give the
+ custom scan state a chance to do whatever else is needed.
+
+
+void (*TextOutCustomScan) (StringInfo str,
+ const CustomScan *node);
+
+ Generate additional output when nodeToString> is invoked on
+ this custom plan. This callback is optional. Since a
+ CustomScan> must be copyable by copyObject>,
+ custom scan providers cannot substitute a larger structure that embeds a
+ CustomScan> for the structure itself, as would be possible
+ for a CustomPath> or CustomScanState>.
+ Therefore, providing this callback is unlikely to be useful.
+
+
+
+
+
+
Implementing Custom Scans
+
+ When a CustomScan> is executed, its execution state is
+ represented by a CustomScanState>, which is declared as
+ follows.
+typedef struct CustomScanState
+{
+ ScanState ss;
+ uint32 flags;
+ const CustomExecMethods *methods;
+} CustomScanState;
+
+
+
+ ss> must be initialized as for any other scanstate;
+ flags> is a bitmask with the same meaning as in
+ CustomPath> and CustomScan>.
+ methods> must point to a (usually statically allocated)
+ object implementing the required custom scan state methods, which are
+ further detailed below. Typically, a CustomScanState>, which
+ need not support copyObject>, will actually be a larger
+ structure embedding the above as its first member.
+
+
+
+
Custom Execution-Time Callbacks
+
+void (*BeginCustomScan) (CustomScanState *node,
+ EState *estate,
+ int eflags);
+
+ Complete initialization of the supplied CustomScanState>.
+ Some initialization is performed by ExecInitCustomScan>, but
+ any private fields should be initialized here.
+
+
+TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
+
+ Fetch the next scan tuple. If any tuples remain, it should fill
+ ps_ResultTupleSlot> with the next tuple in the current scan
+ direction, and then return the tuple slot. If not,
+ NULL> or an empty slot should be returned.
+
+
+void (*EndCustomScan) (CustomScanState *node);
+
+ Clean up any private data associated with the CustomScanState>.
+ This method is required, but may not need to do anything if the associated
+ data does not exist or will be cleaned up automatically.
+
+
+void (*ReScanCustomScan) (CustomScanState *node);
+
+ Rewind the current scan to the beginning and prepare to rescan the
+ relation.
+
+
+void (*MarkPosCustomScan) (CustomScanState *node);
+
+ Save the current scan position so that it can subsequently be restored
+ by the RestrPosCustomScan> callback. This calback is optional,
+ and need only be supplied if
+ CUSTOMPATH_SUPPORT_MARK_RESTORE> flag is set.
+
+
+void (*RestrPosCustomScan) (CustomScanState *node);
+
+ Restore the previous scan position as saved by the
+ MarkPosCustomScan> callback. This callback is optional,
+ and need only be supplied if
+ CUSTOMPATH_SUPPORT_MARK_RESTORE> flag is set.
+
+
+void (*ExplainCustomScan) (CustomScanState *node,
+ List *ancestors,
+ ExplainState *es);
+
+ Output additional information on EXPLAIN> that involves
+ custom-scan node. This callback is optional. Common data stored in the
+ ScanState>, such as the target list and scan relation, will
+ be shown even without this callback, but the callback allows the display
+ of additional, private state.
+
+
+
+