Hi hackers, I have write an initial patch to retire the disable_cost GUC, which labeled a flag on the Path struct instead of adding up a big cost which is hard to estimate. Though it involved in tons of plan changes in regression tests, I have tested on some simple test cases such as eagerly generate a two-stage agg plans and it worked. Could someone help to review?
regards, Jian ________________________________ From: Euler Taveira <eu...@timbira.com.br> Sent: Friday, November 1, 2019 22:48 To: Zhenghua Lyu <z...@vmware.com> Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org> Subject: Re: On disable_cost !! External Email Em sex, 1 de nov de 2019 às 03:42, Zhenghua Lyu <z...@pivotal.io> escreveu: > > My issue: I did some spikes and tests on TPCDS 1TB Bytes data. For query > 104, it generates > nestloop join even with enable_nestloop set off. And the final plan's total > cost is very huge (about 1e24). But If I enlarge the disable_cost to 1e30, > then, planner will generate hash join. > > So I guess that disable_cost is not large enough for huge amount of data. > > It is tricky to set disable_cost a huge number. Can we come up with > better solution? > Isn't it a case for a GUC disable_cost? As Thomas suggested, DBL_MAX upper limit should be sufficient. > The following thoughts are from Heikki: >> >> Aside from not having a large enough disable cost, there's also the fact >> that the high cost might affect the rest of the plan, if we have to use a >> plan type that's disabled. For example, if a table doesn't have any indexes, >> but enable_seqscan is off, we might put the unavoidable Seq Scan on >> different side of a join than we we would with enable_seqscan=on, because of >> the high cost estimate. > > >> >> I think a more robust way to disable forbidden plan types would be to handle >> the disabling in add_path(). Instead of having a high disable cost on the >> Path itself, the comparison add_path() would always consider disabled paths >> as more expensive than others, regardless of the cost. > I'm afraid it is not as cheap as using diable_cost as a node cost. Are you proposing to add a new boolean variable in Path struct to handle those cases in compare_path_costs_fuzzily? -- Euler Taveira Timbira - https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.timbira.com.br%2F&data=05%7C01%7Cgjian%40vmware.com%7C12a30b2852dd4651667608db9401d056%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C638266507757076648%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=v54JhsW8FX4mSmjgt2yP59t7xtv1mZvC%2BBhtKrfp%2FBY%3D&reserved=0<http://www.timbira.com.br/> PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento !! External Email: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender.
From baf0143438a91c8739534c7d85b9d121a7bb560e Mon Sep 17 00:00:00 2001 From: Jian Guo <gj...@vmware.com> Date: Thu, 3 Aug 2023 17:03:49 +0800 Subject: [PATCH] Retire disable_cost, introduce new flag is_disabled into Path struct. Signed-off-by: Jian Guo <gj...@vmware.com> --- src/backend/optimizer/path/costsize.c | 30 +++++++------- src/backend/optimizer/util/pathnode.c | 58 +++++++++++++++++++++++++++ src/include/nodes/pathnodes.h | 1 + 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index ef475d95a1..0814604c49 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -274,7 +274,7 @@ cost_seqscan(Path *path, PlannerInfo *root, path->rows = baserel->rows; if (!enable_seqscan) - startup_cost += disable_cost; + path->is_disabled = true; /* fetch estimated page cost for tablespace containing table */ get_tablespace_page_costs(baserel->reltablespace, @@ -463,7 +463,7 @@ cost_gather_merge(GatherMergePath *path, PlannerInfo *root, path->path.rows = rel->rows; if (!enable_gathermerge) - startup_cost += disable_cost; + path->path.is_disabled = true; /* * Add one to the number of workers to account for the leader. This might @@ -576,7 +576,7 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count, } if (!enable_indexscan) - startup_cost += disable_cost; + path->path.is_disabled = true; /* we don't need to check enable_indexonlyscan; indxpath.c does that */ /* @@ -1011,7 +1011,7 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, path->rows = baserel->rows; if (!enable_bitmapscan) - startup_cost += disable_cost; + path->is_disabled = true; pages_fetched = compute_bitmap_pages(root, baserel, bitmapqual, loop_count, &indexTotalCost, @@ -1279,11 +1279,10 @@ cost_tidscan(Path *path, PlannerInfo *root, */ if (isCurrentOf) { - Assert(baserel->baserestrictcost.startup >= disable_cost); - startup_cost -= disable_cost; + path->is_disabled = false; } else if (!enable_tidscan) - startup_cost += disable_cost; + path->is_disabled = true; /* * The TID qual expressions will be computed once, any other baserestrict @@ -1372,7 +1371,7 @@ cost_tidrangescan(Path *path, PlannerInfo *root, nseqpages = pages - 1.0; if (!enable_tidscan) - startup_cost += disable_cost; + path->is_disabled = true; /* * The TID qual expressions will be computed once, any other baserestrict @@ -2108,7 +2107,7 @@ cost_sort(Path *path, PlannerInfo *root, limit_tuples); if (!enable_sort) - startup_cost += disable_cost; + path->is_disabled = true; startup_cost += input_cost; @@ -2679,8 +2678,7 @@ cost_agg(Path *path, PlannerInfo *root, total_cost = input_total_cost; if (aggstrategy == AGG_MIXED && !enable_hashagg) { - startup_cost += disable_cost; - total_cost += disable_cost; + path->is_disabled = true; } /* calcs phrased this way to match HASHED case, see note above */ total_cost += aggcosts->transCost.startup; @@ -2696,7 +2694,7 @@ cost_agg(Path *path, PlannerInfo *root, /* must be AGG_HASHED */ startup_cost = input_total_cost; if (!enable_hashagg) - startup_cost += disable_cost; + path->is_disabled = true; startup_cost += aggcosts->transCost.startup; startup_cost += aggcosts->transCost.per_tuple * input_tuples; /* cost of computing hash value */ @@ -3076,7 +3074,7 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path, * disabled, which doesn't seem like the way to bet. */ if (!enable_nestloop) - startup_cost += disable_cost; + path->jpath.path.is_disabled = true; /* cost of inner-relation source data (we already dealt with outer rel) */ @@ -3523,7 +3521,7 @@ final_cost_mergejoin(PlannerInfo *root, MergePath *path, * disabled, which doesn't seem like the way to bet. */ if (!enable_mergejoin) - startup_cost += disable_cost; + path->jpath.path.is_disabled = true; /* * Compute cost of the mergequals and qpquals (other restriction clauses) @@ -3953,7 +3951,7 @@ final_cost_hashjoin(PlannerInfo *root, HashPath *path, * disabled, which doesn't seem like the way to bet. */ if (!enable_hashjoin) - startup_cost += disable_cost; + path->jpath.path.is_disabled = true; /* mark the path with estimated # of batches */ path->num_batches = numbatches; @@ -4050,7 +4048,7 @@ final_cost_hashjoin(PlannerInfo *root, HashPath *path, */ if (relation_byte_size(clamp_row_est(inner_path_rows * innermcvfreq), inner_path->pathtarget->width) > get_hash_memory_limit()) - startup_cost += disable_cost; + path->jpath.path.is_disabled = true; /* * Compute cost of the hashquals and qpquals (other restriction clauses) diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index f123fcb41e..42d72cb1d5 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -165,6 +165,19 @@ compare_fractional_path_costs(Path *path1, Path *path2, static PathCostComparison compare_path_costs_fuzzily(Path *path1, Path *path2, double fuzz_factor) { + if (path1->is_disabled && path2->is_disabled) + { + return COSTS_EQUAL; + } + else if (path1->is_disabled) + { + return COSTS_BETTER2; + } + else if (path2->is_disabled) + { + return COSTS_BETTER1; + } + #define CONSIDER_PATH_STARTUP_COST(p) \ ((p)->param_info == NULL ? (p)->parent->consider_startup : (p)->parent->consider_param_startup) @@ -940,6 +953,7 @@ create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = parallel_workers; pathnode->pathkeys = NIL; /* seqscan has unordered result */ + pathnode->is_disabled = false; cost_seqscan(pathnode, root, rel, pathnode->param_info); @@ -964,6 +978,7 @@ create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* samplescan has unordered result */ + pathnode->is_disabled = false; cost_samplescan(pathnode, root, rel, pathnode->param_info); @@ -1016,6 +1031,7 @@ create_index_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->indexinfo = index; pathnode->indexclauses = indexclauses; @@ -1059,6 +1075,7 @@ create_bitmap_heap_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = parallel_degree; pathnode->path.pathkeys = NIL; /* always unordered */ + pathnode->path.is_disabled = false; pathnode->bitmapqual = bitmapqual; @@ -1112,6 +1129,7 @@ create_bitmap_and_path(PlannerInfo *root, pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; /* always unordered */ + pathnode->path.is_disabled = false; pathnode->bitmapquals = bitmapquals; @@ -1164,6 +1182,7 @@ create_bitmap_or_path(PlannerInfo *root, pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; /* always unordered */ + pathnode->path.is_disabled = false; pathnode->bitmapquals = bitmapquals; @@ -1192,6 +1211,7 @@ create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; /* always unordered */ + pathnode->path.is_disabled = false; pathnode->tidquals = tidquals; @@ -1221,6 +1241,7 @@ create_tidrangescan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; /* always unordered */ + pathnode->path.is_disabled = false; pathnode->tidrangequals = tidrangequals; @@ -1278,6 +1299,7 @@ create_append_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = parallel_workers; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; /* * For parallel append, non-partial paths are sorted by descending total @@ -1430,6 +1452,7 @@ create_merge_append_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->subpaths = subpaths; /* @@ -1537,6 +1560,7 @@ create_group_result_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = target->cost.startup; pathnode->path.total_cost = target->cost.startup + cpu_tuple_cost + target->cost.per_tuple; + pathnode->path.is_disabled = false; /* * Add cost of qual, if any --- but we ignore its selectivity, since our @@ -1576,6 +1600,7 @@ create_material_path(RelOptInfo *rel, Path *subpath) subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -1610,6 +1635,7 @@ create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->hash_operators = hash_operators; @@ -1701,6 +1727,7 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, * to represent it. (This might get overridden below.) */ pathnode->path.pathkeys = NIL; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->in_operators = sjinfo->semi_operators; @@ -1892,6 +1919,7 @@ create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, pathnode->path.pathkeys = pathkeys; pathnode->path.pathtarget = target ? target : rel->reltarget; pathnode->path.rows += subpath->rows; + pathnode->path.is_disabled = false; if (pathkeys_contained_in(pathkeys, subpath->pathkeys)) { @@ -1977,6 +2005,7 @@ create_gather_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, pathnode->path.parallel_safe = false; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; /* Gather has unordered result */ + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->num_workers = subpath->parallel_workers; @@ -2021,6 +2050,7 @@ create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; cost_subqueryscan(pathnode, root, rel, pathnode->path.param_info, @@ -2049,6 +2079,7 @@ create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = pathkeys; + pathnode->is_disabled = false; cost_functionscan(pathnode, root, rel, pathnode->param_info); @@ -2075,6 +2106,7 @@ create_tablefuncscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* result is always unordered */ + pathnode->is_disabled = false; cost_tablefuncscan(pathnode, root, rel, pathnode->param_info); @@ -2101,6 +2133,7 @@ create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* result is always unordered */ + pathnode->is_disabled = false; cost_valuesscan(pathnode, root, rel, pathnode->param_info); @@ -2126,6 +2159,7 @@ create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer) pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* XXX for now, result is always unordered */ + pathnode->is_disabled = false; cost_ctescan(pathnode, root, rel, pathnode->param_info); @@ -2152,6 +2186,7 @@ create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* result is always unordered */ + pathnode->is_disabled = false; cost_namedtuplestorescan(pathnode, root, rel, pathnode->param_info); @@ -2178,6 +2213,7 @@ create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* result is always unordered */ + pathnode->is_disabled = false; cost_resultscan(pathnode, root, rel, pathnode->param_info); @@ -2204,6 +2240,7 @@ create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->parallel_safe = rel->consider_parallel; pathnode->parallel_workers = 0; pathnode->pathkeys = NIL; /* result is always unordered */ + pathnode->is_disabled = false; /* Cost is the same as for a regular CTE scan */ cost_ctescan(pathnode, root, rel, pathnode->param_info); @@ -2248,6 +2285,7 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = startup_cost; pathnode->path.total_cost = total_cost; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->fdw_outerpath = fdw_outerpath; pathnode->fdw_private = fdw_private; @@ -2298,6 +2336,7 @@ create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = startup_cost; pathnode->path.total_cost = total_cost; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->fdw_outerpath = fdw_outerpath; pathnode->fdw_private = fdw_private; @@ -2343,6 +2382,7 @@ create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = startup_cost; pathnode->path.total_cost = total_cost; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->fdw_outerpath = fdw_outerpath; pathnode->fdw_private = fdw_private; @@ -2472,6 +2512,7 @@ create_nestloop_path(PlannerInfo *root, /* This is a foolish way to estimate parallel_workers, but for now... */ pathnode->jpath.path.parallel_workers = outer_path->parallel_workers; pathnode->jpath.path.pathkeys = pathkeys; + pathnode->jpath.path.is_disabled = false; pathnode->jpath.jointype = jointype; pathnode->jpath.inner_unique = extra->inner_unique; pathnode->jpath.outerjoinpath = outer_path; @@ -2536,6 +2577,7 @@ create_mergejoin_path(PlannerInfo *root, /* This is a foolish way to estimate parallel_workers, but for now... */ pathnode->jpath.path.parallel_workers = outer_path->parallel_workers; pathnode->jpath.path.pathkeys = pathkeys; + pathnode->jpath.path.is_disabled = false; pathnode->jpath.jointype = jointype; pathnode->jpath.inner_unique = extra->inner_unique; pathnode->jpath.outerjoinpath = outer_path; @@ -2613,6 +2655,7 @@ create_hashjoin_path(PlannerInfo *root, * outer rel than it does now.) */ pathnode->jpath.path.pathkeys = NIL; + pathnode->jpath.path.is_disabled = false; pathnode->jpath.jointype = jointype; pathnode->jpath.inner_unique = extra->inner_unique; pathnode->jpath.outerjoinpath = outer_path; @@ -2671,6 +2714,7 @@ create_projection_path(PlannerInfo *root, pathnode->path.parallel_workers = subpath->parallel_workers; /* Projection does not change the sort order */ pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -2853,6 +2897,7 @@ create_set_projection_path(PlannerInfo *root, pathnode->path.parallel_workers = subpath->parallel_workers; /* Projection does not change the sort order XXX? */ pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -2922,6 +2967,7 @@ create_incremental_sort_path(PlannerInfo *root, subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -2969,6 +3015,7 @@ create_sort_path(PlannerInfo *root, subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; pathnode->path.pathkeys = pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -3015,6 +3062,7 @@ create_group_path(PlannerInfo *root, pathnode->path.parallel_workers = subpath->parallel_workers; /* Group doesn't change sort ordering */ pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; @@ -3073,6 +3121,7 @@ create_upper_unique_path(PlannerInfo *root, pathnode->path.parallel_workers = subpath->parallel_workers; /* Unique doesn't change the input ordering */ pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->numkeys = numCols; @@ -3151,6 +3200,7 @@ create_agg_path(PlannerInfo *root, pathnode->path.startup_cost += target->cost.startup; pathnode->path.total_cost += target->cost.startup + target->cost.per_tuple * pathnode->path.rows; + pathnode->path.is_disabled = false; return pathnode; } @@ -3194,6 +3244,7 @@ create_groupingsets_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel && subpath->parallel_safe; pathnode->path.parallel_workers = subpath->parallel_workers; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; /* @@ -3353,6 +3404,7 @@ create_minmaxagg_path(PlannerInfo *root, /* Result is one unordered row */ pathnode->path.rows = 1; pathnode->path.pathkeys = NIL; + pathnode->path.is_disabled = false; pathnode->mmaggregates = mmaggregates; pathnode->quals = quals; @@ -3443,6 +3495,7 @@ create_windowagg_path(PlannerInfo *root, pathnode->path.parallel_workers = subpath->parallel_workers; /* WindowAgg preserves the input sort order */ pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->winclause = winclause; @@ -3513,6 +3566,7 @@ create_setop_path(PlannerInfo *root, /* SetOp preserves the input sort order if in sort mode */ pathnode->path.pathkeys = (strategy == SETOP_SORTED) ? subpath->pathkeys : NIL; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->cmd = cmd; @@ -3572,6 +3626,7 @@ create_recursiveunion_path(PlannerInfo *root, pathnode->path.parallel_workers = leftpath->parallel_workers; /* RecursiveUnion result is always unsorted */ pathnode->path.pathkeys = NIL; + pathnode->path.is_disabled = false; pathnode->leftpath = leftpath; pathnode->rightpath = rightpath; @@ -3628,6 +3683,7 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = subpath->startup_cost; pathnode->path.total_cost = subpath->total_cost + cpu_tuple_cost * subpath->rows; + pathnode->path.is_disabled = false; return pathnode; } @@ -3688,6 +3744,7 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.parallel_safe = false; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; + pathnode->path.is_disabled = false; /* * Compute cost & rowcount as subpath cost & rowcount (if RETURNING) @@ -3777,6 +3834,7 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.startup_cost = subpath->startup_cost; pathnode->path.total_cost = subpath->total_cost; pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.is_disabled = false; pathnode->subpath = subpath; pathnode->limitOffset = limitOffset; pathnode->limitCount = limitCount; diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index a1dc1d07e1..50c5b65bde 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -1631,6 +1631,7 @@ typedef struct Path /* sort ordering of path's output; a List of PathKey nodes; see above */ List *pathkeys; + bool is_disabled; } Path; /* Macro for extracting a path's parameterization relids; beware double eval */ -- 2.41.0