Change NestPath node to contain JoinPath node
authorPeter Eisentraut <peter@eisentraut.org>
Sun, 8 Aug 2021 14:55:51 +0000 (16:55 +0200)
committerPeter Eisentraut <peter@eisentraut.org>
Sun, 8 Aug 2021 16:46:34 +0000 (18:46 +0200)
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

src/backend/optimizer/path/costsize.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/util/pathnode.c
src/include/nodes/pathnodes.h

index 30c8595f7619da4449605fbd3fc7a9f8ca06de6f..1fd53b40bb082db208c91c08ec27367ec6ad0b58 100644 (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,
                                      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,
@@ -2978,8 +2978,8 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
                    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;
@@ -2994,18 +2994,18 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
    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);
    }
 
    /*
@@ -3018,7 +3018,7 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
 
    /* 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)
    {
        /*
@@ -3136,17 +3136,17 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
    }
 
    /* 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;
 }
 
 /*
@@ -4771,8 +4771,9 @@ compute_semi_anti_join_factors(PlannerInfo *root,
  * 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;
index 0738d7055c952fc1d413886fcca3d2edcd2baf41..a5f6d678ccda22ebca3d2a3c59169005142094e6 100644 (file)
@@ -4221,8 +4221,8 @@ create_nestloop_plan(PlannerInfo *root,
    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;
@@ -4230,13 +4230,13 @@ create_nestloop_plan(PlannerInfo *root,
    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);
@@ -4247,10 +4247,10 @@ create_nestloop_plan(PlannerInfo *root,
 
    /* 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
@@ -4261,7 +4261,7 @@ create_nestloop_plan(PlannerInfo *root,
    }
 
    /* 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);
@@ -4273,7 +4273,7 @@ create_nestloop_plan(PlannerInfo *root,
     * 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,
@@ -4282,10 +4282,10 @@ create_nestloop_plan(PlannerInfo *root,
                              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;
 }
index 41cbf328c4657caa88986e668ffae500681306c3..a53850b3702145dbf0fbba52c9953413104202ae 100644 (file)
@@ -2443,10 +2443,10 @@ create_nestloop_path(PlannerInfo *root,
        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,
@@ -2454,17 +2454,17 @@ create_nestloop_path(PlannerInfo *root,
                                  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);
 
@@ -4110,13 +4110,15 @@ do { \
        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;
 
index ce7908c32679fd0001f5ef2d9fe322f5a6901957..6e068f2c8b387a28932fab0aa45e2a5d45991c91 100644 (file)
@@ -1598,7 +1598,10 @@ typedef struct JoinPath
  * A nested-loop path needs no special fields.
  */
 
-typedef JoinPath NestPath;
+typedef struct NestPath
+{
+   JoinPath    jpath;
+} NestPath;
 
 /*
  * A mergejoin path has these fields.