static void get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel,
ParamPathInfo *param_info,
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,
List *quals);
static double calc_joinrel_size_estimate(PlannerInfo *root,
JoinCostWorkspace *workspace,
JoinPathExtraData *extra)
{
- Path *outer_path = path->outerjoinpath;
- Path *inner_path = path->innerjoinpath;
+ Path *outer_path = path->jpath.outerjoinpath;
+ Path *inner_path = path->jpath.innerjoinpath;
double outer_path_rows = outer_path->rows;
double inner_path_rows = inner_path->rows;
Cost startup_cost = workspace->startup_cost;
if (inner_path_rows <= 0)
inner_path_rows = 1;
/* Mark the path with the correct row estimate */
- if (path->path.param_info)
- path->path.rows = path->path.param_info->ppi_rows;
+ if (path->jpath.path.param_info)
+ path->jpath.path.rows = path->jpath.path.param_info->ppi_rows;
else
- path->path.rows = path->path.parent->rows;
+ path->jpath.path.rows = path->jpath.path.parent->rows;
/* 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 =
- clamp_row_est(path->path.rows / parallel_divisor);
+ path->jpath.path.rows =
+ clamp_row_est(path->jpath.path.rows / parallel_divisor);
}
/*
/* 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)
{
/*
}
/* 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;
cpu_per_tuple = cpu_tuple_cost + restrict_qual_cost.per_tuple;
run_cost += cpu_per_tuple * ntuples;
/* tlist eval costs are paid per output row, not per tuple scanned */
- startup_cost += path->path.pathtarget->cost.startup;
- run_cost += path->path.pathtarget->cost.per_tuple * path->path.rows;
+ startup_cost += path->jpath.path.pathtarget->cost.startup;
+ run_cost += path->jpath.path.pathtarget->cost.per_tuple * path->jpath.path.rows;
- path->path.startup_cost = startup_cost;
- path->path.total_cost = startup_cost + run_cost;
+ path->jpath.path.startup_cost = startup_cost;
+ path->jpath.path.total_cost = startup_cost + run_cost;
}
/*
* expensive.
*/
static bool
-has_indexed_join_quals(NestPath *joinpath)
+has_indexed_join_quals(NestPath *path)
{
+ JoinPath *joinpath = &path->jpath;
Relids joinrelids = joinpath->path.parent->relids;
Path *innerpath = joinpath->innerjoinpath;
List *indexclauses;
NestLoop *join_plan;
Plan *outer_plan;
Plan *inner_plan;
- List *tlist = build_path_tlist(root, &best_path->path);
- List *joinrestrictclauses = best_path->joinrestrictinfo;
+ List *tlist = build_path_tlist(root, &best_path->jpath.path);
+ List *joinrestrictclauses = best_path->jpath.joinrestrictinfo;
List *joinclauses;
List *otherclauses;
Relids outerrelids;
Relids saveOuterRels = root->curOuterRels;
/* 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 */
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 */
bms_free(root->curOuterRels);
/* Get the join qual clauses (in plain expression form) */
/* 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,
- best_path->path.parent->relids,
+ best_path->jpath.path.parent->relids,
&joinclauses, &otherclauses);
}
else
}
/* Replace any outer-relation variables with nestloop params */
- if (best_path->path.param_info)
+ if (best_path->jpath.path.param_info)
{
joinclauses = (List *)
replace_nestloop_params(root, (Node *) joinclauses);
* Identify any nestloop parameters that should be supplied by this join
* 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);
join_plan = make_nestloop(tlist,
nestParams,
outer_plan,
inner_plan,
- best_path->jointype,
- best_path->inner_unique);
+ best_path->jpath.jointype,
+ 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;
}
restrict_clauses = jclauses;
}
- pathnode->path.pathtype = T_NestLoop;
- pathnode->path.parent = joinrel;
- pathnode->path.pathtarget = joinrel->reltarget;
- pathnode->path.param_info =
+ pathnode->jpath.path.pathtype = T_NestLoop;
+ pathnode->jpath.path.parent = joinrel;
+ pathnode->jpath.path.pathtarget = joinrel->reltarget;
+ pathnode->jpath.path.param_info =
get_joinrel_parampathinfo(root,
joinrel,
outer_path,
extra->sjinfo,
required_outer,
&restrict_clauses);
- pathnode->path.parallel_aware = false;
- pathnode->path.parallel_safe = joinrel->consider_parallel &&
+ pathnode->jpath.path.parallel_aware = false;
+ pathnode->jpath.path.parallel_safe = joinrel->consider_parallel &&
outer_path->parallel_safe && inner_path->parallel_safe;
/* This is a foolish way to estimate parallel_workers, but for now... */
- pathnode->path.parallel_workers = outer_path->parallel_workers;
- pathnode->path.pathkeys = pathkeys;
- pathnode->jointype = jointype;
- pathnode->inner_unique = extra->inner_unique;
- pathnode->outerjoinpath = outer_path;
- pathnode->innerjoinpath = inner_path;
- pathnode->joinrestrictinfo = restrict_clauses;
+ pathnode->jpath.path.parallel_workers = outer_path->parallel_workers;
+ pathnode->jpath.path.pathkeys = pathkeys;
+ pathnode->jpath.jointype = jointype;
+ pathnode->jpath.inner_unique = extra->inner_unique;
+ pathnode->jpath.outerjoinpath = outer_path;
+ pathnode->jpath.innerjoinpath = inner_path;
+ pathnode->jpath.joinrestrictinfo = restrict_clauses;
final_cost_nestloop(root, pathnode, workspace, extra);
case T_NestPath:
{
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->innerjoinpath);
ADJUST_CHILD_ATTRS(jpath->joinrestrictinfo);
- new_path = (Path *) jpath;
+ new_path = (Path *) npath;
}
break;
* A nested-loop path needs no special fields.
*/
-typedef JoinPath NestPath;
+typedef struct NestPath
+{
+ JoinPath jpath;
+} NestPath;
/*
* A mergejoin path has these fields.