I spent some time experimenting with the idea mentioned upthread of adding a macro to support deletion of a foreach loop's current element (adjusting the loop's state behind the scenes). This turns out to work really well: it reduces the complexity of fixing existing loops around element deletions quite a bit. Whereas in existing code you have to not use foreach() at all, and you have to track both the next list element and the previous undeleted element, now you can use foreach() and you don't have to mess with extra variables at all.
A good example appears in the trgm_regexp.c changes below. Typically we've coded such loops with a handmade expansion of foreach, like prev = NULL; cell = list_head(state->enterKeys); while (cell) { TrgmStateKey *existingKey = (TrgmStateKey *) lfirst(cell); next = lnext(cell); if (need to delete) state->enterKeys = list_delete_cell(state->enterKeys, cell, prev); else prev = cell; cell = next; } My previous patch would have had you replace this with a loop using an integer list-position index. You can still do that if you like, but it's less change to convert the loop to a foreach(), drop the prev/next variables, and replace the list_delete_cell call with foreach_delete_current: foreach(cell, state->enterKeys) { TrgmStateKey *existingKey = (TrgmStateKey *) lfirst(cell); if (need to delete) state->enterKeys = foreach_delete_current(state->enterKeys, cell); } So I think this is a win, and attached is v7. regards, tom lane
reimplement-List-as-array-7.patch.gz
Description: reimplement-List-as-array-7.patch.gz