]> granicus.if.org Git - postgresql/blob - src/backend/nodes/list.c
ab54d9aa5954133e67ed0a9013f991faa8ac7e38
[postgresql] / src / backend / nodes / list.c
1 /*-------------------------------------------------------------------------
2  *
3  * list.c
4  *        implementation for PostgreSQL generic linked list package
5  *
6  *
7  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.69 2008/01/01 19:45:50 momjian Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include "nodes/pg_list.h"
19
20
21 /*
22  * Routines to simplify writing assertions about the type of a list; a
23  * NIL list is considered to be an empty list of any type.
24  */
25 #define IsPointerList(l)                ((l) == NIL || IsA((l), List))
26 #define IsIntegerList(l)                ((l) == NIL || IsA((l), IntList))
27 #define IsOidList(l)                    ((l) == NIL || IsA((l), OidList))
28
29 #ifdef USE_ASSERT_CHECKING
30 /*
31  * Check that the specified List is valid (so far as we can tell).
32  */
33 static void
34 check_list_invariants(List *list)
35 {
36         if (list == NIL)
37                 return;
38
39         Assert(list->length > 0);
40         Assert(list->head != NULL);
41         Assert(list->tail != NULL);
42
43         Assert(list->type == T_List ||
44                    list->type == T_IntList ||
45                    list->type == T_OidList);
46
47         if (list->length == 1)
48                 Assert(list->head == list->tail);
49         if (list->length == 2)
50                 Assert(list->head->next == list->tail);
51         Assert(list->tail->next == NULL);
52 }
53 #else
54 #define check_list_invariants(l)
55 #endif   /* USE_ASSERT_CHECKING */
56
57 /*
58  * Return a freshly allocated List. Since empty non-NIL lists are
59  * invalid, new_list() also allocates the head cell of the new list:
60  * the caller should be sure to fill in that cell's data.
61  */
62 static List *
63 new_list(NodeTag type)
64 {
65         List       *new_list;
66         ListCell   *new_head;
67
68         new_head = (ListCell *) palloc(sizeof(*new_head));
69         new_head->next = NULL;
70         /* new_head->data is left undefined! */
71
72         new_list = (List *) palloc(sizeof(*new_list));
73         new_list->type = type;
74         new_list->length = 1;
75         new_list->head = new_head;
76         new_list->tail = new_head;
77
78         return new_list;
79 }
80
81 /*
82  * Allocate a new cell and make it the head of the specified
83  * list. Assumes the list it is passed is non-NIL.
84  *
85  * The data in the new head cell is undefined; the caller should be
86  * sure to fill it in
87  */
88 static void
89 new_head_cell(List *list)
90 {
91         ListCell   *new_head;
92
93         new_head = (ListCell *) palloc(sizeof(*new_head));
94         new_head->next = list->head;
95
96         list->head = new_head;
97         list->length++;
98 }
99
100 /*
101  * Allocate a new cell and make it the tail of the specified
102  * list. Assumes the list it is passed is non-NIL.
103  *
104  * The data in the new tail cell is undefined; the caller should be
105  * sure to fill it in
106  */
107 static void
108 new_tail_cell(List *list)
109 {
110         ListCell   *new_tail;
111
112         new_tail = (ListCell *) palloc(sizeof(*new_tail));
113         new_tail->next = NULL;
114
115         list->tail->next = new_tail;
116         list->tail = new_tail;
117         list->length++;
118 }
119
120 /*
121  * Append a pointer to the list. A pointer to the modified list is
122  * returned. Note that this function may or may not destructively
123  * modify the list; callers should always use this function's return
124  * value, rather than continuing to use the pointer passed as the
125  * first argument.
126  */
127 List *
128 lappend(List *list, void *datum)
129 {
130         Assert(IsPointerList(list));
131
132         if (list == NIL)
133                 list = new_list(T_List);
134         else
135                 new_tail_cell(list);
136
137         lfirst(list->tail) = datum;
138         check_list_invariants(list);
139         return list;
140 }
141
142 /*
143  * Append an integer to the specified list. See lappend()
144  */
145 List *
146 lappend_int(List *list, int datum)
147 {
148         Assert(IsIntegerList(list));
149
150         if (list == NIL)
151                 list = new_list(T_IntList);
152         else
153                 new_tail_cell(list);
154
155         lfirst_int(list->tail) = datum;
156         check_list_invariants(list);
157         return list;
158 }
159
160 /*
161  * Append an OID to the specified list. See lappend()
162  */
163 List *
164 lappend_oid(List *list, Oid datum)
165 {
166         Assert(IsOidList(list));
167
168         if (list == NIL)
169                 list = new_list(T_OidList);
170         else
171                 new_tail_cell(list);
172
173         lfirst_oid(list->tail) = datum;
174         check_list_invariants(list);
175         return list;
176 }
177
178 /*
179  * Add a new cell to the list, in the position after 'prev_cell'. The
180  * data in the cell is left undefined, and must be filled in by the
181  * caller. 'list' is assumed to be non-NIL, and 'prev_cell' is assumed
182  * to be non-NULL and a member of 'list'.
183  */
184 static ListCell *
185 add_new_cell(List *list, ListCell *prev_cell)
186 {
187         ListCell   *new_cell;
188
189         new_cell = (ListCell *) palloc(sizeof(*new_cell));
190         /* new_cell->data is left undefined! */
191         new_cell->next = prev_cell->next;
192         prev_cell->next = new_cell;
193
194         if (list->tail == prev_cell)
195                 list->tail = new_cell;
196
197         list->length++;
198
199         return new_cell;
200 }
201
202 /*
203  * Add a new cell to the specified list (which must be non-NIL);
204  * it will be placed after the list cell 'prev' (which must be
205  * non-NULL and a member of 'list'). The data placed in the new cell
206  * is 'datum'. The newly-constructed cell is returned.
207  */
208 ListCell *
209 lappend_cell(List *list, ListCell *prev, void *datum)
210 {
211         ListCell   *new_cell;
212
213         Assert(IsPointerList(list));
214
215         new_cell = add_new_cell(list, prev);
216         lfirst(new_cell) = datum;
217         check_list_invariants(list);
218         return new_cell;
219 }
220
221 ListCell *
222 lappend_cell_int(List *list, ListCell *prev, int datum)
223 {
224         ListCell   *new_cell;
225
226         Assert(IsIntegerList(list));
227
228         new_cell = add_new_cell(list, prev);
229         lfirst_int(new_cell) = datum;
230         check_list_invariants(list);
231         return new_cell;
232 }
233
234 ListCell *
235 lappend_cell_oid(List *list, ListCell *prev, Oid datum)
236 {
237         ListCell   *new_cell;
238
239         Assert(IsOidList(list));
240
241         new_cell = add_new_cell(list, prev);
242         lfirst_oid(new_cell) = datum;
243         check_list_invariants(list);
244         return new_cell;
245 }
246
247 /*
248  * Prepend a new element to the list. A pointer to the modified list
249  * is returned. Note that this function may or may not destructively
250  * modify the list; callers should always use this function's return
251  * value, rather than continuing to use the pointer passed as the
252  * second argument.
253  *
254  * Caution: before Postgres 8.0, the original List was unmodified and
255  * could be considered to retain its separate identity.  This is no longer
256  * the case.
257  */
258 List *
259 lcons(void *datum, List *list)
260 {
261         Assert(IsPointerList(list));
262
263         if (list == NIL)
264                 list = new_list(T_List);
265         else
266                 new_head_cell(list);
267
268         lfirst(list->head) = datum;
269         check_list_invariants(list);
270         return list;
271 }
272
273 /*
274  * Prepend an integer to the list. See lcons()
275  */
276 List *
277 lcons_int(int datum, List *list)
278 {
279         Assert(IsIntegerList(list));
280
281         if (list == NIL)
282                 list = new_list(T_IntList);
283         else
284                 new_head_cell(list);
285
286         lfirst_int(list->head) = datum;
287         check_list_invariants(list);
288         return list;
289 }
290
291 /*
292  * Prepend an OID to the list. See lcons()
293  */
294 List *
295 lcons_oid(Oid datum, List *list)
296 {
297         Assert(IsOidList(list));
298
299         if (list == NIL)
300                 list = new_list(T_OidList);
301         else
302                 new_head_cell(list);
303
304         lfirst_oid(list->head) = datum;
305         check_list_invariants(list);
306         return list;
307 }
308
309 /*
310  * Concatenate list2 to the end of list1, and return list1. list1 is
311  * destructively changed. Callers should be sure to use the return
312  * value as the new pointer to the concatenated list: the 'list1'
313  * input pointer may or may not be the same as the returned pointer.
314  *
315  * The nodes in list2 are merely appended to the end of list1 in-place
316  * (i.e. they aren't copied; the two lists will share some of the same
317  * storage). Therefore, invoking list_free() on list2 will also
318  * invalidate a portion of list1.
319  */
320 List *
321 list_concat(List *list1, List *list2)
322 {
323         if (list1 == NIL)
324                 return list2;
325         if (list2 == NIL)
326                 return list1;
327         if (list1 == list2)
328                 elog(ERROR, "cannot list_concat() a list to itself");
329
330         Assert(list1->type == list2->type);
331
332         list1->length += list2->length;
333         list1->tail->next = list2->head;
334         list1->tail = list2->tail;
335
336         check_list_invariants(list1);
337         return list1;
338 }
339
340 /*
341  * Truncate 'list' to contain no more than 'new_size' elements. This
342  * modifies the list in-place! Despite this, callers should use the
343  * pointer returned by this function to refer to the newly truncated
344  * list -- it may or may not be the same as the pointer that was
345  * passed.
346  *
347  * Note that any cells removed by list_truncate() are NOT pfree'd.
348  */
349 List *
350 list_truncate(List *list, int new_size)
351 {
352         ListCell   *cell;
353         int                     n;
354
355         if (new_size <= 0)
356                 return NIL;                             /* truncate to zero length */
357
358         /* If asked to effectively extend the list, do nothing */
359         if (new_size >= list_length(list))
360                 return list;
361
362         n = 1;
363         foreach(cell, list)
364         {
365                 if (n == new_size)
366                 {
367                         cell->next = NULL;
368                         list->tail = cell;
369                         list->length = new_size;
370                         check_list_invariants(list);
371                         return list;
372                 }
373                 n++;
374         }
375
376         /* keep the compiler quiet; never reached */
377         Assert(false);
378         return list;
379 }
380
381 /*
382  * Locate the n'th cell (counting from 0) of the list.  It is an assertion
383  * failure if there is no such cell.
384  */
385 static ListCell *
386 list_nth_cell(List *list, int n)
387 {
388         ListCell   *match;
389
390         Assert(list != NIL);
391         Assert(n >= 0);
392         Assert(n < list->length);
393         check_list_invariants(list);
394
395         /* Does the caller actually mean to fetch the tail? */
396         if (n == list->length - 1)
397                 return list->tail;
398
399         for (match = list->head; n-- > 0; match = match->next)
400                 ;
401
402         return match;
403 }
404
405 /*
406  * Return the data value contained in the n'th element of the
407  * specified list. (List elements begin at 0.)
408  */
409 void *
410 list_nth(List *list, int n)
411 {
412         Assert(IsPointerList(list));
413         return lfirst(list_nth_cell(list, n));
414 }
415
416 /*
417  * Return the integer value contained in the n'th element of the
418  * specified list.
419  */
420 int
421 list_nth_int(List *list, int n)
422 {
423         Assert(IsIntegerList(list));
424         return lfirst_int(list_nth_cell(list, n));
425 }
426
427 /*
428  * Return the OID value contained in the n'th element of the specified
429  * list.
430  */
431 Oid
432 list_nth_oid(List *list, int n)
433 {
434         Assert(IsOidList(list));
435         return lfirst_oid(list_nth_cell(list, n));
436 }
437
438 /*
439  * Return true iff 'datum' is a member of the list. Equality is
440  * determined via equal(), so callers should ensure that they pass a
441  * Node as 'datum'.
442  */
443 bool
444 list_member(List *list, void *datum)
445 {
446         ListCell   *cell;
447
448         Assert(IsPointerList(list));
449         check_list_invariants(list);
450
451         foreach(cell, list)
452         {
453                 if (equal(lfirst(cell), datum))
454                         return true;
455         }
456
457         return false;
458 }
459
460 /*
461  * Return true iff 'datum' is a member of the list. Equality is
462  * determined by using simple pointer comparison.
463  */
464 bool
465 list_member_ptr(List *list, void *datum)
466 {
467         ListCell   *cell;
468
469         Assert(IsPointerList(list));
470         check_list_invariants(list);
471
472         foreach(cell, list)
473         {
474                 if (lfirst(cell) == datum)
475                         return true;
476         }
477
478         return false;
479 }
480
481 /*
482  * Return true iff the integer 'datum' is a member of the list.
483  */
484 bool
485 list_member_int(List *list, int datum)
486 {
487         ListCell   *cell;
488
489         Assert(IsIntegerList(list));
490         check_list_invariants(list);
491
492         foreach(cell, list)
493         {
494                 if (lfirst_int(cell) == datum)
495                         return true;
496         }
497
498         return false;
499 }
500
501 /*
502  * Return true iff the OID 'datum' is a member of the list.
503  */
504 bool
505 list_member_oid(List *list, Oid datum)
506 {
507         ListCell   *cell;
508
509         Assert(IsOidList(list));
510         check_list_invariants(list);
511
512         foreach(cell, list)
513         {
514                 if (lfirst_oid(cell) == datum)
515                         return true;
516         }
517
518         return false;
519 }
520
521 /*
522  * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell'
523  * in 'list', if any (i.e. prev == NULL iff list->head == cell)
524  *
525  * The cell is pfree'd, as is the List header if this was the last member.
526  */
527 List *
528 list_delete_cell(List *list, ListCell *cell, ListCell *prev)
529 {
530         check_list_invariants(list);
531         Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell);
532
533         /*
534          * If we're about to delete the last node from the list, free the whole
535          * list instead and return NIL, which is the only valid representation of
536          * a zero-length list.
537          */
538         if (list->length == 1)
539         {
540                 list_free(list);
541                 return NIL;
542         }
543
544         /*
545          * Otherwise, adjust the necessary list links, deallocate the particular
546          * node we have just removed, and return the list we were given.
547          */
548         list->length--;
549
550         if (prev)
551                 prev->next = cell->next;
552         else
553                 list->head = cell->next;
554
555         if (list->tail == cell)
556                 list->tail = prev;
557
558         pfree(cell);
559         return list;
560 }
561
562 /*
563  * Delete the first cell in list that matches datum, if any.
564  * Equality is determined via equal().
565  */
566 List *
567 list_delete(List *list, void *datum)
568 {
569         ListCell   *cell;
570         ListCell   *prev;
571
572         Assert(IsPointerList(list));
573         check_list_invariants(list);
574
575         prev = NULL;
576         foreach(cell, list)
577         {
578                 if (equal(lfirst(cell), datum))
579                         return list_delete_cell(list, cell, prev);
580
581                 prev = cell;
582         }
583
584         /* Didn't find a match: return the list unmodified */
585         return list;
586 }
587
588 /* As above, but use simple pointer equality */
589 List *
590 list_delete_ptr(List *list, void *datum)
591 {
592         ListCell   *cell;
593         ListCell   *prev;
594
595         Assert(IsPointerList(list));
596         check_list_invariants(list);
597
598         prev = NULL;
599         foreach(cell, list)
600         {
601                 if (lfirst(cell) == datum)
602                         return list_delete_cell(list, cell, prev);
603
604                 prev = cell;
605         }
606
607         /* Didn't find a match: return the list unmodified */
608         return list;
609 }
610
611 /* As above, but for integers */
612 List *
613 list_delete_int(List *list, int datum)
614 {
615         ListCell   *cell;
616         ListCell   *prev;
617
618         Assert(IsIntegerList(list));
619         check_list_invariants(list);
620
621         prev = NULL;
622         foreach(cell, list)
623         {
624                 if (lfirst_int(cell) == datum)
625                         return list_delete_cell(list, cell, prev);
626
627                 prev = cell;
628         }
629
630         /* Didn't find a match: return the list unmodified */
631         return list;
632 }
633
634 /* As above, but for OIDs */
635 List *
636 list_delete_oid(List *list, Oid datum)
637 {
638         ListCell   *cell;
639         ListCell   *prev;
640
641         Assert(IsOidList(list));
642         check_list_invariants(list);
643
644         prev = NULL;
645         foreach(cell, list)
646         {
647                 if (lfirst_oid(cell) == datum)
648                         return list_delete_cell(list, cell, prev);
649
650                 prev = cell;
651         }
652
653         /* Didn't find a match: return the list unmodified */
654         return list;
655 }
656
657 /*
658  * Delete the first element of the list.
659  *
660  * This is useful to replace the Lisp-y code "list = lnext(list);" in cases
661  * where the intent is to alter the list rather than just traverse it.
662  * Beware that the removed cell is freed, whereas the lnext() coding leaves
663  * the original list head intact if there's another pointer to it.
664  */
665 List *
666 list_delete_first(List *list)
667 {
668         check_list_invariants(list);
669
670         if (list == NIL)
671                 return NIL;                             /* would an error be better? */
672
673         return list_delete_cell(list, list_head(list), NULL);
674 }
675
676 /*
677  * Generate the union of two lists. This is calculated by copying
678  * list1 via list_copy(), then adding to it all the members of list2
679  * that aren't already in list1.
680  *
681  * Whether an element is already a member of the list is determined
682  * via equal().
683  *
684  * The returned list is newly-allocated, although the content of the
685  * cells is the same (i.e. any pointed-to objects are not copied).
686  *
687  * NB: this function will NOT remove any duplicates that are present
688  * in list1 (so it only performs a "union" if list1 is known unique to
689  * start with).  Also, if you are about to write "x = list_union(x, y)"
690  * you probably want to use list_concat_unique() instead to avoid wasting
691  * the list cells of the old x list.
692  *
693  * This function could probably be implemented a lot faster if it is a
694  * performance bottleneck.
695  */
696 List *
697 list_union(List *list1, List *list2)
698 {
699         List       *result;
700         ListCell   *cell;
701
702         Assert(IsPointerList(list1));
703         Assert(IsPointerList(list2));
704
705         result = list_copy(list1);
706         foreach(cell, list2)
707         {
708                 if (!list_member(result, lfirst(cell)))
709                         result = lappend(result, lfirst(cell));
710         }
711
712         check_list_invariants(result);
713         return result;
714 }
715
716 /*
717  * This variant of list_union() determines duplicates via simple
718  * pointer comparison.
719  */
720 List *
721 list_union_ptr(List *list1, List *list2)
722 {
723         List       *result;
724         ListCell   *cell;
725
726         Assert(IsPointerList(list1));
727         Assert(IsPointerList(list2));
728
729         result = list_copy(list1);
730         foreach(cell, list2)
731         {
732                 if (!list_member_ptr(result, lfirst(cell)))
733                         result = lappend(result, lfirst(cell));
734         }
735
736         check_list_invariants(result);
737         return result;
738 }
739
740 /*
741  * This variant of list_union() operates upon lists of integers.
742  */
743 List *
744 list_union_int(List *list1, List *list2)
745 {
746         List       *result;
747         ListCell   *cell;
748
749         Assert(IsIntegerList(list1));
750         Assert(IsIntegerList(list2));
751
752         result = list_copy(list1);
753         foreach(cell, list2)
754         {
755                 if (!list_member_int(result, lfirst_int(cell)))
756                         result = lappend_int(result, lfirst_int(cell));
757         }
758
759         check_list_invariants(result);
760         return result;
761 }
762
763 /*
764  * This variant of list_union() operates upon lists of OIDs.
765  */
766 List *
767 list_union_oid(List *list1, List *list2)
768 {
769         List       *result;
770         ListCell   *cell;
771
772         Assert(IsOidList(list1));
773         Assert(IsOidList(list2));
774
775         result = list_copy(list1);
776         foreach(cell, list2)
777         {
778                 if (!list_member_oid(result, lfirst_oid(cell)))
779                         result = lappend_oid(result, lfirst_oid(cell));
780         }
781
782         check_list_invariants(result);
783         return result;
784 }
785
786 /*
787  * Return a list that contains all the cells in list1 that are not in
788  * list2. The returned list is freshly allocated via palloc(), but the
789  * cells themselves point to the same objects as the cells of the
790  * input lists.
791  *
792  * This variant works on lists of pointers, and determines list
793  * membership via equal()
794  */
795 List *
796 list_difference(List *list1, List *list2)
797 {
798         ListCell   *cell;
799         List       *result = NIL;
800
801         Assert(IsPointerList(list1));
802         Assert(IsPointerList(list2));
803
804         if (list2 == NIL)
805                 return list_copy(list1);
806
807         foreach(cell, list1)
808         {
809                 if (!list_member(list2, lfirst(cell)))
810                         result = lappend(result, lfirst(cell));
811         }
812
813         check_list_invariants(result);
814         return result;
815 }
816
817 /*
818  * This variant of list_difference() determines list membership via
819  * simple pointer equality.
820  */
821 List *
822 list_difference_ptr(List *list1, List *list2)
823 {
824         ListCell   *cell;
825         List       *result = NIL;
826
827         Assert(IsPointerList(list1));
828         Assert(IsPointerList(list2));
829
830         if (list2 == NIL)
831                 return list_copy(list1);
832
833         foreach(cell, list1)
834         {
835                 if (!list_member_ptr(list2, lfirst(cell)))
836                         result = lappend(result, lfirst(cell));
837         }
838
839         check_list_invariants(result);
840         return result;
841 }
842
843 /*
844  * This variant of list_difference() operates upon lists of integers.
845  */
846 List *
847 list_difference_int(List *list1, List *list2)
848 {
849         ListCell   *cell;
850         List       *result = NIL;
851
852         Assert(IsIntegerList(list1));
853         Assert(IsIntegerList(list2));
854
855         if (list2 == NIL)
856                 return list_copy(list1);
857
858         foreach(cell, list1)
859         {
860                 if (!list_member_int(list2, lfirst_int(cell)))
861                         result = lappend_int(result, lfirst_int(cell));
862         }
863
864         check_list_invariants(result);
865         return result;
866 }
867
868 /*
869  * This variant of list_difference() operates upon lists of OIDs.
870  */
871 List *
872 list_difference_oid(List *list1, List *list2)
873 {
874         ListCell   *cell;
875         List       *result = NIL;
876
877         Assert(IsOidList(list1));
878         Assert(IsOidList(list2));
879
880         if (list2 == NIL)
881                 return list_copy(list1);
882
883         foreach(cell, list1)
884         {
885                 if (!list_member_oid(list2, lfirst_oid(cell)))
886                         result = lappend_oid(result, lfirst_oid(cell));
887         }
888
889         check_list_invariants(result);
890         return result;
891 }
892
893 /*
894  * Append datum to list, but only if it isn't already in the list.
895  *
896  * Whether an element is already a member of the list is determined
897  * via equal().
898  */
899 List *
900 list_append_unique(List *list, void *datum)
901 {
902         if (list_member(list, datum))
903                 return list;
904         else
905                 return lappend(list, datum);
906 }
907
908 /*
909  * This variant of list_append_unique() determines list membership via
910  * simple pointer equality.
911  */
912 List *
913 list_append_unique_ptr(List *list, void *datum)
914 {
915         if (list_member_ptr(list, datum))
916                 return list;
917         else
918                 return lappend(list, datum);
919 }
920
921 /*
922  * This variant of list_append_unique() operates upon lists of integers.
923  */
924 List *
925 list_append_unique_int(List *list, int datum)
926 {
927         if (list_member_int(list, datum))
928                 return list;
929         else
930                 return lappend_int(list, datum);
931 }
932
933 /*
934  * This variant of list_append_unique() operates upon lists of OIDs.
935  */
936 List *
937 list_append_unique_oid(List *list, Oid datum)
938 {
939         if (list_member_oid(list, datum))
940                 return list;
941         else
942                 return lappend_oid(list, datum);
943 }
944
945 /*
946  * Append to list1 each member of list2 that isn't already in list1.
947  *
948  * Whether an element is already a member of the list is determined
949  * via equal().
950  *
951  * This is almost the same functionality as list_union(), but list1 is
952  * modified in-place rather than being copied.  Note also that list2's cells
953  * are not inserted in list1, so the analogy to list_concat() isn't perfect.
954  */
955 List *
956 list_concat_unique(List *list1, List *list2)
957 {
958         ListCell   *cell;
959
960         Assert(IsPointerList(list1));
961         Assert(IsPointerList(list2));
962
963         foreach(cell, list2)
964         {
965                 if (!list_member(list1, lfirst(cell)))
966                         list1 = lappend(list1, lfirst(cell));
967         }
968
969         check_list_invariants(list1);
970         return list1;
971 }
972
973 /*
974  * This variant of list_concat_unique() determines list membership via
975  * simple pointer equality.
976  */
977 List *
978 list_concat_unique_ptr(List *list1, List *list2)
979 {
980         ListCell   *cell;
981
982         Assert(IsPointerList(list1));
983         Assert(IsPointerList(list2));
984
985         foreach(cell, list2)
986         {
987                 if (!list_member_ptr(list1, lfirst(cell)))
988                         list1 = lappend(list1, lfirst(cell));
989         }
990
991         check_list_invariants(list1);
992         return list1;
993 }
994
995 /*
996  * This variant of list_concat_unique() operates upon lists of integers.
997  */
998 List *
999 list_concat_unique_int(List *list1, List *list2)
1000 {
1001         ListCell   *cell;
1002
1003         Assert(IsIntegerList(list1));
1004         Assert(IsIntegerList(list2));
1005
1006         foreach(cell, list2)
1007         {
1008                 if (!list_member_int(list1, lfirst_int(cell)))
1009                         list1 = lappend_int(list1, lfirst_int(cell));
1010         }
1011
1012         check_list_invariants(list1);
1013         return list1;
1014 }
1015
1016 /*
1017  * This variant of list_concat_unique() operates upon lists of OIDs.
1018  */
1019 List *
1020 list_concat_unique_oid(List *list1, List *list2)
1021 {
1022         ListCell   *cell;
1023
1024         Assert(IsOidList(list1));
1025         Assert(IsOidList(list2));
1026
1027         foreach(cell, list2)
1028         {
1029                 if (!list_member_oid(list1, lfirst_oid(cell)))
1030                         list1 = lappend_oid(list1, lfirst_oid(cell));
1031         }
1032
1033         check_list_invariants(list1);
1034         return list1;
1035 }
1036
1037 /*
1038  * Free all storage in a list, and optionally the pointed-to elements
1039  */
1040 static void
1041 list_free_private(List *list, bool deep)
1042 {
1043         ListCell   *cell;
1044
1045         check_list_invariants(list);
1046
1047         cell = list_head(list);
1048         while (cell != NULL)
1049         {
1050                 ListCell   *tmp = cell;
1051
1052                 cell = lnext(cell);
1053                 if (deep)
1054                         pfree(lfirst(tmp));
1055                 pfree(tmp);
1056         }
1057
1058         if (list)
1059                 pfree(list);
1060 }
1061
1062 /*
1063  * Free all the cells of the list, as well as the list itself. Any
1064  * objects that are pointed-to by the cells of the list are NOT
1065  * free'd.
1066  *
1067  * On return, the argument to this function has been freed, so the
1068  * caller would be wise to set it to NIL for safety's sake.
1069  */
1070 void
1071 list_free(List *list)
1072 {
1073         list_free_private(list, false);
1074 }
1075
1076 /*
1077  * Free all the cells of the list, the list itself, and all the
1078  * objects pointed-to by the cells of the list (each element in the
1079  * list must contain a pointer to a palloc()'d region of memory!)
1080  *
1081  * On return, the argument to this function has been freed, so the
1082  * caller would be wise to set it to NIL for safety's sake.
1083  */
1084 void
1085 list_free_deep(List *list)
1086 {
1087         /*
1088          * A "deep" free operation only makes sense on a list of pointers.
1089          */
1090         Assert(IsPointerList(list));
1091         list_free_private(list, true);
1092 }
1093
1094 /*
1095  * Return a shallow copy of the specified list.
1096  */
1097 List *
1098 list_copy(List *oldlist)
1099 {
1100         List       *newlist;
1101         ListCell   *newlist_prev;
1102         ListCell   *oldlist_cur;
1103
1104         if (oldlist == NIL)
1105                 return NIL;
1106
1107         newlist = new_list(oldlist->type);
1108         newlist->length = oldlist->length;
1109
1110         /*
1111          * Copy over the data in the first cell; new_list() has already allocated
1112          * the head cell itself
1113          */
1114         newlist->head->data = oldlist->head->data;
1115
1116         newlist_prev = newlist->head;
1117         oldlist_cur = oldlist->head->next;
1118         while (oldlist_cur)
1119         {
1120                 ListCell   *newlist_cur;
1121
1122                 newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
1123                 newlist_cur->data = oldlist_cur->data;
1124                 newlist_prev->next = newlist_cur;
1125
1126                 newlist_prev = newlist_cur;
1127                 oldlist_cur = oldlist_cur->next;
1128         }
1129
1130         newlist_prev->next = NULL;
1131         newlist->tail = newlist_prev;
1132
1133         check_list_invariants(newlist);
1134         return newlist;
1135 }
1136
1137 /*
1138  * Return a shallow copy of the specified list, without the first N elements.
1139  */
1140 List *
1141 list_copy_tail(List *oldlist, int nskip)
1142 {
1143         List       *newlist;
1144         ListCell   *newlist_prev;
1145         ListCell   *oldlist_cur;
1146
1147         if (nskip < 0)
1148                 nskip = 0;                              /* would it be better to elog? */
1149
1150         if (oldlist == NIL || nskip >= oldlist->length)
1151                 return NIL;
1152
1153         newlist = new_list(oldlist->type);
1154         newlist->length = oldlist->length - nskip;
1155
1156         /*
1157          * Skip over the unwanted elements.
1158          */
1159         oldlist_cur = oldlist->head;
1160         while (nskip-- > 0)
1161                 oldlist_cur = oldlist_cur->next;
1162
1163         /*
1164          * Copy over the data in the first remaining cell; new_list() has already
1165          * allocated the head cell itself
1166          */
1167         newlist->head->data = oldlist_cur->data;
1168
1169         newlist_prev = newlist->head;
1170         oldlist_cur = oldlist_cur->next;
1171         while (oldlist_cur)
1172         {
1173                 ListCell   *newlist_cur;
1174
1175                 newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
1176                 newlist_cur->data = oldlist_cur->data;
1177                 newlist_prev->next = newlist_cur;
1178
1179                 newlist_prev = newlist_cur;
1180                 oldlist_cur = oldlist_cur->next;
1181         }
1182
1183         newlist_prev->next = NULL;
1184         newlist->tail = newlist_prev;
1185
1186         check_list_invariants(newlist);
1187         return newlist;
1188 }
1189
1190 /*
1191  * When using non-GCC compilers, we can't define these as inline
1192  * functions in pg_list.h, so they are defined here.
1193  *
1194  * TODO: investigate supporting inlining for some non-GCC compilers.
1195  */
1196 #ifndef __GNUC__
1197
1198 ListCell *
1199 list_head(List *l)
1200 {
1201         return l ? l->head : NULL;
1202 }
1203
1204 ListCell *
1205 list_tail(List *l)
1206 {
1207         return l ? l->tail : NULL;
1208 }
1209
1210 int
1211 list_length(List *l)
1212 {
1213         return l ? l->length : 0;
1214 }
1215 #endif   /* ! __GNUC__ */
1216
1217 /*
1218  * Temporary compatibility functions
1219  *
1220  * In order to avoid warnings for these function definitions, we need
1221  * to include a prototype here as well as in pg_list.h. That's because
1222  * we don't enable list API compatibility in list.c, so we
1223  * don't see the prototypes for these functions.
1224  */
1225
1226 /*
1227  * Given a list, return its length. This is merely defined for the
1228  * sake of backward compatibility: we can't afford to define a macro
1229  * called "length", so it must be a function. New code should use the
1230  * list_length() macro in order to avoid the overhead of a function
1231  * call.
1232  */
1233 int                     length(List *list);
1234
1235 int
1236 length(List *list)
1237 {
1238         return list_length(list);
1239 }