1
<!-- doc/src/sgml/fdwhandler.sgml -->
3
<chapter id="fdwhandler">
4
<title>Writing A Foreign Data Wrapper</title>
6
<indexterm zone="fdwhandler">
7
<primary>foreign data wrapper</primary>
8
<secondary>handler for</secondary>
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.
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">.
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
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.
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.
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
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.
68
<sect1 id="fdw-routines">
69
<title>Foreign Data Wrapper Callback Routines</title>
72
The FDW handler function returns a palloc'd <structname>FdwRoutine</>
73
struct containing pointers to the following callback functions:
79
PlanForeignScan (Oid foreigntableid,
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
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.)
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->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->reltargetlist</> can be used to determine which
104
columns need to be fetched.
108
In addition to returning cost estimates, the function should update
109
<literal>baserel->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->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->width</> if
114
it can compute a better estimate of the average result row width.
120
ExplainForeignScan (ForeignScanState *node,
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
137
BeginForeignScan (ForeignScanState *node,
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</>).
153
Note that when <literal>(eflags & 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</>.
162
IterateForeignScan (ForeignScanState *node);
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</>.
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.
185
ReScanForeignScan (ForeignScanState *node);
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.
196
EndForeignScan (ForeignScanState *node);
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.
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.