From 28048cbaa285b8ac46940e4b39f985d9885fc698 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 14 Mar 2016 17:31:28 -0400
Subject: [PATCH] Allow callers of create_foreignscan_path to specify
 nondefault PathTarget.

Although the default choice of rel->reltarget should typically be
sufficient for scan or join paths, it's not at all sufficient for the
purposes PathTargets were invented for; in particular not for
upper-relation Paths.  So break API compatibility by adding a PathTarget
argument to create_foreignscan_path().  To ease updating of existing
code, accept a NULL value of the argument as selecting rel->reltarget.
---
 contrib/file_fdw/file_fdw.c           | 1 +
 contrib/postgres_fdw/postgres_fdw.c   | 4 ++++
 src/backend/optimizer/util/pathnode.c | 7 +++++--
 src/include/optimizer/pathnode.h      | 1 +
 4 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index 0ac4658e84d..bc4d2d70824 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -524,6 +524,7 @@ fileGetForeignPaths(PlannerInfo *root,
 	 */
 	add_path(baserel, (Path *)
 			 create_foreignscan_path(root, baserel,
+									 NULL,		/* default pathtarget */
 									 baserel->rows,
 									 startup_cost,
 									 total_cost,
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index d4ee2a8548f..96875b41848 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -793,6 +793,7 @@ postgresGetForeignPaths(PlannerInfo *root,
 	 * to estimate cost and size of this path.
 	 */
 	path = create_foreignscan_path(root, baserel,
+								   NULL,		/* default pathtarget */
 								   fpinfo->rows,
 								   fpinfo->startup_cost,
 								   fpinfo->total_cost,
@@ -964,6 +965,7 @@ postgresGetForeignPaths(PlannerInfo *root,
 
 		/* Make the path */
 		path = create_foreignscan_path(root, baserel,
+									   NULL,	/* default pathtarget */
 									   rows,
 									   startup_cost,
 									   total_cost,
@@ -3565,6 +3567,7 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel,
 
 		add_path(rel, (Path *)
 				 create_foreignscan_path(root, rel,
+										 NULL,
 										 rows,
 										 startup_cost,
 										 total_cost,
@@ -3702,6 +3705,7 @@ postgresGetForeignJoinPaths(PlannerInfo *root,
 	 */
 	joinpath = create_foreignscan_path(root,
 									   joinrel,
+									   NULL,	/* default pathtarget */
 									   rows,
 									   startup_cost,
 									   total_cost,
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 8f089c59884..675e47cdd01 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -1819,10 +1819,13 @@ create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel,
  * This function is never called from core Postgres; rather, it's expected
  * to be called by the GetForeignPaths or GetForeignJoinPaths function of
  * a foreign data wrapper.  We make the FDW supply all fields of the path,
- * since we do not have any way to calculate them in core.
+ * since we do not have any way to calculate them in core.  However, there
+ * is a sane default for the pathtarget (rel->reltarget), so we let a NULL
+ * for "target" select that.
  */
 ForeignPath *
 create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
+						PathTarget *target,
 						double rows, Cost startup_cost, Cost total_cost,
 						List *pathkeys,
 						Relids required_outer,
@@ -1833,7 +1836,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
 
 	pathnode->path.pathtype = T_ForeignScan;
 	pathnode->path.parent = rel;
-	pathnode->path.pathtarget = rel->reltarget;
+	pathnode->path.pathtarget = target ? target : rel->reltarget;
 	pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
 														  required_outer);
 	pathnode->path.parallel_aware = false;
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 3007adb8c2d..d1eb22f27a4 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -87,6 +87,7 @@ extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel,
 extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel,
 						  Relids required_outer);
 extern ForeignPath *create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel,
+						PathTarget *target,
 						double rows, Cost startup_cost, Cost total_cost,
 						List *pathkeys,
 						Relids required_outer,
-- 
GitLab