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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy