LCOV - code coverage report
Current view: top level - src/include/nodes - pg_list.h (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 37 42 88.1 %
Date: 2019-11-21 14:06:36 Functions: 13 14 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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-2019, 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;
      47             :     Oid         oid_value;
      48             : } ListCell;
      49             : 
      50             : typedef struct List
      51             : {
      52             :     NodeTag     type;           /* T_List, T_IntList, or T_OidList */
      53             :     int         length;         /* number of elements currently present */
      54             :     int         max_length;     /* allocated length of elements[] */
      55             :     ListCell   *elements;       /* re-allocatable array of cells */
      56             :     /* We may allocate some cells along with the List header: */
      57             :     ListCell    initial_elements[FLEXIBLE_ARRAY_MEMBER];
      58             :     /* If elements == initial_elements, it's not a separate allocation */
      59             : } List;
      60             : 
      61             : /*
      62             :  * The *only* valid representation of an empty list is NIL; in other
      63             :  * words, a non-NIL list is guaranteed to have length >= 1.
      64             :  */
      65             : #define NIL                     ((List *) NULL)
      66             : 
      67             : /*
      68             :  * State structs for various looping macros below.
      69             :  */
      70             : typedef struct ForEachState
      71             : {
      72             :     const List *l;              /* list we're looping through */
      73             :     int         i;              /* current element index */
      74             : } ForEachState;
      75             : 
      76             : typedef struct ForBothState
      77             : {
      78             :     const List *l1;             /* lists we're looping through */
      79             :     const List *l2;
      80             :     int         i;              /* common element index */
      81             : } ForBothState;
      82             : 
      83             : typedef struct ForBothCellState
      84             : {
      85             :     const List *l1;             /* lists we're looping through */
      86             :     const List *l2;
      87             :     int         i1;             /* current element indexes */
      88             :     int         i2;
      89             : } ForBothCellState;
      90             : 
      91             : typedef struct ForThreeState
      92             : {
      93             :     const List *l1;             /* lists we're looping through */
      94             :     const List *l2;
      95             :     const List *l3;
      96             :     int         i;              /* common element index */
      97             : } ForThreeState;
      98             : 
      99             : typedef struct ForFourState
     100             : {
     101             :     const List *l1;             /* lists we're looping through */
     102             :     const List *l2;
     103             :     const List *l3;
     104             :     const List *l4;
     105             :     int         i;              /* common element index */
     106             : } ForFourState;
     107             : 
     108             : typedef struct ForFiveState
     109             : {
     110             :     const List *l1;             /* lists we're looping through */
     111             :     const List *l2;
     112             :     const List *l3;
     113             :     const List *l4;
     114             :     const List *l5;
     115             :     int         i;              /* common element index */
     116             : } ForFiveState;
     117             : 
     118             : /*
     119             :  * These routines are small enough, and used often enough, to justify being
     120             :  * inline.
     121             :  */
     122             : 
     123             : /* Fetch address of list's first cell; NULL if empty list */
     124             : static inline ListCell *
     125    52412962 : list_head(const List *l)
     126             : {
     127    52412962 :     return l ? &l->elements[0] : NULL;
     128             : }
     129             : 
     130             : /* Fetch address of list's last cell; NULL if empty list */
     131             : static inline ListCell *
     132   103586056 : list_tail(const List *l)
     133             : {
     134   103586056 :     return l ? &l->elements[l->length - 1] : NULL;
     135             : }
     136             : 
     137             : /* Fetch address of list's second cell, if it has one, else NULL */
     138             : static inline ListCell *
     139     4797992 : list_second_cell(const List *l)
     140             : {
     141     4797992 :     if (l && l->length >= 2)
     142     4789764 :         return &l->elements[1];
     143             :     else
     144        8228 :         return NULL;
     145             : }
     146             : 
     147             : /* Fetch address of list's third cell, if it has one, else NULL */
     148             : static inline ListCell *
     149         370 : list_third_cell(const List *l)
     150             : {
     151         370 :     if (l && l->length >= 3)
     152         370 :         return &l->elements[2];
     153             :     else
     154           0 :         return NULL;
     155             : }
     156             : 
     157             : /* Fetch address of list's fourth cell, if it has one, else NULL */
     158             : static inline ListCell *
     159           0 : list_fourth_cell(const List *l)
     160             : {
     161           0 :     if (l && l->length >= 4)
     162           0 :         return &l->elements[3];
     163             :     else
     164           0 :         return NULL;
     165             : }
     166             : 
     167             : /* Fetch list's length */
     168             : static inline int
     169    49674180 : list_length(const List *l)
     170             : {
     171    49674180 :     return l ? l->length : 0;
     172             : }
     173             : 
     174             : /*
     175             :  * Macros to access the data values within List cells.
     176             :  *
     177             :  * Note that with the exception of the "xxx_node" macros, these are
     178             :  * lvalues and can be assigned to.
     179             :  *
     180             :  * NB: There is an unfortunate legacy from a previous incarnation of
     181             :  * the List API: the macro lfirst() was used to mean "the data in this
     182             :  * cons cell". To avoid changing every usage of lfirst(), that meaning
     183             :  * has been kept. As a result, lfirst() takes a ListCell and returns
     184             :  * the data it contains; to get the data in the first cell of a
     185             :  * List, use linitial(). Worse, lsecond() is more closely related to
     186             :  * linitial() than lfirst(): given a List, lsecond() returns the data
     187             :  * in the second list cell.
     188             :  */
     189             : 
     190             : #define lfirst(lc)              ((lc)->ptr_value)
     191             : #define lfirst_int(lc)          ((lc)->int_value)
     192             : #define lfirst_oid(lc)          ((lc)->oid_value)
     193             : #define lfirst_node(type,lc)    castNode(type, lfirst(lc))
     194             : 
     195             : #define linitial(l)             lfirst(list_head(l))
     196             : #define linitial_int(l)         lfirst_int(list_head(l))
     197             : #define linitial_oid(l)         lfirst_oid(list_head(l))
     198             : #define linitial_node(type,l)   castNode(type, linitial(l))
     199             : 
     200             : #define lsecond(l)              lfirst(list_second_cell(l))
     201             : #define lsecond_int(l)          lfirst_int(list_second_cell(l))
     202             : #define lsecond_oid(l)          lfirst_oid(list_second_cell(l))
     203             : #define lsecond_node(type,l)    castNode(type, lsecond(l))
     204             : 
     205             : #define lthird(l)               lfirst(list_third_cell(l))
     206             : #define lthird_int(l)           lfirst_int(list_third_cell(l))
     207             : #define lthird_oid(l)           lfirst_oid(list_third_cell(l))
     208             : #define lthird_node(type,l)     castNode(type, lthird(l))
     209             : 
     210             : #define lfourth(l)              lfirst(list_fourth_cell(l))
     211             : #define lfourth_int(l)          lfirst_int(list_fourth_cell(l))
     212             : #define lfourth_oid(l)          lfirst_oid(list_fourth_cell(l))
     213             : #define lfourth_node(type,l)    castNode(type, lfourth(l))
     214             : 
     215             : #define llast(l)                lfirst(list_tail(l))
     216             : #define llast_int(l)            lfirst_int(list_tail(l))
     217             : #define llast_oid(l)            lfirst_oid(list_tail(l))
     218             : #define llast_node(type,l)      castNode(type, llast(l))
     219             : 
     220             : /*
     221             :  * Convenience macros for building fixed-length lists
     222             :  */
     223             : #define list_make_ptr_cell(v)   ((ListCell) {.ptr_value = (v)})
     224             : #define list_make_int_cell(v)   ((ListCell) {.int_value = (v)})
     225             : #define list_make_oid_cell(v)   ((ListCell) {.oid_value = (v)})
     226             : 
     227             : #define list_make1(x1) \
     228             :     list_make1_impl(T_List, list_make_ptr_cell(x1))
     229             : #define list_make2(x1,x2) \
     230             :     list_make2_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2))
     231             : #define list_make3(x1,x2,x3) \
     232             :     list_make3_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
     233             :                     list_make_ptr_cell(x3))
     234             : #define list_make4(x1,x2,x3,x4) \
     235             :     list_make4_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \
     236             :                     list_make_ptr_cell(x3), list_make_ptr_cell(x4))
     237             : 
     238             : #define list_make1_int(x1) \
     239             :     list_make1_impl(T_IntList, list_make_int_cell(x1))
     240             : #define list_make2_int(x1,x2) \
     241             :     list_make2_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2))
     242             : #define list_make3_int(x1,x2,x3) \
     243             :     list_make3_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
     244             :                     list_make_int_cell(x3))
     245             : #define list_make4_int(x1,x2,x3,x4) \
     246             :     list_make4_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \
     247             :                     list_make_int_cell(x3), list_make_int_cell(x4))
     248             : 
     249             : #define list_make1_oid(x1) \
     250             :     list_make1_impl(T_OidList, list_make_oid_cell(x1))
     251             : #define list_make2_oid(x1,x2) \
     252             :     list_make2_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2))
     253             : #define list_make3_oid(x1,x2,x3) \
     254             :     list_make3_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
     255             :                     list_make_oid_cell(x3))
     256             : #define list_make4_oid(x1,x2,x3,x4) \
     257             :     list_make4_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \
     258             :                     list_make_oid_cell(x3), list_make_oid_cell(x4))
     259             : 
     260             : /*
     261             :  * Locate the n'th cell (counting from 0) of the list.
     262             :  * It is an assertion failure if there is no such cell.
     263             :  */
     264             : static inline ListCell *
     265    16732914 : list_nth_cell(const List *list, int n)
     266             : {
     267             :     Assert(list != NIL);
     268             :     Assert(n >= 0 && n < list->length);
     269    16732914 :     return &list->elements[n];
     270             : }
     271             : 
     272             : /*
     273             :  * Return the pointer value contained in the n'th element of the
     274             :  * specified list. (List elements begin at 0.)
     275             :  */
     276             : static inline void *
     277    16548946 : list_nth(const List *list, int n)
     278             : {
     279             :     Assert(IsA(list, List));
     280    16548946 :     return lfirst(list_nth_cell(list, n));
     281             : }
     282             : 
     283             : /*
     284             :  * Return the integer value contained in the n'th element of the
     285             :  * specified list.
     286             :  */
     287             : static inline int
     288        5648 : list_nth_int(const List *list, int n)
     289             : {
     290             :     Assert(IsA(list, IntList));
     291        5648 :     return lfirst_int(list_nth_cell(list, n));
     292             : }
     293             : 
     294             : /*
     295             :  * Return the OID value contained in the n'th element of the specified
     296             :  * list.
     297             :  */
     298             : static inline Oid
     299       11378 : list_nth_oid(const List *list, int n)
     300             : {
     301             :     Assert(IsA(list, OidList));
     302       11378 :     return lfirst_oid(list_nth_cell(list, n));
     303             : }
     304             : 
     305             : #define list_nth_node(type,list,n)  castNode(type, list_nth(list, n))
     306             : 
     307             : /*
     308             :  * Get the given ListCell's index (from 0) in the given List.
     309             :  */
     310             : static inline int
     311      380866 : list_cell_number(const List *l, const ListCell *c)
     312             : {
     313             :     Assert(c >= &l->elements[0] && c < &l->elements[l->length]);
     314      380866 :     return c - l->elements;
     315             : }
     316             : 
     317             : /*
     318             :  * Get the address of the next cell after "c" within list "l", or NULL if none.
     319             :  */
     320             : static inline ListCell *
     321    39864328 : lnext(const List *l, const ListCell *c)
     322             : {
     323             :     Assert(c >= &l->elements[0] && c < &l->elements[l->length]);
     324    39864328 :     c++;
     325    39864328 :     if (c < &l->elements[l->length])
     326    30779232 :         return (ListCell *) c;
     327             :     else
     328     9085096 :         return NULL;
     329             : }
     330             : 
     331             : /*
     332             :  * foreach -
     333             :  *    a convenience macro for looping through a list
     334             :  *
     335             :  * "cell" must be the name of a "ListCell *" variable; it's made to point
     336             :  * to each List element in turn.  "cell" will be NULL after normal exit from
     337             :  * the loop, but an early "break" will leave it pointing at the current
     338             :  * List element.
     339             :  *
     340             :  * Beware of changing the List object while the loop is iterating.
     341             :  * The current semantics are that we examine successive list indices in
     342             :  * each iteration, so that insertion or deletion of list elements could
     343             :  * cause elements to be re-visited or skipped unexpectedly.  Previous
     344             :  * implementations of foreach() behaved differently.  However, it's safe
     345             :  * to append elements to the List (or in general, insert them after the
     346             :  * current element); such new elements are guaranteed to be visited.
     347             :  * Also, the current element of the List can be deleted, if you use
     348             :  * foreach_delete_current() to do so.  BUT: either of these actions will
     349             :  * invalidate the "cell" pointer for the remainder of the current iteration.
     350             :  */
     351             : #define foreach(cell, lst)  \
     352             :     for (ForEachState cell##__state = {(lst), 0}; \
     353             :          (cell##__state.l != NIL && \
     354             :           cell##__state.i < cell##__state.l->length) ? \
     355             :          (cell = &cell##__state.l->elements[cell##__state.i], true) : \
     356             :          (cell = NULL, false); \
     357             :          cell##__state.i++)
     358             : 
     359             : /*
     360             :  * foreach_delete_current -
     361             :  *    delete the current list element from the List associated with a
     362             :  *    surrounding foreach() loop, returning the new List pointer.
     363             :  *
     364             :  * This is equivalent to list_delete_cell(), but it also adjusts the foreach
     365             :  * loop's state so that no list elements will be missed.  Do not delete
     366             :  * elements from an active foreach loop's list in any other way!
     367             :  */
     368             : #define foreach_delete_current(lst, cell)   \
     369             :     (cell##__state.i--, \
     370             :      (List *) (cell##__state.l = list_delete_cell(lst, cell)))
     371             : 
     372             : /*
     373             :  * foreach_current_index -
     374             :  *    get the zero-based list index of a surrounding foreach() loop's
     375             :  *    current element; pass the name of the "ListCell *" iterator variable.
     376             :  *
     377             :  * Beware of using this after foreach_delete_current(); the value will be
     378             :  * out of sync for the rest of the current loop iteration.  Anyway, since
     379             :  * you just deleted the current element, the value is pretty meaningless.
     380             :  */
     381             : #define foreach_current_index(cell)  (cell##__state.i)
     382             : 
     383             : /*
     384             :  * for_each_cell -
     385             :  *    a convenience macro which loops through a list starting from a
     386             :  *    specified cell
     387             :  *
     388             :  * The caveats for foreach() apply equally here.
     389             :  */
     390             : #define for_each_cell(cell, lst, initcell)  \
     391             :     for (ForEachState cell##__state = for_each_cell_setup(lst, initcell); \
     392             :          (cell##__state.l != NIL && \
     393             :           cell##__state.i < cell##__state.l->length) ? \
     394             :          (cell = &cell##__state.l->elements[cell##__state.i], true) : \
     395             :          (cell = NULL, false); \
     396             :          cell##__state.i++)
     397             : 
     398             : static inline ForEachState
     399      433282 : for_each_cell_setup(List *lst, ListCell *initcell)
     400             : {
     401      866564 :     ForEachState r = {lst,
     402      433282 :     initcell ? list_cell_number(lst, initcell) : list_length(lst)};
     403             : 
     404      433282 :     return r;
     405             : }
     406             : 
     407             : /*
     408             :  * forboth -
     409             :  *    a convenience macro for advancing through two linked lists
     410             :  *    simultaneously. This macro loops through both lists at the same
     411             :  *    time, stopping when either list runs out of elements. Depending
     412             :  *    on the requirements of the call site, it may also be wise to
     413             :  *    assert that the lengths of the two lists are equal. (But, if they
     414             :  *    are not, some callers rely on the ending cell values being separately
     415             :  *    NULL or non-NULL as defined here; don't try to optimize that.)
     416             :  *
     417             :  * The caveats for foreach() apply equally here.
     418             :  */
     419             : #define forboth(cell1, list1, cell2, list2)                         \
     420             :     for (ForBothState cell1##__state = {(list1), (list2), 0}; \
     421             :          multi_for_advance_cell(cell1, cell1##__state, l1, i), \
     422             :          multi_for_advance_cell(cell2, cell1##__state, l2, i), \
     423             :          (cell1 != NULL && cell2 != NULL); \
     424             :          cell1##__state.i++)
     425             : 
     426             : #define multi_for_advance_cell(cell, state, l, i) \
     427             :     (cell = (state.l != NIL && state.i < state.l->length) ? \
     428             :      &state.l->elements[state.i] : NULL)
     429             : 
     430             : /*
     431             :  * for_both_cell -
     432             :  *    a convenience macro which loops through two lists starting from the
     433             :  *    specified cells of each. This macro loops through both lists at the same
     434             :  *    time, stopping when either list runs out of elements.  Depending on the
     435             :  *    requirements of the call site, it may also be wise to assert that the
     436             :  *    lengths of the two lists are equal, and initcell1 and initcell2 are at
     437             :  *    the same position in the respective lists.
     438             :  *
     439             :  * The caveats for foreach() apply equally here.
     440             :  */
     441             : #define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2) \
     442             :     for (ForBothCellState cell1##__state = \
     443             :              for_both_cell_setup(list1, initcell1, list2, initcell2); \
     444             :          multi_for_advance_cell(cell1, cell1##__state, l1, i1), \
     445             :          multi_for_advance_cell(cell2, cell1##__state, l2, i2), \
     446             :          (cell1 != NULL && cell2 != NULL); \
     447             :          cell1##__state.i1++, cell1##__state.i2++)
     448             : 
     449             : static inline ForBothCellState
     450        3104 : for_both_cell_setup(List *list1, ListCell *initcell1,
     451             :                     List *list2, ListCell *initcell2)
     452             : {
     453        9312 :     ForBothCellState r = {list1, list2,
     454        3104 :         initcell1 ? list_cell_number(list1, initcell1) : list_length(list1),
     455        3104 :     initcell2 ? list_cell_number(list2, initcell2) : list_length(list2)};
     456             : 
     457        3104 :     return r;
     458             : }
     459             : 
     460             : /*
     461             :  * forthree -
     462             :  *    the same for three lists
     463             :  */
     464             : #define forthree(cell1, list1, cell2, list2, cell3, list3) \
     465             :     for (ForThreeState cell1##__state = {(list1), (list2), (list3), 0}; \
     466             :          multi_for_advance_cell(cell1, cell1##__state, l1, i), \
     467             :          multi_for_advance_cell(cell2, cell1##__state, l2, i), \
     468             :          multi_for_advance_cell(cell3, cell1##__state, l3, i), \
     469             :          (cell1 != NULL && cell2 != NULL && cell3 != NULL); \
     470             :          cell1##__state.i++)
     471             : 
     472             : /*
     473             :  * forfour -
     474             :  *    the same for four lists
     475             :  */
     476             : #define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4) \
     477             :     for (ForFourState cell1##__state = {(list1), (list2), (list3), (list4), 0}; \
     478             :          multi_for_advance_cell(cell1, cell1##__state, l1, i), \
     479             :          multi_for_advance_cell(cell2, cell1##__state, l2, i), \
     480             :          multi_for_advance_cell(cell3, cell1##__state, l3, i), \
     481             :          multi_for_advance_cell(cell4, cell1##__state, l4, i), \
     482             :          (cell1 != NULL && cell2 != NULL && cell3 != NULL && cell4 != NULL); \
     483             :          cell1##__state.i++)
     484             : 
     485             : /*
     486             :  * forfive -
     487             :  *    the same for five lists
     488             :  */
     489             : #define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5) \
     490             :     for (ForFiveState cell1##__state = {(list1), (list2), (list3), (list4), (list5), 0}; \
     491             :          multi_for_advance_cell(cell1, cell1##__state, l1, i), \
     492             :          multi_for_advance_cell(cell2, cell1##__state, l2, i), \
     493             :          multi_for_advance_cell(cell3, cell1##__state, l3, i), \
     494             :          multi_for_advance_cell(cell4, cell1##__state, l4, i), \
     495             :          multi_for_advance_cell(cell5, cell1##__state, l5, i), \
     496             :          (cell1 != NULL && cell2 != NULL && cell3 != NULL && \
     497             :           cell4 != NULL && cell5 != NULL); \
     498             :          cell1##__state.i++)
     499             : 
     500             : /* Functions in src/backend/nodes/list.c */
     501             : 
     502             : extern List *list_make1_impl(NodeTag t, ListCell datum1);
     503             : extern List *list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2);
     504             : extern List *list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2,
     505             :                              ListCell datum3);
     506             : extern List *list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2,
     507             :                              ListCell datum3, ListCell datum4);
     508             : 
     509             : extern List *lappend(List *list, void *datum);
     510             : extern List *lappend_int(List *list, int datum);
     511             : extern List *lappend_oid(List *list, Oid datum);
     512             : 
     513             : extern List *list_insert_nth(List *list, int pos, void *datum);
     514             : extern List *list_insert_nth_int(List *list, int pos, int datum);
     515             : extern List *list_insert_nth_oid(List *list, int pos, Oid datum);
     516             : 
     517             : extern List *lcons(void *datum, List *list);
     518             : extern List *lcons_int(int datum, List *list);
     519             : extern List *lcons_oid(Oid datum, List *list);
     520             : 
     521             : extern List *list_concat(List *list1, const List *list2);
     522             : extern List *list_concat_copy(const List *list1, const List *list2);
     523             : 
     524             : extern List *list_truncate(List *list, int new_size);
     525             : 
     526             : extern bool list_member(const List *list, const void *datum);
     527             : extern bool list_member_ptr(const List *list, const void *datum);
     528             : extern bool list_member_int(const List *list, int datum);
     529             : extern bool list_member_oid(const List *list, Oid datum);
     530             : 
     531             : extern List *list_delete(List *list, void *datum);
     532             : extern List *list_delete_ptr(List *list, void *datum);
     533             : extern List *list_delete_int(List *list, int datum);
     534             : extern List *list_delete_oid(List *list, Oid datum);
     535             : extern List *list_delete_first(List *list);
     536             : extern List *list_delete_last(List *list);
     537             : extern List *list_delete_nth_cell(List *list, int n);
     538             : extern List *list_delete_cell(List *list, ListCell *cell);
     539             : 
     540             : extern List *list_union(const List *list1, const List *list2);
     541             : extern List *list_union_ptr(const List *list1, const List *list2);
     542             : extern List *list_union_int(const List *list1, const List *list2);
     543             : extern List *list_union_oid(const List *list1, const List *list2);
     544             : 
     545             : extern List *list_intersection(const List *list1, const List *list2);
     546             : extern List *list_intersection_int(const List *list1, const List *list2);
     547             : 
     548             : /* currently, there's no need for list_intersection_ptr etc */
     549             : 
     550             : extern List *list_difference(const List *list1, const List *list2);
     551             : extern List *list_difference_ptr(const List *list1, const List *list2);
     552             : extern List *list_difference_int(const List *list1, const List *list2);
     553             : extern List *list_difference_oid(const List *list1, const List *list2);
     554             : 
     555             : extern List *list_append_unique(List *list, void *datum);
     556             : extern List *list_append_unique_ptr(List *list, void *datum);
     557             : extern List *list_append_unique_int(List *list, int datum);
     558             : extern List *list_append_unique_oid(List *list, Oid datum);
     559             : 
     560             : extern List *list_concat_unique(List *list1, const List *list2);
     561             : extern List *list_concat_unique_ptr(List *list1, const List *list2);
     562             : extern List *list_concat_unique_int(List *list1, const List *list2);
     563             : extern List *list_concat_unique_oid(List *list1, const List *list2);
     564             : 
     565             : extern void list_deduplicate_oid(List *list);
     566             : 
     567             : extern void list_free(List *list);
     568             : extern void list_free_deep(List *list);
     569             : 
     570             : extern List *list_copy(const List *list);
     571             : extern List *list_copy_tail(const List *list, int nskip);
     572             : extern List *list_copy_deep(const List *oldlist);
     573             : 
     574             : typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b);
     575             : extern void list_sort(List *list, list_sort_comparator cmp);
     576             : 
     577             : extern int  list_oid_cmp(const ListCell *p1, const ListCell *p2);
     578             : 
     579             : #endif                          /* PG_LIST_H */

Generated by: LCOV version 1.13