@@ -43,6 +43,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
43
43
JoinPathExtraData * extra )
44
44
{
45
45
JoinCostWorkspace workspace ;
46
+ JoinType saved_jointype = jointype ;
46
47
RangeTblEntry * inner_rte = root -> simple_rte_array [innerrel -> relid ];
47
48
const PartRelationInfo * inner_prel ;
48
49
List * pathkeys = NIL ,
@@ -118,6 +119,12 @@ pathman_join_pathlist_hook(PlannerInfo *root,
118
119
119
120
/* Select cheapest path for outerrel */
120
121
outer = 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
+ }
121
128
122
129
/* Make innerrel path depend on outerrel's column */
123
130
inner_required = bms_union (PATH_REQ_OUTER ((Path * )cur_inner_path ),
@@ -133,6 +140,8 @@ pathman_join_pathlist_hook(PlannerInfo *root,
133
140
continue ;
134
141
135
142
inner = 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 */
136
145
137
146
initial_cost_nestloop (root ,& workspace ,jointype ,
138
147
outer ,inner ,/* built paths */
@@ -204,7 +213,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
204
213
Oid * children ;
205
214
List * ranges ,
206
215
* wrappers ,
207
- * rel_partattr_clauses = NIL ;
216
+ * rel_part_clauses = NIL ;
208
217
PathKey * pathkeyAsc = NULL ,
209
218
* pathkeyDesc = NULL ;
210
219
double paramsel = 1.0 ;
@@ -310,8 +319,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
310
319
IndexRange irange = lfirst_irange (lc );
311
320
312
321
for (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 );
315
323
}
316
324
317
325
/* Clear old path list */
@@ -327,19 +335,26 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
327
335
return ;
328
336
329
337
/* 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 );
332
340
333
341
/* 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 ))
335
343
return ;
336
344
337
345
foreach (lc ,rel -> pathlist )
338
346
{
339
347
AppendPath * cur_path = (AppendPath * )lfirst (lc );
340
348
Relids inner_required = PATH_REQ_OUTER ((Path * )cur_path );
341
- ParamPathInfo * ppi = get_baserel_parampathinfo (root ,rel ,inner_required );
342
349
Path * 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 );
343
358
344
359
/* Skip if rel contains some join-related stuff or path type mismatched */
345
360
if (!(IsA (cur_path ,AppendPath )|| IsA (cur_path ,MergeAppendPath ))||
@@ -352,9 +367,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
352
367
* Skip if neither rel->baserestrictinfo nor
353
368
* ppi->ppi_clauses reference partition attribute
354
369
*/
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 ))
358
371
continue ;
359
372
360
373
if (IsA (cur_path ,AppendPath )&& pg_pathman_enable_runtimeappend )