1/*-------------------------------------------------------------------------
4 * implementation for PostgreSQL generic list package
6 * See comments in pg_list.h.
9 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
14 * src/backend/nodes/list.c
16 *-------------------------------------------------------------------------
28 * The previous List implementation, since it used a separate palloc chunk
29 * for each cons cell, had the property that adding or deleting list cells
30 * did not move the storage of other existing cells in the list. Quite a
31 * bit of existing code depended on that, by retaining ListCell pointers
32 * across such operations on a list. There is no such guarantee in this
33 * implementation, so instead we have debugging support that is meant to
34 * help flush out now-broken assumptions. Defining DEBUG_LIST_MEMORY_USAGE
35 * while building this file causes the List operations to forcibly move
36 * all cells in a list whenever a cell is added or deleted. In combination
37 * with MEMORY_CONTEXT_CHECKING and/or Valgrind, this can usually expose
38 * broken code. It's a bit expensive though, as there's many more palloc
39 * cycles and a lot more data-copying than in a default build.
41 * By default, we enable this when building for Valgrind.
44#define DEBUG_LIST_MEMORY_USAGE
47/* Overhead for the fixed part of a List header, measured in ListCells */
48 #define LIST_HEADER_OVERHEAD \
49 ((int) ((offsetof(List, initial_elements) - 1) / sizeof(ListCell) + 1))
52 * Macros to simplify writing assertions about the type of a list; a
53 * NIL list is considered to be an empty list of any type.
55 #define IsPointerList(l) ((l) == NIL || IsA((l), List))
56 #define IsIntegerList(l) ((l) == NIL || IsA((l), IntList))
57 #define IsOidList(l) ((l) == NIL || IsA((l), OidList))
58 #define IsXidList(l) ((l) == NIL || IsA((l), XidList))
60#ifdef USE_ASSERT_CHECKING
62 * Check that the specified List is valid (so far as we can tell).
75 list->type == T_IntList ||
76 list->type == T_OidList ||
77 list->type == T_XidList);
80 #define check_list_invariants(l) ((void) 0)
81#endif /* USE_ASSERT_CHECKING */
84 * Return a freshly allocated List with room for at least min_size cells.
86 * Since empty non-NIL lists are invalid, new_list() sets the initial length
87 * to min_size, effectively marking that number of cells as valid; the caller
88 * is responsible for filling in their data.
99 * We allocate all the requested cells, and possibly some more, as part of
100 * the same palloc request as the List header. This is a big win for the
101 * typical case of short fixed-length lists. It can lose if we allocate a
102 * moderately long list and then it gets extended; we'll be wasting more
103 * initial_elements[] space than if we'd made the header small. However,
104 * rounding up the request as we do in the normal code path provides some
105 * defense against small extensions.
108#ifndef DEBUG_LIST_MEMORY_USAGE
111 * Normally, we set up a list with some extra cells, to allow it to grow
112 * without a repalloc. Prefer cell counts chosen to make the total
113 * allocation a power-of-2, since palloc would round it up to that anyway.
114 * (That stops being true for very large allocations, but very long lists
115 * are infrequent, so it doesn't seem worth special logic for such cases.)
117 * The minimum allocation is 8 ListCell units, providing either 4 or 5
118 * available ListCells depending on the machine's word width. Counting
119 * palloc's overhead, this uses the same amount of space as a one-cell
120 * list did in the old implementation, and less space for any longer list.
122 * We needn't worry about integer overflow; no caller passes min_size
123 * that's more than twice the size of an existing list, so the size limits
124 * within palloc will ensure that we don't overflow here.
131 * For debugging, don't allow any extra space. This forces any cell
132 * addition to go through enlarge_list() and thus move the existing data.
140 newlist->
length = min_size;
148 * Enlarge an existing non-NIL List to have room for at least min_size cells.
150 * This does *not* update list->length, as some callers would find that
151 * inconvenient. (list->length had better be the correct number of existing
152 * valid cells, though.)
159 Assert(min_size >
list->max_length);
/* else we shouldn't be here */
161#ifndef DEBUG_LIST_MEMORY_USAGE
164 * As above, we prefer power-of-two total allocations; but here we need
165 * not account for list header overhead.
168 /* clamp the minimum value to 16, a semi-arbitrary small power of 2 */
172 /* As above, don't allocate anything extra */
173 new_max_len = min_size;
176 if (
list->elements ==
list->initial_elements)
179 * Replace original in-line allocation with a separate palloc block.
180 * Ensure it is in the same memory context as the List header. (The
181 * previous List implementation did not offer any guarantees about
182 * keeping all list cells in the same context, but it seems reasonable
183 * to create such a guarantee now.)
188 memcpy(
list->elements,
list->initial_elements,
192 * We must not move the list header, so it's unsafe to try to reclaim
193 * the initial_elements[] space via repalloc. In debugging builds,
194 * however, we can clear that space and/or mark it inaccessible.
195 * (wipe_mem includes VALGRIND_MAKE_MEM_NOACCESS.)
197#ifdef CLOBBER_FREED_MEMORY
198 wipe_mem(
list->initial_elements,
207#ifndef DEBUG_LIST_MEMORY_USAGE
208 /* Normally, let repalloc deal with enlargement */
213 * repalloc() might enlarge the space in-place, which we don't want
214 * for debugging purposes, so forcibly move the data somewhere else.
221 memcpy(newelements,
list->elements,
224 list->elements = newelements;
228 list->max_length = new_max_len;
232 * Convenience functions to construct short Lists from given values.
233 * (These are normally invoked via the list_makeN macros.)
240 list->elements[0] = datum1;
250 list->elements[0] = datum1;
251 list->elements[1] = datum2;
262 list->elements[0] = datum1;
263 list->elements[1] = datum2;
264 list->elements[2] = datum3;
275 list->elements[0] = datum1;
276 list->elements[1] = datum2;
277 list->elements[2] = datum3;
278 list->elements[3] = datum4;
289 list->elements[0] = datum1;
290 list->elements[1] = datum2;
291 list->elements[2] = datum3;
292 list->elements[3] = datum4;
293 list->elements[4] = datum5;
299 * Make room for a new head cell in the given (non-NIL) list.
301 * The data in the new head cell is undefined; the caller should be
307 /* Enlarge array if necessary */
308 if (
list->length >=
list->max_length)
310 /* Now shove the existing data over */
311 memmove(&
list->elements[1], &
list->elements[0],
317 * Make room for a new tail cell in the given (non-NIL) list.
319 * The data in the new tail cell is undefined; the caller should be
325 /* Enlarge array if necessary */
326 if (
list->length >=
list->max_length)
332 * Append a pointer to the list. A pointer to the modified list is
333 * returned. Note that this function may or may not destructively
334 * modify the list; callers should always use this function's return
335 * value, rather than continuing to use the pointer passed as the
354 * Append an integer to the specified list. See lappend()
372 * Append an OID to the specified list. See lappend()
390 * Append a TransactionId to the specified list. See lappend()
408 * Make room for a new cell at position 'pos' (measured from 0).
409 * The data in the cell is left undefined, and must be filled in by the
410 * caller. 'list' is assumed to be non-NIL, and 'pos' must be a valid
411 * list position, ie, 0 <= pos <= list's length.
412 * Returns address of the new cell.
417 Assert(pos >= 0 && pos <= list->length);
419 /* Enlarge array if necessary */
420 if (
list->length >=
list->max_length)
422 /* Now shove the existing data over */
423 if (pos < list->length)
424 memmove(&
list->elements[pos + 1], &
list->elements[pos],
428 return &
list->elements[pos];
432 * Insert the given datum at position 'pos' (measured from 0) in the list.
433 * 'pos' must be valid, ie, 0 <= pos <= list's length.
435 * Note that this takes time proportional to the distance to the end of the
436 * list, since the following entries must be moved.
481 * Prepend a new element to the list. A pointer to the modified list
482 * is returned. Note that this function may or may not destructively
483 * modify the list; callers should always use this function's return
484 * value, rather than continuing to use the pointer passed as the
487 * Note that this takes time proportional to the length of the list,
488 * since the existing entries must be moved.
490 * Caution: before Postgres 8.0, the original List was unmodified and
491 * could be considered to retain its separate identity. This is no longer
510 * Prepend an integer to the list. See lcons()
528 * Prepend an OID to the list. See lcons()
546 * Concatenate list2 to the end of list1, and return list1.
548 * This is equivalent to lappend'ing each element of list2, in order, to list1.
549 * list1 is destructively changed, list2 is not. (However, in the case of
550 * pointer lists, list1 and list2 will point to the same structures.)
552 * Callers should be sure to use the return value as the new pointer to the
553 * concatenated list: the 'list1' input pointer may or may not be the same
554 * as the returned pointer.
556 * Note that this takes at least time proportional to the length of list2.
557 * It'd typically be the case that we have to enlarge list1's storage,
558 * probably adding time proportional to the length of list1.
573 /* Enlarge array if necessary */
577 /* Even if list1 == list2, using memcpy should be safe here */
587 * Form a new list by concatenating the elements of list1 and list2.
589 * Neither input list is modified. (However, if they are pointer lists,
590 * the output list will point to the same structures.)
592 * This is equivalent to, but more efficient than,
593 * list_concat(list_copy(list1), list2).
594 * Note that some pre-v13 code might list_copy list2 as well, but that's
622 * Truncate 'list' to contain no more than 'new_size' elements. This
623 * modifies the list in-place! Despite this, callers should use the
624 * pointer returned by this function to refer to the newly truncated
625 * list -- it may or may not be the same as the pointer that was
628 * Note that any cells removed by list_truncate() are NOT pfree'd.
634 return NIL;
/* truncate to zero length */
636 /* If asked to effectively extend the list, do nothing */
638 list->length = new_size;
641 * Note: unlike the individual-list-cell deletion functions, we don't move
642 * the list cells to new storage, even in DEBUG_LIST_MEMORY_USAGE mode.
643 * This is because none of them can move in this operation, so just like
644 * in the old cons-cell-based implementation, this function doesn't
645 * invalidate any pointers to cells of the list. This is also the reason
646 * for not wiping the memory of the deleted cells: the old code didn't
647 * free them either. Perhaps later we'll tighten this up.
654 * Return true iff 'datum' is a member of the list. Equality is
655 * determined via equal(), so callers should ensure that they pass a
658 * This does a simple linear search --- avoid using it on long lists.
678 * Return true iff 'datum' is a member of the list. Equality is
679 * determined by using simple pointer comparison.
691 if (
lfirst(cell) == datum)
699 * Return true iff the integer 'datum' is a member of the list.
719 * Return true iff the OID 'datum' is a member of the list.
739 * Return true iff the TransactionId 'datum' is a member of the list.
759 * Delete the n'th cell (counting from 0) in list.
761 * The List is pfree'd if this was the last member.
763 * Note that this takes time proportional to the distance to the end of the
764 * list, since the following entries must be moved.
771 Assert(n >= 0 && n < list->length);
774 * If we're about to delete the last node from the list, free the whole
775 * list instead and return NIL, which is the only valid representation of
776 * a zero-length list.
778 if (
list->length == 1)
785 * Otherwise, we normally just collapse out the removed element. But for
786 * debugging purposes, move the whole list contents someplace else.
788 * (Note that we *must* keep the contents in the same memory context.)
790#ifndef DEBUG_LIST_MEMORY_USAGE
791 memmove(&
list->elements[n], &
list->elements[n + 1],
797 int newmaxlen =
list->length - 1;
803 memcpy(&newelems[n], &
list->elements[n + 1],
805 if (
list->elements !=
list->initial_elements)
810 * As in enlarge_list(), clear the initial_elements[] space and/or
811 * mark it inaccessible.
813#ifdef CLOBBER_FREED_MEMORY
814 wipe_mem(
list->initial_elements,
821 list->elements = newelems;
822 list->max_length = newmaxlen;
832 * Delete 'cell' from 'list'.
834 * The List is pfree'd if this was the last member. However, we do not
835 * touch any data the cell might've been pointing to.
837 * Note that this takes time proportional to the distance to the end of the
838 * list, since the following entries must be moved.
847 * Delete the first cell in list that matches datum, if any.
848 * Equality is determined via equal().
850 * This does a simple linear search --- avoid using it on long lists.
866 /* Didn't find a match: return the list unmodified */
870/* As above, but use simple pointer equality */
881 if (
lfirst(cell) == datum)
885 /* Didn't find a match: return the list unmodified */
889/* As above, but for integers */
904 /* Didn't find a match: return the list unmodified */
908/* As above, but for OIDs */
923 /* Didn't find a match: return the list unmodified */
928 * Delete the first element of the list.
930 * This is useful to replace the Lisp-y code "list = lnext(list);" in cases
931 * where the intent is to alter the list rather than just traverse it.
932 * Beware that the list is modified, whereas the Lisp-y coding leaves
933 * the original list head intact in case there's another pointer to it.
935 * Note that this takes time proportional to the length of the list,
936 * since the remaining entries must be moved. Consider reversing the
937 * list order so that you can use list_delete_last() instead. However,
938 * if that causes you to replace lappend() with lcons(), you haven't
939 * improved matters. (In short, you can make an efficient stack from
940 * a List, but not an efficient FIFO queue.)
948 return NIL;
/* would an error be better? */
954 * Delete the last element of the list.
962 return NIL;
/* would an error be better? */
964 /* list_truncate won't free list if it goes to empty, but this should */
975 * Delete the first N cells of the list.
977 * The List is pfree'd if the request causes all cells to be deleted.
979 * Note that this takes time proportional to the distance to the end of the
980 * list, since the following entries must be moved.
991 /* Delete whole list? */
999 * Otherwise, we normally just collapse out the removed elements. But for
1000 * debugging purposes, move the whole list contents someplace else.
1002 * (Note that we *must* keep the contents in the same memory context.)
1004#ifndef DEBUG_LIST_MEMORY_USAGE
1005 memmove(&
list->elements[0], &
list->elements[n],
1011 int newmaxlen =
list->length - n;
1016 memcpy(newelems, &
list->elements[n], newmaxlen *
sizeof(
ListCell));
1017 if (
list->elements !=
list->initial_elements)
1022 * As in enlarge_list(), clear the initial_elements[] space and/or
1023 * mark it inaccessible.
1025#ifdef CLOBBER_FREED_MEMORY
1026 wipe_mem(
list->initial_elements,
1033 list->elements = newelems;
1034 list->max_length = newmaxlen;
1035 list->length = newmaxlen;
1044 * Generate the union of two lists. This is calculated by copying
1045 * list1 via list_copy(), then adding to it all the members of list2
1046 * that aren't already in list1.
1048 * Whether an element is already a member of the list is determined
1051 * The returned list is newly-allocated, although the content of the
1052 * cells is the same (i.e. any pointed-to objects are not copied).
1054 * NB: this function will NOT remove any duplicates that are present
1055 * in list1 (so it only performs a "union" if list1 is known unique to
1056 * start with). Also, if you are about to write "x = list_union(x, y)"
1057 * you probably want to use list_concat_unique() instead to avoid wasting
1058 * the storage of the old x list.
1060 * Note that this takes time proportional to the product of the list
1061 * lengths, so beware of using it on long lists. (We could probably
1062 * improve that, but really you should be using some other data structure
1063 * if this'd be a performance bottleneck.)
1075 foreach(cell, list2)
1086 * This variant of list_union() determines duplicates via simple
1087 * pointer comparison.
1099 foreach(cell, list2)
1110 * This variant of list_union() operates upon lists of integers.
1122 foreach(cell, list2)
1133 * This variant of list_union() operates upon lists of OIDs.
1145 foreach(cell, list2)
1156 * Return a list that contains all the cells that are in both list1 and
1157 * list2. The returned list is freshly allocated via palloc(), but the
1158 * cells themselves point to the same objects as the cells of the
1161 * Duplicate entries in list1 will not be suppressed, so it's only a true
1162 * "intersection" if list1 is known unique beforehand.
1164 * This variant works on lists of pointers, and determines list
1165 * membership via equal(). Note that the list1 member will be pointed
1168 * Note that this takes time proportional to the product of the list
1169 * lengths, so beware of using it on long lists. (We could probably
1170 * improve that, but really you should be using some other data structure
1171 * if this'd be a performance bottleneck.)
1179 if (list1 ==
NIL || list2 ==
NIL)
1186 foreach(cell, list1)
1197 * As list_intersection but operates on lists of integers.
1205 if (list1 ==
NIL || list2 ==
NIL)
1212 foreach(cell, list1)
1223 * Return a list that contains all the cells in list1 that are not in
1224 * list2. The returned list is freshly allocated via palloc(), but the
1225 * cells themselves point to the same objects as the cells of the
1228 * This variant works on lists of pointers, and determines list
1229 * membership via equal()
1231 * Note that this takes time proportional to the product of the list
1232 * lengths, so beware of using it on long lists. (We could probably
1233 * improve that, but really you should be using some other data structure
1234 * if this'd be a performance bottleneck.)
1248 foreach(cell, list1)
1259 * This variant of list_difference() determines list membership via
1260 * simple pointer equality.
1274 foreach(cell, list1)
1285 * This variant of list_difference() operates upon lists of integers.
1299 foreach(cell, list1)
1310 * This variant of list_difference() operates upon lists of OIDs.
1324 foreach(cell, list1)
1335 * Append datum to list, but only if it isn't already in the list.
1337 * Whether an element is already a member of the list is determined
1340 * This does a simple linear search --- avoid using it on long lists.
1352 * This variant of list_append_unique() determines list membership via
1353 * simple pointer equality.
1365 * This variant of list_append_unique() operates upon lists of integers.
1377 * This variant of list_append_unique() operates upon lists of OIDs.
1389 * Append to list1 each member of list2 that isn't already in list1.
1391 * Whether an element is already a member of the list is determined
1394 * This is almost the same functionality as list_union(), but list1 is
1395 * modified in-place rather than being copied. However, callers of this
1396 * function may have strict ordering expectations -- i.e. that the relative
1397 * order of those list2 elements that are not duplicates is preserved.
1399 * Note that this takes time proportional to the product of the list
1400 * lengths, so beware of using it on long lists. (We could probably
1401 * improve that, but really you should be using some other data structure
1402 * if this'd be a performance bottleneck.)
1412 foreach(cell, list2)
1423 * This variant of list_concat_unique() determines list membership via
1424 * simple pointer equality.
1434 foreach(cell, list2)
1445 * This variant of list_concat_unique() operates upon lists of integers.
1455 foreach(cell, list2)
1466 * This variant of list_concat_unique() operates upon lists of OIDs.
1476 foreach(cell, list2)
1487 * Remove adjacent duplicates in a list of OIDs.
1489 * It is caller's responsibility to have sorted the list to bring duplicates
1490 * together, perhaps via list_sort(list, list_oid_cmp).
1492 * Note that this takes time proportional to the length of the list.
1506 for (
int j = 1;
j <
len;
j++)
1508 if (elements[
i].oid_value != elements[
j].oid_value)
1511 list->length =
i + 1;
1517 * Free all storage in a list, and optionally the pointed-to elements
1523 return;
/* nothing to do */
1529 for (
int i = 0;
i <
list->length;
i++)
1532 if (
list->elements !=
list->initial_elements)
1538 * Free all the cells of the list, as well as the list itself. Any
1539 * objects that are pointed-to by the cells of the list are NOT
1542 * On return, the argument to this function has been freed, so the
1543 * caller would be wise to set it to NIL for safety's sake.
1552 * Free all the cells of the list, the list itself, and all the
1553 * objects pointed-to by the cells of the list (each element in the
1554 * list must contain a pointer to a palloc()'d region of memory!)
1556 * On return, the argument to this function has been freed, so the
1557 * caller would be wise to set it to NIL for safety's sake.
1563 * A "deep" free operation only makes sense on a list of pointers.
1570 * Return a shallow copy of the specified list.
1589 * Return a shallow copy of the specified list containing only the first 'len'
1590 * elements. If oldlist is shorter than 'len' then we copy the entire list.
1597 if (oldlist ==
NIL ||
len <= 0)
1610 * Return a shallow copy of the specified list, without the first N elements.
1618 nskip = 0;
/* would it be better to elog? */
1620 if (oldlist ==
NIL || nskip >= oldlist->
length)
1632 * Return a deep copy of the specified list.
1634 * The list elements are copied via copyObject(), so that this function's
1635 * idea of a "deep" copy is considerably deeper than what list_free_deep()
1636 * means by the same word.
1646 /* This is only sensible for pointer Lists */
1650 for (
int i = 0;
i < newlist->
length;
i++)
1659 * Sort a list according to the specified comparator function.
1661 * The list is sorted in-place.
1663 * The comparator function is declared to receive arguments of type
1664 * const ListCell *; this allows it to use lfirst() and variants
1665 * without casting its arguments. Otherwise it behaves the same as
1666 * the comparator function for standard qsort().
1668 * Like qsort(), this provides no guarantees about sort stability
1671 * This is based on qsort(), so it likewise has O(N log N) runtime.
1676 typedef int (*qsort_comparator) (
const void *
a,
const void *
b);
1681 /* Nothing to do if there's less than two elements */
1688 * list_sort comparator for sorting a list into ascending int order.
1700 * list_sort comparator for sorting a list into ascending OID order.
void * copyObjectImpl(const void *from)
bool equal(const void *a, const void *b)
Assert(PointerIsAligned(start, uint64))
static int pg_cmp_u32(uint32 a, uint32 b)
static int pg_cmp_s32(int32 a, int32 b)
List * lcons_oid(Oid datum, List *list)
List * list_difference(const List *list1, const List *list2)
List * list_union_ptr(const List *list1, const List *list2)
List * list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3, ListCell datum4)
static void new_head_cell(List *list)
List * list_delete_ptr(List *list, void *datum)
List * list_copy_deep(const List *oldlist)
List * list_concat_unique_oid(List *list1, const List *list2)
List * lappend(List *list, void *datum)
List * list_delete(List *list, void *datum)
void list_sort(List *list, list_sort_comparator cmp)
List * list_difference_ptr(const List *list1, const List *list2)
List * list_difference_int(const List *list1, const List *list2)
List * list_intersection(const List *list1, const List *list2)
List * list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3)
List * list_delete_oid(List *list, Oid datum)
List * list_insert_nth_oid(List *list, int pos, Oid datum)
List * list_concat_unique_ptr(List *list1, const List *list2)
static void enlarge_list(List *list, int min_size)
#define LIST_HEADER_OVERHEAD
List * list_append_unique(List *list, void *datum)
List * lappend_xid(List *list, TransactionId datum)
List * list_copy_tail(const List *oldlist, int nskip)
List * list_delete_nth_cell(List *list, int n)
List * list_delete_first(List *list)
List * list_difference_oid(const List *list1, const List *list2)
List * list_concat(List *list1, const List *list2)
static ListCell * insert_new_cell(List *list, int pos)
List * list_delete_cell(List *list, ListCell *cell)
List * list_concat_copy(const List *list1, const List *list2)
List * list_copy(const List *oldlist)
List * list_union_oid(const List *list1, const List *list2)
bool list_member_xid(const List *list, TransactionId datum)
List * lappend_int(List *list, int datum)
static void list_free_private(List *list, bool deep)
List * list_make1_impl(NodeTag t, ListCell datum1)
List * list_intersection_int(const List *list1, const List *list2)
List * lappend_oid(List *list, Oid datum)
List * lcons(void *datum, List *list)
#define check_list_invariants(l)
List * list_append_unique_oid(List *list, Oid datum)
List * lcons_int(int datum, List *list)
List * list_insert_nth_int(List *list, int pos, int datum)
void list_deduplicate_oid(List *list)
static void new_tail_cell(List *list)
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
List * list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2)
List * list_delete_int(List *list, int datum)
static List * new_list(NodeTag type, int min_size)
List * list_delete_last(List *list)
bool list_member_ptr(const List *list, const void *datum)
void list_free(List *list)
bool list_member_int(const List *list, int datum)
bool list_member_oid(const List *list, Oid datum)
List * list_append_unique_int(List *list, int datum)
int list_int_cmp(const ListCell *p1, const ListCell *p2)
List * list_delete_first_n(List *list, int n)
List * list_truncate(List *list, int new_size)
bool list_member(const List *list, const void *datum)
List * list_concat_unique_int(List *list1, const List *list2)
List * list_copy_head(const List *oldlist, int len)
List * list_union_int(const List *list1, const List *list2)
List * list_concat_unique(List *list1, const List *list2)
List * list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3, ListCell datum4, ListCell datum5)
List * list_append_unique_ptr(List *list, void *datum)
void list_free_deep(List *list)
List * list_insert_nth(List *list, int pos, void *datum)
List * list_union(const List *list1, const List *list2)
void * MemoryContextAlloc(MemoryContext context, Size size)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
MemoryContext GetMemoryChunkContext(void *pointer)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define IsA(nodeptr, _type_)
static uint32 pg_nextpower2_32(uint32 num)
static int list_length(const List *l)
#define list_make1_oid(x1)
int(* list_sort_comparator)(const ListCell *a, const ListCell *b)
#define list_make1_int(x1)
#define qsort(a, b, c, d)
static int cmp(const chr *x, const chr *y, size_t len)
ListCell initial_elements[FLEXIBLE_ARRAY_MEMBER]