@@ -43,6 +43,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
4343JoinPathExtraData * extra )
4444{
4545JoinCostWorkspace workspace ;
46+ JoinType saved_jointype = jointype ;
4647RangeTblEntry * inner_rte = root -> simple_rte_array [innerrel -> relid ];
4748const PartRelationInfo * inner_prel ;
4849List * pathkeys = NIL ,
@@ -118,6 +119,12 @@ pathman_join_pathlist_hook(PlannerInfo *root,
118119
119120/* Select cheapest path for outerrel */
120121outer = outerrel -> cheapest_total_path ;
122+ if (saved_jointype == JOIN_UNIQUE_OUTER )
123+ {
124+ outer = (Path * )create_unique_path (root ,outerrel ,
125+ outer ,extra -> sjinfo );
126+ Assert (outer );
127+ }
121128
122129/* Make innerrel path depend on outerrel's column */
123130inner_required = bms_union (PATH_REQ_OUTER ((Path * )cur_inner_path ),
@@ -133,6 +140,8 @@ pathman_join_pathlist_hook(PlannerInfo *root,
133140continue ;
134141
135142inner = create_runtimeappend_path (root ,cur_inner_path ,ppi ,paramsel );
143+ if (saved_jointype == JOIN_UNIQUE_INNER )
144+ return ;/* No way to do this with a parameterized inner path */
136145
137146initial_cost_nestloop (root ,& workspace ,jointype ,
138147outer ,inner ,/* built paths */
@@ -204,7 +213,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
204213Oid * children ;
205214List * ranges ,
206215* wrappers ,
207- * rel_partattr_clauses = NIL ;
216+ * rel_part_clauses = NIL ;
208217PathKey * pathkeyAsc = NULL ,
209218* pathkeyDesc = NULL ;
210219double paramsel = 1.0 ;
@@ -310,8 +319,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
310319IndexRange irange = lfirst_irange (lc );
311320
312321for (i = irange .ir_lower ;i <=irange .ir_upper ;i ++ )
313- append_child_relation (root ,rel ,rti ,rte ,i ,children [i ],
314- wrappers );
322+ append_child_relation (root ,rel ,rti ,rte ,i ,children [i ],wrappers );
315323}
316324
317325/* Clear old path list */
@@ -327,19 +335,26 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
327335return ;
328336
329337/* Check that rel's RestrictInfo contains partitioned column */
330- rel_partattr_clauses = get_partitioned_attr_clauses (rel -> baserestrictinfo ,
331- prel ,rel -> relid );
338+ rel_part_clauses = get_partitioned_attr_clauses (rel -> baserestrictinfo ,
339+ prel ,rel -> relid );
332340
333341/* Runtime[Merge]Append is pointless if there are no params in clauses */
334- if (!clause_contains_params ((Node * )rel_partattr_clauses ))
342+ if (!clause_contains_params ((Node * )rel_part_clauses ))
335343return ;
336344
337345foreach (lc ,rel -> pathlist )
338346{
339347AppendPath * cur_path = (AppendPath * )lfirst (lc );
340348Relids inner_required = PATH_REQ_OUTER ((Path * )cur_path );
341- ParamPathInfo * ppi = get_baserel_parampathinfo (root ,rel ,inner_required );
342349Path * inner_path = NULL ;
350+ ParamPathInfo * ppi ;
351+ List * ppi_part_clauses = NIL ;
352+
353+ /* Fetch ParamPathInfo & try to extract part-related clauses */
354+ ppi = get_baserel_parampathinfo (root ,rel ,inner_required );
355+ if (ppi && ppi -> ppi_clauses )
356+ ppi_part_clauses = get_partitioned_attr_clauses (ppi -> ppi_clauses ,
357+ prel ,rel -> relid );
343358
344359/* Skip if rel contains some join-related stuff or path type mismatched */
345360if (!(IsA (cur_path ,AppendPath )|| IsA (cur_path ,MergeAppendPath ))||
@@ -352,9 +367,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
352367 * Skip if neither rel->baserestrictinfo nor
353368 * ppi->ppi_clauses reference partition attribute
354369 */
355- if (!(rel_partattr_clauses ||
356- (ppi && get_partitioned_attr_clauses (ppi -> ppi_clauses ,
357- prel ,rel -> relid ))))
370+ if (!(rel_part_clauses || ppi_part_clauses ))
358371continue ;
359372
360373if (IsA (cur_path ,AppendPath )&& pg_pathman_enable_runtimeappend )