mirror of https://github.com/citusdata/citus.git
Introduce foreach_ptr_modify macro (#4303)
If one wishes to iterate through a List and insert list elements in PG13, it is not safe to use for_each_ptr as the List representation in PostgreSQL no longer linked lists, but arrays, and it is possible that the whole array is repalloc'ed if ther is not sufficient space available. See postgres commit 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164 for more informationpull/4304/head
parent
5d5966f700
commit
d3019f1b6d
|
@ -1097,7 +1097,7 @@ GetDependingViews(Oid relationId)
|
|||
List *dependingViews = NIL;
|
||||
List *nodeQueue = list_make1(tableNode);
|
||||
ViewDependencyNode *node = NULL;
|
||||
foreach_ptr(node, nodeQueue)
|
||||
foreach_ptr_append(node, nodeQueue)
|
||||
{
|
||||
ViewDependencyNode *dependingNode = NULL;
|
||||
foreach_ptr(dependingNode, node->dependingNodes)
|
||||
|
|
|
@ -80,6 +80,38 @@ typedef struct ListCellAndListWrapper
|
|||
(((var) = lfirst_oid(var ## CellDoNotUse)) || true); \
|
||||
var ## CellDoNotUse = lnext_compat(l, var ## CellDoNotUse))
|
||||
|
||||
/*
|
||||
* foreach_ptr_append -
|
||||
* a convenience macro which loops through a pointer List and can append list
|
||||
* elements without needing a ListCell or and index variable, just a declared
|
||||
* pointer variable to store the iterated values.
|
||||
*
|
||||
* PostgreSQL 13 changed the representation of Lists to expansible arrays,
|
||||
* not chains of cons-cells. This changes the costs for accessing and
|
||||
* mutating List contents. Therefore different implementations are provided.
|
||||
*
|
||||
* For more information, see postgres commit with sha
|
||||
* 1cff1b95ab6ddae32faa3efe0d95a820dbfdc164
|
||||
*/
|
||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
||||
|
||||
/*
|
||||
* How it works:
|
||||
* - An index is declared with the name {var}PositionDoNotUse and used
|
||||
* throughout the for loop using ## to concat.
|
||||
* - To assign to var it needs to be done in the condition of the for loop,
|
||||
* because we cannot use the initializer since the index variable is
|
||||
* declared there.
|
||||
* - || true is used to always enter the loop even if var is NULL.
|
||||
*/
|
||||
#define foreach_ptr_append(var, l) \
|
||||
for (int var ## PositionDoNotUse = 0; \
|
||||
(var ## PositionDoNotUse) < list_length(l) && \
|
||||
(((var) = list_nth(l, var ## PositionDoNotUse)) || true); \
|
||||
var ## PositionDoNotUse ++)
|
||||
#else
|
||||
#define foreach_ptr_append(var, l) foreach_ptr(var, l)
|
||||
#endif
|
||||
|
||||
/* utility functions declaration shared within this module */
|
||||
extern List * SortList(List *pointerList,
|
||||
|
|
Loading…
Reference in New Issue