Content-Length: 485281 | pFad | http://github.com/tonybelloni/postgres/commit/35746bc348b6bf1f690fe17f4f80cfb68e22f504

78 Add new FDW API to test for parallel-safety. · tonybelloni/postgres@35746bc · GitHub
Skip to content

Commit 35746bc

Browse files
committed
Add new FDW API to test for parallel-safety.
This is basically a bug fix; the old code assumes that a ForeignScan is always parallel-safe, but for postgres_fdw, for example, this is definitely false. It should be true for file_fdw, though, since a worker can read a file from the filesystem just as well as any other backend process. Original patch by Thomas Munro. Documentation, and changes to the comments, by me.
1 parent 9117985 commit 35746bc

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

contrib/file_fdw/file_fdw.c

+15
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static void fileEndForeignScan(ForeignScanState *node);
131131
static bool fileAnalyzeForeignTable(Relation relation,
132132
AcquireSampleRowsFunc *func,
133133
BlockNumber *totalpages);
134+
static bool fileIsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
135+
RangeTblEntry *rte);
134136

135137
/*
136138
* Helper functions
@@ -170,6 +172,7 @@ file_fdw_handler(PG_FUNCTION_ARGS)
170172
fdwroutine->ReScanForeignScan = fileReScanForeignScan;
171173
fdwroutine->EndForeignScan = fileEndForeignScan;
172174
fdwroutine->AnalyzeForeignTable = fileAnalyzeForeignTable;
175+
fdwroutine->IsForeignScanParallelSafe = fileIsForeignScanParallelSafe;
173176

174177
PG_RETURN_POINTER(fdwroutine);
175178
}
@@ -761,6 +764,18 @@ fileAnalyzeForeignTable(Relation relation,
761764
return true;
762765
}
763766

767+
/*
768+
* fileIsForeignScanParallelSafe
769+
* Reading a file in a parallel worker should work just the same as
770+
* reading it in the leader, so mark scans safe.
771+
*/
772+
static bool
773+
fileIsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
774+
RangeTblEntry *rte)
775+
{
776+
return true;
777+
}
778+
764779
/*
765780
* check_selective_binary_conversion
766781
*

doc/src/sgml/fdwhandler.sgml

+23
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,29 @@ ImportForeignSchema (ImportForeignSchemaStmt *stmt, Oid serverOid);
988988
<para>
989989
<programlisting>
990990
Size
991+
IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
992+
RangeTblEntry *rte);
993+
</programlisting>
994+
Test whether a scan can be performed within a parallel worker. This
995+
function will only be called when the planner believes that a parallel
996+
plan might be possible, and should return true if it is safe for that scan
997+
to run within a parallel worker. This will generally not be the case if
998+
the remote data source has transaction semantics, unless the worker's
999+
connection to the data can somehow be made to share the same transaction
1000+
context as the leader.
1001+
</para>
1002+
1003+
<para>
1004+
If this callback is not defined, it is assumed that the scan must take
1005+
place within the parallel leader. Note that returning true does not mean
1006+
that the scan itself can be done in parallel, only that the scan can be
1007+
performed within a parallel worker. Therefore, it can be useful to define
1008+
this method even when parallel execution is not supported.
1009+
</para>
1010+
1011+
<para>
1012+
<programlisting>
1013+
Size
9911014
EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt);
9921015
</programlisting>
9931016
Estimate the amount of dynamic shared memory that will be required

src/backend/optimizer/path/allpaths.c

+17
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,23 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
527527
return;
528528
return;
529529
}
530+
531+
/*
532+
* Ask FDWs whether they can support performing a ForeignScan
533+
* within a worker. Most often, the answer will be no. For
534+
* example, if the nature of the FDW is such that it opens a TCP
535+
* connection with a remote server, each parallel worker would end
536+
* up with a separate connection, and these connections might not
537+
* be appropriately coordinated between workers and the leader.
538+
*/
539+
if (rte->relkind == RELKIND_FOREIGN_TABLE)
540+
{
541+
Assert(rel->fdwroutine);
542+
if (!rel->fdwroutine->IsForeignScanParallelSafe)
543+
return;
544+
if (!rel->fdwroutine->IsForeignScanParallelSafe(root, rel, rte))
545+
return;
546+
}
530547
break;
531548

532549
case RTE_SUBQUERY:

src/include/foreign/fdwapi.h

+5
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ typedef void (*InitializeDSMForeignScan_function) (ForeignScanState *node,
131131
typedef void (*InitializeWorkerForeignScan_function) (ForeignScanState *node,
132132
shm_toc *toc,
133133
void *coordinate);
134+
typedef bool (*IsForeignScanParallelSafe_function) (PlannerInfo *root,
135+
RelOptInfo *rel,
136+
RangeTblEntry *rte);
137+
134138
/*
135139
* FdwRoutine is the struct returned by a foreign-data wrapper's handler
136140
* function. It provides pointers to the callback functions needed by the
@@ -188,6 +192,7 @@ typedef struct FdwRoutine
188192
ImportForeignSchema_function ImportForeignSchema;
189193

190194
/* Support functions for parallelism under Gather node */
195+
IsForeignScanParallelSafe_function IsForeignScanParallelSafe;
191196
EstimateDSMForeignScan_function EstimateDSMForeignScan;
192197
InitializeDSMForeignScan_function InitializeDSMForeignScan;
193198
InitializeWorkerForeignScan_function InitializeWorkerForeignScan;

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tonybelloni/postgres/commit/35746bc348b6bf1f690fe17f4f80cfb68e22f504

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy