Commit aef65db6 authored by Etsuro Fujita's avatar Etsuro Fujita

Refactor create_limit_path() to share cost adjustment code with FDWs.

This is in preparation for an upcoming commit.

Author: Etsuro Fujita
Reviewed-By: Antonin Houska and Jeff Janes
Discussion: https://postgr.es/m/87pnz1aby9.fsf@news-spur.riddles.org.uk
parent 0269edef
...@@ -3578,17 +3578,42 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, ...@@ -3578,17 +3578,42 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
/* /*
* Adjust the output rows count and costs according to the offset/limit. * Adjust the output rows count and costs according to the offset/limit.
* This is only a cosmetic issue if we are at top level, but if we are
* building a subquery then it's important to report correct info to the
* outer planner.
*
* When the offset or count couldn't be estimated, use 10% of the
* estimated number of rows emitted from the subpath.
*
* XXX we don't bother to add eval costs of the offset/limit expressions
* themselves to the path costs. In theory we should, but in most cases
* those expressions are trivial and it's just not worth the trouble.
*/ */
adjust_limit_rows_costs(&pathnode->path.rows,
&pathnode->path.startup_cost,
&pathnode->path.total_cost,
offset_est, count_est);
return pathnode;
}
/*
* adjust_limit_rows_costs
* Adjust the size and cost estimates for a LimitPath node according to the
* offset/limit.
*
* This is only a cosmetic issue if we are at top level, but if we are
* building a subquery then it's important to report correct info to the outer
* planner.
*
* When the offset or count couldn't be estimated, use 10% of the estimated
* number of rows emitted from the subpath.
*
* XXX we don't bother to add eval costs of the offset/limit expressions
* themselves to the path costs. In theory we should, but in most cases those
* expressions are trivial and it's just not worth the trouble.
*/
void
adjust_limit_rows_costs(double *rows, /* in/out parameter */
Cost *startup_cost, /* in/out parameter */
Cost *total_cost, /* in/out parameter */
int64 offset_est,
int64 count_est)
{
double input_rows = *rows;
Cost input_startup_cost = *startup_cost;
Cost input_total_cost = *total_cost;
if (offset_est != 0) if (offset_est != 0)
{ {
double offset_rows; double offset_rows;
...@@ -3596,16 +3621,16 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, ...@@ -3596,16 +3621,16 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
if (offset_est > 0) if (offset_est > 0)
offset_rows = (double) offset_est; offset_rows = (double) offset_est;
else else
offset_rows = clamp_row_est(subpath->rows * 0.10); offset_rows = clamp_row_est(input_rows * 0.10);
if (offset_rows > pathnode->path.rows) if (offset_rows > *rows)
offset_rows = pathnode->path.rows; offset_rows = *rows;
if (subpath->rows > 0) if (input_rows > 0)
pathnode->path.startup_cost += *startup_cost +=
(subpath->total_cost - subpath->startup_cost) (input_total_cost - input_startup_cost)
* offset_rows / subpath->rows; * offset_rows / input_rows;
pathnode->path.rows -= offset_rows; *rows -= offset_rows;
if (pathnode->path.rows < 1) if (*rows < 1)
pathnode->path.rows = 1; *rows = 1;
} }
if (count_est != 0) if (count_est != 0)
...@@ -3615,19 +3640,17 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, ...@@ -3615,19 +3640,17 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
if (count_est > 0) if (count_est > 0)
count_rows = (double) count_est; count_rows = (double) count_est;
else else
count_rows = clamp_row_est(subpath->rows * 0.10); count_rows = clamp_row_est(input_rows * 0.10);
if (count_rows > pathnode->path.rows) if (count_rows > *rows)
count_rows = pathnode->path.rows; count_rows = *rows;
if (subpath->rows > 0) if (input_rows > 0)
pathnode->path.total_cost = pathnode->path.startup_cost + *total_cost = *startup_cost +
(subpath->total_cost - subpath->startup_cost) (input_total_cost - input_startup_cost)
* count_rows / subpath->rows; * count_rows / input_rows;
pathnode->path.rows = count_rows; *rows = count_rows;
if (pathnode->path.rows < 1) if (*rows < 1)
pathnode->path.rows = 1; *rows = 1;
} }
return pathnode;
} }
......
...@@ -265,6 +265,9 @@ extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel, ...@@ -265,6 +265,9 @@ extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel,
Path *subpath, Path *subpath,
Node *limitOffset, Node *limitCount, Node *limitOffset, Node *limitCount,
int64 offset_est, int64 count_est); int64 offset_est, int64 count_est);
extern void adjust_limit_rows_costs(double *rows,
Cost *startup_cost, Cost *total_cost,
int64 offset_est, int64 count_est);
extern Path *reparameterize_path(PlannerInfo *root, Path *path, extern Path *reparameterize_path(PlannerInfo *root, Path *path,
Relids required_outer, Relids required_outer,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment