Skip to content

Commit aef65db

Browse files
author
Etsuro Fujita
committed
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
1 parent 0269ede commit aef65db

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

src/backend/optimizer/util/pathnode.c

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3578,34 +3578,59 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
35783578

35793579
/*
35803580
* Adjust the output rows count and costs according to the offset/limit.
3581-
* This is only a cosmetic issue if we are at top level, but if we are
3582-
* building a subquery then it's important to report correct info to the
3583-
* outer planner.
3584-
*
3585-
* When the offset or count couldn't be estimated, use 10% of the
3586-
* estimated number of rows emitted from the subpath.
3587-
*
3588-
* XXX we don't bother to add eval costs of the offset/limit expressions
3589-
* themselves to the path costs. In theory we should, but in most cases
3590-
* those expressions are trivial and it's just not worth the trouble.
35913581
*/
3582+
adjust_limit_rows_costs(&pathnode->path.rows,
3583+
&pathnode->path.startup_cost,
3584+
&pathnode->path.total_cost,
3585+
offset_est, count_est);
3586+
3587+
return pathnode;
3588+
}
3589+
3590+
/*
3591+
* adjust_limit_rows_costs
3592+
* Adjust the size and cost estimates for a LimitPath node according to the
3593+
* offset/limit.
3594+
*
3595+
* This is only a cosmetic issue if we are at top level, but if we are
3596+
* building a subquery then it's important to report correct info to the outer
3597+
* planner.
3598+
*
3599+
* When the offset or count couldn't be estimated, use 10% of the estimated
3600+
* number of rows emitted from the subpath.
3601+
*
3602+
* XXX we don't bother to add eval costs of the offset/limit expressions
3603+
* themselves to the path costs. In theory we should, but in most cases those
3604+
* expressions are trivial and it's just not worth the trouble.
3605+
*/
3606+
void
3607+
adjust_limit_rows_costs(double *rows, /* in/out parameter */
3608+
Cost *startup_cost, /* in/out parameter */
3609+
Cost *total_cost, /* in/out parameter */
3610+
int64 offset_est,
3611+
int64 count_est)
3612+
{
3613+
double input_rows = *rows;
3614+
Cost input_startup_cost = *startup_cost;
3615+
Cost input_total_cost = *total_cost;
3616+
35923617
if (offset_est != 0)
35933618
{
35943619
double offset_rows;
35953620

35963621
if (offset_est > 0)
35973622
offset_rows = (double) offset_est;
35983623
else
3599-
offset_rows = clamp_row_est(subpath->rows * 0.10);
3600-
if (offset_rows > pathnode->path.rows)
3601-
offset_rows = pathnode->path.rows;
3602-
if (subpath->rows > 0)
3603-
pathnode->path.startup_cost +=
3604-
(subpath->total_cost - subpath->startup_cost)
3605-
* offset_rows / subpath->rows;
3606-
pathnode->path.rows -= offset_rows;
3607-
if (pathnode->path.rows < 1)
3608-
pathnode->path.rows = 1;
3624+
offset_rows = clamp_row_est(input_rows * 0.10);
3625+
if (offset_rows > *rows)
3626+
offset_rows = *rows;
3627+
if (input_rows > 0)
3628+
*startup_cost +=
3629+
(input_total_cost - input_startup_cost)
3630+
* offset_rows / input_rows;
3631+
*rows -= offset_rows;
3632+
if (*rows < 1)
3633+
*rows = 1;
36093634
}
36103635

36113636
if (count_est != 0)
@@ -3615,19 +3640,17 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
36153640
if (count_est > 0)
36163641
count_rows = (double) count_est;
36173642
else
3618-
count_rows = clamp_row_est(subpath->rows * 0.10);
3619-
if (count_rows > pathnode->path.rows)
3620-
count_rows = pathnode->path.rows;
3621-
if (subpath->rows > 0)
3622-
pathnode->path.total_cost = pathnode->path.startup_cost +
3623-
(subpath->total_cost - subpath->startup_cost)
3624-
* count_rows / subpath->rows;
3625-
pathnode->path.rows = count_rows;
3626-
if (pathnode->path.rows < 1)
3627-
pathnode->path.rows = 1;
3643+
count_rows = clamp_row_est(input_rows * 0.10);
3644+
if (count_rows > *rows)
3645+
count_rows = *rows;
3646+
if (input_rows > 0)
3647+
*total_cost = *startup_cost +
3648+
(input_total_cost - input_startup_cost)
3649+
* count_rows / input_rows;
3650+
*rows = count_rows;
3651+
if (*rows < 1)
3652+
*rows = 1;
36283653
}
3629-
3630-
return pathnode;
36313654
}
36323655

36333656

src/include/optimizer/pathnode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel,
265265
Path *subpath,
266266
Node *limitOffset, Node *limitCount,
267267
int64 offset_est, int64 count_est);
268+
extern void adjust_limit_rows_costs(double *rows,
269+
Cost *startup_cost, Cost *total_cost,
270+
int64 offset_est, int64 count_est);
268271

269272
extern Path *reparameterize_path(PlannerInfo *root, Path *path,
270273
Relids required_outer,

0 commit comments

Comments
 (0)