LCOV - differential code coverage report
Current view: top level - src/backend/nodes - list.c (source / functions) Coverage Total Hit LBC UIC UBC GBC GIC GNC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.4 % 536 458 12 56 10 13 264 15 166 55 280
Current Date: 2023-04-08 15:15:32 Functions: 88.1 % 67 59 8 57 2 8 59
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * list.c
       4                 :  *    implementation for PostgreSQL generic list package
       5                 :  *
       6                 :  * See comments in pg_list.h.
       7                 :  *
       8                 :  *
       9                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
      10                 :  * Portions Copyright (c) 1994, Regents of the University of California
      11                 :  *
      12                 :  *
      13                 :  * IDENTIFICATION
      14                 :  *    src/backend/nodes/list.c
      15                 :  *
      16                 :  *-------------------------------------------------------------------------
      17                 :  */
      18                 : #include "postgres.h"
      19                 : 
      20                 : #include "nodes/pg_list.h"
      21                 : #include "port/pg_bitutils.h"
      22                 : #include "utils/memdebug.h"
      23                 : #include "utils/memutils.h"
      24                 : 
      25                 : 
      26                 : /*
      27                 :  * The previous List implementation, since it used a separate palloc chunk
      28                 :  * for each cons cell, had the property that adding or deleting list cells
      29                 :  * did not move the storage of other existing cells in the list.  Quite a
      30                 :  * bit of existing code depended on that, by retaining ListCell pointers
      31                 :  * across such operations on a list.  There is no such guarantee in this
      32                 :  * implementation, so instead we have debugging support that is meant to
      33                 :  * help flush out now-broken assumptions.  Defining DEBUG_LIST_MEMORY_USAGE
      34                 :  * while building this file causes the List operations to forcibly move
      35                 :  * all cells in a list whenever a cell is added or deleted.  In combination
      36                 :  * with MEMORY_CONTEXT_CHECKING and/or Valgrind, this can usually expose
      37                 :  * broken code.  It's a bit expensive though, as there's many more palloc
      38                 :  * cycles and a lot more data-copying than in a default build.
      39                 :  *
      40                 :  * By default, we enable this when building for Valgrind.
      41                 :  */
      42                 : #ifdef USE_VALGRIND
      43                 : #define DEBUG_LIST_MEMORY_USAGE
      44                 : #endif
      45                 : 
      46                 : /* Overhead for the fixed part of a List header, measured in ListCells */
      47                 : #define LIST_HEADER_OVERHEAD  \
      48                 :     ((int) ((offsetof(List, initial_elements) - 1) / sizeof(ListCell) + 1))
      49                 : 
      50                 : /*
      51                 :  * Macros to simplify writing assertions about the type of a list; a
      52                 :  * NIL list is considered to be an empty list of any type.
      53                 :  */
      54                 : #define IsPointerList(l)        ((l) == NIL || IsA((l), List))
      55                 : #define IsIntegerList(l)        ((l) == NIL || IsA((l), IntList))
      56                 : #define IsOidList(l)            ((l) == NIL || IsA((l), OidList))
      57                 : #define IsXidList(l)            ((l) == NIL || IsA((l), XidList))
      58                 : 
      59                 : #ifdef USE_ASSERT_CHECKING
      60                 : /*
      61                 :  * Check that the specified List is valid (so far as we can tell).
      62                 :  */
      63                 : static void
      64 GIC   142445164 : check_list_invariants(const List *list)
      65 ECB             : {
      66 GIC   142445164 :     if (list == NIL)
      67 CBC    45937872 :         return;
      68 ECB             : 
      69 GIC    96507292 :     Assert(list->length > 0);
      70 CBC    96507292 :     Assert(list->length <= list->max_length);
      71        96507292 :     Assert(list->elements != NULL);
      72 ECB             : 
      73 GIC    96507292 :     Assert(list->type == T_List ||
      74 ECB             :            list->type == T_IntList ||
      75                 :            list->type == T_OidList ||
      76                 :            list->type == T_XidList);
      77                 : }
      78                 : #else
      79                 : #define check_list_invariants(l)  ((void) 0)
      80                 : #endif                          /* USE_ASSERT_CHECKING */
      81                 : 
      82                 : /*
      83                 :  * Return a freshly allocated List with room for at least min_size cells.
      84                 :  *
      85                 :  * Since empty non-NIL lists are invalid, new_list() sets the initial length
      86                 :  * to min_size, effectively marking that number of cells as valid; the caller
      87                 :  * is responsible for filling in their data.
      88                 :  */
      89                 : static List *
      90 GIC    38742563 : new_list(NodeTag type, int min_size)
      91                 : {
      92 ECB             :     List       *newlist;
      93                 :     int         max_size;
      94                 : 
      95 GIC    38742563 :     Assert(min_size > 0);
      96                 : 
      97 ECB             :     /*
      98                 :      * We allocate all the requested cells, and possibly some more, as part of
      99                 :      * the same palloc request as the List header.  This is a big win for the
     100                 :      * typical case of short fixed-length lists.  It can lose if we allocate a
     101                 :      * moderately long list and then it gets extended; we'll be wasting more
     102                 :      * initial_elements[] space than if we'd made the header small.  However,
     103                 :      * rounding up the request as we do in the normal code path provides some
     104                 :      * defense against small extensions.
     105                 :      */
     106                 : 
     107                 : #ifndef DEBUG_LIST_MEMORY_USAGE
     108                 : 
     109                 :     /*
     110                 :      * Normally, we set up a list with some extra cells, to allow it to grow
     111                 :      * without a repalloc.  Prefer cell counts chosen to make the total
     112                 :      * allocation a power-of-2, since palloc would round it up to that anyway.
     113                 :      * (That stops being true for very large allocations, but very long lists
     114                 :      * are infrequent, so it doesn't seem worth special logic for such cases.)
     115                 :      *
     116                 :      * The minimum allocation is 8 ListCell units, providing either 4 or 5
     117                 :      * available ListCells depending on the machine's word width.  Counting
     118                 :      * palloc's overhead, this uses the same amount of space as a one-cell
     119                 :      * list did in the old implementation, and less space for any longer list.
     120                 :      *
     121                 :      * We needn't worry about integer overflow; no caller passes min_size
     122                 :      * that's more than twice the size of an existing list, so the size limits
     123                 :      * within palloc will ensure that we don't overflow here.
     124                 :      */
     125 GIC    38742563 :     max_size = pg_nextpower2_32(Max(8, min_size + LIST_HEADER_OVERHEAD));
     126        38742563 :     max_size -= LIST_HEADER_OVERHEAD;
     127 ECB             : #else
     128                 : 
     129                 :     /*
     130                 :      * For debugging, don't allow any extra space.  This forces any cell
     131                 :      * addition to go through enlarge_list() and thus move the existing data.
     132                 :      */
     133                 :     max_size = min_size;
     134                 : #endif
     135                 : 
     136 GIC    38742563 :     newlist = (List *) palloc(offsetof(List, initial_elements) +
     137                 :                               max_size * sizeof(ListCell));
     138 CBC    38742563 :     newlist->type = type;
     139 GIC    38742563 :     newlist->length = min_size;
     140 CBC    38742563 :     newlist->max_length = max_size;
     141        38742563 :     newlist->elements = newlist->initial_elements;
     142 ECB             : 
     143 CBC    38742563 :     return newlist;
     144                 : }
     145 ECB             : 
     146                 : /*
     147                 :  * Enlarge an existing non-NIL List to have room for at least min_size cells.
     148                 :  *
     149                 :  * This does *not* update list->length, as some callers would find that
     150                 :  * inconvenient.  (list->length had better be the correct number of existing
     151                 :  * valid cells, though.)
     152                 :  */
     153                 : static void
     154 GIC     2915555 : enlarge_list(List *list, int min_size)
     155                 : {
     156 ECB             :     int         new_max_len;
     157                 : 
     158 GIC     2915555 :     Assert(min_size > list->max_length);  /* else we shouldn't be here */
     159                 : 
     160 ECB             : #ifndef DEBUG_LIST_MEMORY_USAGE
     161                 : 
     162                 :     /*
     163                 :      * As above, we prefer power-of-two total allocations; but here we need
     164                 :      * not account for list header overhead.
     165                 :      */
     166                 : 
     167                 :     /* clamp the minimum value to 16, a semi-arbitrary small power of 2 */
     168 GIC     2915555 :     new_max_len = pg_nextpower2_32(Max(16, min_size));
     169                 : 
     170 ECB             : #else
     171                 :     /* As above, don't allocate anything extra */
     172                 :     new_max_len = min_size;
     173                 : #endif
     174                 : 
     175 GIC     2915555 :     if (list->elements == list->initial_elements)
     176                 :     {
     177 ECB             :         /*
     178                 :          * Replace original in-line allocation with a separate palloc block.
     179                 :          * Ensure it is in the same memory context as the List header.  (The
     180                 :          * previous List implementation did not offer any guarantees about
     181                 :          * keeping all list cells in the same context, but it seems reasonable
     182                 :          * to create such a guarantee now.)
     183                 :          */
     184 GIC     1756938 :         list->elements = (ListCell *)
     185         1756938 :             MemoryContextAlloc(GetMemoryChunkContext(list),
     186 ECB             :                                new_max_len * sizeof(ListCell));
     187 CBC     1756938 :         memcpy(list->elements, list->initial_elements,
     188 GIC     1756938 :                list->length * sizeof(ListCell));
     189 ECB             : 
     190                 :         /*
     191                 :          * We must not move the list header, so it's unsafe to try to reclaim
     192                 :          * the initial_elements[] space via repalloc.  In debugging builds,
     193                 :          * however, we can clear that space and/or mark it inaccessible.
     194                 :          * (wipe_mem includes VALGRIND_MAKE_MEM_NOACCESS.)
     195                 :          */
     196                 : #ifdef CLOBBER_FREED_MEMORY
     197 GIC     1756938 :         wipe_mem(list->initial_elements,
     198         1756938 :                  list->max_length * sizeof(ListCell));
     199 ECB             : #else
     200                 :         VALGRIND_MAKE_MEM_NOACCESS(list->initial_elements,
     201                 :                                    list->max_length * sizeof(ListCell));
     202                 : #endif
     203                 :     }
     204                 :     else
     205                 :     {
     206                 : #ifndef DEBUG_LIST_MEMORY_USAGE
     207                 :         /* Normally, let repalloc deal with enlargement */
     208 GIC     1158617 :         list->elements = (ListCell *) repalloc(list->elements,
     209                 :                                                new_max_len * sizeof(ListCell));
     210 ECB             : #else
     211                 :         /*
     212                 :          * repalloc() might enlarge the space in-place, which we don't want
     213                 :          * for debugging purposes, so forcibly move the data somewhere else.
     214                 :          */
     215                 :         ListCell   *newelements;
     216                 : 
     217                 :         newelements = (ListCell *)
     218                 :             MemoryContextAlloc(GetMemoryChunkContext(list),
     219                 :                                new_max_len * sizeof(ListCell));
     220                 :         memcpy(newelements, list->elements,
     221                 :                list->length * sizeof(ListCell));
     222                 :         pfree(list->elements);
     223                 :         list->elements = newelements;
     224                 : #endif
     225                 :     }
     226                 : 
     227 GIC     2915555 :     list->max_length = new_max_len;
     228         2915555 : }
     229 ECB             : 
     230                 : /*
     231                 :  * Convenience functions to construct short Lists from given values.
     232                 :  * (These are normally invoked via the list_makeN macros.)
     233                 :  */
     234                 : List *
     235 GIC     8198297 : list_make1_impl(NodeTag t, ListCell datum1)
     236                 : {
     237 CBC     8198297 :     List       *list = new_list(t, 1);
     238                 : 
     239         8198297 :     list->elements[0] = datum1;
     240 GIC     8198297 :     check_list_invariants(list);
     241 CBC     8198297 :     return list;
     242 ECB             : }
     243                 : 
     244                 : List *
     245 GIC     1138922 : list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2)
     246                 : {
     247 CBC     1138922 :     List       *list = new_list(t, 2);
     248                 : 
     249         1138922 :     list->elements[0] = datum1;
     250 GIC     1138922 :     list->elements[1] = datum2;
     251 CBC     1138922 :     check_list_invariants(list);
     252         1138922 :     return list;
     253 ECB             : }
     254                 : 
     255                 : List *
     256 GIC        2759 : list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2,
     257                 :                 ListCell datum3)
     258 ECB             : {
     259 GIC        2759 :     List       *list = new_list(t, 3);
     260                 : 
     261 CBC        2759 :     list->elements[0] = datum1;
     262 GIC        2759 :     list->elements[1] = datum2;
     263 CBC        2759 :     list->elements[2] = datum3;
     264            2759 :     check_list_invariants(list);
     265            2759 :     return list;
     266 ECB             : }
     267                 : 
     268                 : List *
     269 GIC         121 : list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2,
     270                 :                 ListCell datum3, ListCell datum4)
     271 ECB             : {
     272 GIC         121 :     List       *list = new_list(t, 4);
     273                 : 
     274 CBC         121 :     list->elements[0] = datum1;
     275 GIC         121 :     list->elements[1] = datum2;
     276 CBC         121 :     list->elements[2] = datum3;
     277             121 :     list->elements[3] = datum4;
     278             121 :     check_list_invariants(list);
     279             121 :     return list;
     280 ECB             : }
     281                 : 
     282                 : List *
     283 GIC         154 : list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2,
     284                 :                 ListCell datum3, ListCell datum4, ListCell datum5)
     285 ECB             : {
     286 GIC         154 :     List       *list = new_list(t, 5);
     287                 : 
     288 CBC         154 :     list->elements[0] = datum1;
     289 GIC         154 :     list->elements[1] = datum2;
     290 CBC         154 :     list->elements[2] = datum3;
     291             154 :     list->elements[3] = datum4;
     292             154 :     list->elements[4] = datum5;
     293             154 :     check_list_invariants(list);
     294             154 :     return list;
     295 ECB             : }
     296                 : 
     297                 : /*
     298                 :  * Make room for a new head cell in the given (non-NIL) list.
     299                 :  *
     300                 :  * The data in the new head cell is undefined; the caller should be
     301                 :  * sure to fill it in
     302                 :  */
     303                 : static void
     304 GIC     1858216 : new_head_cell(List *list)
     305                 : {
     306 ECB             :     /* Enlarge array if necessary */
     307 GIC     1858216 :     if (list->length >= list->max_length)
     308           26210 :         enlarge_list(list, list->length + 1);
     309 ECB             :     /* Now shove the existing data over */
     310 CBC     1858216 :     memmove(&list->elements[1], &list->elements[0],
     311 GIC     1858216 :             list->length * sizeof(ListCell));
     312 CBC     1858216 :     list->length++;
     313         1858216 : }
     314 ECB             : 
     315                 : /*
     316                 :  * Make room for a new tail cell in the given (non-NIL) list.
     317                 :  *
     318                 :  * The data in the new tail cell is undefined; the caller should be
     319                 :  * sure to fill it in
     320                 :  */
     321                 : static void
     322 GIC    46274453 : new_tail_cell(List *list)
     323                 : {
     324 ECB             :     /* Enlarge array if necessary */
     325 GIC    46274453 :     if (list->length >= list->max_length)
     326         2868711 :         enlarge_list(list, list->length + 1);
     327 CBC    46274453 :     list->length++;
     328        46274453 : }
     329 ECB             : 
     330                 : /*
     331                 :  * Append a pointer to the list. A pointer to the modified list is
     332                 :  * returned. Note that this function may or may not destructively
     333                 :  * modify the list; callers should always use this function's return
     334                 :  * value, rather than continuing to use the pointer passed as the
     335                 :  * first argument.
     336                 :  */
     337                 : List *
     338 GIC    57207668 : lappend(List *list, void *datum)
     339                 : {
     340 CBC    57207668 :     Assert(IsPointerList(list));
     341                 : 
     342        57207668 :     if (list == NIL)
     343 GIC    18672160 :         list = new_list(T_List, 1);
     344 ECB             :     else
     345 CBC    38535508 :         new_tail_cell(list);
     346                 : 
     347        57207668 :     llast(list) = datum;
     348 GIC    57207668 :     check_list_invariants(list);
     349 CBC    57207668 :     return list;
     350 ECB             : }
     351                 : 
     352                 : /*
     353                 :  * Append an integer to the specified list. See lappend()
     354                 :  */
     355                 : List *
     356 GIC     7442162 : lappend_int(List *list, int datum)
     357                 : {
     358 CBC     7442162 :     Assert(IsIntegerList(list));
     359                 : 
     360         7442162 :     if (list == NIL)
     361 GIC      679776 :         list = new_list(T_IntList, 1);
     362 ECB             :     else
     363 CBC     6762386 :         new_tail_cell(list);
     364                 : 
     365         7442162 :     llast_int(list) = datum;
     366 GIC     7442162 :     check_list_invariants(list);
     367 CBC     7442162 :     return list;
     368 ECB             : }
     369                 : 
     370                 : /*
     371                 :  * Append an OID to the specified list. See lappend()
     372                 :  */
     373                 : List *
     374 GIC     2621924 : lappend_oid(List *list, Oid datum)
     375                 : {
     376 CBC     2621924 :     Assert(IsOidList(list));
     377                 : 
     378         2621924 :     if (list == NIL)
     379 GIC     1645395 :         list = new_list(T_OidList, 1);
     380 ECB             :     else
     381 CBC      976529 :         new_tail_cell(list);
     382                 : 
     383         2621924 :     llast_oid(list) = datum;
     384 GIC     2621924 :     check_list_invariants(list);
     385 CBC     2621924 :     return list;
     386 ECB             : }
     387                 : 
     388                 : /*
     389                 :  * Append a TransactionId to the specified list. See lappend()
     390                 :  */
     391                 : List *
     392 GNC          85 : lappend_xid(List *list, TransactionId datum)
     393                 : {
     394              85 :     Assert(IsXidList(list));
     395                 : 
     396              85 :     if (list == NIL)
     397              55 :         list = new_list(T_XidList, 1);
     398                 :     else
     399              30 :         new_tail_cell(list);
     400                 : 
     401              85 :     llast_xid(list) = datum;
     402              85 :     check_list_invariants(list);
     403              85 :     return list;
     404                 : }
     405                 : 
     406                 : /*
     407                 :  * Make room for a new cell at position 'pos' (measured from 0).
     408                 :  * The data in the cell is left undefined, and must be filled in by the
     409                 :  * caller. 'list' is assumed to be non-NIL, and 'pos' must be a valid
     410                 :  * list position, ie, 0 <= pos <= list's length.
     411                 :  * Returns address of the new cell.
     412 ECB             :  */
     413                 : static ListCell *
     414 CBC      242692 : insert_new_cell(List *list, int pos)
     415                 : {
     416          242692 :     Assert(pos >= 0 && pos <= list->length);
     417 ECB             : 
     418                 :     /* Enlarge array if necessary */
     419 CBC      242692 :     if (list->length >= list->max_length)
     420 GIC         393 :         enlarge_list(list, list->length + 1);
     421 ECB             :     /* Now shove the existing data over */
     422 CBC      242692 :     if (pos < list->length)
     423          110602 :         memmove(&list->elements[pos + 1], &list->elements[pos],
     424 GIC      110602 :                 (list->length - pos) * sizeof(ListCell));
     425          242692 :     list->length++;
     426                 : 
     427          242692 :     return &list->elements[pos];
     428                 : }
     429                 : 
     430                 : /*
     431                 :  * Insert the given datum at position 'pos' (measured from 0) in the list.
     432                 :  * 'pos' must be valid, ie, 0 <= pos <= list's length.
     433                 :  *
     434 ECB             :  * Note that this takes time proportional to the distance to the end of the
     435                 :  * list, since the following entries must be moved.
     436                 :  */
     437                 : List *
     438 GIC     1056526 : list_insert_nth(List *list, int pos, void *datum)
     439 ECB             : {
     440 CBC     1056526 :     if (list == NIL)
     441                 :     {
     442          813834 :         Assert(pos == 0);
     443          813834 :         return list_make1(datum);
     444 ECB             :     }
     445 CBC      242692 :     Assert(IsPointerList(list));
     446 GIC      242692 :     lfirst(insert_new_cell(list, pos)) = datum;
     447 CBC      242692 :     check_list_invariants(list);
     448 GIC      242692 :     return list;
     449                 : }
     450                 : 
     451                 : List *
     452 UIC           0 : list_insert_nth_int(List *list, int pos, int datum)
     453                 : {
     454               0 :     if (list == NIL)
     455                 :     {
     456               0 :         Assert(pos == 0);
     457               0 :         return list_make1_int(datum);
     458 ECB             :     }
     459 UIC           0 :     Assert(IsIntegerList(list));
     460 LBC           0 :     lfirst_int(insert_new_cell(list, pos)) = datum;
     461 UIC           0 :     check_list_invariants(list);
     462 LBC           0 :     return list;
     463 ECB             : }
     464                 : 
     465                 : List *
     466 LBC           0 : list_insert_nth_oid(List *list, int pos, Oid datum)
     467 ECB             : {
     468 LBC           0 :     if (list == NIL)
     469                 :     {
     470 UIC           0 :         Assert(pos == 0);
     471               0 :         return list_make1_oid(datum);
     472 EUB             :     }
     473 UIC           0 :     Assert(IsOidList(list));
     474 UBC           0 :     lfirst_oid(insert_new_cell(list, pos)) = datum;
     475 UIC           0 :     check_list_invariants(list);
     476 UBC           0 :     return list;
     477 EUB             : }
     478                 : 
     479                 : /*
     480                 :  * Prepend a new element to the list. A pointer to the modified list
     481                 :  * is returned. Note that this function may or may not destructively
     482                 :  * modify the list; callers should always use this function's return
     483                 :  * value, rather than continuing to use the pointer passed as the
     484                 :  * second argument.
     485                 :  *
     486                 :  * Note that this takes time proportional to the length of the list,
     487                 :  * since the existing entries must be moved.
     488                 :  *
     489                 :  * Caution: before Postgres 8.0, the original List was unmodified and
     490                 :  * could be considered to retain its separate identity.  This is no longer
     491                 :  * the case.
     492                 :  */
     493                 : List *
     494 GBC     3891825 : lcons(void *datum, List *list)
     495 EUB             : {
     496 GBC     3891825 :     Assert(IsPointerList(list));
     497                 : 
     498 GIC     3891825 :     if (list == NIL)
     499         2054547 :         list = new_list(T_List, 1);
     500                 :     else
     501         1837278 :         new_head_cell(list);
     502                 : 
     503         3891825 :     linitial(list) = datum;
     504         3891825 :     check_list_invariants(list);
     505         3891825 :     return list;
     506                 : }
     507                 : 
     508                 : /*
     509                 :  * Prepend an integer to the list. See lcons()
     510                 :  */
     511                 : List *
     512            9928 : lcons_int(int datum, List *list)
     513                 : {
     514 CBC        9928 :     Assert(IsIntegerList(list));
     515                 : 
     516            9928 :     if (list == NIL)
     517 GIC        4322 :         list = new_list(T_IntList, 1);
     518 ECB             :     else
     519 CBC        5606 :         new_head_cell(list);
     520                 : 
     521            9928 :     linitial_int(list) = datum;
     522 GIC        9928 :     check_list_invariants(list);
     523 CBC        9928 :     return list;
     524 ECB             : }
     525                 : 
     526                 : /*
     527                 :  * Prepend an OID to the list. See lcons()
     528                 :  */
     529                 : List *
     530 GIC       16431 : lcons_oid(Oid datum, List *list)
     531                 : {
     532 CBC       16431 :     Assert(IsOidList(list));
     533                 : 
     534           16431 :     if (list == NIL)
     535 GIC        1099 :         list = new_list(T_OidList, 1);
     536 ECB             :     else
     537 CBC       15332 :         new_head_cell(list);
     538                 : 
     539           16431 :     linitial_oid(list) = datum;
     540 GIC       16431 :     check_list_invariants(list);
     541 CBC       16431 :     return list;
     542 ECB             : }
     543                 : 
     544                 : /*
     545                 :  * Concatenate list2 to the end of list1, and return list1.
     546                 :  *
     547                 :  * This is equivalent to lappend'ing each element of list2, in order, to list1.
     548                 :  * list1 is destructively changed, list2 is not.  (However, in the case of
     549                 :  * pointer lists, list1 and list2 will point to the same structures.)
     550                 :  *
     551                 :  * Callers should be sure to use the return value as the new pointer to the
     552                 :  * concatenated list: the 'list1' input pointer may or may not be the same
     553                 :  * as the returned pointer.
     554                 :  *
     555                 :  * Note that this takes at least time proportional to the length of list2.
     556                 :  * It'd typically be the case that we have to enlarge list1's storage,
     557                 :  * probably adding time proportional to the length of list1.
     558                 :  */
     559                 : List *
     560 CBC     2621141 : list_concat(List *list1, const List *list2)
     561 ECB             : {
     562                 :     int         new_len;
     563                 : 
     564 GIC     2621141 :     if (list1 == NIL)
     565         1852513 :         return list_copy(list2);
     566          768628 :     if (list2 == NIL)
     567          396467 :         return list1;
     568                 : 
     569          372161 :     Assert(list1->type == list2->type);
     570                 : 
     571          372161 :     new_len = list1->length + list2->length;
     572                 :     /* Enlarge array if necessary */
     573          372161 :     if (new_len > list1->max_length)
     574           20241 :         enlarge_list(list1, new_len);
     575                 : 
     576                 :     /* Even if list1 == list2, using memcpy should be safe here */
     577          372161 :     memcpy(&list1->elements[list1->length], &list2->elements[0],
     578          372161 :            list2->length * sizeof(ListCell));
     579          372161 :     list1->length = new_len;
     580 ECB             : 
     581 GIC      372161 :     check_list_invariants(list1);
     582          372161 :     return list1;
     583                 : }
     584 ECB             : 
     585                 : /*
     586                 :  * Form a new list by concatenating the elements of list1 and list2.
     587                 :  *
     588                 :  * Neither input list is modified.  (However, if they are pointer lists,
     589                 :  * the output list will point to the same structures.)
     590                 :  *
     591                 :  * This is equivalent to, but more efficient than,
     592                 :  * list_concat(list_copy(list1), list2).
     593                 :  * Note that some pre-v13 code might list_copy list2 as well, but that's
     594                 :  * pointless now.
     595                 :  */
     596                 : List *
     597 CBC      416583 : list_concat_copy(const List *list1, const List *list2)
     598 ECB             : {
     599                 :     List       *result;
     600                 :     int         new_len;
     601                 : 
     602 CBC      416583 :     if (list1 == NIL)
     603 GIC      177950 :         return list_copy(list2);
     604          238633 :     if (list2 == NIL)
     605          208677 :         return list_copy(list1);
     606                 : 
     607           29956 :     Assert(list1->type == list2->type);
     608                 : 
     609           29956 :     new_len = list1->length + list2->length;
     610           29956 :     result = new_list(list1->type, new_len);
     611           29956 :     memcpy(result->elements, list1->elements,
     612           29956 :            list1->length * sizeof(ListCell));
     613           29956 :     memcpy(result->elements + list1->length, list2->elements,
     614           29956 :            list2->length * sizeof(ListCell));
     615                 : 
     616           29956 :     check_list_invariants(result);
     617 CBC       29956 :     return result;
     618                 : }
     619                 : 
     620                 : /*
     621                 :  * Truncate 'list' to contain no more than 'new_size' elements. This
     622 ECB             :  * modifies the list in-place! Despite this, callers should use the
     623                 :  * pointer returned by this function to refer to the newly truncated
     624                 :  * list -- it may or may not be the same as the pointer that was
     625                 :  * passed.
     626                 :  *
     627                 :  * Note that any cells removed by list_truncate() are NOT pfree'd.
     628                 :  */
     629                 : List *
     630 CBC      258385 : list_truncate(List *list, int new_size)
     631 ECB             : {
     632 CBC      258385 :     if (new_size <= 0)
     633           67962 :         return NIL;             /* truncate to zero length */
     634 ECB             : 
     635                 :     /* If asked to effectively extend the list, do nothing */
     636 CBC      190423 :     if (new_size < list_length(list))
     637           48839 :         list->length = new_size;
     638                 : 
     639                 :     /*
     640                 :      * Note: unlike the individual-list-cell deletion functions, we don't move
     641                 :      * the list cells to new storage, even in DEBUG_LIST_MEMORY_USAGE mode.
     642                 :      * This is because none of them can move in this operation, so just like
     643                 :      * in the old cons-cell-based implementation, this function doesn't
     644                 :      * invalidate any pointers to cells of the list.  This is also the reason
     645                 :      * for not wiping the memory of the deleted cells: the old code didn't
     646                 :      * free them either.  Perhaps later we'll tighten this up.
     647                 :      */
     648                 : 
     649 GIC      190423 :     return list;
     650 ECB             : }
     651                 : 
     652                 : /*
     653                 :  * Return true iff 'datum' is a member of the list. Equality is
     654                 :  * determined via equal(), so callers should ensure that they pass a
     655                 :  * Node as 'datum'.
     656                 :  *
     657                 :  * This does a simple linear search --- avoid using it on long lists.
     658                 :  */
     659                 : bool
     660 GIC      236039 : list_member(const List *list, const void *datum)
     661                 : {
     662                 :     const ListCell *cell;
     663                 : 
     664          236039 :     Assert(IsPointerList(list));
     665          236039 :     check_list_invariants(list);
     666                 : 
     667          283830 :     foreach(cell, list)
     668                 :     {
     669 CBC       84973 :         if (equal(lfirst(cell), datum))
     670 GIC       37182 :             return true;
     671                 :     }
     672                 : 
     673          198857 :     return false;
     674                 : }
     675                 : 
     676                 : /*
     677                 :  * Return true iff 'datum' is a member of the list. Equality is
     678                 :  * determined by using simple pointer comparison.
     679                 :  */
     680 ECB             : bool
     681 GIC      257932 : list_member_ptr(const List *list, const void *datum)
     682                 : {
     683                 :     const ListCell *cell;
     684 ECB             : 
     685 CBC      257932 :     Assert(IsPointerList(list));
     686 GIC      257932 :     check_list_invariants(list);
     687 ECB             : 
     688 GIC      321663 :     foreach(cell, list)
     689 ECB             :     {
     690 CBC      213510 :         if (lfirst(cell) == datum)
     691 GIC      149779 :             return true;
     692                 :     }
     693 ECB             : 
     694 GIC      108153 :     return false;
     695                 : }
     696                 : 
     697                 : /*
     698                 :  * Return true iff the integer 'datum' is a member of the list.
     699                 :  */
     700                 : bool
     701 CBC       54685 : list_member_int(const List *list, int datum)
     702                 : {
     703                 :     const ListCell *cell;
     704                 : 
     705           54685 :     Assert(IsIntegerList(list));
     706           54685 :     check_list_invariants(list);
     707                 : 
     708         4964943 :     foreach(cell, list)
     709                 :     {
     710         4919382 :         if (lfirst_int(cell) == datum)
     711            9124 :             return true;
     712                 :     }
     713                 : 
     714           45561 :     return false;
     715                 : }
     716                 : 
     717                 : /*
     718                 :  * Return true iff the OID 'datum' is a member of the list.
     719                 :  */
     720                 : bool
     721        46922880 : list_member_oid(const List *list, Oid datum)
     722                 : {
     723                 :     const ListCell *cell;
     724                 : 
     725        46922880 :     Assert(IsOidList(list));
     726        46922880 :     check_list_invariants(list);
     727                 : 
     728        48663228 :     foreach(cell, list)
     729                 :     {
     730         2075895 :         if (lfirst_oid(cell) == datum)
     731          335547 :             return true;
     732                 :     }
     733                 : 
     734        46587333 :     return false;
     735                 : }
     736                 : 
     737                 : /*
     738                 :  * Return true iff the TransactionId 'datum' is a member of the list.
     739                 :  */
     740                 : bool
     741 GNC      175973 : list_member_xid(const List *list, TransactionId datum)
     742                 : {
     743                 :     const ListCell *cell;
     744                 : 
     745          175973 :     Assert(IsXidList(list));
     746          175973 :     check_list_invariants(list);
     747                 : 
     748          216823 :     foreach(cell, list)
     749                 :     {
     750          216738 :         if (lfirst_xid(cell) == datum)
     751          175888 :             return true;
     752                 :     }
     753                 : 
     754              85 :     return false;
     755                 : }
     756                 : 
     757                 : /*
     758                 :  * Delete the n'th cell (counting from 0) in list.
     759                 :  *
     760                 :  * The List is pfree'd if this was the last member.
     761 ECB             :  *
     762                 :  * Note that this takes time proportional to the distance to the end of the
     763                 :  * list, since the following entries must be moved.
     764                 :  */
     765                 : List *
     766 CBC     1613627 : list_delete_nth_cell(List *list, int n)
     767                 : {
     768         1613627 :     check_list_invariants(list);
     769                 : 
     770         1613627 :     Assert(n >= 0 && n < list->length);
     771 ECB             : 
     772                 :     /*
     773                 :      * If we're about to delete the last node from the list, free the whole
     774                 :      * list instead and return NIL, which is the only valid representation of
     775                 :      * a zero-length list.
     776                 :      */
     777 GIC     1613627 :     if (list->length == 1)
     778                 :     {
     779          879341 :         list_free(list);
     780          879341 :         return NIL;
     781 ECB             :     }
     782                 : 
     783                 :     /*
     784                 :      * Otherwise, we normally just collapse out the removed element.  But for
     785                 :      * debugging purposes, move the whole list contents someplace else.
     786                 :      *
     787                 :      * (Note that we *must* keep the contents in the same memory context.)
     788                 :      */
     789                 : #ifndef DEBUG_LIST_MEMORY_USAGE
     790 CBC      734286 :     memmove(&list->elements[n], &list->elements[n + 1],
     791          734286 :             (list->length - 1 - n) * sizeof(ListCell));
     792 GIC      734286 :     list->length--;
     793                 : #else
     794 ECB             :     {
     795                 :         ListCell   *newelems;
     796                 :         int         newmaxlen = list->length - 1;
     797                 : 
     798                 :         newelems = (ListCell *)
     799                 :             MemoryContextAlloc(GetMemoryChunkContext(list),
     800                 :                                newmaxlen * sizeof(ListCell));
     801                 :         memcpy(newelems, list->elements, n * sizeof(ListCell));
     802                 :         memcpy(&newelems[n], &list->elements[n + 1],
     803                 :                (list->length - 1 - n) * sizeof(ListCell));
     804                 :         if (list->elements != list->initial_elements)
     805                 :             pfree(list->elements);
     806                 :         else
     807                 :         {
     808                 :             /*
     809                 :              * As in enlarge_list(), clear the initial_elements[] space and/or
     810                 :              * mark it inaccessible.
     811                 :              */
     812                 : #ifdef CLOBBER_FREED_MEMORY
     813                 :             wipe_mem(list->initial_elements,
     814                 :                      list->max_length * sizeof(ListCell));
     815                 : #else
     816                 :             VALGRIND_MAKE_MEM_NOACCESS(list->initial_elements,
     817                 :                                        list->max_length * sizeof(ListCell));
     818                 : #endif
     819                 :         }
     820                 :         list->elements = newelems;
     821                 :         list->max_length = newmaxlen;
     822                 :         list->length--;
     823                 :         check_list_invariants(list);
     824                 :     }
     825                 : #endif
     826                 : 
     827 GIC      734286 :     return list;
     828                 : }
     829                 : 
     830 ECB             : /*
     831                 :  * Delete 'cell' from 'list'.
     832                 :  *
     833                 :  * The List is pfree'd if this was the last member.  However, we do not
     834                 :  * touch any data the cell might've been pointing to.
     835                 :  *
     836                 :  * Note that this takes time proportional to the distance to the end of the
     837                 :  * list, since the following entries must be moved.
     838                 :  */
     839                 : List *
     840 GIC     1192308 : list_delete_cell(List *list, ListCell *cell)
     841                 : {
     842         1192308 :     return list_delete_nth_cell(list, cell - list->elements);
     843                 : }
     844                 : 
     845                 : /*
     846                 :  * Delete the first cell in list that matches datum, if any.
     847                 :  * Equality is determined via equal().
     848                 :  *
     849                 :  * This does a simple linear search --- avoid using it on long lists.
     850                 :  */
     851                 : List *
     852             119 : list_delete(List *list, void *datum)
     853                 : {
     854                 :     ListCell   *cell;
     855                 : 
     856             119 :     Assert(IsPointerList(list));
     857             119 :     check_list_invariants(list);
     858                 : 
     859             122 :     foreach(cell, list)
     860                 :     {
     861             119 :         if (equal(lfirst(cell), datum))
     862             116 :             return list_delete_cell(list, cell);
     863                 :     }
     864                 : 
     865                 :     /* Didn't find a match: return the list unmodified */
     866               3 :     return list;
     867 ECB             : }
     868                 : 
     869                 : /* As above, but use simple pointer equality */
     870                 : List *
     871 GIC      943882 : list_delete_ptr(List *list, void *datum)
     872                 : {
     873                 :     ListCell   *cell;
     874                 : 
     875          943882 :     Assert(IsPointerList(list));
     876          943882 :     check_list_invariants(list);
     877                 : 
     878          944072 :     foreach(cell, list)
     879                 :     {
     880 CBC      944072 :         if (lfirst(cell) == datum)
     881 GIC      943882 :             return list_delete_cell(list, cell);
     882 ECB             :     }
     883                 : 
     884                 :     /* Didn't find a match: return the list unmodified */
     885 UIC           0 :     return list;
     886                 : }
     887                 : 
     888                 : /* As above, but for integers */
     889                 : List *
     890 GIC          40 : list_delete_int(List *list, int datum)
     891                 : {
     892 ECB             :     ListCell   *cell;
     893                 : 
     894 GIC          40 :     Assert(IsIntegerList(list));
     895              40 :     check_list_invariants(list);
     896 ECB             : 
     897 CBC          43 :     foreach(cell, list)
     898                 :     {
     899              43 :         if (lfirst_int(cell) == datum)
     900 GIC          40 :             return list_delete_cell(list, cell);
     901 ECB             :     }
     902                 : 
     903                 :     /* Didn't find a match: return the list unmodified */
     904 UIC           0 :     return list;
     905                 : }
     906 ECB             : 
     907                 : /* As above, but for OIDs */
     908                 : List *
     909 GIC        2478 : list_delete_oid(List *list, Oid datum)
     910                 : {
     911 ECB             :     ListCell   *cell;
     912                 : 
     913 GIC        2478 :     Assert(IsOidList(list));
     914            2478 :     check_list_invariants(list);
     915 ECB             : 
     916 CBC        2478 :     foreach(cell, list)
     917                 :     {
     918             750 :         if (lfirst_oid(cell) == datum)
     919 GIC         750 :             return list_delete_cell(list, cell);
     920 ECB             :     }
     921                 : 
     922                 :     /* Didn't find a match: return the list unmodified */
     923 GIC        1728 :     return list;
     924                 : }
     925 EUB             : 
     926                 : /*
     927                 :  * Delete the first element of the list.
     928                 :  *
     929                 :  * This is useful to replace the Lisp-y code "list = lnext(list);" in cases
     930 ECB             :  * where the intent is to alter the list rather than just traverse it.
     931                 :  * Beware that the list is modified, whereas the Lisp-y coding leaves
     932                 :  * the original list head intact in case there's another pointer to it.
     933                 :  *
     934                 :  * Note that this takes time proportional to the length of the list,
     935                 :  * since the remaining entries must be moved.  Consider reversing the
     936                 :  * list order so that you can use list_delete_last() instead.  However,
     937                 :  * if that causes you to replace lappend() with lcons(), you haven't
     938                 :  * improved matters.  (In short, you can make an efficient stack from
     939                 :  * a List, but not an efficient FIFO queue.)
     940                 :  */
     941                 : List *
     942 GIC      402374 : list_delete_first(List *list)
     943                 : {
     944 GBC      402374 :     check_list_invariants(list);
     945                 : 
     946 GIC      402374 :     if (list == NIL)
     947 UIC           0 :         return NIL;             /* would an error be better? */
     948                 : 
     949 CBC      402374 :     return list_delete_nth_cell(list, 0);
     950                 : }
     951                 : 
     952                 : /*
     953 ECB             :  * Delete the last element of the list.
     954                 :  */
     955                 : List *
     956 CBC       28226 : list_delete_last(List *list)
     957                 : {
     958           28226 :     check_list_invariants(list);
     959 ECB             : 
     960 GIC       28226 :     if (list == NIL)
     961 UIC           0 :         return NIL;             /* would an error be better? */
     962                 : 
     963 ECB             :     /* list_truncate won't free list if it goes to empty, but this should */
     964 GIC       28226 :     if (list_length(list) <= 1)
     965                 :     {
     966           13325 :         list_free(list);
     967           13325 :         return NIL;
     968                 :     }
     969                 : 
     970           14901 :     return list_truncate(list, list_length(list) - 1);
     971                 : }
     972                 : 
     973                 : /*
     974                 :  * Delete the first N cells of the list.
     975                 :  *
     976                 :  * The List is pfree'd if the request causes all cells to be deleted.
     977                 :  *
     978                 :  * Note that this takes time proportional to the distance to the end of the
     979                 :  * list, since the following entries must be moved.
     980                 :  */
     981                 : List *
     982 CBC         218 : list_delete_first_n(List *list, int n)
     983                 : {
     984             218 :     check_list_invariants(list);
     985                 : 
     986 ECB             :     /* No-op request? */
     987 GBC         218 :     if (n <= 0)
     988 GIC           1 :         return list;
     989 ECB             : 
     990                 :     /* Delete whole list? */
     991 GIC         217 :     if (n >= list_length(list))
     992                 :     {
     993 UIC           0 :         list_free(list);
     994               0 :         return NIL;
     995                 :     }
     996 ECB             : 
     997                 :     /*
     998                 :      * Otherwise, we normally just collapse out the removed elements.  But for
     999                 :      * debugging purposes, move the whole list contents someplace else.
    1000                 :      *
    1001 EUB             :      * (Note that we *must* keep the contents in the same memory context.)
    1002                 :      */
    1003                 : #ifndef DEBUG_LIST_MEMORY_USAGE
    1004 CBC         217 :     memmove(&list->elements[0], &list->elements[n],
    1005 GIC         217 :             (list->length - n) * sizeof(ListCell));
    1006 CBC         217 :     list->length -= n;
    1007 ECB             : #else
    1008                 :     {
    1009                 :         ListCell   *newelems;
    1010                 :         int         newmaxlen = list->length - n;
    1011                 : 
    1012                 :         newelems = (ListCell *)
    1013                 :             MemoryContextAlloc(GetMemoryChunkContext(list),
    1014                 :                                newmaxlen * sizeof(ListCell));
    1015                 :         memcpy(newelems, &list->elements[n], newmaxlen * sizeof(ListCell));
    1016                 :         if (list->elements != list->initial_elements)
    1017                 :             pfree(list->elements);
    1018                 :         else
    1019                 :         {
    1020                 :             /*
    1021                 :              * As in enlarge_list(), clear the initial_elements[] space and/or
    1022                 :              * mark it inaccessible.
    1023                 :              */
    1024                 : #ifdef CLOBBER_FREED_MEMORY
    1025                 :             wipe_mem(list->initial_elements,
    1026                 :                      list->max_length * sizeof(ListCell));
    1027                 : #else
    1028                 :             VALGRIND_MAKE_MEM_NOACCESS(list->initial_elements,
    1029                 :                                        list->max_length * sizeof(ListCell));
    1030                 : #endif
    1031                 :         }
    1032                 :         list->elements = newelems;
    1033 EUB             :         list->max_length = newmaxlen;
    1034                 :         list->length = newmaxlen;
    1035                 :         check_list_invariants(list);
    1036                 :     }
    1037                 : #endif
    1038                 : 
    1039 GIC         217 :     return list;
    1040                 : }
    1041                 : 
    1042                 : /*
    1043                 :  * Generate the union of two lists. This is calculated by copying
    1044 ECB             :  * list1 via list_copy(), then adding to it all the members of list2
    1045                 :  * that aren't already in list1.
    1046                 :  *
    1047                 :  * Whether an element is already a member of the list is determined
    1048                 :  * via equal().
    1049                 :  *
    1050                 :  * The returned list is newly-allocated, although the content of the
    1051                 :  * cells is the same (i.e. any pointed-to objects are not copied).
    1052                 :  *
    1053                 :  * NB: this function will NOT remove any duplicates that are present
    1054                 :  * in list1 (so it only performs a "union" if list1 is known unique to
    1055                 :  * start with).  Also, if you are about to write "x = list_union(x, y)"
    1056                 :  * you probably want to use list_concat_unique() instead to avoid wasting
    1057                 :  * the storage of the old x list.
    1058                 :  *
    1059                 :  * Note that this takes time proportional to the product of the list
    1060                 :  * lengths, so beware of using it on long lists.  (We could probably
    1061                 :  * improve that, but really you should be using some other data structure
    1062                 :  * if this'd be a performance bottleneck.)
    1063                 :  */
    1064                 : List *
    1065 GIC        3720 : list_union(const List *list1, const List *list2)
    1066                 : {
    1067                 :     List       *result;
    1068                 :     const ListCell *cell;
    1069                 : 
    1070            3720 :     Assert(IsPointerList(list1));
    1071            3720 :     Assert(IsPointerList(list2));
    1072                 : 
    1073            3720 :     result = list_copy(list1);
    1074            7741 :     foreach(cell, list2)
    1075                 :     {
    1076            4021 :         if (!list_member(result, lfirst(cell)))
    1077            3897 :             result = lappend(result, lfirst(cell));
    1078                 :     }
    1079 ECB             : 
    1080 GIC        3720 :     check_list_invariants(result);
    1081            3720 :     return result;
    1082                 : }
    1083                 : 
    1084                 : /*
    1085                 :  * This variant of list_union() determines duplicates via simple
    1086                 :  * pointer comparison.
    1087                 :  */
    1088                 : List *
    1089 UIC           0 : list_union_ptr(const List *list1, const List *list2)
    1090                 : {
    1091                 :     List       *result;
    1092                 :     const ListCell *cell;
    1093                 : 
    1094               0 :     Assert(IsPointerList(list1));
    1095               0 :     Assert(IsPointerList(list2));
    1096                 : 
    1097               0 :     result = list_copy(list1);
    1098               0 :     foreach(cell, list2)
    1099                 :     {
    1100               0 :         if (!list_member_ptr(result, lfirst(cell)))
    1101               0 :             result = lappend(result, lfirst(cell));
    1102                 :     }
    1103                 : 
    1104               0 :     check_list_invariants(result);
    1105 LBC           0 :     return result;
    1106                 : }
    1107                 : 
    1108                 : /*
    1109                 :  * This variant of list_union() operates upon lists of integers.
    1110 ECB             :  */
    1111                 : List *
    1112 GIC        2661 : list_union_int(const List *list1, const List *list2)
    1113 ECB             : {
    1114                 :     List       *result;
    1115                 :     const ListCell *cell;
    1116                 : 
    1117 CBC        2661 :     Assert(IsIntegerList(list1));
    1118 GIC        2661 :     Assert(IsIntegerList(list2));
    1119                 : 
    1120 CBC        2661 :     result = list_copy(list1);
    1121            5413 :     foreach(cell, list2)
    1122                 :     {
    1123 GIC        2752 :         if (!list_member_int(result, lfirst_int(cell)))
    1124            2634 :             result = lappend_int(result, lfirst_int(cell));
    1125                 :     }
    1126                 : 
    1127            2661 :     check_list_invariants(result);
    1128            2661 :     return result;
    1129 EUB             : }
    1130                 : 
    1131                 : /*
    1132                 :  * This variant of list_union() operates upon lists of OIDs.
    1133                 :  */
    1134                 : List *
    1135 UBC           0 : list_union_oid(const List *list1, const List *list2)
    1136                 : {
    1137 EUB             :     List       *result;
    1138                 :     const ListCell *cell;
    1139                 : 
    1140 UBC           0 :     Assert(IsOidList(list1));
    1141               0 :     Assert(IsOidList(list2));
    1142                 : 
    1143 UIC           0 :     result = list_copy(list1);
    1144 UBC           0 :     foreach(cell, list2)
    1145 EUB             :     {
    1146 UIC           0 :         if (!list_member_oid(result, lfirst_oid(cell)))
    1147               0 :             result = lappend_oid(result, lfirst_oid(cell));
    1148                 :     }
    1149                 : 
    1150               0 :     check_list_invariants(result);
    1151               0 :     return result;
    1152 ECB             : }
    1153                 : 
    1154                 : /*
    1155                 :  * Return a list that contains all the cells that are in both list1 and
    1156                 :  * list2.  The returned list is freshly allocated via palloc(), but the
    1157                 :  * cells themselves point to the same objects as the cells of the
    1158                 :  * input lists.
    1159                 :  *
    1160                 :  * Duplicate entries in list1 will not be suppressed, so it's only a true
    1161                 :  * "intersection" if list1 is known unique beforehand.
    1162                 :  *
    1163                 :  * This variant works on lists of pointers, and determines list
    1164                 :  * membership via equal().  Note that the list1 member will be pointed
    1165                 :  * to in the result.
    1166                 :  *
    1167                 :  * Note that this takes time proportional to the product of the list
    1168                 :  * lengths, so beware of using it on long lists.  (We could probably
    1169                 :  * improve that, but really you should be using some other data structure
    1170                 :  * if this'd be a performance bottleneck.)
    1171                 :  */
    1172                 : List *
    1173 UIC           0 : list_intersection(const List *list1, const List *list2)
    1174                 : {
    1175 EUB             :     List       *result;
    1176                 :     const ListCell *cell;
    1177                 : 
    1178 UIC           0 :     if (list1 == NIL || list2 == NIL)
    1179               0 :         return NIL;
    1180 EUB             : 
    1181 UBC           0 :     Assert(IsPointerList(list1));
    1182 UIC           0 :     Assert(IsPointerList(list2));
    1183 EUB             : 
    1184 UBC           0 :     result = NIL;
    1185 UIC           0 :     foreach(cell, list1)
    1186 EUB             :     {
    1187 UBC           0 :         if (list_member(list2, lfirst(cell)))
    1188 UIC           0 :             result = lappend(result, lfirst(cell));
    1189                 :     }
    1190 EUB             : 
    1191 UBC           0 :     check_list_invariants(result);
    1192 UIC           0 :     return result;
    1193                 : }
    1194                 : 
    1195                 : /*
    1196                 :  * As list_intersection but operates on lists of integers.
    1197                 :  */
    1198                 : List *
    1199 GIC         149 : list_intersection_int(const List *list1, const List *list2)
    1200                 : {
    1201                 :     List       *result;
    1202                 :     const ListCell *cell;
    1203                 : 
    1204             149 :     if (list1 == NIL || list2 == NIL)
    1205 UIC           0 :         return NIL;
    1206                 : 
    1207 GIC         149 :     Assert(IsIntegerList(list1));
    1208             149 :     Assert(IsIntegerList(list2));
    1209                 : 
    1210             149 :     result = NIL;
    1211             322 :     foreach(cell, list1)
    1212                 :     {
    1213 GBC         173 :         if (list_member_int(list2, lfirst_int(cell)))
    1214 GIC          81 :             result = lappend_int(result, lfirst_int(cell));
    1215                 :     }
    1216                 : 
    1217             149 :     check_list_invariants(result);
    1218 GBC         149 :     return result;
    1219 EUB             : }
    1220                 : 
    1221                 : /*
    1222                 :  * Return a list that contains all the cells in list1 that are not in
    1223                 :  * list2. The returned list is freshly allocated via palloc(), but the
    1224                 :  * cells themselves point to the same objects as the cells of the
    1225                 :  * input lists.
    1226                 :  *
    1227                 :  * This variant works on lists of pointers, and determines list
    1228                 :  * membership via equal()
    1229                 :  *
    1230                 :  * Note that this takes time proportional to the product of the list
    1231                 :  * lengths, so beware of using it on long lists.  (We could probably
    1232                 :  * improve that, but really you should be using some other data structure
    1233                 :  * if this'd be a performance bottleneck.)
    1234                 :  */
    1235                 : List *
    1236 GIC       16979 : list_difference(const List *list1, const List *list2)
    1237                 : {
    1238                 :     const ListCell *cell;
    1239 CBC       16979 :     List       *result = NIL;
    1240                 : 
    1241 GIC       16979 :     Assert(IsPointerList(list1));
    1242           16979 :     Assert(IsPointerList(list2));
    1243                 : 
    1244 CBC       16979 :     if (list2 == NIL)
    1245 GBC         565 :         return list_copy(list1);
    1246                 : 
    1247 CBC       35007 :     foreach(cell, list1)
    1248 ECB             :     {
    1249 GIC       18593 :         if (!list_member(list2, lfirst(cell)))
    1250 CBC         762 :             result = lappend(result, lfirst(cell));
    1251 ECB             :     }
    1252                 : 
    1253 CBC       16414 :     check_list_invariants(result);
    1254           16414 :     return result;
    1255                 : }
    1256                 : 
    1257 ECB             : /*
    1258                 :  * This variant of list_difference() determines list membership via
    1259                 :  * simple pointer equality.
    1260                 :  */
    1261                 : List *
    1262 GIC       11097 : list_difference_ptr(const List *list1, const List *list2)
    1263                 : {
    1264                 :     const ListCell *cell;
    1265           11097 :     List       *result = NIL;
    1266                 : 
    1267           11097 :     Assert(IsPointerList(list1));
    1268           11097 :     Assert(IsPointerList(list2));
    1269                 : 
    1270           11097 :     if (list2 == NIL)
    1271            9482 :         return list_copy(list1);
    1272                 : 
    1273            4237 :     foreach(cell, list1)
    1274                 :     {
    1275            2622 :         if (!list_member_ptr(list2, lfirst(cell)))
    1276 CBC        1007 :             result = lappend(result, lfirst(cell));
    1277                 :     }
    1278                 : 
    1279            1615 :     check_list_invariants(result);
    1280 GIC        1615 :     return result;
    1281 ECB             : }
    1282                 : 
    1283                 : /*
    1284                 :  * This variant of list_difference() operates upon lists of integers.
    1285                 :  */
    1286                 : List *
    1287 CBC        1205 : list_difference_int(const List *list1, const List *list2)
    1288                 : {
    1289 ECB             :     const ListCell *cell;
    1290 CBC        1205 :     List       *result = NIL;
    1291                 : 
    1292 GIC        1205 :     Assert(IsIntegerList(list1));
    1293 CBC        1205 :     Assert(IsIntegerList(list2));
    1294 ECB             : 
    1295 GIC        1205 :     if (list2 == NIL)
    1296             871 :         return list_copy(list1);
    1297                 : 
    1298             990 :     foreach(cell, list1)
    1299                 :     {
    1300             656 :         if (!list_member_int(list2, lfirst_int(cell)))
    1301             258 :             result = lappend_int(result, lfirst_int(cell));
    1302 ECB             :     }
    1303                 : 
    1304 GIC         334 :     check_list_invariants(result);
    1305 CBC         334 :     return result;
    1306                 : }
    1307 ECB             : 
    1308                 : /*
    1309                 :  * This variant of list_difference() operates upon lists of OIDs.
    1310                 :  */
    1311                 : List *
    1312 GIC         196 : list_difference_oid(const List *list1, const List *list2)
    1313 ECB             : {
    1314                 :     const ListCell *cell;
    1315 CBC         196 :     List       *result = NIL;
    1316 ECB             : 
    1317 GIC         196 :     Assert(IsOidList(list1));
    1318             196 :     Assert(IsOidList(list2));
    1319 ECB             : 
    1320 CBC         196 :     if (list2 == NIL)
    1321 GIC         178 :         return list_copy(list1);
    1322                 : 
    1323              27 :     foreach(cell, list1)
    1324                 :     {
    1325               9 :         if (!list_member_oid(list2, lfirst_oid(cell)))
    1326               3 :             result = lappend_oid(result, lfirst_oid(cell));
    1327 ECB             :     }
    1328                 : 
    1329 GIC          18 :     check_list_invariants(result);
    1330 CBC          18 :     return result;
    1331                 : }
    1332 ECB             : 
    1333                 : /*
    1334                 :  * Append datum to list, but only if it isn't already in the list.
    1335                 :  *
    1336                 :  * Whether an element is already a member of the list is determined
    1337                 :  * via equal().
    1338                 :  *
    1339                 :  * This does a simple linear search --- avoid using it on long lists.
    1340                 :  */
    1341                 : List *
    1342 GIC       52823 : list_append_unique(List *list, void *datum)
    1343                 : {
    1344 CBC       52823 :     if (list_member(list, datum))
    1345            2741 :         return list;
    1346                 :     else
    1347 GIC       50082 :         return lappend(list, datum);
    1348                 : }
    1349                 : 
    1350                 : /*
    1351                 :  * This variant of list_append_unique() determines list membership via
    1352 ECB             :  * simple pointer equality.
    1353                 :  */
    1354                 : List *
    1355 CBC      174528 : list_append_unique_ptr(List *list, void *datum)
    1356                 : {
    1357          174528 :     if (list_member_ptr(list, datum))
    1358           67792 :         return list;
    1359                 :     else
    1360          106736 :         return lappend(list, datum);
    1361 ECB             : }
    1362                 : 
    1363                 : /*
    1364                 :  * This variant of list_append_unique() operates upon lists of integers.
    1365                 :  */
    1366                 : List *
    1367 UIC           0 : list_append_unique_int(List *list, int datum)
    1368                 : {
    1369 LBC           0 :     if (list_member_int(list, datum))
    1370               0 :         return list;
    1371                 :     else
    1372 UIC           0 :         return lappend_int(list, datum);
    1373                 : }
    1374                 : 
    1375                 : /*
    1376                 :  * This variant of list_append_unique() operates upon lists of OIDs.
    1377                 :  */
    1378                 : List *
    1379 GIC        4186 : list_append_unique_oid(List *list, Oid datum)
    1380                 : {
    1381            4186 :     if (list_member_oid(list, datum))
    1382 CBC        1515 :         return list;
    1383                 :     else
    1384            2671 :         return lappend_oid(list, datum);
    1385 ECB             : }
    1386                 : 
    1387                 : /*
    1388                 :  * Append to list1 each member of list2 that isn't already in list1.
    1389                 :  *
    1390                 :  * Whether an element is already a member of the list is determined
    1391                 :  * via equal().
    1392                 :  *
    1393                 :  * This is almost the same functionality as list_union(), but list1 is
    1394                 :  * modified in-place rather than being copied. However, callers of this
    1395                 :  * function may have strict ordering expectations -- i.e. that the relative
    1396                 :  * order of those list2 elements that are not duplicates is preserved.
    1397                 :  *
    1398                 :  * Note that this takes time proportional to the product of the list
    1399                 :  * lengths, so beware of using it on long lists.  (We could probably
    1400                 :  * improve that, but really you should be using some other data structure
    1401                 :  * if this'd be a performance bottleneck.)
    1402                 :  */
    1403                 : List *
    1404 GIC        1241 : list_concat_unique(List *list1, const List *list2)
    1405                 : {
    1406                 :     ListCell   *cell;
    1407 EUB             : 
    1408 GIC        1241 :     Assert(IsPointerList(list1));
    1409 GBC        1241 :     Assert(IsPointerList(list2));
    1410 EUB             : 
    1411 GIC        2348 :     foreach(cell, list2)
    1412 EUB             :     {
    1413 GIC        1107 :         if (!list_member(list1, lfirst(cell)))
    1414            1095 :             list1 = lappend(list1, lfirst(cell));
    1415                 :     }
    1416                 : 
    1417            1241 :     check_list_invariants(list1);
    1418            1241 :     return list1;
    1419 ECB             : }
    1420                 : 
    1421                 : /*
    1422                 :  * This variant of list_concat_unique() determines list membership via
    1423                 :  * simple pointer equality.
    1424                 :  */
    1425                 : List *
    1426 UIC           0 : list_concat_unique_ptr(List *list1, const List *list2)
    1427                 : {
    1428                 :     ListCell   *cell;
    1429                 : 
    1430               0 :     Assert(IsPointerList(list1));
    1431               0 :     Assert(IsPointerList(list2));
    1432                 : 
    1433               0 :     foreach(cell, list2)
    1434                 :     {
    1435               0 :         if (!list_member_ptr(list1, lfirst(cell)))
    1436               0 :             list1 = lappend(list1, lfirst(cell));
    1437                 :     }
    1438                 : 
    1439               0 :     check_list_invariants(list1);
    1440               0 :     return list1;
    1441                 : }
    1442                 : 
    1443                 : /*
    1444 ECB             :  * This variant of list_concat_unique() operates upon lists of integers.
    1445                 :  */
    1446                 : List *
    1447 UIC           0 : list_concat_unique_int(List *list1, const List *list2)
    1448 ECB             : {
    1449                 :     ListCell   *cell;
    1450                 : 
    1451 LBC           0 :     Assert(IsIntegerList(list1));
    1452 UIC           0 :     Assert(IsIntegerList(list2));
    1453 ECB             : 
    1454 LBC           0 :     foreach(cell, list2)
    1455                 :     {
    1456 UIC           0 :         if (!list_member_int(list1, lfirst_int(cell)))
    1457 LBC           0 :             list1 = lappend_int(list1, lfirst_int(cell));
    1458 ECB             :     }
    1459                 : 
    1460 UIC           0 :     check_list_invariants(list1);
    1461               0 :     return list1;
    1462                 : }
    1463                 : 
    1464                 : /*
    1465                 :  * This variant of list_concat_unique() operates upon lists of OIDs.
    1466 EUB             :  */
    1467                 : List *
    1468 GIC       10541 : list_concat_unique_oid(List *list1, const List *list2)
    1469                 : {
    1470 EUB             :     ListCell   *cell;
    1471                 : 
    1472 GIC       10541 :     Assert(IsOidList(list1));
    1473 GBC       10541 :     Assert(IsOidList(list2));
    1474                 : 
    1475           11811 :     foreach(cell, list2)
    1476 EUB             :     {
    1477 GIC        1270 :         if (!list_member_oid(list1, lfirst_oid(cell)))
    1478             908 :             list1 = lappend_oid(list1, lfirst_oid(cell));
    1479 EUB             :     }
    1480                 : 
    1481 GIC       10541 :     check_list_invariants(list1);
    1482           10541 :     return list1;
    1483                 : }
    1484                 : 
    1485                 : /*
    1486                 :  * Remove adjacent duplicates in a list of OIDs.
    1487 EUB             :  *
    1488                 :  * It is caller's responsibility to have sorted the list to bring duplicates
    1489                 :  * together, perhaps via list_sort(list, list_oid_cmp).
    1490                 :  *
    1491                 :  * Note that this takes time proportional to the length of the list.
    1492                 :  */
    1493                 : void
    1494 GBC        1428 : list_deduplicate_oid(List *list)
    1495                 : {
    1496 EUB             :     int         len;
    1497                 : 
    1498 GIC        1428 :     Assert(IsOidList(list));
    1499            1428 :     len = list_length(list);
    1500 GBC        1428 :     if (len > 1)
    1501 EUB             :     {
    1502 GIC         301 :         ListCell   *elements = list->elements;
    1503             301 :         int         i = 0;
    1504                 : 
    1505             910 :         for (int j = 1; j < len; j++)
    1506                 :         {
    1507             609 :             if (elements[i].oid_value != elements[j].oid_value)
    1508 CBC         543 :                 elements[++i].oid_value = elements[j].oid_value;
    1509                 :         }
    1510 GIC         301 :         list->length = i + 1;
    1511                 :     }
    1512 CBC        1428 :     check_list_invariants(list);
    1513            1428 : }
    1514                 : 
    1515 ECB             : /*
    1516                 :  * Free all storage in a list, and optionally the pointed-to elements
    1517                 :  */
    1518                 : static void
    1519 GIC    13175210 : list_free_private(List *list, bool deep)
    1520                 : {
    1521 CBC    13175210 :     if (list == NIL)
    1522         9159886 :         return;                 /* nothing to do */
    1523                 : 
    1524 GIC     4015324 :     check_list_invariants(list);
    1525                 : 
    1526         4015324 :     if (deep)
    1527                 :     {
    1528          616467 :         for (int i = 0; i < list->length; i++)
    1529          480363 :             pfree(lfirst(&list->elements[i]));
    1530                 :     }
    1531         4015324 :     if (list->elements != list->initial_elements)
    1532           49375 :         pfree(list->elements);
    1533         4015324 :     pfree(list);
    1534 ECB             : }
    1535                 : 
    1536                 : /*
    1537                 :  * Free all the cells of the list, as well as the list itself. Any
    1538                 :  * objects that are pointed-to by the cells of the list are NOT
    1539                 :  * free'd.
    1540                 :  *
    1541                 :  * On return, the argument to this function has been freed, so the
    1542                 :  * caller would be wise to set it to NIL for safety's sake.
    1543                 :  */
    1544                 : void
    1545 CBC    12236403 : list_free(List *list)
    1546                 : {
    1547        12236403 :     list_free_private(list, false);
    1548        12236403 : }
    1549                 : 
    1550 ECB             : /*
    1551                 :  * Free all the cells of the list, the list itself, and all the
    1552                 :  * objects pointed-to by the cells of the list (each element in the
    1553                 :  * list must contain a pointer to a palloc()'d region of memory!)
    1554                 :  *
    1555                 :  * On return, the argument to this function has been freed, so the
    1556                 :  * caller would be wise to set it to NIL for safety's sake.
    1557                 :  */
    1558                 : void
    1559 CBC      938807 : list_free_deep(List *list)
    1560                 : {
    1561 ECB             :     /*
    1562                 :      * A "deep" free operation only makes sense on a list of pointers.
    1563                 :      */
    1564 CBC      938807 :     Assert(IsPointerList(list));
    1565 GIC      938807 :     list_free_private(list, true);
    1566 CBC      938807 : }
    1567                 : 
    1568 ECB             : /*
    1569                 :  * Return a shallow copy of the specified list.
    1570                 :  */
    1571                 : List *
    1572 CBC     5311961 : list_copy(const List *oldlist)
    1573 ECB             : {
    1574                 :     List       *newlist;
    1575                 : 
    1576 GIC     5311961 :     if (oldlist == NIL)
    1577          914258 :         return NIL;
    1578                 : 
    1579         4397703 :     newlist = new_list(oldlist->type, oldlist->length);
    1580         4397703 :     memcpy(newlist->elements, oldlist->elements,
    1581         4397703 :            newlist->length * sizeof(ListCell));
    1582                 : 
    1583         4397703 :     check_list_invariants(newlist);
    1584         4397703 :     return newlist;
    1585 ECB             : }
    1586                 : 
    1587                 : /*
    1588                 :  * Return a shallow copy of the specified list containing only the first 'len'
    1589                 :  * elements.  If oldlist is shorter than 'len' then we copy the entire list.
    1590                 :  */
    1591                 : List *
    1592 GIC       27093 : list_copy_head(const List *oldlist, int len)
    1593                 : {
    1594                 :     List       *newlist;
    1595                 : 
    1596           27093 :     len = Min(oldlist->length, len);
    1597                 : 
    1598           27093 :     if (len <= 0)
    1599 LBC           0 :         return NIL;
    1600                 : 
    1601 GIC       27093 :     newlist = new_list(oldlist->type, len);
    1602           27093 :     memcpy(newlist->elements, oldlist->elements, len * sizeof(ListCell));
    1603                 : 
    1604 CBC       27093 :     check_list_invariants(newlist);
    1605           27093 :     return newlist;
    1606 ECB             : }
    1607                 : 
    1608                 : /*
    1609                 :  * Return a shallow copy of the specified list, without the first N elements.
    1610                 :  */
    1611                 : List *
    1612 CBC       82998 : list_copy_tail(const List *oldlist, int nskip)
    1613                 : {
    1614                 :     List       *newlist;
    1615                 : 
    1616           82998 :     if (nskip < 0)
    1617 LBC           0 :         nskip = 0;              /* would it be better to elog? */
    1618                 : 
    1619 CBC       82998 :     if (oldlist == NIL || nskip >= oldlist->length)
    1620             744 :         return NIL;
    1621 ECB             : 
    1622 GIC       82254 :     newlist = new_list(oldlist->type, oldlist->length - nskip);
    1623 CBC       82254 :     memcpy(newlist->elements, &oldlist->elements[nskip],
    1624           82254 :            newlist->length * sizeof(ListCell));
    1625                 : 
    1626 GIC       82254 :     check_list_invariants(newlist);
    1627           82254 :     return newlist;
    1628                 : }
    1629                 : 
    1630                 : /*
    1631                 :  * Return a deep copy of the specified list.
    1632 ECB             :  *
    1633                 :  * The list elements are copied via copyObject(), so that this function's
    1634                 :  * idea of a "deep" copy is considerably deeper than what list_free_deep()
    1635                 :  * means by the same word.
    1636                 :  */
    1637                 : List *
    1638 CBC     1807950 : list_copy_deep(const List *oldlist)
    1639 EUB             : {
    1640                 :     List       *newlist;
    1641 ECB             : 
    1642 CBC     1807950 :     if (oldlist == NIL)
    1643 UIC           0 :         return NIL;
    1644 ECB             : 
    1645                 :     /* This is only sensible for pointer Lists */
    1646 GIC     1807950 :     Assert(IsA(oldlist, List));
    1647                 : 
    1648         1807950 :     newlist = new_list(oldlist->type, oldlist->length);
    1649         7876334 :     for (int i = 0; i < newlist->length; i++)
    1650         6068384 :         lfirst(&newlist->elements[i]) =
    1651         6068384 :             copyObjectImpl(lfirst(&oldlist->elements[i]));
    1652 ECB             : 
    1653 GIC     1807950 :     check_list_invariants(newlist);
    1654         1807950 :     return newlist;
    1655                 : }
    1656 ECB             : 
    1657 EUB             : /*
    1658                 :  * Sort a list according to the specified comparator function.
    1659 ECB             :  *
    1660                 :  * The list is sorted in-place.
    1661                 :  *
    1662                 :  * The comparator function is declared to receive arguments of type
    1663                 :  * const ListCell *; this allows it to use lfirst() and variants
    1664                 :  * without casting its arguments.  Otherwise it behaves the same as
    1665                 :  * the comparator function for standard qsort().
    1666                 :  *
    1667                 :  * Like qsort(), this provides no guarantees about sort stability
    1668                 :  * for equal keys.
    1669                 :  *
    1670                 :  * This is based on qsort(), so it likewise has O(N log N) runtime.
    1671                 :  */
    1672                 : void
    1673 GIC      263161 : list_sort(List *list, list_sort_comparator cmp)
    1674                 : {
    1675                 :     typedef int (*qsort_comparator) (const void *a, const void *b);
    1676                 :     int         len;
    1677                 : 
    1678 CBC      263161 :     check_list_invariants(list);
    1679                 : 
    1680                 :     /* Nothing to do if there's less than two elements */
    1681 GIC      263161 :     len = list_length(list);
    1682 CBC      263161 :     if (len > 1)
    1683 GBC       71686 :         qsort(list->elements, len, sizeof(ListCell), (qsort_comparator) cmp);
    1684 GIC      263161 : }
    1685                 : 
    1686 ECB             : /*
    1687                 :  * list_sort comparator for sorting a list into ascending int order.
    1688                 :  */
    1689                 : int
    1690 CBC          48 : list_int_cmp(const ListCell *p1, const ListCell *p2)
    1691 ECB             : {
    1692 GIC          48 :     int         v1 = lfirst_int(p1);
    1693 CBC          48 :     int         v2 = lfirst_int(p2);
    1694 ECB             : 
    1695 GIC          48 :     if (v1 < v2)
    1696              48 :         return -1;
    1697 UIC           0 :     if (v1 > v2)
    1698               0 :         return 1;
    1699               0 :     return 0;
    1700                 : }
    1701                 : 
    1702                 : /*
    1703                 :  * list_sort comparator for sorting a list into ascending OID order.
    1704                 :  */
    1705                 : int
    1706 GIC       91468 : list_oid_cmp(const ListCell *p1, const ListCell *p2)
    1707                 : {
    1708           91468 :     Oid         v1 = lfirst_oid(p1);
    1709           91468 :     Oid         v2 = lfirst_oid(p2);
    1710                 : 
    1711           91468 :     if (v1 < v2)
    1712           71160 :         return -1;
    1713 CBC       20308 :     if (v1 > v2)
    1714 GIC       20242 :         return 1;
    1715              66 :     return 0;
    1716                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a