~ubuntu-branches/ubuntu/precise/postgresql-9.1/precise-security

« back to all changes in this revision

Viewing changes to doc/src/sgml/fdwhandler.sgml

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!-- doc/src/sgml/fdwhandler.sgml -->
 
2
 
 
3
 <chapter id="fdwhandler">
 
4
   <title>Writing A Foreign Data Wrapper</title>
 
5
 
 
6
   <indexterm zone="fdwhandler">
 
7
    <primary>foreign data wrapper</primary>
 
8
    <secondary>handler for</secondary>
 
9
   </indexterm>
 
10
 
 
11
   <para>
 
12
    All operations on a foreign table are handled through its foreign data
 
13
    wrapper, which consists of a set of functions that the planner and
 
14
    executor call. The foreign data wrapper is responsible for fetching
 
15
    data from the remote data source and returning it to the
 
16
    <productname>PostgreSQL</productname> executor. This chapter outlines how
 
17
    to write a new foreign data wrapper.
 
18
   </para>
 
19
 
 
20
   <para>
 
21
    The FDW author needs to implement a handler function, and optionally
 
22
    a validator function. Both functions must be written in a compiled
 
23
    language such as C, using the version-1 interface.
 
24
    For details on C language calling conventions and dynamic loading,
 
25
    see <xref linkend="xfunc-c">.
 
26
   </para>
 
27
 
 
28
   <para>
 
29
    The handler function simply returns a struct of function pointers to
 
30
    callback functions that will be called by the planner and executor.
 
31
    Most of the effort in writing an FDW is in implementing these callback
 
32
    functions.
 
33
    The handler function must be registered with
 
34
    <productname>PostgreSQL</productname> as taking no arguments and returning
 
35
    the special pseudo-type <type>fdw_handler</type>.
 
36
    The callback functions are plain C functions and are not visible or
 
37
    callable at the SQL level.
 
38
   </para>
 
39
 
 
40
   <para>
 
41
    The validator function is responsible for validating options given in the
 
42
    <command>CREATE FOREIGN DATA WRAPPER</command>, <command>CREATE
 
43
    SERVER</command> and <command>CREATE FOREIGN TABLE</command> commands.
 
44
    The validator function must be registered as taking two arguments, a text
 
45
    array containing the options to be validated, and an OID representing the
 
46
    type of object the options are associated with (in the form of the OID
 
47
    of the system catalog the object would be stored in).  If no validator
 
48
    function is supplied, the options are not checked at object creation time.
 
49
   </para>
 
50
 
 
51
   <para>
 
52
    The foreign data wrappers included in the standard distribution are good
 
53
    references when trying to write your own.  Look into the
 
54
    <filename>contrib/file_fdw</> subdirectory of the source tree.
 
55
    The <xref linkend="sql-createforeigndatawrapper"> reference page also has
 
56
    some useful details.
 
57
   </para>
 
58
 
 
59
   <note>
 
60
    <para>
 
61
     The SQL standard specifies an interface for writing foreign data wrappers.
 
62
     However, PostgreSQL does not implement that API, because the effort to
 
63
     accommodate it into PostgreSQL would be large, and the standard API hasn't
 
64
     gained wide adoption anyway.
 
65
    </para>
 
66
   </note>
 
67
 
 
68
   <sect1 id="fdw-routines">
 
69
    <title>Foreign Data Wrapper Callback Routines</title>
 
70
 
 
71
    <para>
 
72
     The FDW handler function returns a palloc'd <structname>FdwRoutine</>
 
73
     struct containing pointers to the following callback functions:
 
74
    </para>
 
75
 
 
76
    <para>
 
77
<programlisting>
 
78
FdwPlan *
 
79
PlanForeignScan (Oid foreigntableid,
 
80
                 PlannerInfo *root,
 
81
                 RelOptInfo *baserel);
 
82
</programlisting>
 
83
 
 
84
     Plan a scan on a foreign table. This is called when a query is planned.
 
85
     <literal>foreigntableid</> is the <structname>pg_class</> OID of the
 
86
     foreign table.  <literal>root</> is the planner's global information
 
87
     about the query, and <literal>baserel</> is the planner's information
 
88
     about this table.
 
89
     The function must return a palloc'd struct that contains cost estimates
 
90
     plus any FDW-private information that is needed to execute the foreign
 
91
     scan at a later time.  (Note that the private information must be
 
92
     represented in a form that <function>copyObject</> knows how to copy.)
 
93
    </para>
 
94
 
 
95
    <para>
 
96
     The information in <literal>root</> and <literal>baserel</> can be used
 
97
     to reduce the amount of information that has to be fetched from the
 
98
     foreign table (and therefore reduce the cost estimate).
 
99
     <literal>baserel-&gt;baserestrictinfo</> is particularly interesting, as
 
100
     it contains restriction quals (<literal>WHERE</> clauses) that can be
 
