PostgreSQL Source Code  git master
pg_list.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_list.h
4  * interface for PostgreSQL generic list package
5  *
6  * Once upon a time, parts of Postgres were written in Lisp and used real
7  * cons-cell lists for major data structures. When that code was rewritten
8  * in C, we initially had a faithful emulation of cons-cell lists, which
9  * unsurprisingly was a performance bottleneck. A couple of major rewrites
10  * later, these data structures are actually simple expansible arrays;
11  * but the "List" name and a lot of the notation survives.
12  *
13  * One important concession to the original implementation is that an empty
14  * list is always represented by a null pointer (preferentially written NIL).
15  * Non-empty lists have a header, which will not be relocated as long as the
16  * list remains non-empty, and an expansible data array.
17  *
18  * We support three types of lists:
19  *
20  * T_List: lists of pointers
21  * (in practice usually pointers to Nodes, but not always;
22  * declared as "void *" to minimize casting annoyances)
23  * T_IntList: lists of integers
24  * T_OidList: lists of Oids
25  *
26  * (At the moment, ints and Oids are the same size, but they may not
27  * always be so; try to be careful to maintain the distinction.)
28  *
29  *
30  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
31  * Portions Copyright (c) 1994, Regents of the University of California
32  *
33  * src/include/nodes/pg_list.h
34  *
35  *-------------------------------------------------------------------------
36  */
37 #ifndef PG_LIST_H
38 #define PG_LIST_H
39 
40 #include "nodes/nodes.h"
41 
42 
43 typedef union ListCell
44 {
45  void *ptr_value;
46  int int_value;
50 
51 typedef struct List
52 {
53  NodeTag type; /* T_List, T_IntList, or T_OidList */
54  int length; /* number of elements currently present */
55  int max_length; /* allocated length of elements[] */
56  ListCell *elements; /* re-allocatable array of cells */
57  /* We may allocate some cells along with the List header: */
59  /* If elements == initial_elements, it's not a separate allocation */
60 } List;
61 
62 /*
63  * The *only* valid representation of an empty list is NIL; in other
64  * words, a non-NIL list is guaranteed to have length >= 1.
65  */
66 #define NIL ((List *) NULL)
67 
68 /*
69  * State structs for various looping macros below.
70  */
71 typedef struct ForEachState
72 {
73  const List *l; /* list we're looping through */
74  int i; /* current element index */
76 
77 typedef struct ForBothState
78 {
79  const List *l1; /* lists we're looping through */
80  const List *l2;
81  int i; /* common element index */
83 
84 typedef struct ForBothCellState
85 {
86  const List *l1; /* lists we're looping through */
87  const List *l2;
88  int i1; /* current element indexes */
89  int i2;
91 
92 typedef struct ForThreeState
93 {
94  const List *l1; /* lists we're looping through */
95  const List *l2;
96  const List *l3;
97  int i; /* common element index */
99 
100 typedef struct ForFourState
101 {
102  const List *l1; /* lists we're looping through */
103  const List *l2;
104  const List *l3;
105  const List *l4;
106  int i; /* common element index */
108 
109 typedef struct ForFiveState
110 {
111  const List *l1; /* lists we're looping through */
112  const List *l2;
113  const List *l3;
114  const List *l4;
115  const List *l5;
116  int i; /* common element index */
118 
119 /*
120  * These routines are small enough, and used often enough, to justify being
121  * inline.
122  */
123 
124 /* Fetch address of list's first cell; NULL if empty list */
125 static inline ListCell *
126 list_head(const List *l)
127 {
128  return l ? &l->elements[0] : NULL;
129 }
130 
131 /* Fetch address of list's last cell; NULL if empty list */
132 static inline ListCell *
133 list_tail(const List *l)
134 {
135  return l ? &l->elements[l->length - 1] : NULL;
136 }
137 
138 /* Fetch address of list's second cell, if it has one, else NULL */
139 static inline ListCell *
141 {
142  if (l && l->length >= 2)
143  return &l->elements[1];
144  else
145  return NULL;
146 }
147 
148 /* Fetch list's length */
149 static inline int
150 list_length(const List *l)
151 {
152  return l ? l->length : 0;
153 }
154 
155 /*
156  * Macros to access the data values within List cells.
157  *
158  * Note that with the exception of the "xxx_node" macros, these are
159  * lvalues and can be assigned to.
160  *
161  * NB: There is an unfortunate legacy from a previous incarnation of
162  * the List API: the macro lfirst() was used to mean "the data in this
163  * cons cell". To avoid changing every usage of lfirst(), that meaning
164  * has been kept. As a result, lfirst() takes a ListCell and returns
165  * the data it contains; to get the data in the first cell of a
166  * List, use linitial(). Worse, lsecond() is more closely related to
167  * linitial() than lfirst(): given a List, lsecond() returns the data
168  * in the second list cell.
169  */
170 #define lfirst(lc) ((lc)->ptr_value)
171 #define lfirst_int(lc) ((lc)->int_value)
172 #define lfirst_oid(lc) ((lc)->oid_value)
173 #define lfirst_xid(lc) ((lc)->xid_value)
174 #define lfirst_node(type,lc) castNode(type, lfirst(lc))
175 
176 #define linitial(l) lfirst(list_nth_cell(l, 0))
177 #define linitial_int(l) lfirst_int(list_nth_cell(l, 0))
178 #define linitial_oid(l) lfirst_oid(list_nth_cell(l, 0))
179 #define linitial_node(type,l) castNode(type, linitial(l))
180 
181 #define lsecond(l) lfirst(list_nth_cell(l, 1))
182 #define lsecond_int(l) lfirst_int(list_nth_cell(l, 1))
183 #define lsecond_oid(l) lfirst_oid(list_nth_cell(l, 1))
184 #define lsecond_node(type,l) castNode(type, lsecond(l))
185 
186 #define lthird(l) lfirst(list_nth_cell(l, 2))
187 #define lthird_int(l) lfirst_int(list_nth_cell(l, 2))
188 #define lthird_oid(l) lfirst_oid(list_nth_cell(l, 2))
189 #define lthird_node(type,l) castNode(type, lthird(l))
190 
191 #define lfourth(l) lfirst(list_nth_cell(l, 3))
192 #define lfourth_int(l) lfirst_int(list_nth_cell(l, 3))
193 #define lfourth_oid(l) lfirst_oid(list_nth_cell(l, 3))
194 #define lfourth_node(type,l) castNode(type, lfourth(l))
195 
196 #define llast(l) lfirst(list_last_cell(l))
197 #define llast_int(l) lfirst_int(list_last_cell(l))
198 #define llast_oid(l) lfirst_oid(list_last_cell(l))
199 #define llast_xid(l) lfirst_xid(list_last_cell(l))
200 #define llast_node(type,l) castNode(type, llast(l))
201 
202 /*
203  * Convenience macros for building fixed-length lists
204  */
205 #define list_make_ptr_cell(v) ((ListCell) {.ptr_value = (v)})
206 #define list_make_int_cell(v) ((ListCell) {.int_value = (v)})
207 #define list_make_oid_cell(v) ((ListCell) {.oid_value = (v)})
208 #define list_make_xid_cell(v) ((ListCell) {.xid_value = (v)})
209 
210 #define list_make1(x1) \
211  list_make1_impl(T_List, list_make_ptr_cell(x1))
212 #define list_make2(x1,x2) \
213  list_make2_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2))
214 #define list_make3(x1,x2,x3) \
215  list_make3_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
216  list_make_ptr_cell(x3))
217 #define list_make4(x1,x2,x3,x4) \
218  list_make4_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
219  list_make_ptr_cell(x3), list_make_ptr_cell(x4))
220 #define list_make5(x1,x2,x3,x4,x5) \
221  list_make5_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
222  list_make_ptr_cell(x3), list_make_ptr_cell(x4), \
223  list_make_ptr_cell(x5))
224 
225 #define list_make1_int(x1) \
226  list_make1_impl(T_IntList, list_make_int_cell(x1))
227 #define list_make2_int(x1,x2) \
228  list_make2_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2))
229 #define list_make3_int(x1,x2,x3) \
230  list_make3_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
231  list_make_int_cell(x3))
232 #define list_make4_int(x1,x2,x3,x4) \
233  list_make4_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
234  list_make_int_cell(x3), list_make_int_cell(x4))
235 #define list_make5_int(x1,x2,x3,x4,x5) \
236  list_make5_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
237  list_make_int_cell(x3), list_make_int_cell(x4), \
238  list_make_int_cell(x5))
239 
240 #define list_make1_oid(x1) \
241  list_make1_impl(T_OidList, list_make_oid_cell(x1))
242 #define list_make2_oid(x1,x2) \
243  list_make2_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2))
244 #define list_make3_oid(x1,x2,x3) \
245  list_make3_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
246  list_make_oid_cell(x3))
247 #define list_make4_oid(x1,x2,x3,x4) \
248  list_make4_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
249  list_make_oid_cell(x3), list_make_oid_cell(x4))
250 #define list_make5_oid(x1,x2,x3,x4,x5) \
251  list_make5_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
252  list_make_oid_cell(x3), list_make_oid_cell(x4), \
253  list_make_oid_cell(x5))
254 
255 #define list_make1_xid(x1) \
256  list_make1_impl(T_XidList, list_make_xid_cell(x1))
257 #define list_make2_xid(x1,x2) \
258  list_make2_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2))
259 #define list_make3_xid(x1,x2,x3) \
260  list_make3_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
261  list_make_xid_cell(x3))
262 #define list_make4_xid(x1,x2,x3,x4) \
263  list_make4_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
264  list_make_xid_cell(x3), list_make_xid_cell(x4))
265 #define list_make5_xid(x1,x2,x3,x4,x5) \
266  list_make5_impl(T_XidList, list_make_xid_cell(x1), list_make_xid_cell(x2), \
267  list_make_xid_cell(x3), list_make_xid_cell(x4), \
268  list_make_xid_cell(x5))
269 
270 /*
271  * Locate the n'th cell (counting from 0) of the list.
272  * It is an assertion failure if there is no such cell.
273  */
274 static inline ListCell *
275 list_nth_cell(const List *list, int n)
276 {
277  Assert(list != NIL);
278  Assert(n >= 0 && n < list->length);
279  return &list->elements[n];
280 }
281 
282 /*
283  * Return the last cell in a non-NIL List.
284  */
285 static inline ListCell *
287 {
288  Assert(list != NIL);
289  return &list->elements[list->length - 1];
290 }
291 
292 /*
293  * Return the pointer value contained in the n'th element of the
294  * specified list. (List elements begin at 0.)
295  */
296 static inline void *
297 list_nth(const List *list, int n)
298 {
299  Assert(IsA(list, List));
300  return lfirst(list_nth_cell(list, n));
301 }
302 
303 /*
304  * Return the integer value contained in the n'th element of the
305  * specified list.
306  */
307 static inline int
308 list_nth_int(const List *list, int n)
309 {
310  Assert(IsA(list, IntList));
311  return lfirst_int(list_nth_cell(list, n));
312 }
313 
314 /*
315  * Return the OID value contained in the n'th element of the specified
316  * list.
317  */
318 static inline Oid
319 list_nth_oid(const List *list, int n)
320 {
321  Assert(IsA(list, OidList));
322  return lfirst_oid(list_nth_cell(list, n));
323 }
324 
325 #define list_nth_node(type,list,n) castNode(type, list_nth(list, n))
326 
327 /*
328  * Get the given ListCell's index (from 0) in the given List.
329  */
330 static inline int
331 list_cell_number(const List *l, const ListCell *c)
332 {
333  Assert(c >= &l->elements[0] && c < &l->elements[l->length]);
334  return c - l->elements;
335 }
336 
337 /*
338  * Get the address of the next cell after "c" within list "l", or NULL if none.
339  */
340 static inline ListCell *
341 lnext(const List *l, const ListCell *c)
342 {
343  Assert(c >= &l->elements[0] && c < &l->elements[l->length]);
344  c++;
345  if (c < &l->elements[l->length])
346  return (ListCell *) c;
347  else
348  return NULL;
349 }
350 
351 /*
352  * foreach -
353  * a convenience macro for looping through a list
354  *
355  * "cell" must be the name of a "ListCell *" variable; it's made to point
356  * to each List element in turn. "cell" will be NULL after normal exit from
357  * the loop, but an early "break" will leave it pointing at the current
358  * List element.
359  *
360  * Beware of changing the List object while the loop is iterating.
361  * The current semantics are that we examine successive list indices in
362  * each iteration, so that insertion or deletion of list elements could
363  * cause elements to be re-visited or skipped unexpectedly. Previous
364  * implementations of foreach() behaved differently. However, it's safe
365  * to append elements to the List (or in general, insert them after the
366  * current element); such new elements are guaranteed to be visited.
367  * Also, the current element of the List can be deleted, if you use
368  * foreach_delete_current() to do so. BUT: either of these actions will
369  * invalidate the "cell" pointer for the remainder of the current iteration.
370  */
371 #define foreach(cell, lst) \
372  for (ForEachState cell##__state = {(lst), 0}; \
373  (cell##__state.l != NIL && \
374  cell##__state.i < cell##__state.l->length) ? \
375  (cell = &cell##__state.l->elements[cell##__state.i], true) : \
376  (cell = NULL, false); \
377  cell##__state.i++)
378 
379 /*
380  * foreach_delete_current -
381  * delete the current list element from the List associated with a
382  * surrounding foreach() loop, returning the new List pointer.
383  *
384  * This is equivalent to list_delete_cell(), but it also adjusts the foreach
385  * loop's state so that no list elements will be missed. Do not delete
386  * elements from an active foreach loop's list in any other way!
387  */
388 #define foreach_delete_current(lst, cell) \
389  (cell##__state.i--, \
390  (List *) (cell##__state.l = list_delete_cell(lst, cell)))
391 
392 /*
393  * foreach_current_index -
394  * get the zero-based list index of a surrounding foreach() loop's
395  * current element; pass the name of the "ListCell *" iterator variable.
396  *
397  * Beware of using this after foreach_delete_current(); the value will be
398  * out of sync for the rest of the current loop iteration. Anyway, since
399  * you just deleted the current element, the value is pretty meaningless.
400  */
401 #define foreach_current_index(cell) (cell##__state.i)
402 
403 /*
404  * for_each_from -
405  * Like foreach(), but start from the N'th (zero-based) list element,
406  * not necessarily the first one.
407  *
408  * It's okay for N to exceed the list length, but not for it to be negative.
409  *
410  * The caveats for foreach() apply equally here.
411  */
412 #define for_each_from(cell, lst, N) \
413  for (ForEachState cell##__state = for_each_from_setup(lst, N); \
414  (cell##__state.l != NIL && \
415  cell##__state.i < cell##__state.l->length) ? \
416  (cell = &cell##__state.l->elements[cell##__state.i], true) : \
417  (cell = NULL, false); \
418  cell##__state.i++)
419 
420 static inline ForEachState
421 for_each_from_setup(const List *lst, int N)
422 {
423  ForEachState r = {lst, N};
424 
425  Assert(N >= 0);
426  return r;
427 }
428 
429 /*
430  * for_each_cell -
431  * a convenience macro which loops through a list starting from a
432  * specified cell
433  *
434  * The caveats for foreach() apply equally here.
435  */
436 #define for_each_cell(cell, lst, initcell) \
437  for (ForEachState cell##__state = for_each_cell_setup(lst, initcell); \
438  (cell##__state.l != NIL && \
439  cell##__state.i < cell##__state.l->length) ? \
440  (cell = &cell##__state.l->elements[cell##__state.i], true) : \
441  (cell = NULL, false); \
442  cell##__state.i++)
443 
444 static inline ForEachState
445 for_each_cell_setup(const List *lst, const ListCell *initcell)
446 {
447  ForEachState r = {lst,
448  initcell ? list_cell_number(lst, initcell) : list_length(lst)};
449 
450  return r;
451 }
452 
453 /*
454  * forboth -
455  * a convenience macro for advancing through two linked lists
456  * simultaneously. This macro loops through both lists at the same
457  * time, stopping when either list runs out of elements. Depending
458  * on the requirements of the call site, it may also be wise to
459  * assert that the lengths of the two lists are equal. (But, if they
460  * are not, some callers rely on the ending cell values being separately
461  * NULL or non-NULL as defined here; don't try to optimize that.)
462  *
463  * The caveats for foreach() apply equally here.
464  */
465 #define forboth(cell1, list1, cell2, list2) \
466  for (ForBothState cell1##__state = {(list1), (list2), 0}; \
467  multi_for_advance_cell(cell1, cell1##__state, l1, i), \
468  multi_for_advance_cell(cell2, cell1##__state, l2, i), \
469  (cell1 != NULL && cell2 != NULL); \
470  cell1##__state.i++)
471 
472 #define multi_for_advance_cell(cell, state, l, i) \
473  (cell = (state.l != NIL && state.i < state.l->length) ? \
474  &state.l->elements[state.i] : NULL)
475 
476 /*
477  * for_both_cell -
478  * a convenience macro which loops through two lists starting from the
479  * specified cells of each. This macro loops through both lists at the same
480  * time, stopping when either list runs out of elements. Depending on the
481  * requirements of the call site, it may also be wise to assert that the
482  * lengths of the two lists are equal, and initcell1 and initcell2 are at
483  * the same position in the respective lists.
484  *
485  * The caveats for foreach() apply equally here.
486  */
487 #define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2) \
488  for (ForBothCellState cell1##__state = \
489  for_both_cell_setup(list1, initcell1, list2, initcell2); \
490  multi_for_advance_cell(cell1, cell1##__state, l1, i1), \
491  multi_for_advance_cell(cell2, cell1##__state, l2, i2), \
492  (cell1 != NULL && cell2 != NULL); \
493  cell1##__state.i1++, cell1##__state.i2++)
494 
495 static inline ForBothCellState
496 for_both_cell_setup(const List *list1, const ListCell *initcell1,
497  const List *list2, const ListCell *initcell2)
498 {
499  ForBothCellState r = {list1, list2,
500  initcell1 ? list_cell_number(list1, initcell1) : list_length(list1),
501  initcell2 ? list_cell_number(list2, initcell2) : list_length(list2)};
502 
503  return r;
504 }
505 
506 /*
507  * forthree -
508  * the same for three lists
509  */
510 #define forthree(cell1, list1, cell2, list2, cell3, list3) \
511  for (ForThreeState cell1##__state = {(list1), (list2), (list3), 0}; \
512  multi_for_advance_cell(cell1, cell1##__state, l1, i), \
513  multi_for_advance_cell(cell2, cell1##__state, l2, i), \
514  multi_for_advance_cell(cell3, cell1##__state, l3, i), \
515  (cell1 != NULL && cell2 != NULL && cell3 != NULL); \
516  cell1##__state.i++)
517 
518 /*
519  * forfour -
520  * the same for four lists
521  */
522 #define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4) \
523  for (ForFourState cell1##__state = {(list1), (list2), (list3), (list4), 0}; \
524  multi_for_advance_cell(cell1, cell1##__state, l1, i), \
525  multi_for_advance_cell(cell2, cell1##__state, l2, i), \
526  multi_for_advance_cell(cell3, cell1##__state, l3, i), \
527  multi_for_advance_cell(cell4, cell1##__state, l4, i), \
528  (cell1 != NULL && cell2 != NULL && cell3 != NULL && cell4 != NULL); \
529  cell1##__state.i++)
530 
531 /*
532  * forfive -
533  * the same for five lists
534  */
535 #define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5) \
536  for (ForFiveState cell1##__state = {(list1), (list2), (list3), (list4), (list5), 0}; \
537  multi_for_advance_cell(cell1, cell1##__state, l1, i), \
538  multi_for_advance_cell(cell2, cell1##__state, l2, i), \
539  multi_for_advance_cell(cell3, cell1##__state, l3, i), \
540  multi_for_advance_cell(cell4, cell1##__state, l4, i), \
541  multi_for_advance_cell(cell5, cell1##__state, l5, i), \
542  (cell1 != NULL && cell2 != NULL && cell3 != NULL && \
543  cell4 != NULL && cell5 != NULL); \
544  cell1##__state.i++)
545 
546 /* Functions in src/backend/nodes/list.c */
547 
548 extern List *list_make1_impl(NodeTag t, ListCell datum1);
549 extern List *list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2);
550 extern List *list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2,
551  ListCell datum3);
552 extern List *list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2,
553  ListCell datum3, ListCell datum4);
554 extern List *list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2,
555  ListCell datum3, ListCell datum4,
556  ListCell datum5);
557 
558 extern pg_nodiscard List *lappend(List *list, void *datum);
559 extern pg_nodiscard List *lappend_int(List *list, int datum);
560 extern pg_nodiscard List *lappend_oid(List *list, Oid datum);
562 
563 extern pg_nodiscard List *list_insert_nth(List *list, int pos, void *datum);
564 extern pg_nodiscard List *list_insert_nth_int(List *list, int pos, int datum);
565 extern pg_nodiscard List *list_insert_nth_oid(List *list, int pos, Oid datum);
566 
567 extern pg_nodiscard List *lcons(void *datum, List *list);
568 extern pg_nodiscard List *lcons_int(int datum, List *list);
569 extern pg_nodiscard List *lcons_oid(Oid datum, List *list);
570 
571 extern pg_nodiscard List *list_concat(List *list1, const List *list2);
572 extern pg_nodiscard List *list_concat_copy(const List *list1, const List *list2);
573 
574 extern pg_nodiscard List *list_truncate(List *list, int new_size);
575 
576 extern bool list_member(const List *list, const void *datum);
577 extern bool list_member_ptr(const List *list, const void *datum);
578 extern bool list_member_int(const List *list, int datum);
579 extern bool list_member_oid(const List *list, Oid datum);
580 extern bool list_member_xid(const List *list, TransactionId datum);
581 
582 extern pg_nodiscard List *list_delete(List *list, void *datum);
583 extern pg_nodiscard List *list_delete_ptr(List *list, void *datum);
584 extern pg_nodiscard List *list_delete_int(List *list, int datum);
585 extern pg_nodiscard List *list_delete_oid(List *list, Oid datum);
591 
592 extern List *list_union(const List *list1, const List *list2);
593 extern List *list_union_ptr(const List *list1, const List *list2);
594 extern List *list_union_int(const List *list1, const List *list2);
595 extern List *list_union_oid(const List *list1, const List *list2);
596 
597 extern List *list_intersection(const List *list1, const List *list2);
598 extern List *list_intersection_int(const List *list1, const List *list2);
599 
600 /* currently, there's no need for list_intersection_ptr etc */
601 
602 extern List *list_difference(const List *list1, const List *list2);
603 extern List *list_difference_ptr(const List *list1, const List *list2);
604 extern List *list_difference_int(const List *list1, const List *list2);
605 extern List *list_difference_oid(const List *list1, const List *list2);
606 
607 extern pg_nodiscard List *list_append_unique(List *list, void *datum);
608 extern pg_nodiscard List *list_append_unique_ptr(List *list, void *datum);
609 extern pg_nodiscard List *list_append_unique_int(List *list, int datum);
611 
612 extern pg_nodiscard List *list_concat_unique(List *list1, const List *list2);
613 extern pg_nodiscard List *list_concat_unique_ptr(List *list1, const List *list2);
614 extern pg_nodiscard List *list_concat_unique_int(List *list1, const List *list2);
615 extern pg_nodiscard List *list_concat_unique_oid(List *list1, const List *list2);
616 
617 extern void list_deduplicate_oid(List *list);
618 
619 extern void list_free(List *list);
620 extern void list_free_deep(List *list);
621 
622 extern pg_nodiscard List *list_copy(const List *oldlist);
623 extern pg_nodiscard List *list_copy_head(const List *oldlist, int len);
624 extern pg_nodiscard List *list_copy_tail(const List *oldlist, int nskip);
625 extern pg_nodiscard List *list_copy_deep(const List *oldlist);
626 
627 typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b);
629 
630 extern int list_int_cmp(const ListCell *p1, const ListCell *p2);
631 extern int list_oid_cmp(const ListCell *p1, const ListCell *p2);
632 
633 #endif /* PG_LIST_H */
#define pg_nodiscard
Definition: c.h:132
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:362
uint32 TransactionId
Definition: c.h:588
int b
Definition: isn.c:70
int a
Definition: isn.c:69
Assert(fmt[strlen(fmt) - 1] !='\n')
#define IsA(nodeptr, _type_)
Definition: nodes.h:168
NodeTag
Definition: nodes.h:27
const void size_t len
#define lfirst(lc)
Definition: pg_list.h:170
List * list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3, ListCell datum4, ListCell datum5)
Definition: list.c:283
pg_nodiscard List * list_copy_head(const List *oldlist, int len)
Definition: list.c:1592
void list_sort(List *list, list_sort_comparator cmp)
Definition: list.c:1673
static int list_length(const List *l)
Definition: pg_list.h:150
pg_nodiscard List * list_copy_deep(const List *oldlist)
Definition: list.c:1638
pg_nodiscard List * lcons_int(int datum, List *list)
Definition: list.c:512
pg_nodiscard List * list_delete_first_n(List *list, int n)
Definition: list.c:982
#define NIL
Definition: pg_list.h:66
struct ForFiveState ForFiveState
static ForEachState for_each_cell_setup(const List *lst, const ListCell *initcell)
Definition: pg_list.h:445
static Oid list_nth_oid(const List *list, int n)
Definition: pg_list.h:319
#define lfirst_int(lc)
Definition: pg_list.h:171
List * list_difference_ptr(const List *list1, const List *list2)
Definition: list.c:1262
List * list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2)
Definition: list.c:245
List * list_union(const List *list1, const List *list2)
Definition: list.c:1065
pg_nodiscard List * lappend_xid(List *list, TransactionId datum)
Definition: list.c:392
pg_nodiscard List * list_delete_oid(List *list, Oid datum)
Definition: list.c:909
pg_nodiscard List * list_concat_unique_oid(List *list1, const List *list2)
Definition: list.c:1468
struct ForThreeState ForThreeState
pg_nodiscard List * lappend_int(List *list, int datum)
Definition: list.c:356
pg_nodiscard List * list_delete_ptr(List *list, void *datum)
Definition: list.c:871
struct List List
static ListCell * list_head(const List *l)
Definition: pg_list.h:126
List * list_make1_impl(NodeTag t, ListCell datum1)
Definition: list.c:235
pg_nodiscard List * list_concat_unique_int(List *list1, const List *list2)
Definition: list.c:1447
union ListCell ListCell
static ListCell * list_nth_cell(const List *list, int n)
Definition: pg_list.h:275
List * list_difference_oid(const List *list1, const List *list2)
Definition: list.c:1312
pg_nodiscard List * list_append_unique_oid(List *list, Oid datum)
Definition: list.c:1379
pg_nodiscard List * list_concat_copy(const List *list1, const List *list2)
Definition: list.c:597
static ListCell * list_last_cell(const List *list)
Definition: pg_list.h:286
bool list_member_xid(const List *list, TransactionId datum)
Definition: list.c:741
pg_nodiscard List * list_truncate(List *list, int new_size)
Definition: list.c:630
pg_nodiscard List * list_concat_unique(List *list1, const List *list2)
Definition: list.c:1404
pg_nodiscard List * list_delete_int(List *list, int datum)
Definition: list.c:890
pg_nodiscard List * lcons(void *datum, List *list)
Definition: list.c:494
pg_nodiscard List * list_delete_last(List *list)
Definition: list.c:956
List * list_intersection_int(const List *list1, const List *list2)
Definition: list.c:1199
pg_nodiscard List * list_copy_tail(const List *oldlist, int nskip)
Definition: list.c:1612
List * list_difference_int(const List *list1, const List *list2)
Definition: list.c:1287
pg_nodiscard List * list_append_unique_int(List *list, int datum)
Definition: list.c:1367
pg_nodiscard List * list_copy(const List *oldlist)
Definition: list.c:1572
pg_nodiscard List * list_concat_unique_ptr(List *list1, const List *list2)
Definition: list.c:1426
static ListCell * list_tail(const List *l)
Definition: pg_list.h:133
List * list_intersection(const List *list1, const List *list2)
Definition: list.c:1173
pg_nodiscard List * list_insert_nth_oid(List *list, int pos, Oid datum)
Definition: list.c:466
pg_nodiscard List * lcons_oid(Oid datum, List *list)
Definition: list.c:530
int(* list_sort_comparator)(const ListCell *a, const ListCell *b)
Definition: pg_list.h:627
static void * list_nth(const List *list, int n)
Definition: pg_list.h:297
void list_deduplicate_oid(List *list)
Definition: list.c:1494
int list_oid_cmp(const ListCell *p1, const ListCell *p2)
Definition: list.c:1706
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:341
pg_nodiscard List * list_delete_first(List *list)
Definition: list.c:942
static ForEachState for_each_from_setup(const List *lst, int N)
Definition: pg_list.h:421
static ForBothCellState for_both_cell_setup(const List *list1, const ListCell *initcell1, const List *list2, const ListCell *initcell2)
Definition: pg_list.h:496
struct ForBothState ForBothState
List * list_union_oid(const List *list1, const List *list2)
Definition: list.c:1135
struct ForEachState ForEachState
bool list_member_ptr(const List *list, const void *datum)
Definition: list.c:681
void list_free(List *list)
Definition: list.c:1545
bool list_member_int(const List *list, int datum)
Definition: list.c:701
pg_nodiscard List * lappend(List *list, void *datum)
Definition: list.c:338
pg_nodiscard List * list_concat(List *list1, const List *list2)
Definition: list.c:560
pg_nodiscard List * list_insert_nth_int(List *list, int pos, int datum)
Definition: list.c:452
pg_nodiscard List * list_delete_nth_cell(List *list, int n)
Definition: list.c:766
bool list_member_oid(const List *list, Oid datum)
Definition: list.c:721
List * list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3)
Definition: list.c:256
List * list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, ListCell datum3, ListCell datum4)
Definition: list.c:269
#define lfirst_oid(lc)
Definition: pg_list.h:172
int list_int_cmp(const ListCell *p1, const ListCell *p2)
Definition: list.c:1690
static ListCell * list_second_cell(const List *l)
Definition: pg_list.h:140
bool list_member(const List *list, const void *datum)
Definition: list.c:660
struct ForFourState ForFourState
List * list_union_ptr(const List *list1, const List *list2)
Definition: list.c:1089
pg_nodiscard List * list_insert_nth(List *list, int pos, void *datum)
Definition: list.c:438
pg_nodiscard List * list_delete_cell(List *list, ListCell *cell)
Definition: list.c:840
List * list_difference(const List *list1, const List *list2)
Definition: list.c:1236
pg_nodiscard List * list_append_unique(List *list, void *datum)
Definition: list.c:1342
static int list_nth_int(const List *list, int n)
Definition: pg_list.h:308
pg_nodiscard List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
pg_nodiscard List * list_append_unique_ptr(List *list, void *datum)
Definition: list.c:1355
void list_free_deep(List *list)
Definition: list.c:1559
static int list_cell_number(const List *l, const ListCell *c)
Definition: pg_list.h:331
struct ForBothCellState ForBothCellState
List * list_union_int(const List *list1, const List *list2)
Definition: list.c:1112
pg_nodiscard List * list_delete(List *list, void *datum)
Definition: list.c:852
unsigned int Oid
Definition: postgres_ext.h:31
char * c
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747
const List * l1
Definition: pg_list.h:86
const List * l2
Definition: pg_list.h:87
const List * l1
Definition: pg_list.h:79
const List * l2
Definition: pg_list.h:80
const List * l
Definition: pg_list.h:73
const List * l5
Definition: pg_list.h:115
const List * l3
Definition: pg_list.h:113
const List * l4
Definition: pg_list.h:114
const List * l2
Definition: pg_list.h:112
const List * l1
Definition: pg_list.h:111
const List * l1
Definition: pg_list.h:102
const List * l4
Definition: pg_list.h:105
const List * l2
Definition: pg_list.h:103
const List * l3
Definition: pg_list.h:104
const List * l2
Definition: pg_list.h:95
const List * l3
Definition: pg_list.h:96
const List * l1
Definition: pg_list.h:94
Definition: pg_list.h:52
int max_length
Definition: pg_list.h:55
int length
Definition: pg_list.h:54
ListCell * elements
Definition: pg_list.h:56
NodeTag type
Definition: pg_list.h:53
ListCell initial_elements[FLEXIBLE_ARRAY_MEMBER]
Definition: pg_list.h:58
int int_value
Definition: pg_list.h:46
Oid oid_value
Definition: pg_list.h:47
void * ptr_value
Definition: pg_list.h:45
TransactionId xid_value
Definition: pg_list.h:48