mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Pass InitPlan values to workers via Gather (Merge).
If a PARAM_EXEC parameter is used below a Gather (Merge) but the InitPlan that computes it is attached to or above the Gather (Merge), force the value to be computed before starting parallelism and pass it down to all workers. This allows us to use parallelism in cases where it previously would have had to be rejected as unsafe. We do - in this case - lose the optimization that the value is only computed if it's actually used. An alternative strategy would be to have the first worker that needs the value compute it, but one downside of that approach is that we'd then need to select a parallel-safe path to compute the parameter value; it couldn't for example contain a Gather (Merge) node. At some point in the future, we might want to consider both approaches. Independent of that consideration, there is a great deal more work that could be done to make more kinds of PARAM_EXEC parameters parallel-safe. This infrastructure could be used to allow a Gather (Merge) on the inner side of a nested loop (although that's not a very appealing plan) and cases where the InitPlan is attached below the Gather (Merge) could be addressed as well using various techniques. But this is a good start. Amit Kapila, reviewed and revised by me. Reviewing and testing from Kuntal Ghosh, Haribabu Kommi, and Tushar Ahuja. Discussion: http://postgr.es/m/CAA4eK1LV0Y1AUV4cUCdC+sYOx0Z0-8NAJ2Pd9=UKsbQ5Sr7+JQ@mail.gmail.com
This commit is contained in:
@ -107,6 +107,7 @@ static void show_tidbitmap_info(BitmapHeapScanState *planstate,
|
||||
static void show_instrumentation_count(const char *qlabel, int which,
|
||||
PlanState *planstate, ExplainState *es);
|
||||
static void show_foreignscan_info(ForeignScanState *fsstate, ExplainState *es);
|
||||
static void show_eval_params(Bitmapset *bms_params, ExplainState *es);
|
||||
static const char *explain_get_index_name(Oid indexId);
|
||||
static void show_buffer_usage(ExplainState *es, const BufferUsage *usage);
|
||||
static void ExplainIndexScanDetails(Oid indexid, ScanDirection indexorderdir,
|
||||
@ -1441,6 +1442,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
|
||||
planstate, es);
|
||||
ExplainPropertyInteger("Workers Planned",
|
||||
gather->num_workers, es);
|
||||
|
||||
/* Show params evaluated at gather node */
|
||||
if (gather->initParam)
|
||||
show_eval_params(gather->initParam, es);
|
||||
|
||||
if (es->analyze)
|
||||
{
|
||||
int nworkers;
|
||||
@ -1463,6 +1469,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
|
||||
planstate, es);
|
||||
ExplainPropertyInteger("Workers Planned",
|
||||
gm->num_workers, es);
|
||||
|
||||
/* Show params evaluated at gather-merge node */
|
||||
if (gm->initParam)
|
||||
show_eval_params(gm->initParam, es);
|
||||
|
||||
if (es->analyze)
|
||||
{
|
||||
int nworkers;
|
||||
@ -2487,6 +2498,29 @@ show_foreignscan_info(ForeignScanState *fsstate, ExplainState *es)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Show initplan params evaluated at Gather or Gather Merge node.
|
||||
*/
|
||||
static void
|
||||
show_eval_params(Bitmapset *bms_params, ExplainState *es)
|
||||
{
|
||||
int paramid = -1;
|
||||
List *params = NIL;
|
||||
|
||||
Assert(bms_params);
|
||||
|
||||
while ((paramid = bms_next_member(bms_params, paramid)) >= 0)
|
||||
{
|
||||
char param[32];
|
||||
|
||||
snprintf(param, sizeof(param), "$%d", paramid);
|
||||
params = lappend(params, pstrdup(param));
|
||||
}
|
||||
|
||||
if (params)
|
||||
ExplainPropertyList("Params Evaluated", params, es);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the name of an index in an EXPLAIN
|
||||
*
|
||||
|
Reference in New Issue
Block a user