101
     used to filter the rows to be fetched.  (The FDW is not required to
 
102
     enforce these quals, as the finished plan will recheck them anyway.)
 
103
     <literal>baserel-&gt;reltargetlist</> can be used to determine which
 
104
     columns need to be fetched.
 
105
    </para>
 
106
 
 
107
    <para>
 
108
     In addition to returning cost estimates, the function should update
 
109
     <literal>baserel-&gt;rows</> to be the expected number of rows returned
 
110
     by the scan, after accounting for the filtering done by the restriction
 
111
     quals.  The initial value of <literal>baserel-&gt;rows</> is just a
 
112
     constant default estimate, which should be replaced if at all possible.
 
113
     The function may also choose to update <literal>baserel-&gt;width</> if
 
114
     it can compute a better estimate of the average result row width.
 
115
    </para>
 
116
 
 
117
    <para>
 
118
<programlisting>
 
119
void
 
120
ExplainForeignScan (ForeignScanState *node,
 
121
                    ExplainState *es);
 
122
</programlisting>
 
123
 
 
124
     Print additional <command>EXPLAIN</> output for a foreign table scan.
 
125
     This can just return if there is no need to print anything.
 
126
     Otherwise, it should call <function>ExplainPropertyText</> and
 
127
     related functions to add fields to the <command>EXPLAIN</> output.
 
128
     The flag fields in <literal>es</> can be used to determine what to
 
129
     print, and the state of the <structname>ForeignScanState</> node
 
130
     can be inspected to provide runtime statistics in the <command>EXPLAIN
 
131
     ANALYZE</> case.
 
132
    </para>
 
133
 
 
134
    <para>
 
135
<programlisting>
 
136
void
 
137
BeginForeignScan (ForeignScanState *node,
 
138
                  int eflags);
 
139
</programlisting>
 
140
 
 
141
     Begin executing a foreign scan. This is called during executor startup.
 
142
     It should perform any initialization needed before the scan can start.
 
143
     The <structname>ForeignScanState</> node has already been created, but
 
144
     its <structfield>fdw_state</> field is still NULL.  Information about
 
145
     the table to scan is accessible through the
 
146
     <structname>ForeignScanState</> node (in particular, from the underlying
 
147
     <structname>ForeignScan</> plan node, which contains a pointer to the
 
148
     <structname>FdwPlan</> structure returned by
 
149
     <function>PlanForeignScan</>).
 
150
    </para>
 
151
 
 
152
    <para>
 
153
     Note that when <literal>(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</> is
 
154
     true, this function should not perform any externally-visible actions;
 
155
     it should only do the minimum required to make the node state valid
 
156
     for <function>ExplainForeignScan</> and <function>EndForeignScan</>.
 
157
    </para>
 
158
 
 
159
    <para>
 
160
<programlisting>
 
161
TupleTableSlot *
 
162
IterateForeignScan (ForeignScanState *node);
 
163
</programlisting>
 
164
 
 
165
     Fetch one row from the foreign source, returning it in a tuple table slot
 
166
     (the node's <structfield>ScanTupleSlot</> should be used for this
 
167
     purpose).  Return NULL if no more rows are available.  The tuple table
 
168
     slot infrastructure allows either a physical or virtual tuple to be
 
169
     returned; in most cases the latter choice is preferable from a
 
170
     performance standpoint.  Note that this is called in a short-lived memory
 
171
     context that will be reset between invocations.  Create a memory context
 
172
     in <function>BeginForeignScan</> if you need longer-lived storage, or use
 
173
     the <structfield>es_query_cxt</> of the node's <structname>EState</>.
 
174
    </para>
 
175
 
 
176
    <para>
 
177
     The rows returned must match the column signature of the foreign table
 
178
     being scanned.  If you choose to optimize away fetching columns that
 
179
     are not needed, you should insert nulls in those column positions.
 
180
    </para>
 
181
 
 
182
    <para>
 
183
<programlisting>
 
184
void
 
185
ReScanForeignScan (ForeignScanState *node);
 
186
</programlisting>
 
187
 
 
188
     Restart the scan from the beginning.  Note that any parameters the
 
189
     scan depends on may have changed value, so the new scan does not
 
190
     necessarily return exactly the same rows.
 
191
    </para>
 
192
 
 
193
    <para>
 
194
<programlisting>
 
195
void
 
196
EndForeignScan (ForeignScanState *node);
 
197
</programlisting>
 
198
 
 
199
     End the scan and release resources.  It is normally not important
 
200
     to release palloc'd memory, but for example open files and connections
 
201
     to remote servers should be cleaned up.
 
202
    </para>
 
203
 
 
204
    <para>
 
205
     The <structname>FdwRoutine</> and <structname>FdwPlan</> struct types
 
206
     are declared in <filename>src/include/foreign/fdwapi.h</>, which see
 
207
     for additional details.
 
208
    </para>
 
209
 
 
210
   </sect1>
 
211
 
 
212
 </chapter>