diff --git a/doc/src/sgml/custom-scan.sgml b/doc/src/sgml/custom-scan.sgml new file mode 100644 index 0000000000..8a4a3dfcfe --- /dev/null +++ b/doc/src/sgml/custom-scan.sgml @@ -0,0 +1,285 @@ + + + + Writing A Custom Scan Provider + + + 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. + + + + diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index f03b72ab1d..89fff7739e 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -93,6 +93,7 @@ + diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index a648a4c5f6..e378d6978d 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -242,6 +242,7 @@ &nls; &plhandler; &fdwhandler; + &custom-scan; &geqo; &indexam; &gist;