1 <!-- doc/src/sgml/custom-scan.sgml -->
3 <chapter id="custom-scan">
4 <title>Writing A Custom Scan Provider</title>
6 <indexterm zone="custom-scan">
7 <primary>custom scan provider</primary>
8 <secondary>handler for</secondary>
12 <productname>PostgreSQL</> supports a set of experimental facilities which
13 are intended to allow extension modules to add new scan types to the system.
14 Unlike a <link linkend="fdwhandler">foreign data wrapper</>, which is only
15 responsible for knowing how to scan its own foreign tables, a custom scan
16 provider can provide an alternative method of scanning any relation in the
17 system. Typically, the motivation for writing a custom scan provider will
18 be to allow the use of some optimization not supported by the core
19 system, such as caching or some form of hardware acceleration. This chapter
20 outlines how to write a new custom scan provider.
24 Implementing a new type of custom scan is a three-step process. First,
25 during planning, it is necessary to generate access paths representing a
26 scan using the proposed strategy. Second, if one of those access paths
27 is selected by the planner as the optimal strategy for scanning a
28 particular relation, the access path must be converted to a plan.
29 Finally, it must be possible to execute the plan and generate the same
30 results that would have been generated for any other access path targeting
34 <sect1 id="custom-scan-path">
35 <title>Creating Custom Scan Paths</title>
38 A custom scan provider will typically add paths for a base relation by
39 setting the following hook, which is called after the core code has
40 generated what it believes to be the complete and correct set of access
41 paths for the relation.
43 typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
47 extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
52 Although this hook function can be used to examine, modify, or remove
53 paths generated by the core system, a custom scan provider will typically
54 confine itself to generating <structname>CustomPath</> objects and adding
55 them to <literal>rel</> using <function>add_path</>. The custom scan
56 provider is responsible for initializing the <structname>CustomPath</>
57 object, which is declared like this:
59 typedef struct CustomPath
65 const CustomPathMethods *methods;
71 <structfield>path</> must be initialized as for any other path, including
72 the row-count estimate, start and total cost, and sort ordering provided
73 by this path. <structfield>flags</> is a bit mask, which should include
74 <literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</> if the custom path can support
75 a backward scan and <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> if it
76 can support mark and restore. Both capabilities are optional.
77 An optional <structfield>custom_paths</> is a list of <structname>Path</>
78 nodes used by this custom-path node; these will be transformed into
79 <structname>Plan</> nodes by planner.
80 <structfield>custom_private</> can be used to store the custom path's
81 private data. Private data should be stored in a form that can be handled
82 by <literal>nodeToString</>, so that debugging routines that attempt to
83 print the custom path will work as designed. <structfield>methods</> must
84 point to a (usually statically allocated) object implementing the required
85 custom path methods, of which there is currently only one. The
86 <structfield>LibraryName</> and <structfield>SymbolName</> fields must also
87 be initialized so that the dynamic loader can resolve them to locate the
92 A custom scan provider can also provide join paths. Just as for base
93 relations, such a path must produce the same output as would normally be
94 produced by the join it replaces. To do this, the join provider should
95 set the following hook, and then within the hook function,
96 create <structname>CustomPath</> path(s) for the join relation.
98 typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
100 RelOptInfo *outerrel,
101 RelOptInfo *innerrel,
103 JoinPathExtraData *extra);
104 extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
107 This hook will be invoked repeatedly for the same join relation, with
108 different combinations of inner and outer relations; it is the
109 responsibility of the hook to minimize duplicated work.
112 <sect2 id="custom-scan-path-callbacks">
113 <title>Custom Scan Path Callbacks</title>
117 Plan *(*PlanCustomPath) (PlannerInfo *root,
119 CustomPath *best_path,
124 Convert a custom path to a finished plan. The return value will generally
125 be a <literal>CustomScan</> object, which the callback must allocate and
126 initialize. See <xref linkend="custom-scan-plan"> for more details.
131 <sect1 id="custom-scan-plan">
132 <title>Creating Custom Scan Plans</title>
135 A custom scan is represented in a finished plan tree using the following
138 typedef struct CustomScan
144 List *custom_private;
145 List *custom_scan_tlist;
146 Bitmapset *custom_relids;
147 const CustomScanMethods *methods;
153 <structfield>scan</> must be initialized as for any other scan, including
154 estimated costs, target lists, qualifications, and so on.
155 <structfield>flags</> is a bit mask with the same meaning as in
156 <structname>CustomPath</>.
157 <structfield>custom_plans</> can be used to store child
158 <structname>Plan</> nodes.
159 <structfield>custom_exprs</> should be used to
160 store expression trees that will need to be fixed up by
161 <filename>setrefs.c</> and <filename>subselect.c</>, while
162 <structfield>custom_private</> should be used to store other private data
163 that is only used by the custom scan provider itself.
164 <structfield>custom_scan_tlist</> can be NIL when scanning a base
165 relation, indicating that the custom scan returns scan tuples that match
166 the base relation's row type. Otherwise it is a target list describing
167 the actual scan tuples. <structfield>custom_scan_tlist</> must be
168 provided for joins, and could be provided for scans if the custom scan
169 provider can compute some non-Var expressions.
170 <structfield>custom_relids</> is set by the core code to the set of
171 relations (range table indexes) that this scan node handles; except when
172 this scan is replacing a join, it will have only one member.
173 <structfield>methods</> must point to a (usually statically allocated)
174 object implementing the required custom scan methods, which are further
179 When a <structname>CustomScan</> scans a single relation,
180 <structfield>scan.scanrelid</> must be the range table index of the table
181 to be scanned. When it replaces a join, <structfield>scan.scanrelid</>
186 Plan trees must be able to be duplicated using <function>copyObject</>,
187 so all the data stored within the <quote>custom</> fields must consist of
188 nodes that that function can handle. Furthermore, custom scan providers
189 cannot substitute a larger structure that embeds
190 a <structname>CustomScan</> for the structure itself, as would be possible
191 for a <structname>CustomPath</> or <structname>CustomScanState</>.
194 <sect2 id="custom-scan-plan-callbacks">
195 <title>Custom Scan Plan Callbacks</title>
198 Node *(*CreateCustomScanState) (CustomScan *cscan);
200 Allocate a <structname>CustomScanState</> for this
201 <structname>CustomScan</>. The actual allocation will often be larger than
202 required for an ordinary <structname>CustomScanState</>, because many
203 providers will wish to embed that as the first field of a larger structure.
204 The value returned must have the node tag and <structfield>methods</>
205 set appropriately, but other fields should be left as zeroes at this
206 stage; after <function>ExecInitCustomScan</> performs basic initialization,
207 the <function>BeginCustomScan</> callback will be invoked to give the
208 custom scan provider a chance to do whatever else is needed.
213 <sect1 id="custom-scan-execution">
214 <title>Executing Custom Scans</title>
217 When a <structfield>CustomScan</> is executed, its execution state is
218 represented by a <structfield>CustomScanState</>, which is declared as
221 typedef struct CustomScanState
225 const CustomExecMethods *methods;
231 <structfield>ss</> is initialized as for any other scan state,
232 except that if the scan is for a join rather than a base relation,
233 <literal>ss.ss_currentRelation</> is left NULL.
234 <structfield>flags</> is a bit mask with the same meaning as in
235 <structname>CustomPath</> and <structname>CustomScan</>.
236 <structfield>methods</> must point to a (usually statically allocated)
237 object implementing the required custom scan state methods, which are
238 further detailed below. Typically, a <structname>CustomScanState</>, which
239 need not support <function>copyObject</>, will actually be a larger
240 structure embedding the above as its first member.
243 <sect2 id="custom-scan-execution-callbacks">
244 <title>Custom Scan Execution Callbacks</title>
248 void (*BeginCustomScan) (CustomScanState *node,
252 Complete initialization of the supplied <structname>CustomScanState</>.
253 Standard fields have been initialized by <function>ExecInitCustomScan</>,
254 but any private fields should be initialized here.
259 TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
261 Fetch the next scan tuple. If any tuples remain, it should fill
262 <literal>ps_ResultTupleSlot</> with the next tuple in the current scan
263 direction, and then return the tuple slot. If not,
264 <literal>NULL</> or an empty slot should be returned.
269 void (*EndCustomScan) (CustomScanState *node);
271 Clean up any private data associated with the <literal>CustomScanState</>.
272 This method is required, but it does not need to do anything if there is
273 no associated data or it will be cleaned up automatically.
278 void (*ReScanCustomScan) (CustomScanState *node);
280 Rewind the current scan to the beginning and prepare to rescan the
286 void (*MarkPosCustomScan) (CustomScanState *node);
288 Save the current scan position so that it can subsequently be restored
289 by the <function>RestrPosCustomScan</> callback. This callback is
290 optional, and need only be supplied if the
291 <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set.
296 void (*RestrPosCustomScan) (CustomScanState *node);
298 Restore the previous scan position as saved by the
299 <function>MarkPosCustomScan</> callback. This callback is optional,
300 and need only be supplied if the
301 <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</> flag is set.
306 Size (*EstimateDSMCustomScan) (CustomScanState *node,
307 ParallelContext *pcxt);
309 Estimate the amount of dynamic shared memory that will be required
310 for parallel operation. This may be higher than the amount that will
311 actually be used, but it must not be lower. The return value is in bytes.
312 This callback is optional, and need only be supplied if this custom
313 scan provider supports parallel execution.
318 void (*InitializeDSMCustomScan) (CustomScanState *node,
319 ParallelContext *pcxt,
322 Initialize the dynamic shared memory that will be required for parallel
323 operation; <literal>coordinate</> points to an amount of allocated space
324 equal to the return value of <function>EstimateDSMCustomScan</>.
325 This callback is optional, and need only be supplied if this custom
326 scan provider supports parallel execution.
331 void (*InitializeWorkerCustomScan) (CustomScanState *node,
335 Initialize a parallel worker's custom state based on the shared state
336 set up in the leader by <literal>InitializeDSMCustomScan</>.
337 This callback is optional, and needs only be supplied if this
338 custom path supports parallel execution.
343 void (*ShutdownCustomScan) (CustomScanState *node);
345 Release resources when it is anticipated the node will not be executed
346 to completion. This is not called in all cases; sometimes,
347 <literal>EndCustomScan</> may be called without this function having
348 been called first. Since the DSM segment used by parallel query is
349 destroyed just after this callback is invoked, custom scan providers that
350 wish to take some action before the DSM segment goes away should implement
356 void (*ExplainCustomScan) (CustomScanState *node,
360 Output additional information for <command>EXPLAIN</> of a custom-scan
361 plan node. This callback is optional. Common data stored in the
362 <structname>ScanState</>, such as the target list and scan relation, will
363 be shown even without this callback, but the callback allows the display
364 of additional, private state.