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)
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