mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Simplify list traversal logic in add_path().
Its mechanism for recovering after deleting the current list cell was a bit klugy. Borrow the technique used in other places.
This commit is contained in:
parent
696d1f7f06
commit
a2eb9e0c08
@ -254,8 +254,9 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
|
|||||||
{
|
{
|
||||||
bool accept_new = true; /* unless we find a superior old path */
|
bool accept_new = true; /* unless we find a superior old path */
|
||||||
ListCell *insert_after = NULL; /* where to insert new item */
|
ListCell *insert_after = NULL; /* where to insert new item */
|
||||||
ListCell *p1_prev = NULL;
|
|
||||||
ListCell *p1;
|
ListCell *p1;
|
||||||
|
ListCell *p1_prev;
|
||||||
|
ListCell *p1_next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a convenient place to check for query cancel --- no part of the
|
* This is a convenient place to check for query cancel --- no part of the
|
||||||
@ -267,14 +268,19 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
|
|||||||
* Loop to check proposed new path against old paths. Note it is possible
|
* Loop to check proposed new path against old paths. Note it is possible
|
||||||
* for more than one old path to be tossed out because new_path dominates
|
* for more than one old path to be tossed out because new_path dominates
|
||||||
* it.
|
* it.
|
||||||
|
*
|
||||||
|
* We can't use foreach here because the loop body may delete the current
|
||||||
|
* list cell.
|
||||||
*/
|
*/
|
||||||
p1 = list_head(parent_rel->pathlist); /* cannot use foreach here */
|
p1_prev = NULL;
|
||||||
while (p1 != NULL)
|
for (p1 = list_head(parent_rel->pathlist); p1 != NULL; p1 = p1_next)
|
||||||
{
|
{
|
||||||
Path *old_path = (Path *) lfirst(p1);
|
Path *old_path = (Path *) lfirst(p1);
|
||||||
bool remove_old = false; /* unless new proves superior */
|
bool remove_old = false; /* unless new proves superior */
|
||||||
int costcmp;
|
int costcmp;
|
||||||
|
|
||||||
|
p1_next = lnext(p1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As of Postgres 8.0, we use fuzzy cost comparison to avoid wasting
|
* As of Postgres 8.0, we use fuzzy cost comparison to avoid wasting
|
||||||
* cycles keeping paths that are really not significantly different in
|
* cycles keeping paths that are really not significantly different in
|
||||||
@ -343,20 +349,15 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
|
|||||||
*/
|
*/
|
||||||
if (!IsA(old_path, IndexPath))
|
if (!IsA(old_path, IndexPath))
|
||||||
pfree(old_path);
|
pfree(old_path);
|
||||||
/* Advance list pointer */
|
/* p1_prev does not advance */
|
||||||
if (p1_prev)
|
|
||||||
p1 = lnext(p1_prev);
|
|
||||||
else
|
|
||||||
p1 = list_head(parent_rel->pathlist);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* new belongs after this old path if it has cost >= old's */
|
/* new belongs after this old path if it has cost >= old's */
|
||||||
if (costcmp >= 0)
|
if (costcmp >= 0)
|
||||||
insert_after = p1;
|
insert_after = p1;
|
||||||
/* Advance list pointers */
|
/* p1_prev advances */
|
||||||
p1_prev = p1;
|
p1_prev = p1;
|
||||||
p1 = lnext(p1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user