gooderp18绿色标准版
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

1066 lines
66KB

  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>56.2. Foreign Data Wrapper Callback Routines</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 V1.79.1" /><link rel="prev" href="fdw-functions.html" title="56.1. Foreign Data Wrapper Functions" /><link rel="next" href="fdw-helpers.html" title="56.3. Foreign Data Wrapper Helper Functions" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.2. Foreign Data Wrapper Callback Routines</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-functions.html" title="56.1. Foreign Data Wrapper Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 56. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 56. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-helpers.html" title="56.3. Foreign Data Wrapper Helper Functions">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="FDW-CALLBACKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.2. Foreign Data Wrapper Callback Routines</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-SCAN">56.2.1. FDW Routines for Scanning Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-JOIN-SCAN">56.2.2. FDW Routines for Scanning Foreign Joins</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPPER-PLANNING">56.2.3. FDW Routines for Planning Post-Scan/Join Processing</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPDATE">56.2.4. FDW Routines for Updating Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING">56.2.5. FDW Routines for Row Locking</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-EXPLAIN">56.2.6. FDW Routines for <code class="command">EXPLAIN</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ANALYZE">56.2.7. FDW Routines for <code class="command">ANALYZE</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-IMPORT">56.2.8. FDW Routines for <code class="command">IMPORT FOREIGN SCHEMA</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-PARALLEL">56.2.9. FDW Routines for Parallel Execution</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-REPARAMETERIZE-PATHS">56.2.10. FDW Routines for Reparameterization of Paths</a></span></dt></dl></div><p>
  3. The FDW handler function returns a palloc'd <code class="structname">FdwRoutine</code>
  4. struct containing pointers to the callback functions described below.
  5. The scan-related functions are required, the rest are optional.
  6. </p><p>
  7. The <code class="structname">FdwRoutine</code> struct type is declared in
  8. <code class="filename">src/include/foreign/fdwapi.h</code>, which see for additional
  9. details.
  10. </p><div class="sect2" id="FDW-CALLBACKS-SCAN"><div class="titlepage"><div><div><h3 class="title">56.2.1. FDW Routines for Scanning Foreign Tables</h3></div></div></div><p>
  11. </p><pre class="programlisting">
  12. void
  13. GetForeignRelSize(PlannerInfo *root,
  14. RelOptInfo *baserel,
  15. Oid foreigntableid);
  16. </pre><p>
  17. Obtain relation size estimates for a foreign table. This is called
  18. at the beginning of planning for a query that scans a foreign table.
  19. <code class="literal">root</code> is the planner's global information about the query;
  20. <code class="literal">baserel</code> is the planner's information about this table; and
  21. <code class="literal">foreigntableid</code> is the <code class="structname">pg_class</code> OID of the
  22. foreign table. (<code class="literal">foreigntableid</code> could be obtained from the
  23. planner data structures, but it's passed explicitly to save effort.)
  24. </p><p>
  25. This function should update <code class="literal">baserel-&gt;rows</code> to be the
  26. expected number of rows returned by the table scan, after accounting for
  27. the filtering done by the restriction quals. The initial value of
  28. <code class="literal">baserel-&gt;rows</code> is just a constant default estimate, which
  29. should be replaced if at all possible. The function may also choose to
  30. update <code class="literal">baserel-&gt;width</code> if it can compute a better estimate
  31. of the average result row width.
  32. (The initial value is based on column data types and on column
  33. average-width values measured by the last <code class="command">ANALYZE</code>.)
  34. Also, this function may update <code class="literal">baserel-&gt;tuples</code> if
  35. it can compute a better estimate of the foreign table's total row count.
  36. (The initial value is
  37. from <code class="structname">pg_class</code>.<code class="structfield">reltuples</code>
  38. which represents the total row count seen by the
  39. last <code class="command">ANALYZE</code>.)
  40. </p><p>
  41. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  42. </p><p>
  43. </p><pre class="programlisting">
  44. void
  45. GetForeignPaths(PlannerInfo *root,
  46. RelOptInfo *baserel,
  47. Oid foreigntableid);
  48. </pre><p>
  49. Create possible access paths for a scan on a foreign table.
  50. This is called during query planning.
  51. The parameters are the same as for <code class="function">GetForeignRelSize</code>,
  52. which has already been called.
  53. </p><p>
  54. This function must generate at least one access path
  55. (<code class="structname">ForeignPath</code> node) for a scan on the foreign table and
  56. must call <code class="function">add_path</code> to add each such path to
  57. <code class="literal">baserel-&gt;pathlist</code>. It's recommended to use
  58. <code class="function">create_foreignscan_path</code> to build the
  59. <code class="structname">ForeignPath</code> nodes. The function can generate multiple
  60. access paths, e.g., a path which has valid <code class="literal">pathkeys</code> to
  61. represent a pre-sorted result. Each access path must contain cost
  62. estimates, and can contain any FDW-private information that is needed to
  63. identify the specific scan method intended.
  64. </p><p>
  65. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  66. </p><p>
  67. </p><pre class="programlisting">
  68. ForeignScan *
  69. GetForeignPlan(PlannerInfo *root,
  70. RelOptInfo *baserel,
  71. Oid foreigntableid,
  72. ForeignPath *best_path,
  73. List *tlist,
  74. List *scan_clauses,
  75. Plan *outer_plan);
  76. </pre><p>
  77. Create a <code class="structname">ForeignScan</code> plan node from the selected foreign
  78. access path. This is called at the end of query planning.
  79. The parameters are as for <code class="function">GetForeignRelSize</code>, plus
  80. the selected <code class="structname">ForeignPath</code> (previously produced by
  81. <code class="function">GetForeignPaths</code>, <code class="function">GetForeignJoinPaths</code>,
  82. or <code class="function">GetForeignUpperPaths</code>),
  83. the target list to be emitted by the plan node,
  84. the restriction clauses to be enforced by the plan node,
  85. and the outer subplan of the <code class="structname">ForeignScan</code>,
  86. which is used for rechecks performed by <code class="function">RecheckForeignScan</code>.
  87. (If the path is for a join rather than a base
  88. relation, <code class="literal">foreigntableid</code> is <code class="literal">InvalidOid</code>.)
  89. </p><p>
  90. This function must create and return a <code class="structname">ForeignScan</code> plan
  91. node; it's recommended to use <code class="function">make_foreignscan</code> to build the
  92. <code class="structname">ForeignScan</code> node.
  93. </p><p>
  94. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  95. </p><p>
  96. </p><pre class="programlisting">
  97. void
  98. BeginForeignScan(ForeignScanState *node,
  99. int eflags);
  100. </pre><p>
  101. Begin executing a foreign scan. This is called during executor startup.
  102. It should perform any initialization needed before the scan can start,
  103. but not start executing the actual scan (that should be done upon the
  104. first call to <code class="function">IterateForeignScan</code>).
  105. The <code class="structname">ForeignScanState</code> node has already been created, but
  106. its <code class="structfield">fdw_state</code> field is still NULL. Information about
  107. the table to scan is accessible through the
  108. <code class="structname">ForeignScanState</code> node (in particular, from the underlying
  109. <code class="structname">ForeignScan</code> plan node, which contains any FDW-private
  110. information provided by <code class="function">GetForeignPlan</code>).
  111. <code class="literal">eflags</code> contains flag bits describing the executor's
  112. operating mode for this plan node.
  113. </p><p>
  114. Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
  115. true, this function should not perform any externally-visible actions;
  116. it should only do the minimum required to make the node state valid
  117. for <code class="function">ExplainForeignScan</code> and <code class="function">EndForeignScan</code>.
  118. </p><p>
  119. </p><pre class="programlisting">
  120. TupleTableSlot *
  121. IterateForeignScan(ForeignScanState *node);
  122. </pre><p>
  123. Fetch one row from the foreign source, returning it in a tuple table slot
  124. (the node's <code class="structfield">ScanTupleSlot</code> should be used for this
  125. purpose). Return NULL if no more rows are available. The tuple table
  126. slot infrastructure allows either a physical or virtual tuple to be
  127. returned; in most cases the latter choice is preferable from a
  128. performance standpoint. Note that this is called in a short-lived memory
  129. context that will be reset between invocations. Create a memory context
  130. in <code class="function">BeginForeignScan</code> if you need longer-lived storage, or use
  131. the <code class="structfield">es_query_cxt</code> of the node's <code class="structname">EState</code>.
  132. </p><p>
  133. The rows returned must match the <code class="structfield">fdw_scan_tlist</code> target
  134. list if one was supplied, otherwise they must match the row type of the
  135. foreign table being scanned. If you choose to optimize away fetching
  136. columns that are not needed, you should insert nulls in those column
  137. positions, or else generate a <code class="structfield">fdw_scan_tlist</code> list with
  138. those columns omitted.
  139. </p><p>
  140. Note that <span class="productname">PostgreSQL</span>'s executor doesn't care
  141. whether the rows returned violate any constraints that were defined on
  142. the foreign table — but the planner does care, and may optimize
  143. queries incorrectly if there are rows visible in the foreign table that
  144. do not satisfy a declared constraint. If a constraint is violated when
  145. the user has declared that the constraint should hold true, it may be
  146. appropriate to raise an error (just as you would need to do in the case
  147. of a data type mismatch).
  148. </p><p>
  149. </p><pre class="programlisting">
  150. void
  151. ReScanForeignScan(ForeignScanState *node);
  152. </pre><p>
  153. Restart the scan from the beginning. Note that any parameters the
  154. scan depends on may have changed value, so the new scan does not
  155. necessarily return exactly the same rows.
  156. </p><p>
  157. </p><pre class="programlisting">
  158. void
  159. EndForeignScan(ForeignScanState *node);
  160. </pre><p>
  161. End the scan and release resources. It is normally not important
  162. to release palloc'd memory, but for example open files and connections
  163. to remote servers should be cleaned up.
  164. </p></div><div class="sect2" id="FDW-CALLBACKS-JOIN-SCAN"><div class="titlepage"><div><div><h3 class="title">56.2.2. FDW Routines for Scanning Foreign Joins</h3></div></div></div><p>
  165. If an FDW supports performing foreign joins remotely (rather than
  166. by fetching both tables' data and doing the join locally), it should
  167. provide this callback function:
  168. </p><p>
  169. </p><pre class="programlisting">
  170. void
  171. GetForeignJoinPaths(PlannerInfo *root,
  172. RelOptInfo *joinrel,
  173. RelOptInfo *outerrel,
  174. RelOptInfo *innerrel,
  175. JoinType jointype,
  176. JoinPathExtraData *extra);
  177. </pre><p>
  178. Create possible access paths for a join of two (or more) foreign tables
  179. that all belong to the same foreign server. This optional
  180. function is called during query planning. As
  181. with <code class="function">GetForeignPaths</code>, this function should
  182. generate <code class="structname">ForeignPath</code> path(s) for the
  183. supplied <code class="literal">joinrel</code>
  184. (use <code class="function">create_foreign_join_path</code> to build them),
  185. and call <code class="function">add_path</code> to add these
  186. paths to the set of paths considered for the join. But unlike
  187. <code class="function">GetForeignPaths</code>, it is not necessary that this function
  188. succeed in creating at least one path, since paths involving local
  189. joining are always possible.
  190. </p><p>
  191. Note that this function will be invoked repeatedly for the same join
  192. relation, with different combinations of inner and outer relations; it is
  193. the responsibility of the FDW to minimize duplicated work.
  194. </p><p>
  195. If a <code class="structname">ForeignPath</code> path is chosen for the join, it will
  196. represent the entire join process; paths generated for the component
  197. tables and subsidiary joins will not be used. Subsequent processing of
  198. the join path proceeds much as it does for a path scanning a single
  199. foreign table. One difference is that the <code class="structfield">scanrelid</code> of
  200. the resulting <code class="structname">ForeignScan</code> plan node should be set to zero,
  201. since there is no single relation that it represents; instead,
  202. the <code class="structfield">fs_relids</code> field of the <code class="structname">ForeignScan</code>
  203. node represents the set of relations that were joined. (The latter field
  204. is set up automatically by the core planner code, and need not be filled
  205. by the FDW.) Another difference is that, because the column list for a
  206. remote join cannot be found from the system catalogs, the FDW must
  207. fill <code class="structfield">fdw_scan_tlist</code> with an appropriate list
  208. of <code class="structfield">TargetEntry</code> nodes, representing the set of columns
  209. it will supply at run time in the tuples it returns.
  210. </p><p>
  211. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  212. </p></div><div class="sect2" id="FDW-CALLBACKS-UPPER-PLANNING"><div class="titlepage"><div><div><h3 class="title">56.2.3. FDW Routines for Planning Post-Scan/Join Processing</h3></div></div></div><p>
  213. If an FDW supports performing remote post-scan/join processing, such as
  214. remote aggregation, it should provide this callback function:
  215. </p><p>
  216. </p><pre class="programlisting">
  217. void
  218. GetForeignUpperPaths(PlannerInfo *root,
  219. UpperRelationKind stage,
  220. RelOptInfo *input_rel,
  221. RelOptInfo *output_rel,
  222. void *extra);
  223. </pre><p>
  224. Create possible access paths for <em class="firstterm">upper relation</em> processing,
  225. which is the planner's term for all post-scan/join query processing, such
  226. as aggregation, window functions, sorting, and table updates. This
  227. optional function is called during query planning. Currently, it is
  228. called only if all base relation(s) involved in the query belong to the
  229. same FDW. This function should generate <code class="structname">ForeignPath</code>
  230. path(s) for any post-scan/join processing that the FDW knows how to
  231. perform remotely
  232. (use <code class="function">create_foreign_upper_path</code> to build them),
  233. and call <code class="function">add_path</code> to add these paths to
  234. the indicated upper relation. As with <code class="function">GetForeignJoinPaths</code>,
  235. it is not necessary that this function succeed in creating any paths,
  236. since paths involving local processing are always possible.
  237. </p><p>
  238. The <code class="literal">stage</code> parameter identifies which post-scan/join step is
  239. currently being considered. <code class="literal">output_rel</code> is the upper relation
  240. that should receive paths representing computation of this step,
  241. and <code class="literal">input_rel</code> is the relation representing the input to this
  242. step. The <code class="literal">extra</code> parameter provides additional details,
  243. currently, it is set only for <code class="literal">UPPERREL_PARTIAL_GROUP_AGG</code>
  244. or <code class="literal">UPPERREL_GROUP_AGG</code>, in which case it points to a
  245. <code class="literal">GroupPathExtraData</code> structure;
  246. or for <code class="literal">UPPERREL_FINAL</code>, in which case it points to a
  247. <code class="literal">FinalPathExtraData</code> structure.
  248. (Note that <code class="structname">ForeignPath</code> paths added
  249. to <code class="literal">output_rel</code> would typically not have any direct dependency
  250. on paths of the <code class="literal">input_rel</code>, since their processing is expected
  251. to be done externally. However, examining paths previously generated for
  252. the previous processing step can be useful to avoid redundant planning
  253. work.)
  254. </p><p>
  255. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  256. </p></div><div class="sect2" id="FDW-CALLBACKS-UPDATE"><div class="titlepage"><div><div><h3 class="title">56.2.4. FDW Routines for Updating Foreign Tables</h3></div></div></div><p>
  257. If an FDW supports writable foreign tables, it should provide
  258. some or all of the following callback functions depending on
  259. the needs and capabilities of the FDW:
  260. </p><p>
  261. </p><pre class="programlisting">
  262. void
  263. AddForeignUpdateTargets(Query *parsetree,
  264. RangeTblEntry *target_rte,
  265. Relation target_relation);
  266. </pre><p>
  267. <code class="command">UPDATE</code> and <code class="command">DELETE</code> operations are performed
  268. against rows previously fetched by the table-scanning functions. The
  269. FDW may need extra information, such as a row ID or the values of
  270. primary-key columns, to ensure that it can identify the exact row to
  271. update or delete. To support that, this function can add extra hidden,
  272. or <span class="quote">“<span class="quote">junk</span>”</span>, target columns to the list of columns that are to be
  273. retrieved from the foreign table during an <code class="command">UPDATE</code> or
  274. <code class="command">DELETE</code>.
  275. </p><p>
  276. To do that, add <code class="structname">TargetEntry</code> items to
  277. <code class="literal">parsetree-&gt;targetList</code>, containing expressions for the
  278. extra values to be fetched. Each such entry must be marked
  279. <code class="structfield">resjunk</code> = <code class="literal">true</code>, and must have a distinct
  280. <code class="structfield">resname</code> that will identify it at execution time.
  281. Avoid using names matching <code class="literal">ctid<em class="replaceable"><code>N</code></em></code>,
  282. <code class="literal">wholerow</code>, or
  283. <code class="literal">wholerow<em class="replaceable"><code>N</code></em></code>, as the core system can
  284. generate junk columns of these names.
  285. If the extra expressions are more complex than simple Vars, they
  286. must be run through <code class="function">eval_const_expressions</code>
  287. before adding them to the targetlist.
  288. </p><p>
  289. Although this function is called during planning, the
  290. information provided is a bit different from that available to other
  291. planning routines.
  292. <code class="literal">parsetree</code> is the parse tree for the <code class="command">UPDATE</code> or
  293. <code class="command">DELETE</code> command, while <code class="literal">target_rte</code> and
  294. <code class="literal">target_relation</code> describe the target foreign table.
  295. </p><p>
  296. If the <code class="function">AddForeignUpdateTargets</code> pointer is set to
  297. <code class="literal">NULL</code>, no extra target expressions are added.
  298. (This will make it impossible to implement <code class="command">DELETE</code>
  299. operations, though <code class="command">UPDATE</code> may still be feasible if the FDW
  300. relies on an unchanging primary key to identify rows.)
  301. </p><p>
  302. </p><pre class="programlisting">
  303. List *
  304. PlanForeignModify(PlannerInfo *root,
  305. ModifyTable *plan,
  306. Index resultRelation,
  307. int subplan_index);
  308. </pre><p>
  309. Perform any additional planning actions needed for an insert, update, or
  310. delete on a foreign table. This function generates the FDW-private
  311. information that will be attached to the <code class="structname">ModifyTable</code> plan
  312. node that performs the update action. This private information must
  313. have the form of a <code class="literal">List</code>, and will be delivered to
  314. <code class="function">BeginForeignModify</code> during the execution stage.
  315. </p><p>
  316. <code class="literal">root</code> is the planner's global information about the query.
  317. <code class="literal">plan</code> is the <code class="structname">ModifyTable</code> plan node, which is
  318. complete except for the <code class="structfield">fdwPrivLists</code> field.
  319. <code class="literal">resultRelation</code> identifies the target foreign table by its
  320. range table index. <code class="literal">subplan_index</code> identifies which target of
  321. the <code class="structname">ModifyTable</code> plan node this is, counting from zero;
  322. use this if you want to index into <code class="literal">plan-&gt;plans</code> or other
  323. substructure of the <code class="literal">plan</code> node.
  324. </p><p>
  325. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  326. </p><p>
  327. If the <code class="function">PlanForeignModify</code> pointer is set to
  328. <code class="literal">NULL</code>, no additional plan-time actions are taken, and the
  329. <code class="literal">fdw_private</code> list delivered to
  330. <code class="function">BeginForeignModify</code> will be NIL.
  331. </p><p>
  332. </p><pre class="programlisting">
  333. void
  334. BeginForeignModify(ModifyTableState *mtstate,
  335. ResultRelInfo *rinfo,
  336. List *fdw_private,
  337. int subplan_index,
  338. int eflags);
  339. </pre><p>
  340. Begin executing a foreign table modification operation. This routine is
  341. called during executor startup. It should perform any initialization
  342. needed prior to the actual table modifications. Subsequently,
  343. <code class="function">ExecForeignInsert</code>, <code class="function">ExecForeignUpdate</code> or
  344. <code class="function">ExecForeignDelete</code> will be called for each tuple to be
  345. inserted, updated, or deleted.
  346. </p><p>
  347. <code class="literal">mtstate</code> is the overall state of the
  348. <code class="structname">ModifyTable</code> plan node being executed; global data about
  349. the plan and execution state is available via this structure.
  350. <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
  351. the target foreign table. (The <code class="structfield">ri_FdwState</code> field of
  352. <code class="structname">ResultRelInfo</code> is available for the FDW to store any
  353. private state it needs for this operation.)
  354. <code class="literal">fdw_private</code> contains the private data generated by
  355. <code class="function">PlanForeignModify</code>, if any.
  356. <code class="literal">subplan_index</code> identifies which target of
  357. the <code class="structname">ModifyTable</code> plan node this is.
  358. <code class="literal">eflags</code> contains flag bits describing the executor's
  359. operating mode for this plan node.
  360. </p><p>
  361. Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
  362. true, this function should not perform any externally-visible actions;
  363. it should only do the minimum required to make the node state valid
  364. for <code class="function">ExplainForeignModify</code> and <code class="function">EndForeignModify</code>.
  365. </p><p>
  366. If the <code class="function">BeginForeignModify</code> pointer is set to
  367. <code class="literal">NULL</code>, no action is taken during executor startup.
  368. </p><p>
  369. </p><pre class="programlisting">
  370. TupleTableSlot *
  371. ExecForeignInsert(EState *estate,
  372. ResultRelInfo *rinfo,
  373. TupleTableSlot *slot,
  374. TupleTableSlot *planSlot);
  375. </pre><p>
  376. Insert one tuple into the foreign table.
  377. <code class="literal">estate</code> is global execution state for the query.
  378. <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
  379. the target foreign table.
  380. <code class="literal">slot</code> contains the tuple to be inserted; it will match the
  381. row-type definition of the foreign table.
  382. <code class="literal">planSlot</code> contains the tuple that was generated by the
  383. <code class="structname">ModifyTable</code> plan node's subplan; it differs from
  384. <code class="literal">slot</code> in possibly containing additional <span class="quote">“<span class="quote">junk</span>”</span>
  385. columns. (The <code class="literal">planSlot</code> is typically of little interest
  386. for <code class="command">INSERT</code> cases, but is provided for completeness.)
  387. </p><p>
  388. The return value is either a slot containing the data that was actually
  389. inserted (this might differ from the data supplied, for example as a
  390. result of trigger actions), or NULL if no row was actually inserted
  391. (again, typically as a result of triggers). The passed-in
  392. <code class="literal">slot</code> can be re-used for this purpose.
  393. </p><p>
  394. The data in the returned slot is used only if the <code class="command">INSERT</code>
  395. statement has a <code class="literal">RETURNING</code> clause or involves a view
  396. <code class="literal">WITH CHECK OPTION</code>; or if the foreign table has
  397. an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns,
  398. but the FDW could choose to optimize away returning some or all columns
  399. depending on the contents of the <code class="literal">RETURNING</code> clause or
  400. <code class="literal">WITH CHECK OPTION</code> constraints. Regardless, some slot
  401. must be returned to indicate success, or the query's reported row count
  402. will be wrong.
  403. </p><p>
  404. If the <code class="function">ExecForeignInsert</code> pointer is set to
  405. <code class="literal">NULL</code>, attempts to insert into the foreign table will fail
  406. with an error message.
  407. </p><p>
  408. Note that this function is also called when inserting routed tuples into
  409. a foreign-table partition or executing <code class="command">COPY FROM</code> on
  410. a foreign table, in which case it is called in a different way than it
  411. is in the <code class="command">INSERT</code> case. See the callback functions
  412. described below that allow the FDW to support that.
  413. </p><p>
  414. </p><pre class="programlisting">
  415. TupleTableSlot *
  416. ExecForeignUpdate(EState *estate,
  417. ResultRelInfo *rinfo,
  418. TupleTableSlot *slot,
  419. TupleTableSlot *planSlot);
  420. </pre><p>
  421. Update one tuple in the foreign table.
  422. <code class="literal">estate</code> is global execution state for the query.
  423. <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
  424. the target foreign table.
  425. <code class="literal">slot</code> contains the new data for the tuple; it will match the
  426. row-type definition of the foreign table.
  427. <code class="literal">planSlot</code> contains the tuple that was generated by the
  428. <code class="structname">ModifyTable</code> plan node's subplan; it differs from
  429. <code class="literal">slot</code> in possibly containing additional <span class="quote">“<span class="quote">junk</span>”</span>
  430. columns. In particular, any junk columns that were requested by
  431. <code class="function">AddForeignUpdateTargets</code> will be available from this slot.
  432. </p><p>
  433. The return value is either a slot containing the row as it was actually
  434. updated (this might differ from the data supplied, for example as a
  435. result of trigger actions), or NULL if no row was actually updated
  436. (again, typically as a result of triggers). The passed-in
  437. <code class="literal">slot</code> can be re-used for this purpose.
  438. </p><p>
  439. The data in the returned slot is used only if the <code class="command">UPDATE</code>
  440. statement has a <code class="literal">RETURNING</code> clause or involves a view
  441. <code class="literal">WITH CHECK OPTION</code>; or if the foreign table has
  442. an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns,
  443. but the FDW could choose to optimize away returning some or all columns
  444. depending on the contents of the <code class="literal">RETURNING</code> clause or
  445. <code class="literal">WITH CHECK OPTION</code> constraints. Regardless, some slot
  446. must be returned to indicate success, or the query's reported row count
  447. will be wrong.
  448. </p><p>
  449. If the <code class="function">ExecForeignUpdate</code> pointer is set to
  450. <code class="literal">NULL</code>, attempts to update the foreign table will fail
  451. with an error message.
  452. </p><p>
  453. </p><pre class="programlisting">
  454. TupleTableSlot *
  455. ExecForeignDelete(EState *estate,
  456. ResultRelInfo *rinfo,
  457. TupleTableSlot *slot,
  458. TupleTableSlot *planSlot);
  459. </pre><p>
  460. Delete one tuple from the foreign table.
  461. <code class="literal">estate</code> is global execution state for the query.
  462. <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
  463. the target foreign table.
  464. <code class="literal">slot</code> contains nothing useful upon call, but can be used to
  465. hold the returned tuple.
  466. <code class="literal">planSlot</code> contains the tuple that was generated by the
  467. <code class="structname">ModifyTable</code> plan node's subplan; in particular, it will
  468. carry any junk columns that were requested by
  469. <code class="function">AddForeignUpdateTargets</code>. The junk column(s) must be used
  470. to identify the tuple to be deleted.
  471. </p><p>
  472. The return value is either a slot containing the row that was deleted,
  473. or NULL if no row was deleted (typically as a result of triggers). The
  474. passed-in <code class="literal">slot</code> can be used to hold the tuple to be returned.
  475. </p><p>
  476. The data in the returned slot is used only if the <code class="command">DELETE</code>
  477. query has a <code class="literal">RETURNING</code> clause or the foreign table has
  478. an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns, but the
  479. FDW could choose to optimize away returning some or all columns depending
  480. on the contents of the <code class="literal">RETURNING</code> clause. Regardless, some
  481. slot must be returned to indicate success, or the query's reported row
  482. count will be wrong.
  483. </p><p>
  484. If the <code class="function">ExecForeignDelete</code> pointer is set to
  485. <code class="literal">NULL</code>, attempts to delete from the foreign table will fail
  486. with an error message.
  487. </p><p>
  488. </p><pre class="programlisting">
  489. void
  490. EndForeignModify(EState *estate,
  491. ResultRelInfo *rinfo);
  492. </pre><p>
  493. End the table update and release resources. It is normally not important
  494. to release palloc'd memory, but for example open files and connections
  495. to remote servers should be cleaned up.
  496. </p><p>
  497. If the <code class="function">EndForeignModify</code> pointer is set to
  498. <code class="literal">NULL</code>, no action is taken during executor shutdown.
  499. </p><p>
  500. Tuples inserted into a partitioned table by <code class="command">INSERT</code> or
  501. <code class="command">COPY FROM</code> are routed to partitions. If an FDW
  502. supports routable foreign-table partitions, it should also provide the
  503. following callback functions. These functions are also called when
  504. <code class="command">COPY FROM</code> is executed on a foreign table.
  505. </p><p>
  506. </p><pre class="programlisting">
  507. void
  508. BeginForeignInsert(ModifyTableState *mtstate,
  509. ResultRelInfo *rinfo);
  510. </pre><p>
  511. Begin executing an insert operation on a foreign table. This routine is
  512. called right before the first tuple is inserted into the foreign table
  513. in both cases when it is the partition chosen for tuple routing and the
  514. target specified in a <code class="command">COPY FROM</code> command. It should
  515. perform any initialization needed prior to the actual insertion.
  516. Subsequently, <code class="function">ExecForeignInsert</code> will be called for
  517. each tuple to be inserted into the foreign table.
  518. </p><p>
  519. <code class="literal">mtstate</code> is the overall state of the
  520. <code class="structname">ModifyTable</code> plan node being executed; global data about
  521. the plan and execution state is available via this structure.
  522. <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
  523. the target foreign table. (The <code class="structfield">ri_FdwState</code> field of
  524. <code class="structname">ResultRelInfo</code> is available for the FDW to store any
  525. private state it needs for this operation.)
  526. </p><p>
  527. When this is called by a <code class="command">COPY FROM</code> command, the
  528. plan-related global data in <code class="literal">mtstate</code> is not provided
  529. and the <code class="literal">planSlot</code> parameter of
  530. <code class="function">ExecForeignInsert</code> subsequently called for each
  531. inserted tuple is <code class="literal">NULL</code>, whether the foreign table is
  532. the partition chosen for tuple routing or the target specified in the
  533. command.
  534. </p><p>
  535. If the <code class="function">BeginForeignInsert</code> pointer is set to
  536. <code class="literal">NULL</code>, no action is taken for the initialization.
  537. </p><p>
  538. Note that if the FDW does not support routable foreign-table partitions
  539. and/or executing <code class="command">COPY FROM</code> on foreign tables, this
  540. function or <code class="function">ExecForeignInsert</code> subsequently called
  541. must throw error as needed.
  542. </p><p>
  543. </p><pre class="programlisting">
  544. void
  545. EndForeignInsert(EState *estate,
  546. ResultRelInfo *rinfo);
  547. </pre><p>
  548. End the insert operation and release resources. It is normally not important
  549. to release palloc'd memory, but for example open files and connections
  550. to remote servers should be cleaned up.
  551. </p><p>
  552. If the <code class="function">EndForeignInsert</code> pointer is set to
  553. <code class="literal">NULL</code>, no action is taken for the termination.
  554. </p><p>
  555. </p><pre class="programlisting">
  556. int
  557. IsForeignRelUpdatable(Relation rel);
  558. </pre><p>
  559. Report which update operations the specified foreign table supports.
  560. The return value should be a bit mask of rule event numbers indicating
  561. which operations are supported by the foreign table, using the
  562. <code class="literal">CmdType</code> enumeration; that is,
  563. <code class="literal">(1 &lt;&lt; CMD_UPDATE) = 4</code> for <code class="command">UPDATE</code>,
  564. <code class="literal">(1 &lt;&lt; CMD_INSERT) = 8</code> for <code class="command">INSERT</code>, and
  565. <code class="literal">(1 &lt;&lt; CMD_DELETE) = 16</code> for <code class="command">DELETE</code>.
  566. </p><p>
  567. If the <code class="function">IsForeignRelUpdatable</code> pointer is set to
  568. <code class="literal">NULL</code>, foreign tables are assumed to be insertable, updatable,
  569. or deletable if the FDW provides <code class="function">ExecForeignInsert</code>,
  570. <code class="function">ExecForeignUpdate</code>, or <code class="function">ExecForeignDelete</code>
  571. respectively. This function is only needed if the FDW supports some
  572. tables that are updatable and some that are not. (Even then, it's
  573. permissible to throw an error in the execution routine instead of
  574. checking in this function. However, this function is used to determine
  575. updatability for display in the <code class="literal">information_schema</code> views.)
  576. </p><p>
  577. Some inserts, updates, and deletes to foreign tables can be optimized
  578. by implementing an alternative set of interfaces. The ordinary
  579. interfaces for inserts, updates, and deletes fetch rows from the remote
  580. server and then modify those rows one at a time. In some cases, this
  581. row-by-row approach is necessary, but it can be inefficient. If it is
  582. possible for the foreign server to determine which rows should be
  583. modified without actually retrieving them, and if there are no local
  584. structures which would affect the operation (row-level local triggers,
  585. stored generated columns, or <code class="literal">WITH CHECK OPTION</code>
  586. constraints from parent views), then it is possible to arrange things
  587. so that the entire operation is performed on the remote server. The
  588. interfaces described below make this possible.
  589. </p><p>
  590. </p><pre class="programlisting">
  591. bool
  592. PlanDirectModify(PlannerInfo *root,
  593. ModifyTable *plan,
  594. Index resultRelation,
  595. int subplan_index);
  596. </pre><p>
  597. Decide whether it is safe to execute a direct modification
  598. on the remote server. If so, return <code class="literal">true</code> after performing
  599. planning actions needed for that. Otherwise, return <code class="literal">false</code>.
  600. This optional function is called during query planning.
  601. If this function succeeds, <code class="function">BeginDirectModify</code>,
  602. <code class="function">IterateDirectModify</code> and <code class="function">EndDirectModify</code> will
  603. be called at the execution stage, instead. Otherwise, the table
  604. modification will be executed using the table-updating functions
  605. described above.
  606. The parameters are the same as for <code class="function">PlanForeignModify</code>.
  607. </p><p>
  608. To execute the direct modification on the remote server, this function
  609. must rewrite the target subplan with a <code class="structname">ForeignScan</code> plan
  610. node that executes the direct modification on the remote server. The
  611. <code class="structfield">operation</code> field of the <code class="structname">ForeignScan</code> must
  612. be set to the <code class="literal">CmdType</code> enumeration appropriately; that is,
  613. <code class="literal">CMD_UPDATE</code> for <code class="command">UPDATE</code>,
  614. <code class="literal">CMD_INSERT</code> for <code class="command">INSERT</code>, and
  615. <code class="literal">CMD_DELETE</code> for <code class="command">DELETE</code>.
  616. </p><p>
  617. See <a class="xref" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Section 56.4</a> for additional information.
  618. </p><p>
  619. If the <code class="function">PlanDirectModify</code> pointer is set to
  620. <code class="literal">NULL</code>, no attempts to execute a direct modification on the
  621. remote server are taken.
  622. </p><p>
  623. </p><pre class="programlisting">
  624. void
  625. BeginDirectModify(ForeignScanState *node,
  626. int eflags);
  627. </pre><p>
  628. Prepare to execute a direct modification on the remote server.
  629. This is called during executor startup. It should perform any
  630. initialization needed prior to the direct modification (that should be
  631. done upon the first call to <code class="function">IterateDirectModify</code>).
  632. The <code class="structname">ForeignScanState</code> node has already been created, but
  633. its <code class="structfield">fdw_state</code> field is still NULL. Information about
  634. the table to modify is accessible through the
  635. <code class="structname">ForeignScanState</code> node (in particular, from the underlying
  636. <code class="structname">ForeignScan</code> plan node, which contains any FDW-private
  637. information provided by <code class="function">PlanDirectModify</code>).
  638. <code class="literal">eflags</code> contains flag bits describing the executor's
  639. operating mode for this plan node.
  640. </p><p>
  641. Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
  642. true, this function should not perform any externally-visible actions;
  643. it should only do the minimum required to make the node state valid
  644. for <code class="function">ExplainDirectModify</code> and <code class="function">EndDirectModify</code>.
  645. </p><p>
  646. If the <code class="function">BeginDirectModify</code> pointer is set to
  647. <code class="literal">NULL</code>, no attempts to execute a direct modification on the
  648. remote server are taken.
  649. </p><p>
  650. </p><pre class="programlisting">
  651. TupleTableSlot *
  652. IterateDirectModify(ForeignScanState *node);
  653. </pre><p>
  654. When the <code class="command">INSERT</code>, <code class="command">UPDATE</code> or <code class="command">DELETE</code>
  655. query doesn't have a <code class="literal">RETURNING</code> clause, just return NULL
  656. after a direct modification on the remote server.
  657. When the query has the clause, fetch one result containing the data
  658. needed for the <code class="literal">RETURNING</code> calculation, returning it in a
  659. tuple table slot (the node's <code class="structfield">ScanTupleSlot</code> should be
  660. used for this purpose). The data that was actually inserted, updated
  661. or deleted must be stored in the
  662. <code class="literal">es_result_relation_info-&gt;ri_projectReturning-&gt;pi_exprContext-&gt;ecxt_scantuple</code>
  663. of the node's <code class="structname">EState</code>.
  664. Return NULL if no more rows are available.
  665. Note that this is called in a short-lived memory context that will be
  666. reset between invocations. Create a memory context in
  667. <code class="function">BeginDirectModify</code> if you need longer-lived storage, or use
  668. the <code class="structfield">es_query_cxt</code> of the node's <code class="structname">EState</code>.
  669. </p><p>
  670. The rows returned must match the <code class="structfield">fdw_scan_tlist</code> target
  671. list if one was supplied, otherwise they must match the row type of the
  672. foreign table being updated. If you choose to optimize away fetching
  673. columns that are not needed for the <code class="literal">RETURNING</code> calculation,
  674. you should insert nulls in those column positions, or else generate a
  675. <code class="structfield">fdw_scan_tlist</code> list with those columns omitted.
  676. </p><p>
  677. Whether the query has the clause or not, the query's reported row count
  678. must be incremented by the FDW itself. When the query doesn't have the
  679. clause, the FDW must also increment the row count for the
  680. <code class="structname">ForeignScanState</code> node in the <code class="command">EXPLAIN ANALYZE</code>
  681. case.
  682. </p><p>
  683. If the <code class="function">IterateDirectModify</code> pointer is set to
  684. <code class="literal">NULL</code>, no attempts to execute a direct modification on the
  685. remote server are taken.
  686. </p><p>
  687. </p><pre class="programlisting">
  688. void
  689. EndDirectModify(ForeignScanState *node);
  690. </pre><p>
  691. Clean up following a direct modification on the remote server. It is
  692. normally not important to release palloc'd memory, but for example open
  693. files and connections to the remote server should be cleaned up.
  694. </p><p>
  695. If the <code class="function">EndDirectModify</code> pointer is set to
  696. <code class="literal">NULL</code>, no attempts to execute a direct modification on the
  697. remote server are taken.
  698. </p></div><div class="sect2" id="FDW-CALLBACKS-ROW-LOCKING"><div class="titlepage"><div><div><h3 class="title">56.2.5. FDW Routines for Row Locking</h3></div></div></div><p>
  699. If an FDW wishes to support <em class="firstterm">late row locking</em> (as described
  700. in <a class="xref" href="fdw-row-locking.html" title="56.5. Row Locking in Foreign Data Wrappers">Section 56.5</a>), it must provide the following
  701. callback functions:
  702. </p><p>
  703. </p><pre class="programlisting">
  704. RowMarkType
  705. GetForeignRowMarkType(RangeTblEntry *rte,
  706. LockClauseStrength strength);
  707. </pre><p>
  708. Report which row-marking option to use for a foreign table.
  709. <code class="literal">rte</code> is the <code class="structname">RangeTblEntry</code> node for the table
  710. and <code class="literal">strength</code> describes the lock strength requested by the
  711. relevant <code class="literal">FOR UPDATE/SHARE</code> clause, if any. The result must be
  712. a member of the <code class="literal">RowMarkType</code> enum type.
  713. </p><p>
  714. This function is called during query planning for each foreign table that
  715. appears in an <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or <code class="command">SELECT
  716. FOR UPDATE/SHARE</code> query and is not the target of <code class="command">UPDATE</code>
  717. or <code class="command">DELETE</code>.
  718. </p><p>
  719. If the <code class="function">GetForeignRowMarkType</code> pointer is set to
  720. <code class="literal">NULL</code>, the <code class="literal">ROW_MARK_COPY</code> option is always used.
  721. (This implies that <code class="function">RefetchForeignRow</code> will never be called,
  722. so it need not be provided either.)
  723. </p><p>
  724. See <a class="xref" href="fdw-row-locking.html" title="56.5. Row Locking in Foreign Data Wrappers">Section 56.5</a> for more information.
  725. </p><p>
  726. </p><pre class="programlisting">
  727. void
  728. RefetchForeignRow(EState *estate,
  729. ExecRowMark *erm,
  730. Datum rowid,
  731. TupleTableSlot *slot,
  732. bool *updated);
  733. </pre><p>
  734. Re-fetch one tuple slot from the foreign table, after locking it if required.
  735. <code class="literal">estate</code> is global execution state for the query.
  736. <code class="literal">erm</code> is the <code class="structname">ExecRowMark</code> struct describing
  737. the target foreign table and the row lock type (if any) to acquire.
  738. <code class="literal">rowid</code> identifies the tuple to be fetched.
  739. <code class="literal">slot</code> contains nothing useful upon call, but can be used to
  740. hold the returned tuple. <code class="literal">updated</code> is an output parameter.
  741. </p><p>
  742. This function should store the tuple into the provided slot, or clear it if
  743. the row lock couldn't be obtained. The row lock type to acquire is
  744. defined by <code class="literal">erm-&gt;markType</code>, which is the value
  745. previously returned by <code class="function">GetForeignRowMarkType</code>.
  746. (<code class="literal">ROW_MARK_REFERENCE</code> means to just re-fetch the tuple
  747. without acquiring any lock, and <code class="literal">ROW_MARK_COPY</code> will
  748. never be seen by this routine.)
  749. </p><p>
  750. In addition, <code class="literal">*updated</code> should be set to <code class="literal">true</code>
  751. if what was fetched was an updated version of the tuple rather than
  752. the same version previously obtained. (If the FDW cannot be sure about
  753. this, always returning <code class="literal">true</code> is recommended.)
  754. </p><p>
  755. Note that by default, failure to acquire a row lock should result in
  756. raising an error; returning with an empty slot is only appropriate if
  757. the <code class="literal">SKIP LOCKED</code> option is specified
  758. by <code class="literal">erm-&gt;waitPolicy</code>.
  759. </p><p>
  760. The <code class="literal">rowid</code> is the <code class="structfield">ctid</code> value previously read
  761. for the row to be re-fetched. Although the <code class="literal">rowid</code> value is
  762. passed as a <code class="type">Datum</code>, it can currently only be a <code class="type">tid</code>. The
  763. function API is chosen in hopes that it may be possible to allow other
  764. data types for row IDs in future.
  765. </p><p>
  766. If the <code class="function">RefetchForeignRow</code> pointer is set to
  767. <code class="literal">NULL</code>, attempts to re-fetch rows will fail
  768. with an error message.
  769. </p><p>
  770. See <a class="xref" href="fdw-row-locking.html" title="56.5. Row Locking in Foreign Data Wrappers">Section 56.5</a> for more information.
  771. </p><p>
  772. </p><pre class="programlisting">
  773. bool
  774. RecheckForeignScan(ForeignScanState *node,
  775. TupleTableSlot *slot);
  776. </pre><p>
  777. Recheck that a previously-returned tuple still matches the relevant
  778. scan and join qualifiers, and possibly provide a modified version of
  779. the tuple. For foreign data wrappers which do not perform join pushdown,
  780. it will typically be more convenient to set this to <code class="literal">NULL</code> and
  781. instead set <code class="structfield">fdw_recheck_quals</code> appropriately.
  782. When outer joins are pushed down, however, it isn't sufficient to
  783. reapply the checks relevant to all the base tables to the result tuple,
  784. even if all needed attributes are present, because failure to match some
  785. qualifier might result in some attributes going to NULL, rather than in
  786. no tuple being returned. <code class="literal">RecheckForeignScan</code> can recheck
  787. qualifiers and return true if they are still satisfied and false
  788. otherwise, but it can also store a replacement tuple into the supplied
  789. slot.
  790. </p><p>
  791. To implement join pushdown, a foreign data wrapper will typically
  792. construct an alternative local join plan which is used only for
  793. rechecks; this will become the outer subplan of the
  794. <code class="literal">ForeignScan</code>. When a recheck is required, this subplan
  795. can be executed and the resulting tuple can be stored in the slot.
  796. This plan need not be efficient since no base table will return more
  797. than one row; for example, it may implement all joins as nested loops.
  798. The function <code class="literal">GetExistingLocalJoinPath</code> may be used to search
  799. existing paths for a suitable local join path, which can be used as the
  800. alternative local join plan. <code class="literal">GetExistingLocalJoinPath</code>
  801. searches for an unparameterized path in the path list of the specified
  802. join relation. (If it does not find such a path, it returns NULL, in
  803. which case a foreign data wrapper may build the local path by itself or
  804. may choose not to create access paths for that join.)
  805. </p></div><div class="sect2" id="FDW-CALLBACKS-EXPLAIN"><div class="titlepage"><div><div><h3 class="title">56.2.6. FDW Routines for <code class="command">EXPLAIN</code></h3></div></div></div><p>
  806. </p><pre class="programlisting">
  807. void
  808. ExplainForeignScan(ForeignScanState *node,
  809. ExplainState *es);
  810. </pre><p>
  811. Print additional <code class="command">EXPLAIN</code> output for a foreign table scan.
  812. This function can call <code class="function">ExplainPropertyText</code> and
  813. related functions to add fields to the <code class="command">EXPLAIN</code> output.
  814. The flag fields in <code class="literal">es</code> can be used to determine what to
  815. print, and the state of the <code class="structname">ForeignScanState</code> node
  816. can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
  817. ANALYZE</code> case.
  818. </p><p>
  819. If the <code class="function">ExplainForeignScan</code> pointer is set to
  820. <code class="literal">NULL</code>, no additional information is printed during
  821. <code class="command">EXPLAIN</code>.
  822. </p><p>
  823. </p><pre class="programlisting">
  824. void
  825. ExplainForeignModify(ModifyTableState *mtstate,
  826. ResultRelInfo *rinfo,
  827. List *fdw_private,
  828. int subplan_index,
  829. struct ExplainState *es);
  830. </pre><p>
  831. Print additional <code class="command">EXPLAIN</code> output for a foreign table update.
  832. This function can call <code class="function">ExplainPropertyText</code> and
  833. related functions to add fields to the <code class="command">EXPLAIN</code> output.
  834. The flag fields in <code class="literal">es</code> can be used to determine what to
  835. print, and the state of the <code class="structname">ModifyTableState</code> node
  836. can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
  837. ANALYZE</code> case. The first four arguments are the same as for
  838. <code class="function">BeginForeignModify</code>.
  839. </p><p>
  840. If the <code class="function">ExplainForeignModify</code> pointer is set to
  841. <code class="literal">NULL</code>, no additional information is printed during
  842. <code class="command">EXPLAIN</code>.
  843. </p><p>
  844. </p><pre class="programlisting">
  845. void
  846. ExplainDirectModify(ForeignScanState *node,
  847. ExplainState *es);
  848. </pre><p>
  849. Print additional <code class="command">EXPLAIN</code> output for a direct modification
  850. on the remote server.
  851. This function can call <code class="function">ExplainPropertyText</code> and
  852. related functions to add fields to the <code class="command">EXPLAIN</code> output.
  853. The flag fields in <code class="literal">es</code> can be used to determine what to
  854. print, and the state of the <code class="structname">ForeignScanState</code> node
  855. can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
  856. ANALYZE</code> case.
  857. </p><p>
  858. If the <code class="function">ExplainDirectModify</code> pointer is set to
  859. <code class="literal">NULL</code>, no additional information is printed during
  860. <code class="command">EXPLAIN</code>.
  861. </p></div><div class="sect2" id="FDW-CALLBACKS-ANALYZE"><div class="titlepage"><div><div><h3 class="title">56.2.7. FDW Routines for <code class="command">ANALYZE</code></h3></div></div></div><p>
  862. </p><pre class="programlisting">
  863. bool
  864. AnalyzeForeignTable(Relation relation,
  865. AcquireSampleRowsFunc *func,
  866. BlockNumber *totalpages);
  867. </pre><p>
  868. This function is called when <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a> is executed on
  869. a foreign table. If the FDW can collect statistics for this
  870. foreign table, it should return <code class="literal">true</code>, and provide a pointer
  871. to a function that will collect sample rows from the table in
  872. <em class="parameter"><code>func</code></em>, plus the estimated size of the table in pages in
  873. <em class="parameter"><code>totalpages</code></em>. Otherwise, return <code class="literal">false</code>.
  874. </p><p>
  875. If the FDW does not support collecting statistics for any tables, the
  876. <code class="function">AnalyzeForeignTable</code> pointer can be set to <code class="literal">NULL</code>.
  877. </p><p>
  878. If provided, the sample collection function must have the signature
  879. </p><pre class="programlisting">
  880. int
  881. AcquireSampleRowsFunc(Relation relation,
  882. int elevel,
  883. HeapTuple *rows,
  884. int targrows,
  885. double *totalrows,
  886. double *totaldeadrows);
  887. </pre><p>
  888. A random sample of up to <em class="parameter"><code>targrows</code></em> rows should be collected
  889. from the table and stored into the caller-provided <em class="parameter"><code>rows</code></em>
  890. array. The actual number of rows collected must be returned. In
  891. addition, store estimates of the total numbers of live and dead rows in
  892. the table into the output parameters <em class="parameter"><code>totalrows</code></em> and
  893. <em class="parameter"><code>totaldeadrows</code></em>. (Set <em class="parameter"><code>totaldeadrows</code></em> to zero
  894. if the FDW does not have any concept of dead rows.)
  895. </p></div><div class="sect2" id="FDW-CALLBACKS-IMPORT"><div class="titlepage"><div><div><h3 class="title">56.2.8. FDW Routines for <code class="command">IMPORT FOREIGN SCHEMA</code></h3></div></div></div><p>
  896. </p><pre class="programlisting">
  897. List *
  898. ImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid);
  899. </pre><p>
  900. Obtain a list of foreign table creation commands. This function is
  901. called when executing <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>, and is
  902. passed the parse tree for that statement, as well as the OID of the
  903. foreign server to use. It should return a list of C strings, each of
  904. which must contain a <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a> command.
  905. These strings will be parsed and executed by the core server.
  906. </p><p>
  907. Within the <code class="structname">ImportForeignSchemaStmt</code> struct,
  908. <code class="structfield">remote_schema</code> is the name of the remote schema from
  909. which tables are to be imported.
  910. <code class="structfield">list_type</code> identifies how to filter table names:
  911. <code class="literal">FDW_IMPORT_SCHEMA_ALL</code> means that all tables in the remote
  912. schema should be imported (in this case <code class="structfield">table_list</code> is
  913. empty), <code class="literal">FDW_IMPORT_SCHEMA_LIMIT_TO</code> means to include only
  914. tables listed in <code class="structfield">table_list</code>,
  915. and <code class="literal">FDW_IMPORT_SCHEMA_EXCEPT</code> means to exclude the tables
  916. listed in <code class="structfield">table_list</code>.
  917. <code class="structfield">options</code> is a list of options used for the import process.
  918. The meanings of the options are up to the FDW.
  919. For example, an FDW could use an option to define whether the
  920. <code class="literal">NOT NULL</code> attributes of columns should be imported.
  921. These options need not have anything to do with those supported by the
  922. FDW as database object options.
  923. </p><p>
  924. The FDW may ignore the <code class="structfield">local_schema</code> field of
  925. the <code class="structname">ImportForeignSchemaStmt</code>, because the core server
  926. will automatically insert that name into the parsed <code class="command">CREATE
  927. FOREIGN TABLE</code> commands.
  928. </p><p>
  929. The FDW does not have to concern itself with implementing the filtering
  930. specified by <code class="structfield">list_type</code> and <code class="structfield">table_list</code>,
  931. either, as the core server will automatically skip any returned commands
  932. for tables excluded according to those options. However, it's often
  933. useful to avoid the work of creating commands for excluded tables in the
  934. first place. The function <code class="function">IsImportableForeignTable()</code> may be
  935. useful to test whether a given foreign-table name will pass the filter.
  936. </p><p>
  937. If the FDW does not support importing table definitions, the
  938. <code class="function">ImportForeignSchema</code> pointer can be set to <code class="literal">NULL</code>.
  939. </p></div><div class="sect2" id="FDW-CALLBACKS-PARALLEL"><div class="titlepage"><div><div><h3 class="title">56.2.9. FDW Routines for Parallel Execution</h3></div></div></div><p>
  940. A <code class="structname">ForeignScan</code> node can, optionally, support parallel
  941. execution. A parallel <code class="structname">ForeignScan</code> will be executed
  942. in multiple processes and must return each row exactly once across
  943. all cooperating processes. To do this, processes can coordinate through
  944. fixed-size chunks of dynamic shared memory. This shared memory is not
  945. guaranteed to be mapped at the same address in every process, so it
  946. must not contain pointers. The following functions are all optional,
  947. but most are required if parallel execution is to be supported.
  948. </p><p>
  949. </p><pre class="programlisting">
  950. bool
  951. IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
  952. RangeTblEntry *rte);
  953. </pre><p>
  954. Test whether a scan can be performed within a parallel worker. This
  955. function will only be called when the planner believes that a parallel
  956. plan might be possible, and should return true if it is safe for that scan
  957. to run within a parallel worker. This will generally not be the case if
  958. the remote data source has transaction semantics, unless the worker's
  959. connection to the data can somehow be made to share the same transaction
  960. context as the leader.
  961. </p><p>
  962. If this function is not defined, it is assumed that the scan must take
  963. place within the parallel leader. Note that returning true does not mean
  964. that the scan itself can be done in parallel, only that the scan can be
  965. performed within a parallel worker. Therefore, it can be useful to define
  966. this method even when parallel execution is not supported.
  967. </p><p>
  968. </p><pre class="programlisting">
  969. Size
  970. EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt);
  971. </pre><p>
  972. Estimate the amount of dynamic shared memory that will be required
  973. for parallel operation. This may be higher than the amount that will
  974. actually be used, but it must not be lower. The return value is in bytes.
  975. This function is optional, and can be omitted if not needed; but if it
  976. is omitted, the next three functions must be omitted as well, because
  977. no shared memory will be allocated for the FDW's use.
  978. </p><p>
  979. </p><pre class="programlisting">
  980. void
  981. InitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
  982. void *coordinate);
  983. </pre><p>
  984. Initialize the dynamic shared memory that will be required for parallel
  985. operation. <code class="literal">coordinate</code> points to a shared memory area of
  986. size equal to the return value of <code class="function">EstimateDSMForeignScan</code>.
  987. This function is optional, and can be omitted if not needed.
  988. </p><p>
  989. </p><pre class="programlisting">
  990. void
  991. ReInitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
  992. void *coordinate);
  993. </pre><p>
  994. Re-initialize the dynamic shared memory required for parallel operation
  995. when the foreign-scan plan node is about to be re-scanned.
  996. This function is optional, and can be omitted if not needed.
  997. Recommended practice is that this function reset only shared state,
  998. while the <code class="function">ReScanForeignScan</code> function resets only local
  999. state. Currently, this function will be called
  1000. before <code class="function">ReScanForeignScan</code>, but it's best not to rely on
  1001. that ordering.
  1002. </p><p>
  1003. </p><pre class="programlisting">
  1004. void
  1005. InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc,
  1006. void *coordinate);
  1007. </pre><p>
  1008. Initialize a parallel worker's local state based on the shared state
  1009. set up by the leader during <code class="function">InitializeDSMForeignScan</code>.
  1010. This function is optional, and can be omitted if not needed.
  1011. </p><p>
  1012. </p><pre class="programlisting">
  1013. void
  1014. ShutdownForeignScan(ForeignScanState *node);
  1015. </pre><p>
  1016. Release resources when it is anticipated the node will not be executed
  1017. to completion. This is not called in all cases; sometimes,
  1018. <code class="literal">EndForeignScan</code> may be called without this function having
  1019. been called first. Since the DSM segment used by parallel query is
  1020. destroyed just after this callback is invoked, foreign data wrappers that
  1021. wish to take some action before the DSM segment goes away should implement
  1022. this method.
  1023. </p></div><div class="sect2" id="FDW-CALLBACKS-REPARAMETERIZE-PATHS"><div class="titlepage"><div><div><h3 class="title">56.2.10. FDW Routines for Reparameterization of Paths</h3></div></div></div><p>
  1024. </p><pre class="programlisting">
  1025. List *
  1026. ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private,
  1027. RelOptInfo *child_rel);
  1028. </pre><p>
  1029. This function is called while converting a path parameterized by the
  1030. top-most parent of the given child relation <code class="literal">child_rel</code> to be
  1031. parameterized by the child relation. The function is used to reparameterize
  1032. any paths or translate any expression nodes saved in the given
  1033. <code class="literal">fdw_private</code> member of a <code class="structname">ForeignPath</code>. The
  1034. callback may use <code class="literal">reparameterize_path_by_child</code>,
  1035. <code class="literal">adjust_appendrel_attrs</code> or
  1036. <code class="literal">adjust_appendrel_attrs_multilevel</code> as required.
  1037. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-functions.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-helpers.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.1. Foreign Data Wrapper Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 56.3. Foreign Data Wrapper Helper Functions</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1