* create_foreign_join_path * Creates a path corresponding to a scan of a foreign join, * returning the pathnode. * * This function is never called from core Postgres; rather, it's expected * to be called by the 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. However, there
| 3697 | * the pathtarget (rel->reltarget), so we let a NULL for "target" select that. |
| 3698 | */ |
| 3699 | ForeignPath * |
| 3700 | create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, |
| 3701 | PathTarget *target, |
| 3702 | double rows, Cost startup_cost, Cost total_cost, |
| 3703 | List *pathkeys, |
| 3704 | Relids required_outer, |
| 3705 | Path *fdw_outerpath, |
| 3706 | List *fdw_private) |
| 3707 | { |
| 3708 | ForeignPath *pathnode = makeNode(ForeignPath); |
| 3709 | |
| 3710 | /* |
| 3711 | * We should use get_joinrel_parampathinfo to handle parameterized paths, |
| 3712 | * but the API of this function doesn't support it, and existing |
| 3713 | * extensions aren't yet trying to build such paths anyway. For the |
| 3714 | * moment just throw an error if someone tries it; eventually we should |
| 3715 | * revisit this. |
| 3716 | */ |
| 3717 | if (!bms_is_empty(required_outer) || !bms_is_empty(rel->lateral_relids)) |
| 3718 | elog(ERROR, "parameterized foreign joins are not supported yet"); |
| 3719 | |
| 3720 | pathnode->path.pathtype = T_ForeignScan; |
| 3721 | pathnode->path.parent = rel; |
| 3722 | pathnode->path.pathtarget = target ? target : rel->reltarget; |
| 3723 | pathnode->path.param_info = NULL; /* XXX see above */ |
| 3724 | pathnode->path.parallel_aware = false; |
| 3725 | pathnode->path.parallel_safe = rel->consider_parallel; |
| 3726 | pathnode->path.parallel_workers = 0; |
| 3727 | pathnode->path.rows = rows; |
| 3728 | pathnode->path.startup_cost = startup_cost; |
| 3729 | pathnode->path.total_cost = total_cost; |
| 3730 | pathnode->path.pathkeys = pathkeys; |
| 3731 | if (Gp_role == GP_ROLE_DISPATCH) |
| 3732 | { |
| 3733 | make_cdbpathlocus_for_foreign_relations(root, rel, pathnode); |
| 3734 | } |
| 3735 | else |
| 3736 | { |
| 3737 | /* make entry locus for utility role */ |
| 3738 | CdbPathLocus_MakeEntry(&(pathnode->path.locus)); |
| 3739 | } |
| 3740 | pathnode->fdw_outerpath = fdw_outerpath; |
| 3741 | pathnode->fdw_private = fdw_private; |
| 3742 | |
| 3743 | return pathnode; |
| 3744 | } |
| 3745 | |
| 3746 | /* |
| 3747 | * create_foreign_upper_path |
no test coverage detected