@@ -176,7 +176,8 @@ GetForeignPlan (PlannerInfo *root,
176
176
access path. This is called at the end of query planning.
177
177
The parameters are as for <function>GetForeignRelSize</>, plus
178
178
the selected <structname>ForeignPath</> (previously produced by
179
- <function>GetForeignPaths</> or <function>GetForeignJoinPaths</>),
179
+ <function>GetForeignPaths</>, <function>GetForeignJoinPaths</>,
180
+ or <function>GetForeignUpperPaths</>),
180
181
the target list to be emitted by the plan node,
181
182
the restriction clauses to be enforced by the plan node,
182
183
and the outer subplan of the <structname>ForeignScan</>,
@@ -344,6 +345,38 @@ GetForeignJoinPaths (PlannerInfo *root,
344
345
</para>
345
346
</sect2>
346
347
348
+ <sect2 id="fdw-callbacks-upper-planning">
349
+ <title>FDW Routines For Planning Post-Scan/Join Processing</title>
350
+
351
+ <para>
352
+ If an FDW supports performing remote post-scan/join processing, such as
353
+ remote aggregation, it should provide this callback function:
354
+ </para>
355
+
356
+ <para>
357
+ <programlisting>
358
+ void
359
+ GetForeignUpperPaths (PlannerInfo *root,
360
+ RelOptInfo *scan_join_rel);
361
+ </programlisting>
362
+ Create possible access paths for <firstterm>upper relation</> processing,
363
+ which is the planner's term for all post-scan/join query processing, such
364
+ as aggregation, window functions, sorting, and table updates. This
365
+ optional function is called during query planning. Currently, it is
366
+ called only if all base relation(s) involved in the query belong to the
367
+ same FDW. This function should generate <structname>ForeignPath</>
368
+ path(s) for the steps that the FDW knows how to perform remotely, and
369
+ call <function>add_path</> to add these paths to the appropriate upper
370
+ relation. As with <function>GetForeignJoinPaths</>, it is not necessary
371
+ that this function succeed in creating any paths, since paths involving
372
+ local processing are always possible.
373
+ </para>
374
+
375
+ <para>
376
+ See <xref linkend="fdw-planning"> for additional information.
377
+ </para>
378
+ </sect2>
379
+
347
380
<sect2 id="fdw-callbacks-update">
348
381
<title>FDW Routines For Updating Foreign Tables</title>
349
382
@@ -1160,7 +1193,8 @@ GetForeignServerByName(const char *name, bool missing_ok);
1160
1193
<para>
1161
1194
The FDW callback functions <function>GetForeignRelSize</>,
1162
1195
<function>GetForeignPaths</>, <function>GetForeignPlan</>,
1163
- <function>PlanForeignModify</>, and <function>GetForeignJoinPaths</>
1196
+ <function>PlanForeignModify</>, <function>GetForeignJoinPaths</>,
1197
+ and <function>GetForeignUpperPaths</>
1164
1198
must fit into the workings of the <productname>PostgreSQL</> planner.
1165
1199
Here are some notes about what they must do.
1166
1200
</para>
@@ -1322,7 +1356,7 @@ GetForeignServerByName(const char *name, bool missing_ok);
1322
1356
An FDW might additionally support direct execution of some plan actions
1323
1357
that are above the level of scans and joins, such as grouping or
1324
1358
aggregation. To offer such options, the FDW should generate paths
1325
- (probably ForeignPaths or CustomPaths) and insert them into the
1359
+ and insert them into the
1326
1360
appropriate <firstterm>upper relation</>. For example, a path
1327
1361
representing remote aggregation should be inserted into the relation
1328
1362
obtained from <literal>fetch_upper_rel(root, UPPERREL_GROUP_AGG,
@@ -1332,6 +1366,9 @@ GetForeignServerByName(const char *name, bool missing_ok);
1332
1366
else there will be an error at plan time). If the remote-aggregation
1333
1367
path wins, which it usually would, it will be converted into a plan in
1334
1368
the usual way, by calling <function>GetForeignPlan</>.
1369
+ Usually the most convenient place to generate such paths is in
1370
+ the <function>GetForeignUpperPaths</> callback function, although
1371
+ it can be done earlier if that seems appropriate.
1335
1372
</para>
1336
1373
1337
1374
<para>
0 commit comments