Allow callers of create_foreignscan_path to specify nondefault PathTarget.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 Mar 2016 21:31:28 +0000 (17:31 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 Mar 2016 21:31:28 +0000 (17:31 -0400)
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
contrib/postgres_fdw/postgres_fdw.c
src/backend/optimizer/util/pathnode.c
src/include/optimizer/pathnode.h

index 0ac4658e84dc2a5da3f29e88a38225364547c687..bc4d2d708246d04cc2d5e3bdcc65b5912c1a6ec7 100644 (file)
@@ -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,
index d4ee2a8548fa0dc485d08c852c9f6d8266c9df63..96875b418486fcc1d1739d2af3a5a864e65f367a 100644 (file)
@@ -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,
index 8f089c59884f7232a94062b810c75c0471a44f92..675e47cdd01e5a63d9eb0d8250f0d667c31eac18 100644 (file)
@@ -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;
index 3007adb8c2dfb6445ebd576be0771e088d8a37a4..d1eb22f27a459a5b0f29734469a27ba5b4cd5b14 100644 (file)
@@ -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,