Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a2eb9e0

Browse files
committed
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.
1 parent 696d1f7 commit a2eb9e0

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

src/backend/optimizer/util/pathnode.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,9 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
254254
{
255255
bool accept_new = true; /* unless we find a superior old path */
256256
ListCell *insert_after = NULL; /* where to insert new item */
257-
ListCell *p1_prev = NULL;
258257
ListCell *p1;
258+
ListCell *p1_prev;
259+
ListCell *p1_next;
259260

260261
/*
261262
* 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)
267268
* Loop to check proposed new path against old paths. Note it is possible
268269
* for more than one old path to be tossed out because new_path dominates
269270
* it.
271+
*
272+
* We can't use foreach here because the loop body may delete the current
273+
* list cell.
270274
*/
271-
p1 = list_head(parent_rel->pathlist); /* cannot use foreach here */
272-
while (p1 != NULL)
275+
p1_prev = NULL;
276+
for (p1 = list_head(parent_rel->pathlist); p1 != NULL; p1 = p1_next)
273277
{
274278
Path *old_path = (Path *) lfirst(p1);
275279
bool remove_old = false; /* unless new proves superior */
276280
int costcmp;
277281

282+
p1_next = lnext(p1);
283+
278284
/*
279285
* As of Postgres 8.0, we use fuzzy cost comparison to avoid wasting
280286
* cycles keeping paths that are really not significantly different in
@@ -343,20 +349,15 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
343349
*/
344350
if (!IsA(old_path, IndexPath))
345351
pfree(old_path);
346-
/* Advance list pointer */
347-
if (p1_prev)
348-
p1 = lnext(p1_prev);
349-
else
350-
p1 = list_head(parent_rel->pathlist);
352+
/* p1_prev does not advance */
351353
}
352354
else
353355
{
354356
/* new belongs after this old path if it has cost >= old's */
355357
if (costcmp >= 0)
356358
insert_after = p1;
357-
/* Advance list pointers */
359+
/* p1_prev advances */
358360
p1_prev = p1;
359-
p1 = lnext(p1);
360361
}
361362

362363
/*

0 commit comments

Comments
 (0)