1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>60.1. Creating Custom Scan Paths</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-scan.html" title="Chapter 60. Writing a Custom Scan Provider" /><link rel="next" href="custom-scan-plan.html" title="60.2. Creating Custom Scan Plans" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">60.1. Creating Custom Scan Paths</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-scan.html" title="Chapter 60. Writing a Custom Scan Provider">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="custom-scan.html" title="Chapter 60. Writing a Custom Scan Provider">Up</a></td><th width="60%" align="center">Chapter 60. Writing a Custom Scan Provider</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-scan-plan.html" title="60.2. Creating Custom Scan Plans">Next</a></td></tr></table><hr /></div><div class="sect1" id="CUSTOM-SCAN-PATH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">60.1. Creating Custom Scan Paths <a href="#CUSTOM-SCAN-PATH" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="custom-scan-path.html#CUSTOM-SCAN-PATH-CALLBACKS">60.1.1. Custom Scan Path Callbacks</a></span></dt></dl></div><p>
3 A custom scan provider will typically add paths for a base relation by
4 setting the following hook, which is called after the core code has
5 generated all the access paths it can for the relation (except for
6 Gather and Gather Merge paths, which are made after this call so that
7 they can use partial paths added by the hook):
8 </p><pre class="programlisting">
9 typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
13 extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
16 Although this hook function can be used to examine, modify, or remove
17 paths generated by the core system, a custom scan provider will typically
18 confine itself to generating <code class="structname">CustomPath</code> objects and adding
19 them to <code class="literal">rel</code> using <code class="function">add_path</code>, or
20 <code class="function">add_partial_path</code> if they are partial paths. The
21 custom scan provider is responsible for initializing the
22 <code class="structname">CustomPath</code> object, which is declared like this:
23 </p><pre class="programlisting">
24 typedef struct CustomPath
29 List *custom_restrictinfo;
31 const CustomPathMethods *methods;
35 <code class="structfield">path</code> must be initialized as for any other path, including
36 the row-count estimate, start and total cost, and sort ordering provided
37 by this path. <code class="structfield">flags</code> is a bit mask, which
38 specifies whether the scan provider can support certain optional
39 capabilities. <code class="structfield">flags</code> should include
40 <code class="literal">CUSTOMPATH_SUPPORT_BACKWARD_SCAN</code> if the custom path can support
41 a backward scan, <code class="literal">CUSTOMPATH_SUPPORT_MARK_RESTORE</code> if it
42 can support mark and restore,
43 and <code class="literal">CUSTOMPATH_SUPPORT_PROJECTION</code> if it can perform
44 projections. (If <code class="literal">CUSTOMPATH_SUPPORT_PROJECTION</code> is not
45 set, the scan node will only be asked to produce Vars of the scanned
46 relation; while if that flag is set, the scan node must be able to
47 evaluate scalar expressions over these Vars.)
48 An optional <code class="structfield">custom_paths</code> is a list of <code class="structname">Path</code>
49 nodes used by this custom-path node; these will be transformed into
50 <code class="structname">Plan</code> nodes by planner.
51 As described below, custom paths can be created for join relations as
52 well. In such a case, <code class="structfield">custom_restrictinfo</code>
53 should be used to store the set of join clauses to apply to the join the
54 custom path replaces. Otherwise it should be NIL.
55 <code class="structfield">custom_private</code> can be used to store the custom path's
56 private data. Private data should be stored in a form that can be handled
57 by <code class="literal">nodeToString</code>, so that debugging routines that attempt to
58 print the custom path will work as designed. <code class="structfield">methods</code> must
59 point to a (usually statically allocated) object implementing the required
60 custom path methods, which are further detailed below.
62 A custom scan provider can also provide join paths. Just as for base
63 relations, such a path must produce the same output as would normally be
64 produced by the join it replaces. To do this, the join provider should
65 set the following hook, and then within the hook function,
66 create <code class="structname">CustomPath</code> path(s) for the join relation.
67 </p><pre class="programlisting">
68 typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
73 JoinPathExtraData *extra);
74 extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
77 This hook will be invoked repeatedly for the same join relation, with
78 different combinations of inner and outer relations; it is the
79 responsibility of the hook to minimize duplicated work.
81 Note also that the set of join clauses to apply to the join,
82 which is passed as <code class="literal">extra->restrictlist</code>, varies
83 depending on the combination of inner and outer relations. A
84 <code class="structname">CustomPath</code> path generated for the
85 <code class="literal">joinrel</code> must contain the set of join clauses it uses,
86 which will be used by the planner to convert the
87 <code class="structname">CustomPath</code> path into a plan, if it is selected
88 by the planner as the best path for the <code class="literal">joinrel</code>.
89 </p><div class="sect2" id="CUSTOM-SCAN-PATH-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">60.1.1. Custom Scan Path Callbacks <a href="#CUSTOM-SCAN-PATH-CALLBACKS" class="id_link">#</a></h3></div></div></div><p>
90 </p><pre class="programlisting">
91 Plan *(*PlanCustomPath) (PlannerInfo *root,
93 CustomPath *best_path,
98 Convert a custom path to a finished plan. The return value will generally
99 be a <code class="literal">CustomScan</code> object, which the callback must allocate and
100 initialize. See <a class="xref" href="custom-scan-plan.html" title="60.2. Creating Custom Scan Plans">Section 60.2</a> for more details.
102 </p><pre class="programlisting">
103 List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
104 List *custom_private,
105 RelOptInfo *child_rel);
107 This callback is called while converting a path parameterized by the
108 top-most parent of the given child relation <code class="literal">child_rel</code>
109 to be parameterized by the child relation. The callback is used to
110 reparameterize any paths or translate any expression nodes saved in the
111 given <code class="literal">custom_private</code> member of a
112 <code class="structname">CustomPath</code>. The callback may use
113 <code class="literal">reparameterize_path_by_child</code>,
114 <code class="literal">adjust_appendrel_attrs</code> or
115 <code class="literal">adjust_appendrel_attrs_multilevel</code> as required.
116 </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-scan.html" title="Chapter 60. Writing a Custom Scan Provider">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="custom-scan.html" title="Chapter 60. Writing a Custom Scan Provider">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-scan-plan.html" title="60.2. Creating Custom Scan Plans">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 60. Writing a Custom Scan Provider </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 60.2. Creating Custom Scan Plans</td></tr></table></div></body></html>