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:
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user