1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-31 22:04:40 +03:00

Change NestPath node to contain JoinPath node

This makes the structure of all JoinPath-derived nodes the same,
independent of whether they have additional fields.

Discussion: https://www.postgresql.org/message-id/flat/c1097590-a6a4-486a-64b1-e1f9cc0533ce@enterprisedb.com
This commit is contained in:
Peter Eisentraut
2021-08-08 16:55:51 +02:00
parent 2226b4189b
commit 18fea737b5
4 changed files with 51 additions and 45 deletions

View File

@ -167,7 +167,7 @@ static bool cost_qual_eval_walker(Node *node, cost_qual_eval_context *context);
static void get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel, static void get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel,
ParamPathInfo *param_info, ParamPathInfo *param_info,
QualCost *qpqual_cost); QualCost *qpqual_cost);
static bool has_indexed_join_quals(NestPath *joinpath); static bool has_indexed_join_quals(NestPath *path);
static double approx_tuple_count(PlannerInfo *root, JoinPath *path, static double approx_tuple_count(PlannerInfo *root, JoinPath *path,
List *quals); List *quals);
static double calc_joinrel_size_estimate(PlannerInfo *root, static double calc_joinrel_size_estimate(PlannerInfo *root,
@ -2978,8 +2978,8 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
JoinCostWorkspace *workspace, JoinCostWorkspace *workspace,
JoinPathExtraData *extra) JoinPathExtraData *extra)
{ {
Path *outer_path = path->outerjoinpath; Path *outer_path = path->jpath.outerjoinpath;
Path *inner_path = path->innerjoinpath; Path *inner_path = path->jpath.innerjoinpath;
double outer_path_rows = outer_path->rows; double outer_path_rows = outer_path->rows;
double inner_path_rows = inner_path->rows; double inner_path_rows = inner_path->rows;
Cost startup_cost = workspace->startup_cost; Cost startup_cost = workspace->startup_cost;
@ -2994,18 +2994,18 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
if (inner_path_rows <= 0) if (inner_path_rows <= 0)
inner_path_rows = 1; inner_path_rows = 1;
/* Mark the path with the correct row estimate */ /* Mark the path with the correct row estimate */
if (path->path.param_info) if (path->jpath.path.param_info)
path->path.rows = path->path.param_info->ppi_rows; path->jpath.path.rows = path->jpath.path.param_info->ppi_rows;
else else
path->path.rows = path->path.parent->rows; path->jpath.path.rows = path->jpath.path.parent->rows;
/* For partial paths, scale row estimate. */ /* For partial paths, scale row estimate. */
if (path->path.parallel_workers > 0) if (path->jpath.path.parallel_workers > 0)
{ {
double parallel_divisor = get_parallel_divisor(&path->path); double parallel_divisor = get_parallel_divisor(&path->jpath.path);
path->path.rows = path->jpath.path.rows =
clamp_row_est(path->path.rows / parallel_divisor); clamp_row_est(path->jpath.path.rows / parallel_divisor);
} }
/* /*
@ -3018,7 +3018,7 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
/* cost of inner-relation source data (we already dealt with outer rel) */ /* cost of inner-relation source data (we already dealt with outer rel) */
if (path->jointype == JOIN_SEMI || path->jointype == JOIN_ANTI || if (path->jpath.jointype == JOIN_SEMI || path->jpath.jointype == JOIN_ANTI ||
extra->inner_unique) extra->inner_unique)
{ {
/* /*
@ -3136,17 +3136,17 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
} }
/* CPU costs */ /* CPU costs */
cost_qual_eval(&restrict_qual_cost, path->joinrestrictinfo, root); cost_qual_eval(&restrict_qual_cost, path->jpath.joinrestrictinfo, root);
startup_cost += restrict_qual_cost.startup; startup_cost += restrict_qual_cost.startup;
cpu_per_tuple = cpu_tuple_cost + restrict_qual_cost.per_tuple; cpu_per_tuple = cpu_tuple_cost + restrict_qual_cost.per_tuple;
run_cost += cpu_per_tuple * ntuples; run_cost += cpu_per_tuple * ntuples;
/* tlist eval costs are paid per output row, not per tuple scanned */ /* tlist eval costs are paid per output row, not per tuple scanned */
startup_cost += path->path.pathtarget->cost.startup; startup_cost += path->jpath.path.pathtarget->cost.startup;
run_cost += path->path.pathtarget->cost.per_tuple * path->path.rows; run_cost += path->jpath.path.pathtarget->cost.per_tuple * path->jpath.path.rows;
path->path.startup_cost = startup_cost; path->jpath.path.startup_cost = startup_cost;
path->path.total_cost = startup_cost + run_cost; path->jpath.path.total_cost = startup_cost + run_cost;
} }
/* /*
@ -4771,8 +4771,9 @@ compute_semi_anti_join_factors(PlannerInfo *root,
* expensive. * expensive.
*/ */
static bool static bool
has_indexed_join_quals(NestPath *joinpath) has_indexed_join_quals(NestPath *path)
{ {
JoinPath *joinpath = &path->jpath;
Relids joinrelids = joinpath->path.parent->relids; Relids joinrelids = joinpath->path.parent->relids;
Path *innerpath = joinpath->innerjoinpath; Path *innerpath = joinpath->innerjoinpath;
List *indexclauses; List *indexclauses;

View File

@ -4221,8 +4221,8 @@ create_nestloop_plan(PlannerInfo *root,
NestLoop *join_plan; NestLoop *join_plan;
Plan *outer_plan; Plan *outer_plan;
Plan *inner_plan; Plan *inner_plan;
List *tlist = build_path_tlist(root, &best_path->path); List *tlist = build_path_tlist(root, &best_path->jpath.path);
List *joinrestrictclauses = best_path->joinrestrictinfo; List *joinrestrictclauses = best_path->jpath.joinrestrictinfo;
List *joinclauses; List *joinclauses;
List *otherclauses; List *otherclauses;
Relids outerrelids; Relids outerrelids;
@ -4230,13 +4230,13 @@ create_nestloop_plan(PlannerInfo *root,
Relids saveOuterRels = root->curOuterRels; Relids saveOuterRels = root->curOuterRels;
/* NestLoop can project, so no need to be picky about child tlists */ /* NestLoop can project, so no need to be picky about child tlists */
outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0); outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath, 0);
/* For a nestloop, include outer relids in curOuterRels for inner side */ /* For a nestloop, include outer relids in curOuterRels for inner side */
root->curOuterRels = bms_union(root->curOuterRels, root->curOuterRels = bms_union(root->curOuterRels,
best_path->outerjoinpath->parent->relids); best_path->jpath.outerjoinpath->parent->relids);
inner_plan = create_plan_recurse(root, best_path->innerjoinpath, 0); inner_plan = create_plan_recurse(root, best_path->jpath.innerjoinpath, 0);
/* Restore curOuterRels */ /* Restore curOuterRels */
bms_free(root->curOuterRels); bms_free(root->curOuterRels);
@ -4247,10 +4247,10 @@ create_nestloop_plan(PlannerInfo *root,
/* Get the join qual clauses (in plain expression form) */ /* Get the join qual clauses (in plain expression form) */
/* Any pseudoconstant clauses are ignored here */ /* Any pseudoconstant clauses are ignored here */
if (IS_OUTER_JOIN(best_path->jointype)) if (IS_OUTER_JOIN(best_path->jpath.jointype))
{ {
extract_actual_join_clauses(joinrestrictclauses, extract_actual_join_clauses(joinrestrictclauses,
best_path->path.parent->relids, best_path->jpath.path.parent->relids,
&joinclauses, &otherclauses); &joinclauses, &otherclauses);
} }
else else
@ -4261,7 +4261,7 @@ create_nestloop_plan(PlannerInfo *root,
} }
/* Replace any outer-relation variables with nestloop params */ /* Replace any outer-relation variables with nestloop params */
if (best_path->path.param_info) if (best_path->jpath.path.param_info)
{ {
joinclauses = (List *) joinclauses = (List *)
replace_nestloop_params(root, (Node *) joinclauses); replace_nestloop_params(root, (Node *) joinclauses);
@ -4273,7 +4273,7 @@ create_nestloop_plan(PlannerInfo *root,
* Identify any nestloop parameters that should be supplied by this join * Identify any nestloop parameters that should be supplied by this join
* node, and remove them from root->curOuterParams. * node, and remove them from root->curOuterParams.
*/ */
outerrelids = best_path->outerjoinpath->parent->relids; outerrelids = best_path->jpath.outerjoinpath->parent->relids;
nestParams = identify_current_nestloop_params(root, outerrelids); nestParams = identify_current_nestloop_params(root, outerrelids);
join_plan = make_nestloop(tlist, join_plan = make_nestloop(tlist,
@ -4282,10 +4282,10 @@ create_nestloop_plan(PlannerInfo *root,
nestParams, nestParams,
outer_plan, outer_plan,
inner_plan, inner_plan,
best_path->jointype, best_path->jpath.jointype,
best_path->inner_unique); best_path->jpath.inner_unique);
copy_generic_path_info(&join_plan->join.plan, &best_path->path); copy_generic_path_info(&join_plan->join.plan, &best_path->jpath.path);
return join_plan; return join_plan;
} }

View File

@ -2443,10 +2443,10 @@ create_nestloop_path(PlannerInfo *root,
restrict_clauses = jclauses; restrict_clauses = jclauses;
} }
pathnode->path.pathtype = T_NestLoop; pathnode->jpath.path.pathtype = T_NestLoop;
pathnode->path.parent = joinrel; pathnode->jpath.path.parent = joinrel;
pathnode->path.pathtarget = joinrel->reltarget; pathnode->jpath.path.pathtarget = joinrel->reltarget;
pathnode->path.param_info = pathnode->jpath.path.param_info =
get_joinrel_parampathinfo(root, get_joinrel_parampathinfo(root,
joinrel, joinrel,
outer_path, outer_path,
@ -2454,17 +2454,17 @@ create_nestloop_path(PlannerInfo *root,
extra->sjinfo, extra->sjinfo,
required_outer, required_outer,
&restrict_clauses); &restrict_clauses);
pathnode->path.parallel_aware = false; pathnode->jpath.path.parallel_aware = false;
pathnode->path.parallel_safe = joinrel->consider_parallel && pathnode->jpath.path.parallel_safe = joinrel->consider_parallel &&
outer_path->parallel_safe && inner_path->parallel_safe; outer_path->parallel_safe && inner_path->parallel_safe;
/* This is a foolish way to estimate parallel_workers, but for now... */ /* This is a foolish way to estimate parallel_workers, but for now... */
pathnode->path.parallel_workers = outer_path->parallel_workers; pathnode->jpath.path.parallel_workers = outer_path->parallel_workers;
pathnode->path.pathkeys = pathkeys; pathnode->jpath.path.pathkeys = pathkeys;
pathnode->jointype = jointype; pathnode->jpath.jointype = jointype;
pathnode->inner_unique = extra->inner_unique; pathnode->jpath.inner_unique = extra->inner_unique;
pathnode->outerjoinpath = outer_path; pathnode->jpath.outerjoinpath = outer_path;
pathnode->innerjoinpath = inner_path; pathnode->jpath.innerjoinpath = inner_path;
pathnode->joinrestrictinfo = restrict_clauses; pathnode->jpath.joinrestrictinfo = restrict_clauses;
final_cost_nestloop(root, pathnode, workspace, extra); final_cost_nestloop(root, pathnode, workspace, extra);
@ -4110,13 +4110,15 @@ do { \
case T_NestPath: case T_NestPath:
{ {
JoinPath *jpath; JoinPath *jpath;
NestPath *npath;
FLAT_COPY_PATH(jpath, path, NestPath); FLAT_COPY_PATH(npath, path, NestPath);
jpath = (JoinPath *) npath;
REPARAMETERIZE_CHILD_PATH(jpath->outerjoinpath); REPARAMETERIZE_CHILD_PATH(jpath->outerjoinpath);
REPARAMETERIZE_CHILD_PATH(jpath->innerjoinpath); REPARAMETERIZE_CHILD_PATH(jpath->innerjoinpath);
ADJUST_CHILD_ATTRS(jpath->joinrestrictinfo); ADJUST_CHILD_ATTRS(jpath->joinrestrictinfo);
new_path = (Path *) jpath; new_path = (Path *) npath;
} }
break; break;

View File

@ -1598,7 +1598,10 @@ typedef struct JoinPath
* A nested-loop path needs no special fields. * A nested-loop path needs no special fields.
*/ */
typedef JoinPath NestPath; typedef struct NestPath
{
JoinPath jpath;
} NestPath;
/* /*
* A mergejoin path has these fields. * A mergejoin path has these fields.