+ * Force number of wokers if instructed by hint
+ */
+void
+pg_hint_plan_set_rel_pathlist(PlannerInfo * root, RelOptInfo *rel,
+ Index rti, RangeTblEntry *rte)
+{
+ ParallelHint *phint;
+ ListCell *l;
+ int found_hints;
+
+ /* call the previous hook */
+ if (prev_set_rel_pathlist)
+ prev_set_rel_pathlist(root, rel, rti, rte);
+
+ /* Nothing to do if no hint available */
+ if (current_hint_state == NULL)
+ return;
+
+ /* Don't touch dummy rels. */
+ if (IS_DUMMY_REL(rel))
+ return;
+
+ /*
+ * We can accept only plain relations, foreign tables and table saples are
+ * also unacceptable. See set_rel_pathlist.
+ */
+ if (rel->rtekind != RTE_RELATION ||
+ rte->relkind == RELKIND_FOREIGN_TABLE ||
+ rte->tablesample != NULL)
+ return;
+
+ /* We cannot handle if this requires an outer */
+ if (rel->lateral_relids)
+ return;
+
+ /* Return if this relation gets no enfocement */
+ if ((found_hints = setup_hint_enforcement(root, rel, NULL, &phint)) == 0)
+ return;
+
+ /* Here, we regenerate paths with the current hint restriction */
+ if (found_hints & HINT_BM_SCAN_METHOD || found_hints & HINT_BM_PARALLEL)
+ {
+ /* Just discard all the paths considered so far */
+ list_free_deep(rel->pathlist);
+ rel->pathlist = NIL;
+
+ /* 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;
+ }
+
+ /* Regenerate paths with the current enforcement */
+ set_plain_rel_pathlist(root, rel, rte);
+
+ /* Additional work to enforce parallel query execution */
+ if (phint && phint->nworkers > 0)
+ {
+ /* Lower the priorities of non-parallel paths */
+ foreach (l, rel->pathlist)
+ {
+ Path *path = (Path *) lfirst(l);
+
+ if (path->startup_cost < disable_cost)
+ {
+ path->startup_cost += disable_cost;
+ path->total_cost += disable_cost;
+ }
+ }
+
+ /* enforce number of workers if requested */
+ if (phint->force_parallel)
+ {
+ foreach (l, rel->partial_pathlist)
+ {
+ Path *ppath = (Path *) lfirst(l);
+
+ ppath->parallel_workers = phint->nworkers;
+ }
+ }
+
+ /* Generate gather paths for base rels */
+ if (rel->reloptkind == RELOPT_BASEREL)
+ generate_gather_paths(root, rel);
+ }
+ }
+
+ reset_hint_enforcement();
+}
+
+/*