2 58.2. Foreign Data Wrapper Callback Routines #
4 58.2.1. FDW Routines for Scanning Foreign Tables
5 58.2.2. FDW Routines for Scanning Foreign Joins
6 58.2.3. FDW Routines for Planning Post-Scan/Join Processing
7 58.2.4. FDW Routines for Updating Foreign Tables
8 58.2.5. FDW Routines for TRUNCATE
9 58.2.6. FDW Routines for Row Locking
10 58.2.7. FDW Routines for EXPLAIN
11 58.2.8. FDW Routines for ANALYZE
12 58.2.9. FDW Routines for IMPORT FOREIGN SCHEMA
13 58.2.10. FDW Routines for Parallel Execution
14 58.2.11. FDW Routines for Asynchronous Execution
15 58.2.12. FDW Routines for Reparameterization of Paths
17 The FDW handler function returns a palloc'd FdwRoutine struct
18 containing pointers to the callback functions described below. The
19 scan-related functions are required, the rest are optional.
21 The FdwRoutine struct type is declared in src/include/foreign/fdwapi.h,
22 which see for additional details.
24 58.2.1. FDW Routines for Scanning Foreign Tables #
27 GetForeignRelSize(PlannerInfo *root,
31 Obtain relation size estimates for a foreign table. This is called at
32 the beginning of planning for a query that scans a foreign table. root
33 is the planner's global information about the query; baserel is the
34 planner's information about this table; and foreigntableid is the
35 pg_class OID of the foreign table. (foreigntableid could be obtained
36 from the planner data structures, but it's passed explicitly to save
39 This function should update baserel->rows to be the expected number of
40 rows returned by the table scan, after accounting for the filtering
41 done by the restriction quals. The initial value of baserel->rows is
42 just a constant default estimate, which should be replaced if at all
43 possible. The function may also choose to update baserel->width if it
44 can compute a better estimate of the average result row width. (The
45 initial value is based on column data types and on column average-width
46 values measured by the last ANALYZE.) Also, this function may update
47 baserel->tuples if it can compute a better estimate of the foreign
48 table's total row count. (The initial value is from pg_class.reltuples
49 which represents the total row count seen by the last ANALYZE; it will
50 be -1 if no ANALYZE has been done on this foreign table.)
52 See Section 58.4 for additional information.
55 GetForeignPaths(PlannerInfo *root,
59 Create possible access paths for a scan on a foreign table. This is
60 called during query planning. The parameters are the same as for
61 GetForeignRelSize, which has already been called.
63 This function must generate at least one access path (ForeignPath node)
64 for a scan on the foreign table and must call add_path to add each such
65 path to baserel->pathlist. It's recommended to use
66 create_foreignscan_path to build the ForeignPath nodes. The function
67 can generate multiple access paths, e.g., a path which has valid
68 pathkeys to represent a pre-sorted result. Each access path must
69 contain cost estimates, and can contain any FDW-private information
70 that is needed to identify the specific scan method intended.
72 See Section 58.4 for additional information.
75 GetForeignPlan(PlannerInfo *root,
78 ForeignPath *best_path,
83 Create a ForeignScan plan node from the selected foreign access path.
84 This is called at the end of query planning. The parameters are as for
85 GetForeignRelSize, plus the selected ForeignPath (previously produced
86 by GetForeignPaths, GetForeignJoinPaths, or GetForeignUpperPaths), the
87 target list to be emitted by the plan node, the restriction clauses to
88 be enforced by the plan node, and the outer subplan of the ForeignScan,
89 which is used for rechecks performed by RecheckForeignScan. (If the
90 path is for a join rather than a base relation, foreigntableid is
93 This function must create and return a ForeignScan plan node; it's
94 recommended to use make_foreignscan to build the ForeignScan node.
96 See Section 58.4 for additional information.
99 BeginForeignScan(ForeignScanState *node,
102 Begin executing a foreign scan. This is called during executor startup.
103 It should perform any initialization needed before the scan can start,
104 but not start executing the actual scan (that should be done upon the
105 first call to IterateForeignScan). The ForeignScanState node has
106 already been created, but its fdw_state field is still NULL.
107 Information about the table to scan is accessible through the
108 ForeignScanState node (in particular, from the underlying ForeignScan
109 plan node, which contains any FDW-private information provided by
110 GetForeignPlan). eflags contains flag bits describing the executor's
111 operating mode for this plan node.
113 Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is true, this function
114 should not perform any externally-visible actions; it should only do
115 the minimum required to make the node state valid for
116 ExplainForeignScan and EndForeignScan.
119 IterateForeignScan(ForeignScanState *node);
121 Fetch one row from the foreign source, returning it in a tuple table
122 slot (the node's ScanTupleSlot should be used for this purpose). Return
123 NULL if no more rows are available. The tuple table slot infrastructure
124 allows either a physical or virtual tuple to be returned; in most cases
125 the latter choice is preferable from a performance standpoint. Note
126 that this is called in a short-lived memory context that will be reset
127 between invocations. Create a memory context in BeginForeignScan if you
128 need longer-lived storage, or use the es_query_cxt of the node's
131 The rows returned must match the fdw_scan_tlist target list if one was
132 supplied, otherwise they must match the row type of the foreign table
133 being scanned. If you choose to optimize away fetching columns that are
134 not needed, you should insert nulls in those column positions, or else
135 generate a fdw_scan_tlist list with those columns omitted.
137 Note that PostgreSQL's executor doesn't care whether the rows returned
138 violate any constraints that were defined on the foreign table — but
139 the planner does care, and may optimize queries incorrectly if there
140 are rows visible in the foreign table that do not satisfy a declared
141 constraint. If a constraint is violated when the user has declared that
142 the constraint should hold true, it may be appropriate to raise an
143 error (just as you would need to do in the case of a data type
147 ReScanForeignScan(ForeignScanState *node);
149 Restart the scan from the beginning. Note that any parameters the scan
150 depends on may have changed value, so the new scan does not necessarily
151 return exactly the same rows.
154 EndForeignScan(ForeignScanState *node);
156 End the scan and release resources. It is normally not important to
157 release palloc'd memory, but for example open files and connections to
158 remote servers should be cleaned up.
160 58.2.2. FDW Routines for Scanning Foreign Joins #
162 If an FDW supports performing foreign joins remotely (rather than by
163 fetching both tables' data and doing the join locally), it should
164 provide this callback function:
167 GetForeignJoinPaths(PlannerInfo *root,
169 RelOptInfo *outerrel,
170 RelOptInfo *innerrel,
172 JoinPathExtraData *extra);
174 Create possible access paths for a join of two (or more) foreign tables
175 that all belong to the same foreign server. This optional function is
176 called during query planning. As with GetForeignPaths, this function
177 should generate ForeignPath path(s) for the supplied joinrel (use
178 create_foreign_join_path to build them), and call add_path to add these
179 paths to the set of paths considered for the join. But unlike
180 GetForeignPaths, it is not necessary that this function succeed in
181 creating at least one path, since paths involving local joining are
184 Note that this function will be invoked repeatedly for the same join
185 relation, with different combinations of inner and outer relations; it
186 is the responsibility of the FDW to minimize duplicated work.
188 Note also that the set of join clauses to apply to the join, which is
189 passed as extra->restrictlist, varies depending on the combination of
190 inner and outer relations. A ForeignPath path generated for the joinrel
191 must contain the set of join clauses it uses, which will be used by the
192 planner to convert the ForeignPath path into a plan, if it is selected
193 by the planner as the best path for the joinrel.
195 If a ForeignPath path is chosen for the join, it will represent the
196 entire join process; paths generated for the component tables and
197 subsidiary joins will not be used. Subsequent processing of the join
198 path proceeds much as it does for a path scanning a single foreign
199 table. One difference is that the scanrelid of the resulting
200 ForeignScan plan node should be set to zero, since there is no single
201 relation that it represents; instead, the fs_relids field of the
202 ForeignScan node represents the set of relations that were joined. (The
203 latter field is set up automatically by the core planner code, and need
204 not be filled by the FDW.) Another difference is that, because the
205 column list for a remote join cannot be found from the system catalogs,
206 the FDW must fill fdw_scan_tlist with an appropriate list of
207 TargetEntry nodes, representing the set of columns it will supply at
208 run time in the tuples it returns.
212 Beginning with PostgreSQL 16, fs_relids includes the rangetable indexes
213 of outer joins, if any were involved in this join. The new field
214 fs_base_relids includes only base relation indexes, and thus mimics
215 fs_relids's old semantics.
217 See Section 58.4 for additional information.
219 58.2.3. FDW Routines for Planning Post-Scan/Join Processing #
221 If an FDW supports performing remote post-scan/join processing, such as
222 remote aggregation, it should provide this callback function:
225 GetForeignUpperPaths(PlannerInfo *root,
226 UpperRelationKind stage,
227 RelOptInfo *input_rel,
228 RelOptInfo *output_rel,
231 Create possible access paths for upper relation processing, which is
232 the planner's term for all post-scan/join query processing, such as
233 aggregation, window functions, sorting, and table updates. This
234 optional function is called during query planning. Currently, it is
235 called only if all base relation(s) involved in the query belong to the
236 same FDW. This function should generate ForeignPath path(s) for any
237 post-scan/join processing that the FDW knows how to perform remotely
238 (use create_foreign_upper_path to build them), and call add_path to add
239 these paths to the indicated upper relation. As with
240 GetForeignJoinPaths, it is not necessary that this function succeed in
241 creating any paths, since paths involving local processing are always
244 The stage parameter identifies which post-scan/join step is currently
245 being considered. output_rel is the upper relation that should receive
246 paths representing computation of this step, and input_rel is the
247 relation representing the input to this step. The extra parameter
248 provides additional details, currently, it is set only for
249 UPPERREL_PARTIAL_GROUP_AGG or UPPERREL_GROUP_AGG, in which case it
250 points to a GroupPathExtraData structure; or for UPPERREL_FINAL, in
251 which case it points to a FinalPathExtraData structure. (Note that
252 ForeignPath paths added to output_rel would typically not have any
253 direct dependency on paths of the input_rel, since their processing is
254 expected to be done externally. However, examining paths previously
255 generated for the previous processing step can be useful to avoid
256 redundant planning work.)
258 See Section 58.4 for additional information.
260 58.2.4. FDW Routines for Updating Foreign Tables #
262 If an FDW supports writable foreign tables, it should provide some or
263 all of the following callback functions depending on the needs and
264 capabilities of the FDW:
267 AddForeignUpdateTargets(PlannerInfo *root,
269 RangeTblEntry *target_rte,
270 Relation target_relation);
272 UPDATE and DELETE operations are performed against rows previously
273 fetched by the table-scanning functions. The FDW may need extra
274 information, such as a row ID or the values of primary-key columns, to
275 ensure that it can identify the exact row to update or delete. To
276 support that, this function can add extra hidden, or “junk”, target
277 columns to the list of columns that are to be retrieved from the
278 foreign table during an UPDATE or DELETE.
280 To do that, construct a Var representing an extra value you need, and
281 pass it to add_row_identity_var, along with a name for the junk column.
282 (You can do this more than once if several columns are needed.) You
283 must choose a distinct junk column name for each different Var you
284 need, except that Vars that are identical except for the varno field
285 can and should share a column name. The core system uses the junk
286 column names tableoid for a table's tableoid column, ctid or ctidN for
287 ctid, wholerow for a whole-row Var marked with vartype = RECORD, and
288 wholerowN for a whole-row Var with vartype equal to the table's
289 declared row type. Re-use these names when you can (the planner will
290 combine duplicate requests for identical junk columns). If you need
291 another kind of junk column besides these, it might be wise to choose a
292 name prefixed with your extension name, to avoid conflicts against
295 If the AddForeignUpdateTargets pointer is set to NULL, no extra target
296 expressions are added. (This will make it impossible to implement
297 DELETE operations, though UPDATE may still be feasible if the FDW
298 relies on an unchanging primary key to identify rows.)
301 PlanForeignModify(PlannerInfo *root,
303 Index resultRelation,
306 Perform any additional planning actions needed for an insert, update,
307 or delete on a foreign table. This function generates the FDW-private
308 information that will be attached to the ModifyTable plan node that
309 performs the update action. This private information must have the form
310 of a List, and will be delivered to BeginForeignModify during the
313 root is the planner's global information about the query. plan is the
314 ModifyTable plan node, which is complete except for the fdwPrivLists
315 field. resultRelation identifies the target foreign table by its range
316 table index. subplan_index identifies which target of the ModifyTable
317 plan node this is, counting from zero; use this if you want to index
318 into per-target-relation substructures of the plan node.
320 See Section 58.4 for additional information.
322 If the PlanForeignModify pointer is set to NULL, no additional
323 plan-time actions are taken, and the fdw_private list delivered to
324 BeginForeignModify will be NIL.
327 BeginForeignModify(ModifyTableState *mtstate,
328 ResultRelInfo *rinfo,
333 Begin executing a foreign table modification operation. This routine is
334 called during executor startup. It should perform any initialization
335 needed prior to the actual table modifications. Subsequently,
336 ExecForeignInsert/ExecForeignBatchInsert, ExecForeignUpdate or
337 ExecForeignDelete will be called for tuple(s) to be inserted, updated,
340 mtstate is the overall state of the ModifyTable plan node being
341 executed; global data about the plan and execution state is available
342 via this structure. rinfo is the ResultRelInfo struct describing the
343 target foreign table. (The ri_FdwState field of ResultRelInfo is
344 available for the FDW to store any private state it needs for this
345 operation.) fdw_private contains the private data generated by
346 PlanForeignModify, if any. subplan_index identifies which target of the
347 ModifyTable plan node this is. eflags contains flag bits describing the
348 executor's operating mode for this plan node.
350 Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is true, this function
351 should not perform any externally-visible actions; it should only do
352 the minimum required to make the node state valid for
353 ExplainForeignModify and EndForeignModify.
355 If the BeginForeignModify pointer is set to NULL, no action is taken
356 during executor startup.
359 ExecForeignInsert(EState *estate,
360 ResultRelInfo *rinfo,
361 TupleTableSlot *slot,
362 TupleTableSlot *planSlot);
364 Insert one tuple into the foreign table. estate is global execution
365 state for the query. rinfo is the ResultRelInfo struct describing the
366 target foreign table. slot contains the tuple to be inserted; it will
367 match the row-type definition of the foreign table. planSlot contains
368 the tuple that was generated by the ModifyTable plan node's subplan; it
369 differs from slot in possibly containing additional “junk” columns.
370 (The planSlot is typically of little interest for INSERT cases, but is
371 provided for completeness.)
373 The return value is either a slot containing the data that was actually
374 inserted (this might differ from the data supplied, for example as a
375 result of trigger actions), or NULL if no row was actually inserted
376 (again, typically as a result of triggers). The passed-in slot can be
377 re-used for this purpose.
379 The data in the returned slot is used only if the INSERT statement has
380 a RETURNING clause or involves a view WITH CHECK OPTION; or if the
381 foreign table has an AFTER ROW trigger. Triggers require all columns,
382 but the FDW could choose to optimize away returning some or all columns
383 depending on the contents of the RETURNING clause or WITH CHECK OPTION
384 constraints. Regardless, some slot must be returned to indicate
385 success, or the query's reported row count will be wrong.
387 If the ExecForeignInsert pointer is set to NULL, attempts to insert
388 into the foreign table will fail with an error message.
390 Note that this function is also called when inserting routed tuples
391 into a foreign-table partition or executing COPY FROM on a foreign
392 table, in which case it is called in a different way than it is in the
393 INSERT case. See the callback functions described below that allow the
397 ExecForeignBatchInsert(EState *estate,
398 ResultRelInfo *rinfo,
399 TupleTableSlot **slots,
400 TupleTableSlot **planSlots,
403 Insert multiple tuples in bulk into the foreign table. The parameters
404 are the same for ExecForeignInsert except slots and planSlots contain
405 multiple tuples and *numSlots specifies the number of tuples in those
408 The return value is an array of slots containing the data that was
409 actually inserted (this might differ from the data supplied, for
410 example as a result of trigger actions.) The passed-in slots can be
411 re-used for this purpose. The number of successfully inserted tuples is
412 returned in *numSlots.
414 The data in the returned slot is used only if the INSERT statement
415 involves a view WITH CHECK OPTION; or if the foreign table has an AFTER
416 ROW trigger. Triggers require all columns, but the FDW could choose to
417 optimize away returning some or all columns depending on the contents
418 of the WITH CHECK OPTION constraints.
420 If the ExecForeignBatchInsert or GetForeignModifyBatchSize pointer is
421 set to NULL, attempts to insert into the foreign table will use
422 ExecForeignInsert. This function is not used if the INSERT has the
425 Note that this function is also called when inserting routed tuples
426 into a foreign-table partition or executing COPY FROM on a foreign
427 table, in which case it is called in a different way than it is in the
428 INSERT case. See the callback functions described below that allow the
432 GetForeignModifyBatchSize(ResultRelInfo *rinfo);
434 Report the maximum number of tuples that a single
435 ExecForeignBatchInsert call can handle for the specified foreign table.
436 The executor passes at most the given number of tuples to
437 ExecForeignBatchInsert. rinfo is the ResultRelInfo struct describing
438 the target foreign table. The FDW is expected to provide a foreign
439 server and/or foreign table option for the user to set this value, or
440 some hard-coded value.
442 If the ExecForeignBatchInsert or GetForeignModifyBatchSize pointer is
443 set to NULL, attempts to insert into the foreign table will use
447 ExecForeignUpdate(EState *estate,
448 ResultRelInfo *rinfo,
449 TupleTableSlot *slot,
450 TupleTableSlot *planSlot);
452 Update one tuple in the foreign table. estate is global execution state
453 for the query. rinfo is the ResultRelInfo struct describing the target
454 foreign table. slot contains the new data for the tuple; it will match
455 the row-type definition of the foreign table. planSlot contains the
456 tuple that was generated by the ModifyTable plan node's subplan. Unlike
457 slot, this tuple contains only the new values for columns changed by
458 the query, so do not rely on attribute numbers of the foreign table to
459 index into planSlot. Also, planSlot typically contains additional
460 “junk” columns. In particular, any junk columns that were requested by
461 AddForeignUpdateTargets will be available from this slot.
463 The return value is either a slot containing the row as it was actually
464 updated (this might differ from the data supplied, for example as a
465 result of trigger actions), or NULL if no row was actually updated
466 (again, typically as a result of triggers). The passed-in slot can be
467 re-used for this purpose.
469 The data in the returned slot is used only if the UPDATE statement has
470 a RETURNING clause or involves a view WITH CHECK OPTION; or if the
471 foreign table has an AFTER ROW trigger. Triggers require all columns,
472 but the FDW could choose to optimize away returning some or all columns
473 depending on the contents of the RETURNING clause or WITH CHECK OPTION
474 constraints. Regardless, some slot must be returned to indicate
475 success, or the query's reported row count will be wrong.
477 If the ExecForeignUpdate pointer is set to NULL, attempts to update the
478 foreign table will fail with an error message.
481 ExecForeignDelete(EState *estate,
482 ResultRelInfo *rinfo,
483 TupleTableSlot *slot,
484 TupleTableSlot *planSlot);
486 Delete one tuple from the foreign table. estate is global execution
487 state for the query. rinfo is the ResultRelInfo struct describing the
488 target foreign table. slot contains nothing useful upon call, but can
489 be used to hold the returned tuple. planSlot contains the tuple that
490 was generated by the ModifyTable plan node's subplan; in particular, it
491 will carry any junk columns that were requested by
492 AddForeignUpdateTargets. The junk column(s) must be used to identify
493 the tuple to be deleted.
495 The return value is either a slot containing the row that was deleted,
496 or NULL if no row was deleted (typically as a result of triggers). The
497 passed-in slot can be used to hold the tuple to be returned.
499 The data in the returned slot is used only if the DELETE query has a
500 RETURNING clause or the foreign table has an AFTER ROW trigger.
501 Triggers require all columns, but the FDW could choose to optimize away
502 returning some or all columns depending on the contents of the
503 RETURNING clause. Regardless, some slot must be returned to indicate
504 success, or the query's reported row count will be wrong.
506 If the ExecForeignDelete pointer is set to NULL, attempts to delete
507 from the foreign table will fail with an error message.
510 EndForeignModify(EState *estate,
511 ResultRelInfo *rinfo);
513 End the table update and release resources. It is normally not
514 important to release palloc'd memory, but for example open files and
515 connections to remote servers should be cleaned up.
517 If the EndForeignModify pointer is set to NULL, no action is taken
518 during executor shutdown.
520 Tuples inserted into a partitioned table by INSERT or COPY FROM are
521 routed to partitions. If an FDW supports routable foreign-table
522 partitions, it should also provide the following callback functions.
523 These functions are also called when COPY FROM is executed on a foreign
527 BeginForeignInsert(ModifyTableState *mtstate,
528 ResultRelInfo *rinfo);
530 Begin executing an insert operation on a foreign table. This routine is
531 called right before the first tuple is inserted into the foreign table
532 in both cases when it is the partition chosen for tuple routing and the
533 target specified in a COPY FROM command. It should perform any
534 initialization needed prior to the actual insertion. Subsequently,
535 ExecForeignInsert or ExecForeignBatchInsert will be called for tuple(s)
536 to be inserted into the foreign table.
538 mtstate is the overall state of the ModifyTable plan node being
539 executed; global data about the plan and execution state is available
540 via this structure. rinfo is the ResultRelInfo struct describing the
541 target foreign table. (The ri_FdwState field of ResultRelInfo is
542 available for the FDW to store any private state it needs for this
545 When this is called by a COPY FROM command, the plan-related global
546 data in mtstate is not provided and the planSlot parameter of
547 ExecForeignInsert subsequently called for each inserted tuple is NULL,
548 whether the foreign table is the partition chosen for tuple routing or
549 the target specified in the command.
551 If the BeginForeignInsert pointer is set to NULL, no action is taken
552 for the initialization.
554 Note that if the FDW does not support routable foreign-table partitions
555 and/or executing COPY FROM on foreign tables, this function or
556 ExecForeignInsert/ExecForeignBatchInsert subsequently called must throw
560 EndForeignInsert(EState *estate,
561 ResultRelInfo *rinfo);
563 End the insert operation and release resources. It is normally not
564 important to release palloc'd memory, but for example open files and
565 connections to remote servers should be cleaned up.
567 If the EndForeignInsert pointer is set to NULL, no action is taken for
571 IsForeignRelUpdatable(Relation rel);
573 Report which update operations the specified foreign table supports.
574 The return value should be a bit mask of rule event numbers indicating
575 which operations are supported by the foreign table, using the CmdType
576 enumeration; that is, (1 << CMD_UPDATE) = 4 for UPDATE, (1 <<
577 CMD_INSERT) = 8 for INSERT, and (1 << CMD_DELETE) = 16 for DELETE.
579 If the IsForeignRelUpdatable pointer is set to NULL, foreign tables are
580 assumed to be insertable, updatable, or deletable if the FDW provides
581 ExecForeignInsert, ExecForeignUpdate, or ExecForeignDelete
582 respectively. This function is only needed if the FDW supports some
583 tables that are updatable and some that are not. (Even then, it's
584 permissible to throw an error in the execution routine instead of
585 checking in this function. However, this function is used to determine
586 updatability for display in the information_schema views.)
588 Some inserts, updates, and deletes to foreign tables can be optimized
589 by implementing an alternative set of interfaces. The ordinary
590 interfaces for inserts, updates, and deletes fetch rows from the remote
591 server and then modify those rows one at a time. In some cases, this
592 row-by-row approach is necessary, but it can be inefficient. If it is
593 possible for the foreign server to determine which rows should be
594 modified without actually retrieving them, and if there are no local
595 structures which would affect the operation (row-level local triggers,
596 stored generated columns, or WITH CHECK OPTION constraints from parent
597 views), then it is possible to arrange things so that the entire
598 operation is performed on the remote server. The interfaces described
599 below make this possible.
602 PlanDirectModify(PlannerInfo *root,
604 Index resultRelation,
607 Decide whether it is safe to execute a direct modification on the
608 remote server. If so, return true after performing planning actions
609 needed for that. Otherwise, return false. This optional function is
610 called during query planning. If this function succeeds,
611 BeginDirectModify, IterateDirectModify and EndDirectModify will be
612 called at the execution stage, instead. Otherwise, the table
613 modification will be executed using the table-updating functions
614 described above. The parameters are the same as for PlanForeignModify.
616 To execute the direct modification on the remote server, this function
617 must rewrite the target subplan with a ForeignScan plan node that
618 executes the direct modification on the remote server. The operation
619 and resultRelation fields of the ForeignScan must be set appropriately.
620 operation must be set to the CmdType enumeration corresponding to the
621 statement kind (that is, CMD_UPDATE for UPDATE, CMD_INSERT for INSERT,
622 and CMD_DELETE for DELETE), and the resultRelation argument must be
623 copied to the resultRelation field.
625 See Section 58.4 for additional information.
627 If the PlanDirectModify pointer is set to NULL, no attempts to execute
628 a direct modification on the remote server are taken.
631 BeginDirectModify(ForeignScanState *node,
634 Prepare to execute a direct modification on the remote server. This is
635 called during executor startup. It should perform any initialization
636 needed prior to the direct modification (that should be done upon the
637 first call to IterateDirectModify). The ForeignScanState node has
638 already been created, but its fdw_state field is still NULL.
639 Information about the table to modify is accessible through the
640 ForeignScanState node (in particular, from the underlying ForeignScan
641 plan node, which contains any FDW-private information provided by
642 PlanDirectModify). eflags contains flag bits describing the executor's
643 operating mode for this plan node.
645 Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is true, this function
646 should not perform any externally-visible actions; it should only do
647 the minimum required to make the node state valid for
648 ExplainDirectModify and EndDirectModify.
650 If the BeginDirectModify pointer is set to NULL, no attempts to execute
651 a direct modification on the remote server are taken.
654 IterateDirectModify(ForeignScanState *node);
656 When the INSERT, UPDATE or DELETE query doesn't have a RETURNING
657 clause, just return NULL after a direct modification on the remote
658 server. When the query has the clause, fetch one result containing the
659 data needed for the RETURNING calculation, returning it in a tuple
660 table slot (the node's ScanTupleSlot should be used for this purpose).
661 The data that was actually inserted, updated or deleted must be stored
663 node->resultRelInfo->ri_projectReturning->pi_exprContext->ecxt_scantupl
664 e. Return NULL if no more rows are available. Note that this is called
665 in a short-lived memory context that will be reset between invocations.
666 Create a memory context in BeginDirectModify if you need longer-lived
667 storage, or use the es_query_cxt of the node's EState.
669 The rows returned must match the fdw_scan_tlist target list if one was
670 supplied, otherwise they must match the row type of the foreign table
671 being updated. If you choose to optimize away fetching columns that are
672 not needed for the RETURNING calculation, you should insert nulls in
673 those column positions, or else generate a fdw_scan_tlist list with
674 those columns omitted.
676 Whether the query has the clause or not, the query's reported row count
677 must be incremented by the FDW itself. When the query doesn't have the
678 clause, the FDW must also increment the row count for the
679 ForeignScanState node in the EXPLAIN ANALYZE case.
681 If the IterateDirectModify pointer is set to NULL, no attempts to
682 execute a direct modification on the remote server are taken.
685 EndDirectModify(ForeignScanState *node);
687 Clean up following a direct modification on the remote server. It is
688 normally not important to release palloc'd memory, but for example open
689 files and connections to the remote server should be cleaned up.
691 If the EndDirectModify pointer is set to NULL, no attempts to execute a
692 direct modification on the remote server are taken.
694 58.2.5. FDW Routines for TRUNCATE #
697 ExecForeignTruncate(List *rels,
698 DropBehavior behavior,
701 Truncate foreign tables. This function is called when TRUNCATE is
702 executed on a foreign table. rels is a list of Relation data structures
703 of foreign tables to truncate.
705 behavior is either DROP_RESTRICT or DROP_CASCADE indicating that the
706 RESTRICT or CASCADE option was requested in the original TRUNCATE
707 command, respectively.
709 If restart_seqs is true, the original TRUNCATE command requested the
710 RESTART IDENTITY behavior, otherwise the CONTINUE IDENTITY behavior was
713 Note that the ONLY options specified in the original TRUNCATE command
714 are not passed to ExecForeignTruncate. This behavior is similar to the
715 callback functions of SELECT, UPDATE and DELETE on a foreign table.
717 ExecForeignTruncate is invoked once per foreign server for which
718 foreign tables are to be truncated. This means that all foreign tables
719 included in rels must belong to the same server.
721 If the ExecForeignTruncate pointer is set to NULL, attempts to truncate
722 foreign tables will fail with an error message.
724 58.2.6. FDW Routines for Row Locking #
726 If an FDW wishes to support late row locking (as described in
727 Section 58.5), it must provide the following callback functions:
730 GetForeignRowMarkType(RangeTblEntry *rte,
731 LockClauseStrength strength);
733 Report which row-marking option to use for a foreign table. rte is the
734 RangeTblEntry node for the table and strength describes the lock
735 strength requested by the relevant FOR UPDATE/SHARE clause, if any. The
736 result must be a member of the RowMarkType enum type.
738 This function is called during query planning for each foreign table
739 that appears in an UPDATE, DELETE, or SELECT FOR UPDATE/SHARE query and
740 is not the target of UPDATE or DELETE.
742 If the GetForeignRowMarkType pointer is set to NULL, the ROW_MARK_COPY
743 option is always used. (This implies that RefetchForeignRow will never
744 be called, so it need not be provided either.)
746 See Section 58.5 for more information.
749 RefetchForeignRow(EState *estate,
752 TupleTableSlot *slot,
755 Re-fetch one tuple slot from the foreign table, after locking it if
756 required. estate is global execution state for the query. erm is the
757 ExecRowMark struct describing the target foreign table and the row lock
758 type (if any) to acquire. rowid identifies the tuple to be fetched.
759 slot contains nothing useful upon call, but can be used to hold the
760 returned tuple. updated is an output parameter.
762 This function should store the tuple into the provided slot, or clear
763 it if the row lock couldn't be obtained. The row lock type to acquire
764 is defined by erm->markType, which is the value previously returned by
765 GetForeignRowMarkType. (ROW_MARK_REFERENCE means to just re-fetch the
766 tuple without acquiring any lock, and ROW_MARK_COPY will never be seen
769 In addition, *updated should be set to true if what was fetched was an
770 updated version of the tuple rather than the same version previously
771 obtained. (If the FDW cannot be sure about this, always returning true
774 Note that by default, failure to acquire a row lock should result in
775 raising an error; returning with an empty slot is only appropriate if
776 the SKIP LOCKED option is specified by erm->waitPolicy.
778 The rowid is the ctid value previously read for the row to be
779 re-fetched. Although the rowid value is passed as a Datum, it can
780 currently only be a tid. The function API is chosen in hopes that it
781 may be possible to allow other data types for row IDs in future.
783 If the RefetchForeignRow pointer is set to NULL, attempts to re-fetch
784 rows will fail with an error message.
786 See Section 58.5 for more information.
789 RecheckForeignScan(ForeignScanState *node,
790 TupleTableSlot *slot);
792 Recheck that a previously-returned tuple still matches the relevant
793 scan and join qualifiers, and possibly provide a modified version of
794 the tuple. For foreign data wrappers which do not perform join
795 pushdown, it will typically be more convenient to set this to NULL and
796 instead set fdw_recheck_quals appropriately. When outer joins are
797 pushed down, however, it isn't sufficient to reapply the checks
798 relevant to all the base tables to the result tuple, even if all needed
799 attributes are present, because failure to match some qualifier might
800 result in some attributes going to NULL, rather than in no tuple being
801 returned. RecheckForeignScan can recheck qualifiers and return true if
802 they are still satisfied and false otherwise, but it can also store a
803 replacement tuple into the supplied slot.
805 To implement join pushdown, a foreign data wrapper will typically
806 construct an alternative local join plan which is used only for
807 rechecks; this will become the outer subplan of the ForeignScan. When a
808 recheck is required, this subplan can be executed and the resulting
809 tuple can be stored in the slot. This plan need not be efficient since
810 no base table will return more than one row; for example, it may
811 implement all joins as nested loops. The function
812 GetExistingLocalJoinPath may be used to search existing paths for a
813 suitable local join path, which can be used as the alternative local
814 join plan. GetExistingLocalJoinPath searches for an unparameterized
815 path in the path list of the specified join relation. (If it does not
816 find such a path, it returns NULL, in which case a foreign data wrapper
817 may build the local path by itself or may choose not to create access
818 paths for that join.)
820 58.2.7. FDW Routines for EXPLAIN #
823 ExplainForeignScan(ForeignScanState *node,
826 Print additional EXPLAIN output for a foreign table scan. This function
827 can call ExplainPropertyText and related functions to add fields to the
828 EXPLAIN output. The flag fields in es can be used to determine what to
829 print, and the state of the ForeignScanState node can be inspected to
830 provide run-time statistics in the EXPLAIN ANALYZE case.
832 If the ExplainForeignScan pointer is set to NULL, no additional
833 information is printed during EXPLAIN.
836 ExplainForeignModify(ModifyTableState *mtstate,
837 ResultRelInfo *rinfo,
840 struct ExplainState *es);
842 Print additional EXPLAIN output for a foreign table update. This
843 function can call ExplainPropertyText and related functions to add
844 fields to the EXPLAIN output. The flag fields in es can be used to
845 determine what to print, and the state of the ModifyTableState node can
846 be inspected to provide run-time statistics in the EXPLAIN ANALYZE
847 case. The first four arguments are the same as for BeginForeignModify.
849 If the ExplainForeignModify pointer is set to NULL, no additional
850 information is printed during EXPLAIN.
853 ExplainDirectModify(ForeignScanState *node,
856 Print additional EXPLAIN output for a direct modification on the remote
857 server. This function can call ExplainPropertyText and related
858 functions to add fields to the EXPLAIN output. The flag fields in es
859 can be used to determine what to print, and the state of the
860 ForeignScanState node can be inspected to provide run-time statistics
861 in the EXPLAIN ANALYZE case.
863 If the ExplainDirectModify pointer is set to NULL, no additional
864 information is printed during EXPLAIN.
866 58.2.8. FDW Routines for ANALYZE #
869 AnalyzeForeignTable(Relation relation,
870 AcquireSampleRowsFunc *func,
871 BlockNumber *totalpages);
873 This function is called when ANALYZE is executed on a foreign table. If
874 the FDW can collect statistics for this foreign table, it should return
875 true, and provide a pointer to a function that will collect sample rows
876 from the table in func, plus the estimated size of the table in pages
877 in totalpages. Otherwise, return false.
879 If the FDW does not support collecting statistics for any tables, the
880 AnalyzeForeignTable pointer can be set to NULL.
882 If provided, the sample collection function must have the signature
884 AcquireSampleRowsFunc(Relation relation,
889 double *totaldeadrows);
891 A random sample of up to targrows rows should be collected from the
892 table and stored into the caller-provided rows array. The actual number
893 of rows collected must be returned. In addition, store estimates of the
894 total numbers of live and dead rows in the table into the output
895 parameters totalrows and totaldeadrows. (Set totaldeadrows to zero if
896 the FDW does not have any concept of dead rows.)
898 58.2.9. FDW Routines for IMPORT FOREIGN SCHEMA #
901 ImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid);
903 Obtain a list of foreign table creation commands. This function is
904 called when executing IMPORT FOREIGN SCHEMA, and is passed the parse
905 tree for that statement, as well as the OID of the foreign server to
906 use. It should return a list of C strings, each of which must contain a
907 CREATE FOREIGN TABLE command. These strings will be parsed and executed
910 Within the ImportForeignSchemaStmt struct, remote_schema is the name of
911 the remote schema from which tables are to be imported. list_type
912 identifies how to filter table names: FDW_IMPORT_SCHEMA_ALL means that
913 all tables in the remote schema should be imported (in this case
914 table_list is empty), FDW_IMPORT_SCHEMA_LIMIT_TO means to include only
915 tables listed in table_list, and FDW_IMPORT_SCHEMA_EXCEPT means to
916 exclude the tables listed in table_list. options is a list of options
917 used for the import process. The meanings of the options are up to the
918 FDW. For example, an FDW could use an option to define whether the NOT
919 NULL attributes of columns should be imported. These options need not
920 have anything to do with those supported by the FDW as database object
923 The FDW may ignore the local_schema field of the
924 ImportForeignSchemaStmt, because the core server will automatically
925 insert that name into the parsed CREATE FOREIGN TABLE commands.
927 The FDW does not have to concern itself with implementing the filtering
928 specified by list_type and table_list, either, as the core server will
929 automatically skip any returned commands for tables excluded according
930 to those options. However, it's often useful to avoid the work of
931 creating commands for excluded tables in the first place. The function
932 IsImportableForeignTable() may be useful to test whether a given
933 foreign-table name will pass the filter.
935 If the FDW does not support importing table definitions, the
936 ImportForeignSchema pointer can be set to NULL.
938 58.2.10. FDW Routines for Parallel Execution #
940 A ForeignScan node can, optionally, support parallel execution. A
941 parallel ForeignScan will be executed in multiple processes and must
942 return each row exactly once across all cooperating processes. To do
943 this, processes can coordinate through fixed-size chunks of dynamic
944 shared memory. This shared memory is not guaranteed to be mapped at the
945 same address in every process, so it must not contain pointers. The
946 following functions are all optional, but most are required if parallel
947 execution is to be supported.
950 IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
953 Test whether a scan can be performed within a parallel worker. This
954 function will only be called when the planner believes that a parallel
955 plan might be possible, and should return true if it is safe for that
956 scan to run within a parallel worker. This will generally not be the
957 case if the remote data source has transaction semantics, unless the
958 worker's connection to the data can somehow be made to share the same
959 transaction context as the leader.
961 If this function is not defined, it is assumed that the scan must take
962 place within the parallel leader. Note that returning true does not
963 mean that the scan itself can be done in parallel, only that the scan
964 can be performed within a parallel worker. Therefore, it can be useful
965 to define this method even when parallel execution is not supported.
968 EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt);
970 Estimate the amount of dynamic shared memory that will be required for
971 parallel operation. This may be higher than the amount that will
972 actually be used, but it must not be lower. The return value is in
973 bytes. This function is optional, and can be omitted if not needed; but
974 if it is omitted, the next three functions must be omitted as well,
975 because no shared memory will be allocated for the FDW's use.
978 InitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
981 Initialize the dynamic shared memory that will be required for parallel
982 operation. coordinate points to a shared memory area of size equal to
983 the return value of EstimateDSMForeignScan. This function is optional,
984 and can be omitted if not needed.
987 ReInitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
990 Re-initialize the dynamic shared memory required for parallel operation
991 when the foreign-scan plan node is about to be re-scanned. This
992 function is optional, and can be omitted if not needed. Recommended
993 practice is that this function reset only shared state, while the
994 ReScanForeignScan function resets only local state. Currently, this
995 function will be called before ReScanForeignScan, but it's best not to
996 rely on that ordering.
999 InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc,
1002 Initialize a parallel worker's local state based on the shared state
1003 set up by the leader during InitializeDSMForeignScan. This function is
1004 optional, and can be omitted if not needed.
1007 ShutdownForeignScan(ForeignScanState *node);
1009 Release resources when it is anticipated the node will not be executed
1010 to completion. This is not called in all cases; sometimes,
1011 EndForeignScan may be called without this function having been called
1012 first. Since the DSM segment used by parallel query is destroyed just
1013 after this callback is invoked, foreign data wrappers that wish to take
1014 some action before the DSM segment goes away should implement this
1017 58.2.11. FDW Routines for Asynchronous Execution #
1019 A ForeignScan node can, optionally, support asynchronous execution as
1020 described in src/backend/executor/README. The following functions are
1021 all optional, but are all required if asynchronous execution is to be
1025 IsForeignPathAsyncCapable(ForeignPath *path);
1027 Test whether a given ForeignPath path can scan the underlying foreign
1028 relation asynchronously. This function will only be called at the end
1029 of query planning when the given path is a direct child of an
1030 AppendPath path and when the planner believes that asynchronous
1031 execution improves performance, and should return true if the given
1032 path is able to scan the foreign relation asynchronously.
1034 If this function is not defined, it is assumed that the given path
1035 scans the foreign relation using IterateForeignScan. (This implies that
1036 the callback functions described below will never be called, so they
1037 need not be provided either.)
1040 ForeignAsyncRequest(AsyncRequest *areq);
1042 Produce one tuple asynchronously from the ForeignScan node. areq is the
1043 AsyncRequest struct describing the ForeignScan node and the parent
1044 Append node that requested the tuple from it. This function should
1045 store the tuple into the slot specified by areq->result, and set
1046 areq->request_complete to true; or if it needs to wait on an event
1047 external to the core server such as network I/O, and cannot produce any
1048 tuple immediately, set the flag to false, and set
1049 areq->callback_pending to true for the ForeignScan node to get a
1050 callback from the callback functions described below. If no more tuples
1051 are available, set the slot to NULL or an empty slot, and the
1052 areq->request_complete flag to true. It's recommended to use
1053 ExecAsyncRequestDone or ExecAsyncRequestPending to set the output
1054 parameters in the areq.
1057 ForeignAsyncConfigureWait(AsyncRequest *areq);
1059 Configure a file descriptor event for which the ForeignScan node wishes
1060 to wait. This function will only be called when the ForeignScan node
1061 has the areq->callback_pending flag set, and should add the event to
1062 the as_eventset of the parent Append node described by the areq. See
1063 the comments for ExecAsyncConfigureWait in
1064 src/backend/executor/execAsync.c for additional information. When the
1065 file descriptor event occurs, ForeignAsyncNotify will be called.
1068 ForeignAsyncNotify(AsyncRequest *areq);
1070 Process a relevant event that has occurred, then produce one tuple
1071 asynchronously from the ForeignScan node. This function should set the
1072 output parameters in the areq in the same way as ForeignAsyncRequest.
1074 58.2.12. FDW Routines for Reparameterization of Paths #
1077 ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private,
1078 RelOptInfo *child_rel);
1080 This function is called while converting a path parameterized by the
1081 top-most parent of the given child relation child_rel to be
1082 parameterized by the child relation. The function is used to
1083 reparameterize any paths or translate any expression nodes saved in the
1084 given fdw_private member of a ForeignPath. The callback may use
1085 reparameterize_path_by_child, adjust_appendrel_attrs or
1086 adjust_appendrel_attrs_multilevel as required.