-> Parallel Seq Scan on p1_c3_c2
(25 rows)
--- seqscan doesn't harm parallelism
+-- Parallel sequential scan
/*+Parallel(p1 8 hard) SeqScan(p1) */
EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
LOG: pg_hint_plan:
-> Seq Scan on p2_c3_c2
(25 rows)
--- Index partial scan is not handled yet.
+-- Parallel index scan
/*+Parallel(p1 8 hard) IndexScan(p1) */
EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
LOG: pg_hint_plan:
duplication hint:
error hint:
- QUERY PLAN
---------------------------------------------------------
- Hash Join
- Hash Cond: (p1.id = p2.id)
- -> Append
- -> Index Scan using p1_pkey on p1
- -> Index Scan using p1_c1_pkey on p1_c1
- -> Index Scan using p1_c2_pkey on p1_c2
- -> Index Scan using p1_c3_pkey on p1_c3
- -> Index Scan using p1_c4_pkey on p1_c4
- -> Index Scan using p1_c1_c1_pkey on p1_c1_c1
- -> Index Scan using p1_c1_c2_pkey on p1_c1_c2
- -> Index Scan using p1_c3_c1_pkey on p1_c3_c1
- -> Index Scan using p1_c3_c2_pkey on p1_c3_c2
- -> Hash
+ QUERY PLAN
+-----------------------------------------------------------------------
+ Gather
+ Workers Planned: 8
+ -> Hash Join
+ Hash Cond: (p1.id = p2.id)
-> Append
- -> Seq Scan on p2
- -> Seq Scan on p2_c1
- -> Seq Scan on p2_c2
- -> Seq Scan on p2_c3
- -> Seq Scan on p2_c4
- -> Seq Scan on p2_c1_c1
- -> Seq Scan on p2_c1_c2
- -> Seq Scan on p2_c3_c1
- -> Seq Scan on p2_c3_c2
-(23 rows)
+ -> Parallel Index Scan using p1_pkey on p1
+ -> Parallel Index Scan using p1_c1_pkey on p1_c1
+ -> Parallel Index Scan using p1_c2_pkey on p1_c2
+ -> Parallel Index Scan using p1_c3_pkey on p1_c3
+ -> Parallel Index Scan using p1_c4_pkey on p1_c4
+ -> Parallel Index Scan using p1_c1_c1_pkey on p1_c1_c1
+ -> Parallel Index Scan using p1_c1_c2_pkey on p1_c1_c2
+ -> Parallel Index Scan using p1_c3_c1_pkey on p1_c3_c1
+ -> Parallel Index Scan using p1_c3_c2_pkey on p1_c3_c2
+ -> Hash
+ -> Append
+ -> Seq Scan on p2
+ -> Seq Scan on p2_c1
+ -> Seq Scan on p2_c2
+ -> Seq Scan on p2_c3
+ -> Seq Scan on p2_c4
+ -> Seq Scan on p2_c1_c1
+ -> Seq Scan on p2_c1_c2
+ -> Seq Scan on p2_c3_c1
+ -> Seq Scan on p2_c3_c2
+(25 rows)
-- This hint doesn't turn on parallel, so the Parallel hint is ignored
set max_parallel_workers_per_gather TO 0;
return;
/* Here, we regenerate paths with the current hint restriction */
-
- if (found_hints & HINT_BM_SCAN_METHOD)
+ if (found_hints & HINT_BM_SCAN_METHOD || found_hints & HINT_BM_PARALLEL)
{
- /*
- * With scan hints, we regenerate paths for this relation from the
- * first under the restricion.
- */
+ /* Just discard all the paths considered so far */
list_free_deep(rel->pathlist);
rel->pathlist = NIL;
- set_plain_rel_pathlist(root, rel, rte);
- }
-
- if (found_hints & HINT_BM_PARALLEL)
- {
- Assert (phint);
-
- /* the partial_pathlist may be for different parameters, discard it */
- if (rel->partial_pathlist)
+ /* Remove all the partial paths if Parallel hint is specfied */
+ if ((found_hints & HINT_BM_PARALLEL) && rel->partial_pathlist)
{
list_free_deep(rel->partial_pathlist);
rel->partial_pathlist = NIL;
}
- /* also remove gather path */
- if (rel->pathlist)
- {
- ListCell *cell, *prev = NULL, *next;
-
- for (cell = list_head(rel->pathlist) ; cell; cell = next)
- {
- Path *path = (Path *) lfirst(cell);
-
- next = lnext(cell);
- if (IsA(path, GatherPath))
- rel->pathlist = list_delete_cell(rel->pathlist,
- cell, prev);
- else
- prev = cell;
- }
- }
+ /* Regenerate paths with the current enforcement */
+ set_plain_rel_pathlist(root, rel, rte);
- /* then generate new paths if needed */
- if (phint->nworkers > 0)
+ /* Additional work to enforce parallel query execution */
+ if (phint && phint->nworkers > 0)
{
/* Lower the priorities of non-parallel paths */
foreach (l, rel->pathlist)
}
}
- /*
- * generate partial paths with enforcement, this is affected by
- * scan method enforcement. Specifically, the cost of this partial
- * seqscan path will be disabled_cost if seqscan is inhibited by
- * hint or GUC parameters.
- */
- Assert (rel->partial_pathlist == NIL);
- create_plain_partial_paths(root, rel);
-
/* enforce number of workers if requested */
if (phint->force_parallel)
{
/*+Parallel(p1 8 hard) IndexScan(p2) */
EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
--- seqscan doesn't harm parallelism
+-- Parallel sequential scan
/*+Parallel(p1 8 hard) SeqScan(p1) */
EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;
--- Index partial scan is not handled yet.
+-- Parallel index scan
/*+Parallel(p1 8 hard) IndexScan(p1) */
EXPLAIN (COSTS false) SELECT * FROM p1 join p2 on p1.id = p2.id;