mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
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
This commit is contained in:
parent
0269edefac
commit
aef65db676
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user