PostgreSQL Source Code git master
Loading...
Searching...
No Matches
bitmapset.c File Reference
#include "postgres.h"
#include "common/hashfn.h"
#include "nodes/bitmapset.h"
#include "nodes/pg_list.h"
#include "port/pg_bitutils.h"
Include dependency graph for bitmapset.c:

Go to the source code of this file.

Macros

#define WORDNUM(x)   ((x) / BITS_PER_BITMAPWORD)
 
#define BITNUM(x)   ((x) % BITS_PER_BITMAPWORD)
 
#define BITMAPSET_SIZE(nwords)    (offsetof(Bitmapset, words) + (nwords) * sizeof(bitmapword))
 
#define RIGHTMOST_ONE(x)   ((signedbitmapword) (x) & -((signedbitmapword) (x)))
 
#define HAS_MULTIPLE_ONES(x)   ((bitmapword) RIGHTMOST_ONE(x) != (x))
 

Functions

Bitmapsetbms_copy (const Bitmapset *a)
 
bool bms_equal (const Bitmapset *a, const Bitmapset *b)
 
int bms_compare (const Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_make_singleton (int x)
 
void bms_free (Bitmapset *a)
 
Bitmapsetbms_union (const Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_intersect (const Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_difference (const Bitmapset *a, const Bitmapset *b)
 
bool bms_is_subset (const Bitmapset *a, const Bitmapset *b)
 
BMS_Comparison bms_subset_compare (const Bitmapset *a, const Bitmapset *b)
 
bool bms_is_member (int x, const Bitmapset *a)
 
int bms_member_index (Bitmapset *a, int x)
 
bool bms_overlap (const Bitmapset *a, const Bitmapset *b)
 
bool bms_overlap_list (const Bitmapset *a, const List *b)
 
bool bms_nonempty_difference (const Bitmapset *a, const Bitmapset *b)
 
int bms_singleton_member (const Bitmapset *a)
 
bool bms_get_singleton_member (const Bitmapset *a, int *member)
 
int bms_num_members (const Bitmapset *a)
 
BMS_Membership bms_membership (const Bitmapset *a)
 
Bitmapsetbms_add_member (Bitmapset *a, int x)
 
Bitmapsetbms_del_member (Bitmapset *a, int x)
 
Bitmapsetbms_add_members (Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_replace_members (Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_add_range (Bitmapset *a, int lower, int upper)
 
Bitmapsetbms_int_members (Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_del_members (Bitmapset *a, const Bitmapset *b)
 
Bitmapsetbms_join (Bitmapset *a, Bitmapset *b)
 
int bms_next_member (const Bitmapset *a, int prevbit)
 
int bms_prev_member (const Bitmapset *a, int prevbit)
 
uint32 bms_hash_value (const Bitmapset *a)
 
uint32 bitmap_hash (const void *key, Size keysize)
 
int bitmap_match (const void *key1, const void *key2, Size keysize)
 

Macro Definition Documentation

◆ BITMAPSET_SIZE

#define BITMAPSET_SIZE (   nwords)     (offsetof(Bitmapset, words) + (nwords) * sizeof(bitmapword))

Definition at line 50 of file bitmapset.c.

79{
80 /* NULL is the correct representation of an empty set */
81 if (a == NULL)
82 return true;
83
84 /* check the node tag is set correctly. pfree'd pointer, maybe? */
85 if (!IsA(a, Bitmapset))
86 return false;
87
88 /* trailing zero words are not allowed */
89 if (a->words[a->nwords - 1] == 0)
90 return false;
91
92 return true;
93}
94#endif
95
96#ifdef REALLOCATE_BITMAPSETS
97/*
98 * bms_copy_and_free
99 * Only required in REALLOCATE_BITMAPSETS builds. Provide a simple way
100 * to return a freshly allocated set and pfree the original.
101 *
102 * Note: callers which accept multiple sets must be careful when calling this
103 * function to clone one parameter as other parameters may point to the same
104 * set. A good option is to call this just before returning the resulting
105 * set.
106 */
107static Bitmapset *
109{
110 Bitmapset *c = bms_copy(a);
111
112 bms_free(a);
113 return c;
114}
115#endif
116
117/*
118 * bms_copy - make a palloc'd copy of a bitmapset
119 */
120Bitmapset *
121bms_copy(const Bitmapset *a)
122{
123 Bitmapset *result;
124 size_t size;
125
127
128 if (a == NULL)
129 return NULL;
130
131 size = BITMAPSET_SIZE(a->nwords);
132 result = (Bitmapset *) palloc(size);
133 memcpy(result, a, size);
134 return result;
135}
136
137/*
138 * bms_equal - are two bitmapsets equal? or both NULL?
139 */
140bool
141bms_equal(const Bitmapset *a, const Bitmapset *b)
142{
143 int i;
144
147
148 /* Handle cases where either input is NULL */
149 if (a == NULL)
150 {
151 if (b == NULL)
152 return true;
153 return false;
154 }
155 else if (b == NULL)
156 return false;
157
158 /* can't be equal if the word counts don't match */
159 if (a->nwords != b->nwords)
160 return false;
161
162 /* check each word matches */
163 i = 0;
164 do
165 {
166 if (a->words[i] != b->words[i])
167 return false;
168 } while (++i < a->nwords);
169
170 return true;
171}
172
173/*
174 * bms_compare - qsort-style comparator for bitmapsets
175 *
176 * This guarantees to report values as equal iff bms_equal would say they are
177 * equal. Otherwise, the highest-numbered bit that is set in one value but
178 * not the other determines the result. (This rule means that, for example,
179 * {6} is greater than {5}, which seems plausible.)
180 */
181int
182bms_compare(const Bitmapset *a, const Bitmapset *b)
183{
184 int i;
185
188
189 /* Handle cases where either input is NULL */
190 if (a == NULL)
191 return (b == NULL) ? 0 : -1;
192 else if (b == NULL)
193 return +1;
194
195 /* the set with the most words must be greater */
196 if (a->nwords != b->nwords)
197 return (a->nwords > b->nwords) ? +1 : -1;
198
199 i = a->nwords - 1;
200 do
201 {
202 bitmapword aw = a->words[i];
203 bitmapword bw = b->words[i];
204
205 if (aw != bw)
206 return (aw > bw) ? +1 : -1;
207 } while (--i >= 0);
208 return 0;
209}
210
211/*
212 * bms_make_singleton - build a bitmapset containing a single member
213 */
214Bitmapset *
216{
217 Bitmapset *result;
218 int wordnum,
219 bitnum;
220
221 if (x < 0)
222 elog(ERROR, "negative bitmapset member not allowed");
223 wordnum = WORDNUM(x);
224 bitnum = BITNUM(x);
225 result = (Bitmapset *) palloc0(BITMAPSET_SIZE(wordnum + 1));
226 result->type = T_Bitmapset;
227 result->nwords = wordnum + 1;
228 result->words[wordnum] = ((bitmapword) 1 << bitnum);
229 return result;
230}
231
232/*
233 * bms_free - free a bitmapset
234 *
235 * Same as pfree except for allowing NULL input
236 */
237void
239{
240 if (a)
241 pfree(a);
242}
243
244
245/*
246 * bms_union - create and return a new set containing all members from both
247 * input sets. Both inputs are left unmodified.
248 */
249Bitmapset *
250bms_union(const Bitmapset *a, const Bitmapset *b)
251{
252 Bitmapset *result;
253 const Bitmapset *other;
254 int otherlen;
255 int i;
256
259
260 /* Handle cases where either input is NULL */
261 if (a == NULL)
262 return bms_copy(b);
263 if (b == NULL)
264 return bms_copy(a);
265 /* Identify shorter and longer input; copy the longer one */
266 if (a->nwords <= b->nwords)
267 {
268 result = bms_copy(b);
269 other = a;
270 }
271 else
272 {
273 result = bms_copy(a);
274 other = b;
275 }
276 /* And union the shorter input into the result */
277 otherlen = other->nwords;
278 i = 0;
279 do
280 {
281 result->words[i] |= other->words[i];
282 } while (++i < otherlen);
283 return result;
284}
285
286/*
287 * bms_intersect - create and return a new set containing members which both
288 * input sets have in common. Both inputs are left unmodified.
289 */
290Bitmapset *
291bms_intersect(const Bitmapset *a, const Bitmapset *b)
292{
293 Bitmapset *result;
294 const Bitmapset *other;
295 int lastnonzero;
296 int resultlen;
297 int i;
298
301
302 /* Handle cases where either input is NULL */
303 if (a == NULL || b == NULL)
304 return NULL;
305
306 /* Identify shorter and longer input; copy the shorter one */
307 if (a->nwords <= b->nwords)
308 {
309 result = bms_copy(a);
310 other = b;
311 }
312 else
313 {
314 result = bms_copy(b);
315 other = a;
316 }
317 /* And intersect the longer input with the result */
318 resultlen = result->nwords;
319 lastnonzero = -1;
320 i = 0;
321 do
322 {
323 result->words[i] &= other->words[i];
324
325 if (result->words[i] != 0)
326 lastnonzero = i;
327 } while (++i < resultlen);
328 /* If we computed an empty result, we must return NULL */
329 if (lastnonzero == -1)
330 {
331 pfree(result);
332 return NULL;
333 }
334
335 /* get rid of trailing zero words */
336 result->nwords = lastnonzero + 1;
337 return result;
338}
339
340/*
341 * bms_difference - create and return a new set containing all the members of
342 * 'a' without the members of 'b'.
343 */
344Bitmapset *
345bms_difference(const Bitmapset *a, const Bitmapset *b)
346{
347 Bitmapset *result;
348 int i;
349
352
353 /* Handle cases where either input is NULL */
354 if (a == NULL)
355 return NULL;
356 if (b == NULL)
357 return bms_copy(a);
358
359 /*
360 * In Postgres' usage, an empty result is a very common case, so it's
361 * worth optimizing for that by testing bms_nonempty_difference(). This
362 * saves us a palloc/pfree cycle compared to checking after-the-fact.
363 */
365 return NULL;
366
367 /* Copy the left input */
368 result = bms_copy(a);
369
370 /* And remove b's bits from result */
371 if (result->nwords > b->nwords)
372 {
373 /*
374 * We'll never need to remove trailing zero words when 'a' has more
375 * words than 'b' as the additional words must be non-zero.
376 */
377 i = 0;
378 do
379 {
380 result->words[i] &= ~b->words[i];
381 } while (++i < b->nwords);
382 }
383 else
384 {
385 int lastnonzero = -1;
386
387 /* we may need to remove trailing zero words from the result. */
388 i = 0;
389 do
390 {
391 result->words[i] &= ~b->words[i];
392
393 /* remember the last non-zero word */
394 if (result->words[i] != 0)
395 lastnonzero = i;
396 } while (++i < result->nwords);
397
398 /* trim off trailing zero words */
399 result->nwords = lastnonzero + 1;
400 }
401 Assert(result->nwords != 0);
402
403 /* Need not check for empty result, since we handled that case above */
404 return result;
405}
406
407/*
408 * bms_is_subset - is A a subset of B?
409 */
410bool
411bms_is_subset(const Bitmapset *a, const Bitmapset *b)
412{
413 int i;
414
417
418 /* Handle cases where either input is NULL */
419 if (a == NULL)
420 return true; /* empty set is a subset of anything */
421 if (b == NULL)
422 return false;
423
424 /* 'a' can't be a subset of 'b' if it contains more words */
425 if (a->nwords > b->nwords)
426 return false;
427
428 /* Check all 'a' members are set in 'b' */
429 i = 0;
430 do
431 {
432 if ((a->words[i] & ~b->words[i]) != 0)
433 return false;
434 } while (++i < a->nwords);
435 return true;
436}
437
438/*
439 * bms_subset_compare - compare A and B for equality/subset relationships
440 *
441 * This is more efficient than testing bms_is_subset in both directions.
442 */
445{
446 BMS_Comparison result;
447 int shortlen;
448 int i;
449
452
453 /* Handle cases where either input is NULL */
454 if (a == NULL)
455 {
456 if (b == NULL)
457 return BMS_EQUAL;
458 return BMS_SUBSET1;
459 }
460 if (b == NULL)
461 return BMS_SUBSET2;
462
463 /* Check common words */
464 result = BMS_EQUAL; /* status so far */
465 shortlen = Min(a->nwords, b->nwords);
466 i = 0;
467 do
468 {
469 bitmapword aword = a->words[i];
470 bitmapword bword = b->words[i];
471
472 if ((aword & ~bword) != 0)
473 {
474 /* a is not a subset of b */
475 if (result == BMS_SUBSET1)
476 return BMS_DIFFERENT;
477 result = BMS_SUBSET2;
478 }
479 if ((bword & ~aword) != 0)
480 {
481 /* b is not a subset of a */
482 if (result == BMS_SUBSET2)
483 return BMS_DIFFERENT;
484 result = BMS_SUBSET1;
485 }
486 } while (++i < shortlen);
487 /* Check extra words */
488 if (a->nwords > b->nwords)
489 {
490 /* if a has more words then a is not a subset of b */
491 if (result == BMS_SUBSET1)
492 return BMS_DIFFERENT;
493 return BMS_SUBSET2;
494 }
495 else if (a->nwords < b->nwords)
496 {
497 /* if b has more words then b is not a subset of a */
498 if (result == BMS_SUBSET2)
499 return BMS_DIFFERENT;
500 return BMS_SUBSET1;
501 }
502 return result;
503}
504
505/*
506 * bms_is_member - is X a member of A?
507 */
508bool
509bms_is_member(int x, const Bitmapset *a)
510{
511 int wordnum,
512 bitnum;
513
515
516 /* XXX better to just return false for x<0 ? */
517 if (x < 0)
518 elog(ERROR, "negative bitmapset member not allowed");
519 if (a == NULL)
520 return false;
521
522 wordnum = WORDNUM(x);
523 bitnum = BITNUM(x);
524 if (wordnum >= a->nwords)
525 return false;
526 if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
527 return true;
528 return false;
529}
530
531/*
532 * bms_member_index
533 * determine 0-based index of member x in the bitmap
534 *
535 * Returns (-1) when x is not a member.
536 */
537int
539{
540 int bitnum;
541 int wordnum;
542 int result = 0;
543 bitmapword mask;
544
546
547 /* return -1 if not a member of the bitmap */
548 if (!bms_is_member(x, a))
549 return -1;
550
551 wordnum = WORDNUM(x);
552 bitnum = BITNUM(x);
553
554 /* count bits in preceding words */
555 for (int i = 0; i < wordnum; i++)
556 {
557 bitmapword w = a->words[i];
558
559 /* No need to count the bits in a zero word */
560 if (w != 0)
561 result += bmw_popcount(w);
562 }
563
564 /*
565 * Now add bits of the last word, but only those before the item. We can
566 * do that by applying a mask and then using popcount again. To get
567 * 0-based index, we want to count only preceding bits, not the item
568 * itself, so we subtract 1.
569 */
570 mask = ((bitmapword) 1 << bitnum) - 1;
571 result += bmw_popcount(a->words[wordnum] & mask);
572
573 return result;
574}
575
576/*
577 * bms_overlap - do sets overlap (ie, have a nonempty intersection)?
578 */
579bool
580bms_overlap(const Bitmapset *a, const Bitmapset *b)
581{
582 int shortlen;
583 int i;
584
587
588 /* Handle cases where either input is NULL */
589 if (a == NULL || b == NULL)
590 return false;
591 /* Check words in common */
592 shortlen = Min(a->nwords, b->nwords);
593 i = 0;
594 do
595 {
596 if ((a->words[i] & b->words[i]) != 0)
597 return true;
598 } while (++i < shortlen);
599 return false;
600}
601
602/*
603 * bms_overlap_list - does a set overlap an integer list?
604 */
605bool
606bms_overlap_list(const Bitmapset *a, const List *b)
607{
608 ListCell *lc;
609 int wordnum,
610 bitnum;
611
613
614 if (a == NULL || b == NIL)
615 return false;
616
617 foreach(lc, b)
618 {
619 int x = lfirst_int(lc);
620
621 if (x < 0)
622 elog(ERROR, "negative bitmapset member not allowed");
623 wordnum = WORDNUM(x);
624 bitnum = BITNUM(x);
625 if (wordnum < a->nwords)
626 if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
627 return true;
628 }
629
630 return false;
631}
632
633/*
634 * bms_nonempty_difference - do sets have a nonempty difference?
635 *
636 * i.e., are any members set in 'a' that are not also set in 'b'.
637 */
638bool
640{
641 int i;
642
645
646 /* Handle cases where either input is NULL */
647 if (a == NULL)
648 return false;
649 if (b == NULL)
650 return true;
651 /* if 'a' has more words then it must contain additional members */
652 if (a->nwords > b->nwords)
653 return true;
654 /* Check all 'a' members are set in 'b' */
655 i = 0;
656 do
657 {
658 if ((a->words[i] & ~b->words[i]) != 0)
659 return true;
660 } while (++i < a->nwords);
661 return false;
662}
663
664/*
665 * bms_singleton_member - return the sole integer member of set
666 *
667 * Raises error if |a| is not 1.
668 */
669int
671{
672 int result = -1;
673 int nwords;
674 int wordnum;
675
677
678 if (a == NULL)
679 elog(ERROR, "bitmapset is empty");
680
681 nwords = a->nwords;
682 wordnum = 0;
683 do
684 {
685 bitmapword w = a->words[wordnum];
686
687 if (w != 0)
688 {
689 if (result >= 0 || HAS_MULTIPLE_ONES(w))
690 elog(ERROR, "bitmapset has multiple members");
691 result = wordnum * BITS_PER_BITMAPWORD;
692 result += bmw_rightmost_one_pos(w);
693 }
694 } while (++wordnum < nwords);
695
696 /* we don't expect non-NULL sets to be empty */
697 Assert(result >= 0);
698 return result;
699}
700
701/*
702 * bms_get_singleton_member
703 *
704 * Test whether the given set is a singleton.
705 * If so, set *member to the value of its sole member, and return true.
706 * If not, return false, without changing *member.
707 *
708 * This is more convenient and faster than calling bms_membership() and then
709 * bms_singleton_member(), if we don't care about distinguishing empty sets
710 * from multiple-member sets.
711 */
712bool
713bms_get_singleton_member(const Bitmapset *a, int *member)
714{
715 int result = -1;
716 int nwords;
717 int wordnum;
718
720
721 if (a == NULL)
722 return false;
723
724 nwords = a->nwords;
725 wordnum = 0;
726 do
727 {
728 bitmapword w = a->words[wordnum];
729
730 if (w != 0)
731 {
732 if (result >= 0 || HAS_MULTIPLE_ONES(w))
733 return false;
734 result = wordnum * BITS_PER_BITMAPWORD;
735 result += bmw_rightmost_one_pos(w);
736 }
737 } while (++wordnum < nwords);
738
739 /* we don't expect non-NULL sets to be empty */
740 Assert(result >= 0);
741 *member = result;
742 return true;
743}
744
745/*
746 * bms_num_members - count members of set
747 */
748int
750{
751 int result = 0;
752 int nwords;
753 int wordnum;
754
756
757 if (a == NULL)
758 return 0;
759
760 nwords = a->nwords;
761 wordnum = 0;
762 do
763 {
764 bitmapword w = a->words[wordnum];
765
766 /* No need to count the bits in a zero word */
767 if (w != 0)
768 result += bmw_popcount(w);
769 } while (++wordnum < nwords);
770 return result;
771}
772
773/*
774 * bms_membership - does a set have zero, one, or multiple members?
775 *
776 * This is faster than making an exact count with bms_num_members().
777 */
780{
782 int nwords;
783 int wordnum;
784
786
787 if (a == NULL)
788 return BMS_EMPTY_SET;
789
790 nwords = a->nwords;
791 wordnum = 0;
792 do
793 {
794 bitmapword w = a->words[wordnum];
795
796 if (w != 0)
797 {
798 if (result != BMS_EMPTY_SET || HAS_MULTIPLE_ONES(w))
799 return BMS_MULTIPLE;
800 result = BMS_SINGLETON;
801 }
802 } while (++wordnum < nwords);
803 return result;
804}
805
806
807/*
808 * bms_add_member - add a specified member to set
809 *
810 * 'a' is recycled when possible.
811 */
812Bitmapset *
814{
815 int wordnum,
816 bitnum;
817
819
820 if (x < 0)
821 elog(ERROR, "negative bitmapset member not allowed");
822 if (a == NULL)
823 return bms_make_singleton(x);
824
825 wordnum = WORDNUM(x);
826 bitnum = BITNUM(x);
827
828 /* enlarge the set if necessary */
829 if (wordnum >= a->nwords)
830 {
831 int oldnwords = a->nwords;
832 int i;
833
835 a->nwords = wordnum + 1;
836 /* zero out the enlarged portion */
837 i = oldnwords;
838 do
839 {
840 a->words[i] = 0;
841 } while (++i < a->nwords);
842 }
843
844 a->words[wordnum] |= ((bitmapword) 1 << bitnum);
845
846#ifdef REALLOCATE_BITMAPSETS
847
848 /*
849 * There's no guarantee that the repalloc returned a new pointer, so copy
850 * and free unconditionally here.
851 */
853#endif
854
855 return a;
856}
857
858/*
859 * bms_del_member - remove a specified member from set
860 *
861 * No error if x is not currently a member of set
862 *
863 * 'a' is recycled when possible.
864 */
865Bitmapset *
867{
868 int wordnum,
869 bitnum;
870
872
873 if (x < 0)
874 elog(ERROR, "negative bitmapset member not allowed");
875 if (a == NULL)
876 return NULL;
877
878 wordnum = WORDNUM(x);
879 bitnum = BITNUM(x);
880
881#ifdef REALLOCATE_BITMAPSETS
883#endif
884
885 /* member can't exist. Return 'a' unmodified */
886 if (unlikely(wordnum >= a->nwords))
887 return a;
888
889 a->words[wordnum] &= ~((bitmapword) 1 << bitnum);
890
891 /* when last word becomes empty, trim off all trailing empty words */
892 if (a->words[wordnum] == 0 && wordnum == a->nwords - 1)
893 {
894 /* find the last non-empty word and make that the new final word */
895 for (int i = wordnum - 1; i >= 0; i--)
896 {
897 if (a->words[i] != 0)
898 {
899 a->nwords = i + 1;
900 return a;
901 }
902 }
903
904 /* the set is now empty */
905 pfree(a);
906 return NULL;
907 }
908 return a;
909}
910
911/*
912 * bms_add_members - like bms_union, but left input is recycled when possible
913 */
914Bitmapset *
916{
917 Bitmapset *result;
918 const Bitmapset *other;
919 int otherlen;
920 int i;
921
924
925 /* Handle cases where either input is NULL */
926 if (a == NULL)
927 return bms_copy(b);
928 if (b == NULL)
929 {
930#ifdef REALLOCATE_BITMAPSETS
932#endif
933
934 return a;
935 }
936 /* Identify shorter and longer input; copy the longer one if needed */
937 if (a->nwords < b->nwords)
938 {
939 result = bms_copy(b);
940 other = a;
941 }
942 else
943 {
944 result = a;
945 other = b;
946 }
947 /* And union the shorter input into the result */
949 i = 0;
950 do
951 {
952 result->words[i] |= other->words[i];
953 } while (++i < otherlen);
954 if (result != a)
955 pfree(a);
956#ifdef REALLOCATE_BITMAPSETS
957 else
958 result = bms_copy_and_free(result);
959#endif
960
961 return result;
962}
963
964/*
965 * bms_replace_members
966 * Remove all existing members from 'a' and repopulate the set with members
967 * from 'b', recycling 'a', when possible.
968 */
969Bitmapset *
971{
972 int i;
973
976
977 if (a == NULL)
978 return bms_copy(b);
979 if (b == NULL)
980 {
981 pfree(a);
982 return NULL;
983 }
984
985 if (a->nwords < b->nwords)
986 a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(b->nwords));
987
988 i = 0;
989 do
990 {
991 a->words[i] = b->words[i];
992 } while (++i < b->nwords);
993
994 a->nwords = b->nwords;
995
996#ifdef REALLOCATE_BITMAPSETS
997
998 /*
999 * There's no guarantee that the repalloc returned a new pointer, so copy
1000 * and free unconditionally here.
1001 */
1003#endif
1004
1005 return a;
1006}
1007
1008/*
1009 * bms_add_range
1010 * Add members in the range of 'lower' to 'upper' to the set.
1011 *
1012 * Note this could also be done by calling bms_add_member in a loop, however,
1013 * using this function will be faster when the range is large as we work at
1014 * the bitmapword level rather than at bit level.
1015 */
1016Bitmapset *
1018{
1019 int lwordnum,
1020 lbitnum,
1021 uwordnum,
1022 ushiftbits,
1023 wordnum;
1024
1026
1027 /* do nothing if nothing is called for, without further checking */
1028 if (upper < lower)
1029 {
1030#ifdef REALLOCATE_BITMAPSETS
1032#endif
1033
1034 return a;
1035 }
1036
1037 if (lower < 0)
1038 elog(ERROR, "negative bitmapset member not allowed");
1040
1041 if (a == NULL)
1042 {
1044 a->type = T_Bitmapset;
1045 a->nwords = uwordnum + 1;
1046 }
1047 else if (uwordnum >= a->nwords)
1048 {
1049 int oldnwords = a->nwords;
1050 int i;
1051
1052 /* ensure we have enough words to store the upper bit */
1054 a->nwords = uwordnum + 1;
1055 /* zero out the enlarged portion */
1056 i = oldnwords;
1057 do
1058 {
1059 a->words[i] = 0;
1060 } while (++i < a->nwords);
1061 }
1062
1064
1065 lbitnum = BITNUM(lower);
1067
1068 /*
1069 * Special case when lwordnum is the same as uwordnum we must perform the
1070 * upper and lower masking on the word.
1071 */
1072 if (lwordnum == uwordnum)
1073 {
1074 a->words[lwordnum] |= ~(bitmapword) (((bitmapword) 1 << lbitnum) - 1)
1075 & (~(bitmapword) 0) >> ushiftbits;
1076 }
1077 else
1078 {
1079 /* turn on lbitnum and all bits left of it */
1080 a->words[wordnum++] |= ~(bitmapword) (((bitmapword) 1 << lbitnum) - 1);
1081
1082 /* turn on all bits for any intermediate words */
1083 while (wordnum < uwordnum)
1084 a->words[wordnum++] = ~(bitmapword) 0;
1085
1086 /* turn on upper's bit and all bits right of it. */
1087 a->words[uwordnum] |= (~(bitmapword) 0) >> ushiftbits;
1088 }
1089
1090#ifdef REALLOCATE_BITMAPSETS
1091
1092 /*
1093 * There's no guarantee that the repalloc returned a new pointer, so copy
1094 * and free unconditionally here.
1095 */
1097#endif
1098
1099 return a;
1100}
1101
1102/*
1103 * bms_int_members - like bms_intersect, but left input is recycled when
1104 * possible
1105 */
1106Bitmapset *
1108{
1109 int lastnonzero;
1110 int shortlen;
1111 int i;
1112
1115
1116 /* Handle cases where either input is NULL */
1117 if (a == NULL)
1118 return NULL;
1119 if (b == NULL)
1120 {
1121 pfree(a);
1122 return NULL;
1123 }
1124
1125 /* Intersect b into a; we need never copy */
1126 shortlen = Min(a->nwords, b->nwords);
1127 lastnonzero = -1;
1128 i = 0;
1129 do
1130 {
1131 a->words[i] &= b->words[i];
1132
1133 if (a->words[i] != 0)
1134 lastnonzero = i;
1135 } while (++i < shortlen);
1136
1137 /* If we computed an empty result, we must return NULL */
1138 if (lastnonzero == -1)
1139 {
1140 pfree(a);
1141 return NULL;
1142 }
1143
1144 /* get rid of trailing zero words */
1145 a->nwords = lastnonzero + 1;
1146
1147#ifdef REALLOCATE_BITMAPSETS
1149#endif
1150
1151 return a;
1152}
1153
1154/*
1155 * bms_del_members - delete members in 'a' that are set in 'b'. 'a' is
1156 * recycled when possible.
1157 */
1158Bitmapset *
1160{
1161 int i;
1162
1165
1166 /* Handle cases where either input is NULL */
1167 if (a == NULL)
1168 return NULL;
1169 if (b == NULL)
1170 {
1171#ifdef REALLOCATE_BITMAPSETS
1173#endif
1174
1175 return a;
1176 }
1177
1178 /* Remove b's bits from a; we need never copy */
1179 if (a->nwords > b->nwords)
1180 {
1181 /*
1182 * We'll never need to remove trailing zero words when 'a' has more
1183 * words than 'b'.
1184 */
1185 i = 0;
1186 do
1187 {
1188 a->words[i] &= ~b->words[i];
1189 } while (++i < b->nwords);
1190 }
1191 else
1192 {
1193 int lastnonzero = -1;
1194
1195 /* we may need to remove trailing zero words from the result. */
1196 i = 0;
1197 do
1198 {
1199 a->words[i] &= ~b->words[i];
1200
1201 /* remember the last non-zero word */
1202 if (a->words[i] != 0)
1203 lastnonzero = i;
1204 } while (++i < a->nwords);
1205
1206 /* check if 'a' has become empty */
1207 if (lastnonzero == -1)
1208 {
1209 pfree(a);
1210 return NULL;
1211 }
1212
1213 /* trim off any trailing zero words */
1214 a->nwords = lastnonzero + 1;
1215 }
1216
1217#ifdef REALLOCATE_BITMAPSETS
1219#endif
1220
1221 return a;
1222}
1223
1224/*
1225 * bms_join - like bms_union, but *either* input *may* be recycled
1226 */
1227Bitmapset *
1229{
1230 Bitmapset *result;
1232 int otherlen;
1233 int i;
1234
1237
1238 /* Handle cases where either input is NULL */
1239 if (a == NULL)
1240 {
1241#ifdef REALLOCATE_BITMAPSETS
1243#endif
1244
1245 return b;
1246 }
1247 if (b == NULL)
1248 {
1249#ifdef REALLOCATE_BITMAPSETS
1251#endif
1252
1253 return a;
1254 }
1255
1256 /* Identify shorter and longer input; use longer one as result */
1257 if (a->nwords < b->nwords)
1258 {
1259 result = b;
1260 other = a;
1261 }
1262 else
1263 {
1264 result = a;
1265 other = b;
1266 }
1267 /* And union the shorter input into the result */
1269 i = 0;
1270 do
1271 {
1272 result->words[i] |= other->words[i];
1273 } while (++i < otherlen);
1274 if (other != result) /* pure paranoia */
1275 pfree(other);
1276
1277#ifdef REALLOCATE_BITMAPSETS
1278 result = bms_copy_and_free(result);
1279#endif
1280
1281 return result;
1282}
1283
1284/*
1285 * bms_next_member - find next member of a set
1286 *
1287 * Returns smallest member greater than "prevbit", or -2 if there is none.
1288 * "prevbit" must NOT be less than -1, or the behavior is unpredictable.
1289 *
1290 * This is intended as support for iterating through the members of a set.
1291 * The typical pattern is
1292 *
1293 * x = -1;
1294 * while ((x = bms_next_member(inputset, x)) >= 0)
1295 * process member x;
1296 *
1297 * Notice that when there are no more members, we return -2, not -1 as you
1298 * might expect. The rationale for that is to allow distinguishing the
1299 * loop-not-started state (x == -1) from the loop-completed state (x == -2).
1300 * It makes no difference in simple loop usage, but complex iteration logic
1301 * might need such an ability.
1302 */
1303int
1305{
1306 int nwords;
1307 bitmapword mask;
1308
1310
1311 if (a == NULL)
1312 return -2;
1313 nwords = a->nwords;
1314 prevbit++;
1315 mask = (~(bitmapword) 0) << BITNUM(prevbit);
1316 for (int wordnum = WORDNUM(prevbit); wordnum < nwords; wordnum++)
1317 {
1318 bitmapword w = a->words[wordnum];
1319
1320 /* ignore bits before prevbit */
1321 w &= mask;
1322
1323 if (w != 0)
1324 {
1325 int result;
1326
1327 result = wordnum * BITS_PER_BITMAPWORD;
1328 result += bmw_rightmost_one_pos(w);
1329 return result;
1330 }
1331
1332 /* in subsequent words, consider all bits */
1333 mask = (~(bitmapword) 0);
1334 }
1335 return -2;
1336}
1337
1338/*
1339 * bms_prev_member - find prev member of a set
1340 *
1341 * Returns largest member less than "prevbit", or -2 if there is none.
1342 * "prevbit" must NOT be more than one above the highest possible bit that can
1343 * be set in the Bitmapset at its current size.
1344 *
1345 * To ease finding the highest set bit for the initial loop, the special
1346 * prevbit value of -1 can be passed to have the function find the highest
1347 * valued member in the set.
1348 *
1349 * This is intended as support for iterating through the members of a set in
1350 * reverse. The typical pattern is
1351 *
1352 * x = -1;
1353 * while ((x = bms_prev_member(inputset, x)) >= 0)
1354 * process member x;
1355 *
1356 * Notice that when there are no more members, we return -2, not -1 as you
1357 * might expect. The rationale for that is to allow distinguishing the
1358 * loop-not-started state (x == -1) from the loop-completed state (x == -2).
1359 * It makes no difference in simple loop usage, but complex iteration logic
1360 * might need such an ability.
1361 */
1362
1363int
1365{
1366 int ushiftbits;
1367 bitmapword mask;
1368
1370
1371 /*
1372 * If set is NULL or if there are no more bits to the right then we've
1373 * nothing to do.
1374 */
1375 if (a == NULL || prevbit == 0)
1376 return -2;
1377
1378 /* Validate callers didn't give us something out of range */
1380 Assert(prevbit >= -1);
1381
1382 /* transform -1 to the highest possible bit we could have set */
1383 if (prevbit == -1)
1384 prevbit = a->nwords * BITS_PER_BITMAPWORD - 1;
1385 else
1386 prevbit--;
1387
1389 mask = (~(bitmapword) 0) >> ushiftbits;
1390 for (int wordnum = WORDNUM(prevbit); wordnum >= 0; wordnum--)
1391 {
1392 bitmapword w = a->words[wordnum];
1393
1394 /* mask out bits left of prevbit */
1395 w &= mask;
1396
1397 if (w != 0)
1398 {
1399 int result;
1400
1401 result = wordnum * BITS_PER_BITMAPWORD;
1402 result += bmw_leftmost_one_pos(w);
1403 return result;
1404 }
1405
1406 /* in subsequent words, consider all bits */
1407 mask = (~(bitmapword) 0);
1408 }
1409 return -2;
1410}
1411
1412/*
1413 * bms_hash_value - compute a hash key for a Bitmapset
1414 */
1415uint32
1417{
1419
1420 if (a == NULL)
1421 return 0; /* All empty sets hash to 0 */
1422 return DatumGetUInt32(hash_any((const unsigned char *) a->words,
1423 a->nwords * sizeof(bitmapword)));
1424}
1425
1426/*
1427 * bitmap_hash - hash function for keys that are (pointers to) Bitmapsets
1428 *
1429 * Note: don't forget to specify bitmap_match as the match function!
1430 */
1431uint32
1432bitmap_hash(const void *key, Size keysize)
1433{
1434 Assert(keysize == sizeof(Bitmapset *));
1435 return bms_hash_value(*((const Bitmapset *const *) key));
1436}
1437
1438/*
1439 * bitmap_match - match function to use with bitmap_hash
1440 */
1441int
1442bitmap_match(const void *key1, const void *key2, Size keysize)
1443{
1444 Assert(keysize == sizeof(Bitmapset *));
1445 return !bms_equal(*((const Bitmapset *const *) key1),
1446 *((const Bitmapset *const *) key2));
1447}
#define BITMAPSET_SIZE(nwords)
Definition bitmapset.c:50
Bitmapset * bms_replace_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:971
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:346
int bms_prev_member(const Bitmapset *a, int prevbit)
Definition bitmapset.c:1365
Bitmapset * bms_make_singleton(int x)
Definition bitmapset.c:216
Bitmapset * bms_int_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:1108
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:292
uint32 bitmap_hash(const void *key, Size keysize)
Definition bitmapset.c:1433
#define WORDNUM(x)
Definition bitmapset.c:47
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:142
BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:445
int bms_next_member(const Bitmapset *a, int prevbit)
Definition bitmapset.c:1305
uint32 bms_hash_value(const Bitmapset *a)
Definition bitmapset.c:1417
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:1160
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition bitmapset.c:1018
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition bitmapset.c:867
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:412
int bms_singleton_member(const Bitmapset *a)
Definition bitmapset.c:671
void bms_free(Bitmapset *a)
Definition bitmapset.c:239
int bms_num_members(const Bitmapset *a)
Definition bitmapset.c:750
bool bms_is_member(int x, const Bitmapset *a)
Definition bitmapset.c:510
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:814
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:916
#define BITNUM(x)
Definition bitmapset.c:48
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:251
#define HAS_MULTIPLE_ONES(x)
Definition bitmapset.c:72
int bitmap_match(const void *key1, const void *key2, Size keysize)
Definition bitmapset.c:1443
BMS_Membership bms_membership(const Bitmapset *a)
Definition bitmapset.c:780
int bms_member_index(Bitmapset *a, int x)
Definition bitmapset.c:539
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:581
int bms_compare(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:183
bool bms_get_singleton_member(const Bitmapset *a, int *member)
Definition bitmapset.c:714
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition bitmapset.c:1229
bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:640
Bitmapset * bms_copy(const Bitmapset *a)
Definition bitmapset.c:122
bool bms_overlap_list(const Bitmapset *a, const List *b)
Definition bitmapset.c:607
#define bmw_rightmost_one_pos(w)
Definition bitmapset.h:79
#define bmw_leftmost_one_pos(w)
Definition bitmapset.h:78
BMS_Comparison
Definition bitmapset.h:61
@ BMS_DIFFERENT
Definition bitmapset.h:65
@ BMS_SUBSET1
Definition bitmapset.h:63
@ BMS_EQUAL
Definition bitmapset.h:62
@ BMS_SUBSET2
Definition bitmapset.h:64
BMS_Membership
Definition bitmapset.h:70
@ BMS_SINGLETON
Definition bitmapset.h:72
@ BMS_EMPTY_SET
Definition bitmapset.h:71
@ BMS_MULTIPLE
Definition bitmapset.h:73
uint32 bitmapword
Definition bitmapset.h:44
#define BITS_PER_BITMAPWORD
Definition bitmapset.h:43
#define bmw_popcount(w)
Definition bitmapset.h:80
#define Min(x, y)
Definition c.h:997
#define Assert(condition)
Definition c.h:873
#define unlikely(x)
Definition c.h:412
uint32_t uint32
Definition c.h:546
size_t Size
Definition c.h:619
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
static Datum hash_any(const unsigned char *k, int keylen)
Definition hashfn.h:31
int b
Definition isn.c:74
int x
Definition isn.c:75
int a
Definition isn.c:73
int i
Definition isn.c:77
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void pfree(void *pointer)
Definition mcxt.c:1616
void * palloc0(Size size)
Definition mcxt.c:1417
void * palloc(Size size)
Definition mcxt.c:1387
#define IsA(nodeptr, _type_)
Definition nodes.h:164
Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
#define NIL
Definition pg_list.h:68
#define lfirst_int(lc)
Definition pg_list.h:173
static uint32 DatumGetUInt32(Datum X)
Definition postgres.h:232
char * c
static int fb(int x)
int nwords
Definition bitmapset.h:54
bitmapword words[FLEXIBLE_ARRAY_MEMBER]
Definition bitmapset.h:55
Definition pg_list.h:54

◆ BITNUM

#define BITNUM (   x)    ((x) % BITS_PER_BITMAPWORD)

Definition at line 48 of file bitmapset.c.

◆ HAS_MULTIPLE_ONES

#define HAS_MULTIPLE_ONES (   x)    ((bitmapword) RIGHTMOST_ONE(x) != (x))

Definition at line 72 of file bitmapset.c.

◆ RIGHTMOST_ONE

#define RIGHTMOST_ONE (   x)    ((signedbitmapword) (x) & -((signedbitmapword) (x)))

Definition at line 70 of file bitmapset.c.

◆ WORDNUM

#define WORDNUM (   x)    ((x) / BITS_PER_BITMAPWORD)

Definition at line 47 of file bitmapset.c.

Function Documentation

◆ bitmap_hash()

uint32 bitmap_hash ( const void key,
Size  keysize 
)

Definition at line 1433 of file bitmapset.c.

1434{
1435 Assert(keysize == sizeof(Bitmapset *));
1436 return bms_hash_value(*((const Bitmapset *const *) key));
1437}

References Assert, and bms_hash_value().

Referenced by build_join_rel_hash(), and test_bitmap_hash().

◆ bitmap_match()

int bitmap_match ( const void key1,
const void key2,
Size  keysize 
)

Definition at line 1443 of file bitmapset.c.

1444{
1445 Assert(keysize == sizeof(Bitmapset *));
1446 return !bms_equal(*((const Bitmapset *const *) key1),
1447 *((const Bitmapset *const *) key2));
1448}

References Assert, bms_equal(), and fb().

Referenced by build_join_rel_hash(), and test_bitmap_match().

◆ bms_add_member()

Bitmapset * bms_add_member ( Bitmapset a,
int  x 
)

Definition at line 814 of file bitmapset.c.

815{
816 int wordnum,
817 bitnum;
818
820
821 if (x < 0)
822 elog(ERROR, "negative bitmapset member not allowed");
823 if (a == NULL)
824 return bms_make_singleton(x);
825
826 wordnum = WORDNUM(x);
827 bitnum = BITNUM(x);
828
829 /* enlarge the set if necessary */
830 if (wordnum >= a->nwords)
831 {
832 int oldnwords = a->nwords;
833 int i;
834
836 a->nwords = wordnum + 1;
837 /* zero out the enlarged portion */
838 i = oldnwords;
839 do
840 {
841 a->words[i] = 0;
842 } while (++i < a->nwords);
843 }
844
845 a->words[wordnum] |= ((bitmapword) 1 << bitnum);
846
847#ifdef REALLOCATE_BITMAPSETS
848
849 /*
850 * There's no guarantee that the repalloc returned a new pointer, so copy
851 * and free unconditionally here.
852 */
854#endif
855
856 return a;
857}

References a, Assert, BITMAPSET_SIZE, BITNUM, bms_make_singleton(), elog, ERROR, fb(), i, repalloc(), WORDNUM, and x.

Referenced by _readBitmapset(), add_child_eq_member(), add_outer_joins_to_relids(), add_row_identity_var(), add_rte_to_flat_rtable(), adjust_child_relids(), adjust_group_pathkeys_for_groupagg(), adjust_relid_set(), adjust_view_column_set(), alias_relid_set(), all_rows_selectable(), apply_handle_update(), build_joinrel_tlist(), build_subplan(), buildGroupedVar(), check_functional_grouping(), check_index_only(), checkInsertTargets(), classify_index_clause_usage(), clauselist_apply_dependencies(), convert_EXISTS_sublink_to_join(), create_lateral_join_info(), create_list_bounds(), CreatePartitionPruneState(), DecodeTextArrayToBitmapset(), deconstruct_distribute_oj_quals(), deconstruct_recurse(), deparseColumnRef(), dependencies_clauselist_selectivity(), DiscreteKnapsack(), do_analyze_rel(), DoCopy(), dropconstraint_internal(), estimate_multivariate_ndistinct(), EvalPlanQualBegin(), ExecAsyncAppendResponse(), ExecBuildUpdateProjection(), ExecCheckPermissions(), ExecInitAgg(), ExecInitAppend(), ExecInitGenerated(), ExecNestLoop(), ExecRecursiveUnion(), ExecReScanGather(), ExecReScanGatherMerge(), ExecReScanRecursiveUnion(), ExecReScanSetParamPlan(), ExecScanSubPlan(), execute_attr_map_cols(), expand_single_inheritance_child(), ExplainPreScanNode(), ExplainSubPlans(), extract_rollup_sets(), extractRemainingColumns(), fetch_remote_table_info(), fetch_statentries_for_relation(), finalize_plan(), finalize_primnode(), find_childrel_parents(), find_cols(), find_cols_walker(), find_hash_columns(), find_matching_subplans_recurse(), find_window_run_conditions(), findDefaultOnlyColumns(), fixup_inherited_columns(), fixup_whole_row_references(), func_get_detail(), gen_partprune_steps_internal(), generate_base_implied_equalities(), get_baserel_parampathinfo(), get_dependent_generated_columns(), get_eclass_for_sort_expr(), get_matching_partitions(), get_nullingrels_recurse(), get_param_path_clause_serials(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_relation_notnullatts(), get_relation_statistics(), get_relids_in_jointree(), HeapDetermineColumnsInfo(), infer_arbiter_indexes(), InitExecPartitionPruneContexts(), is_var_needed_by_join(), join_is_removable(), load_enum_cache_data(), logicalrep_read_attrs(), logicalrep_rel_open(), make_datum_param(), make_modifytable(), make_outerjoininfo(), make_partition_pruneinfo(), make_partitionedrel_pruneinfo(), make_row_comparison_op(), make_window_input_target(), makeDependencyGraphWalker(), mark_rels_nulled_by_join(), mark_stmt(), markRelsAsNulledBy(), markRTEForSelectPriv(), mbms_add_member(), mbms_overlap_sets(), MergeAttributes(), nodeRead(), offset_relid_set(), offset_relid_set(), plpgsql_mark_local_assignment_targets(), preprocess_grouping_sets(), pub_collist_to_bitmapset(), pub_collist_validate(), pub_form_cols_map(), pull_exec_paramids_walker(), pull_paramids_walker(), pull_up_sublinks_jointree_recurse(), pull_varattnos_walker(), pull_varnos_walker(), rebuild_joinclause_attr_needed(), reduce_outer_joins_pass2(), register_partpruneinfo(), RelationGetIdentityKeyBitmap(), RelationGetIndexAttrBitmap(), remove_leftjoinrel_from_query(), remove_self_join_rel(), remove_self_joins_one_group(), remove_self_joins_recurse(), remove_useless_groupby_columns(), remove_useless_results_recurse(), rewriteTargetListIU(), rewriteTargetView(), RI_Initial_Check(), set_join_column_names(), set_param_references(), SS_identify_outer_params(), stat_covers_expressions(), statext_is_compatible_clause(), statext_is_compatible_clause_internal(), statext_mcv_clauselist_selectivity(), test_bms_add_member(), test_random_operations(), transformGroupClause(), transformGroupClauseList(), transformInsertStmt(), transformMergeStmt(), transformRangeTableFunc(), transformUpdateTargetList(), translate_col_privs(), try_partitionwise_join(), use_physical_tlist(), and view_cols_are_auto_updatable().

◆ bms_add_members()

Bitmapset * bms_add_members ( Bitmapset a,
const Bitmapset b 
)

Definition at line 916 of file bitmapset.c.

917{
918 Bitmapset *result;
919 const Bitmapset *other;
920 int otherlen;
921 int i;
922
925
926 /* Handle cases where either input is NULL */
927 if (a == NULL)
928 return bms_copy(b);
929 if (b == NULL)
930 {
931#ifdef REALLOCATE_BITMAPSETS
933#endif
934
935 return a;
936 }
937 /* Identify shorter and longer input; copy the longer one if needed */
938 if (a->nwords < b->nwords)
939 {
940 result = bms_copy(b);
941 other = a;
942 }
943 else
944 {
945 result = a;
946 other = b;
947 }
948 /* And union the shorter input into the result */
950 i = 0;
951 do
952 {
953 result->words[i] |= other->words[i];
954 } while (++i < otherlen);
955 if (result != a)
956 pfree(a);
957#ifdef REALLOCATE_BITMAPSETS
958 else
959 result = bms_copy_and_free(result);
960#endif
961
962 return result;
963}

References a, Assert, b, bms_copy(), fb(), i, Bitmapset::nwords, pfree(), and Bitmapset::words.

Referenced by add_child_join_rel_equivalences(), add_child_rel_equivalences(), add_eq_member(), add_outer_joins_to_relids(), add_part_relids(), add_paths_to_joinrel(), add_placeholders_to_joinrel(), add_vars_to_attr_needed(), add_vars_to_targetlist(), adjust_standard_join_alias_expression(), build_index_paths(), choose_best_statistics(), choose_bitmap_and(), create_agg_clause_infos(), create_bitmap_and_path(), create_bitmap_or_path(), create_join_clause(), create_lateral_join_info(), CreatePartitionPruneState(), deconstruct_distribute(), deconstruct_recurse(), ExecDoInitialPruning(), ExecFindMatchingSubPlans(), ExecInitAgg(), expand_partitioned_rtentry(), ExplainPreScanNode(), finalize_plan(), find_nonnullable_rels_walker(), foreign_join_ok(), generate_union_paths(), get_eclass_indexes_for_relids(), get_param_path_clause_serials(), get_placeholder_nulling_relids(), heap_update(), join_is_legal(), make_outerjoininfo(), mbms_add_members(), perform_pruning_combine_step(), pull_varnos_walker(), pullup_replace_vars_callback(), reduce_outer_joins_pass1(), reduce_outer_joins_pass2(), remove_leftjoinrel_from_query(), remove_self_join_rel(), remove_self_joins_recurse(), test_bms_add_members(), transformOnConflictArbiter(), and try_partitionwise_join().

◆ bms_add_range()

Bitmapset * bms_add_range ( Bitmapset a,
int  lower,
int  upper 
)

Definition at line 1018 of file bitmapset.c.

1019{
1020 int lwordnum,
1021 lbitnum,
1022 uwordnum,
1023 ushiftbits,
1024 wordnum;
1025
1027
1028 /* do nothing if nothing is called for, without further checking */
1029 if (upper < lower)
1030 {
1031#ifdef REALLOCATE_BITMAPSETS
1033#endif
1034
1035 return a;
1036 }
1037
1038 if (lower < 0)
1039 elog(ERROR, "negative bitmapset member not allowed");
1041
1042 if (a == NULL)
1043 {
1045 a->type = T_Bitmapset;
1046 a->nwords = uwordnum + 1;
1047 }
1048 else if (uwordnum >= a->nwords)
1049 {
1050 int oldnwords = a->nwords;
1051 int i;
1052
1053 /* ensure we have enough words to store the upper bit */
1055 a->nwords = uwordnum + 1;
1056 /* zero out the enlarged portion */
1057 i = oldnwords;
1058 do
1059 {
1060 a->words[i] = 0;
1061 } while (++i < a->nwords);
1062 }
1063
1065
1066 lbitnum = BITNUM(lower);
1068
1069 /*
1070 * Special case when lwordnum is the same as uwordnum we must perform the
1071 * upper and lower masking on the word.
1072 */
1073 if (lwordnum == uwordnum)
1074 {
1075 a->words[lwordnum] |= ~(bitmapword) (((bitmapword) 1 << lbitnum) - 1)
1076 & (~(bitmapword) 0) >> ushiftbits;
1077 }
1078 else
1079 {
1080 /* turn on lbitnum and all bits left of it */
1081 a->words[wordnum++] |= ~(bitmapword) (((bitmapword) 1 << lbitnum) - 1);
1082
1083 /* turn on all bits for any intermediate words */
1084 while (wordnum < uwordnum)
1085 a->words[wordnum++] = ~(bitmapword) 0;
1086
1087 /* turn on upper's bit and all bits right of it. */
1088 a->words[uwordnum] |= (~(bitmapword) 0) >> ushiftbits;
1089 }
1090
1091#ifdef REALLOCATE_BITMAPSETS
1092
1093 /*
1094 * There's no guarantee that the repalloc returned a new pointer, so copy
1095 * and free unconditionally here.
1096 */
1098#endif
1099
1100 return a;
1101}

References a, Assert, BITMAPSET_SIZE, BITNUM, BITS_PER_BITMAPWORD, elog, ERROR, fb(), i, lower(), palloc0(), repalloc(), upper(), and WORDNUM.

Referenced by add_setop_child_rel_equivalences(), ComputePartitionAttrs(), DoCopy(), ExecInitAppend(), ExecInitMergeAppend(), ExecInitPartitionExecPruning(), get_matching_hash_bounds(), get_matching_list_bounds(), get_matching_partitions(), get_matching_range_bounds(), logicalrep_rel_open(), make_partition_pruneinfo(), perform_pruning_combine_step(), prune_append_rel_partitions(), test_bms_add_range(), and test_random_operations().

◆ bms_compare()

int bms_compare ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 183 of file bitmapset.c.

184{
185 int i;
186
189
190 /* Handle cases where either input is NULL */
191 if (a == NULL)
192 return (b == NULL) ? 0 : -1;
193 else if (b == NULL)
194 return +1;
195
196 /* the set with the most words must be greater */
197 if (a->nwords != b->nwords)
198 return (a->nwords > b->nwords) ? +1 : -1;
199
200 i = a->nwords - 1;
201 do
202 {
203 bitmapword aw = a->words[i];
204 bitmapword bw = b->words[i];
205
206 if (aw != bw)
207 return (aw > bw) ? +1 : -1;
208 } while (--i >= 0);
209 return 0;
210}

References a, Assert, b, fb(), and i.

Referenced by append_startup_cost_compare(), append_total_cost_compare(), and test_bms_compare().

◆ bms_copy()

Bitmapset * bms_copy ( const Bitmapset a)

Definition at line 122 of file bitmapset.c.

123{
124 Bitmapset *result;
125 size_t size;
126
128
129 if (a == NULL)
130 return NULL;
131
132 size = BITMAPSET_SIZE(a->nwords);
133 result = (Bitmapset *) palloc(size);
134 memcpy(result, a, size);
135 return result;
136}

References a, Assert, BITMAPSET_SIZE, fb(), and palloc().

Referenced by _copyBitmapset(), add_nullingrels_if_needed(), add_outer_joins_to_relids(), adjust_child_relids(), adjust_relid_set(), afterTriggerCopyBitmap(), bms_add_members(), bms_difference(), bms_intersect(), bms_replace_members(), bms_union(), build_child_join_rel(), build_index_paths(), build_join_rel(), build_simple_grouped_rel(), calc_nestloop_required_outer(), choose_bitmap_and(), create_lateral_join_info(), CreatePartitionPruneState(), deconstruct_distribute_oj_quals(), deconstruct_recurse(), DiscreteKnapsack(), distribute_qual_to_rels(), ExecFindMatchingSubPlans(), fetch_upper_rel(), finalize_plan(), finalize_primnode(), find_hash_columns(), find_placeholder_info(), fixup_whole_row_references(), get_join_domain_min_rels(), get_nullingrels_recurse(), get_param_path_clause_serials(), get_relation_statistics_worker(), InitPlan(), innerrel_is_unique_ext(), is_var_needed_by_join(), join_is_legal(), join_is_removable(), load_enum_cache_data(), logicalrep_partition_open(), logicalrep_relmap_update(), make_grouped_join_rel(), make_outerjoininfo(), make_partition_pruneinfo(), mark_nullable_by_grouping(), mark_stmt(), partition_bounds_copy(), perform_pruning_combine_step(), reconsider_full_join_clause(), reconsider_outer_join_clause(), RelationGetIdentityKeyBitmap(), RelationGetIndexAttrBitmap(), remove_rel_from_query(), remove_rel_from_restrictinfo(), reparameterize_path_by_child(), and test_bms_copy().

◆ bms_del_member()

Bitmapset * bms_del_member ( Bitmapset a,
int  x 
)

Definition at line 867 of file bitmapset.c.

868{
869 int wordnum,
870 bitnum;
871
873
874 if (x < 0)
875 elog(ERROR, "negative bitmapset member not allowed");
876 if (a == NULL)
877 return NULL;
878
879 wordnum = WORDNUM(x);
880 bitnum = BITNUM(x);
881
882#ifdef REALLOCATE_BITMAPSETS
884#endif
885
886 /* member can't exist. Return 'a' unmodified */
887 if (unlikely(wordnum >= a->nwords))
888 return a;
889
890 a->words[wordnum] &= ~((bitmapword) 1 << bitnum);
891
892 /* when last word becomes empty, trim off all trailing empty words */
893 if (a->words[wordnum] == 0 && wordnum == a->nwords - 1)
894 {
895 /* find the last non-empty word and make that the new final word */
896 for (int i = wordnum - 1; i >= 0; i--)
897 {
898 if (a->words[i] != 0)
899 {
900 a->nwords = i + 1;
901 return a;
902 }
903 }
904
905 /* the set is now empty */
906 pfree(a);
907 return NULL;
908 }
909 return a;
910}

References a, Assert, BITNUM, elog, ERROR, fb(), i, pfree(), unlikely, WORDNUM, and x.

Referenced by add_nullingrels_if_needed(), adjust_child_relids(), adjust_group_pathkeys_for_groupagg(), adjust_relid_set(), build_index_paths(), BuildParameterizedTidPaths(), ComputePartitionAttrs(), deconstruct_distribute_oj_quals(), dependencies_clauselist_selectivity(), DiscreteKnapsack(), DoCopy(), expand_partitioned_rtentry(), finalize_plan(), finalize_primnode(), find_hash_columns(), findDefaultOnlyColumns(), fixup_whole_row_references(), get_join_domain_min_rels(), get_matching_list_bounds(), logicalrep_rel_open(), make_outerjoininfo(), postgresGetForeignPaths(), preprocess_rowmarks(), remove_rel_from_query(), remove_rel_from_restrictinfo(), remove_self_joins_recurse(), substitute_phv_relids_walker(), test_bms_del_member(), test_random_operations(), and TopologicalSort().

◆ bms_del_members()

Bitmapset * bms_del_members ( Bitmapset a,
const Bitmapset b 
)

Definition at line 1160 of file bitmapset.c.

1161{
1162 int i;
1163
1166
1167 /* Handle cases where either input is NULL */
1168 if (a == NULL)
1169 return NULL;
1170 if (b == NULL)
1171 {
1172#ifdef REALLOCATE_BITMAPSETS
1174#endif
1175
1176 return a;
1177 }
1178
1179 /* Remove b's bits from a; we need never copy */
1180 if (a->nwords > b->nwords)
1181 {
1182 /*
1183 * We'll never need to remove trailing zero words when 'a' has more
1184 * words than 'b'.
1185 */
1186 i = 0;
1187 do
1188 {
1189 a->words[i] &= ~b->words[i];
1190 } while (++i < b->nwords);
1191 }
1192 else
1193 {
1194 int lastnonzero = -1;
1195
1196 /* we may need to remove trailing zero words from the result. */
1197 i = 0;
1198 do
1199 {
1200 a->words[i] &= ~b->words[i];
1201
1202 /* remember the last non-zero word */
1203 if (a->words[i] != 0)
1204 lastnonzero = i;
1205 } while (++i < a->nwords);
1206
1207 /* check if 'a' has become empty */
1208 if (lastnonzero == -1)
1209 {
1210 pfree(a);
1211 return NULL;
1212 }
1213
1214 /* trim off any trailing zero words */
1215 a->nwords = lastnonzero + 1;
1216 }
1217
1218#ifdef REALLOCATE_BITMAPSETS
1220#endif
1221
1222 return a;
1223}

References a, Assert, b, fb(), i, and pfree().

Referenced by adjust_group_pathkeys_for_groupagg(), build_join_rel(), calc_nestloop_required_outer(), check_index_predicates(), classify_matching_subplans(), finalize_plan(), get_join_domain_min_rels(), get_placeholder_nulling_relids(), make_outerjoininfo(), make_partition_pruneinfo(), min_join_parameterization(), NumRelids(), pullup_replace_vars_callback(), remove_self_joins_recurse(), and test_bms_del_members().

◆ bms_difference()

Bitmapset * bms_difference ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 346 of file bitmapset.c.

347{
348 Bitmapset *result;
349 int i;
350
353
354 /* Handle cases where either input is NULL */
355 if (a == NULL)
356 return NULL;
357 if (b == NULL)
358 return bms_copy(a);
359
360 /*
361 * In Postgres' usage, an empty result is a very common case, so it's
362 * worth optimizing for that by testing bms_nonempty_difference(). This
363 * saves us a palloc/pfree cycle compared to checking after-the-fact.
364 */
366 return NULL;
367
368 /* Copy the left input */
369 result = bms_copy(a);
370
371 /* And remove b's bits from result */
372 if (result->nwords > b->nwords)
373 {
374 /*
375 * We'll never need to remove trailing zero words when 'a' has more
376 * words than 'b' as the additional words must be non-zero.
377 */
378 i = 0;
379 do
380 {
381 result->words[i] &= ~b->words[i];
382 } while (++i < b->nwords);
383 }
384 else
385 {
386 int lastnonzero = -1;
387
388 /* we may need to remove trailing zero words from the result. */
389 i = 0;
390 do
391 {
392 result->words[i] &= ~b->words[i];
393
394 /* remember the last non-zero word */
395 if (result->words[i] != 0)
396 lastnonzero = i;
397 } while (++i < result->nwords);
398
399 /* trim off trailing zero words */
400 result->nwords = lastnonzero + 1;
401 }
402 Assert(result->nwords != 0);
403
404 /* Need not check for empty result, since we handled that case above */
405 return result;
406}

References a, Assert, b, bms_copy(), bms_nonempty_difference(), fb(), i, Bitmapset::nwords, and Bitmapset::words.

Referenced by add_child_join_rel_equivalences(), add_child_rel_equivalences(), add_paths_to_joinrel(), check_index_predicates(), consider_new_or_clause(), create_foreignscan_plan(), examine_variable(), finalize_plan(), find_placeholder_info(), make_plain_restrictinfo(), pull_varnos_walker(), remove_nulling_relids_mutator(), remove_rel_from_query(), remove_useless_groupby_columns(), standard_planner(), and test_bms_difference().

◆ bms_equal()

bool bms_equal ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 142 of file bitmapset.c.

143{
144 int i;
145
148
149 /* Handle cases where either input is NULL */
150 if (a == NULL)
151 {
152 if (b == NULL)
153 return true;
154 return false;
155 }
156 else if (b == NULL)
157 return false;
158
159 /* can't be equal if the word counts don't match */
160 if (a->nwords != b->nwords)
161 return false;
162
163 /* check each word matches */
164 i = 0;
165 do
166 {
167 if (a->words[i] != b->words[i])
168 return false;
169 } while (++i < a->nwords);
170
171 return true;
172}

References a, Assert, b, fb(), and i.

Referenced by _equalBitmapset(), add_non_redundant_clauses(), add_path_precheck(), add_paths_to_append_rel(), afterTriggerAddEvent(), AlterPublicationTables(), assign_param_for_var(), bitmap_match(), choose_bitmap_and(), create_append_path(), create_merge_append_path(), create_unique_paths(), deconstruct_distribute_oj_quals(), deconstruct_jointree(), ExecInitPartitionExecPruning(), extract_lateral_vars_from_PHVs(), extract_rollup_sets(), fetch_upper_rel(), find_dependent_phvs_walker(), find_join_rel(), find_param_path_info(), generate_grouped_paths(), generate_implied_equalities_for_column(), generate_partitionwise_join_paths(), get_cheapest_parameterized_child_path(), get_eclass_for_sort_expr(), get_join_domain_min_rels(), has_join_restriction(), infer_arbiter_indexes(), innerrel_is_unique_ext(), is_safe_restriction_clause_for(), join_is_legal(), make_grouped_join_rel(), make_one_rel(), make_partitionedrel_pruneinfo(), mark_nullable_by_grouping(), match_pathkeys_to_index(), merge_clump(), pgoutput_column_list_init(), populate_joinrel_with_paths(), pull_varnos_walker(), search_indexed_tlist_for_phv(), search_indexed_tlist_for_var(), set_rel_pathlist(), standard_join_search(), test_bms_equal(), and try_partitionwise_join().

◆ bms_free()

◆ bms_get_singleton_member()

bool bms_get_singleton_member ( const Bitmapset a,
int member 
)

Definition at line 714 of file bitmapset.c.

715{
716 int result = -1;
717 int nwords;
718 int wordnum;
719
721
722 if (a == NULL)
723 return false;
724
725 nwords = a->nwords;
726 wordnum = 0;
727 do
728 {
729 bitmapword w = a->words[wordnum];
730
731 if (w != 0)
732 {
733 if (result >= 0 || HAS_MULTIPLE_ONES(w))
734 return false;
735 result = wordnum * BITS_PER_BITMAPWORD;
736 result += bmw_rightmost_one_pos(w);
737 }
738 } while (++wordnum < nwords);
739
740 /* we don't expect non-NULL sets to be empty */
741 Assert(result >= 0);
742 *member = result;
743 return true;
744}

References a, Assert, BITS_PER_BITMAPWORD, bmw_rightmost_one_pos, fb(), and HAS_MULTIPLE_ONES.

Referenced by add_placeholders_to_base_rels(), create_lateral_join_info(), distribute_restrictinfo_to_rels(), estimate_multivariate_bucketsize(), examine_variable(), find_join_input_rel(), find_single_rel_for_clauses(), generate_base_implied_equalities_no_const(), get_common_eclass_indexes(), join_is_removable(), reduce_unique_semijoins(), replace_relid_callback(), set_base_rel_consider_startup(), statext_is_compatible_clause(), and test_bms_get_singleton_member().

◆ bms_hash_value()

uint32 bms_hash_value ( const Bitmapset a)

Definition at line 1417 of file bitmapset.c.

1418{
1420
1421 if (a == NULL)
1422 return 0; /* All empty sets hash to 0 */
1423 return DatumGetUInt32(hash_any((const unsigned char *) a->words,
1424 a->nwords * sizeof(bitmapword)));
1425}

References a, Assert, DatumGetUInt32(), fb(), and hash_any().

Referenced by bitmap_hash(), and test_bms_hash_value().

◆ bms_int_members()

Bitmapset * bms_int_members ( Bitmapset a,
const Bitmapset b 
)

Definition at line 1108 of file bitmapset.c.

1109{
1110 int lastnonzero;
1111 int shortlen;
1112 int i;
1113
1116
1117 /* Handle cases where either input is NULL */
1118 if (a == NULL)
1119 return NULL;
1120 if (b == NULL)
1121 {
1122 pfree(a);
1123 return NULL;
1124 }
1125
1126 /* Intersect b into a; we need never copy */
1127 shortlen = Min(a->nwords, b->nwords);
1128 lastnonzero = -1;
1129 i = 0;
1130 do
1131 {
1132 a->words[i] &= b->words[i];
1133
1134 if (a->words[i] != 0)
1135 lastnonzero = i;
1136 } while (++i < shortlen);
1137
1138 /* If we computed an empty result, we must return NULL */
1139 if (lastnonzero == -1)
1140 {
1141 pfree(a);
1142 return NULL;
1143 }
1144
1145 /* get rid of trailing zero words */
1146 a->nwords = lastnonzero + 1;
1147
1148#ifdef REALLOCATE_BITMAPSETS
1150#endif
1151
1152 return a;
1153}

References a, Assert, b, fb(), i, Min, and pfree().

Referenced by find_nonnullable_rels_walker(), find_placeholder_info(), get_common_eclass_indexes(), get_param_path_clause_serials(), make_outerjoininfo(), make_row_comparison_op(), mbms_int_members(), perform_pruning_combine_step(), relation_is_updatable(), and test_bms_int_members().

◆ bms_intersect()

Bitmapset * bms_intersect ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 292 of file bitmapset.c.

293{
294 Bitmapset *result;
295 const Bitmapset *other;
296 int lastnonzero;
297 int resultlen;
298 int i;
299
302
303 /* Handle cases where either input is NULL */
304 if (a == NULL || b == NULL)
305 return NULL;
306
307 /* Identify shorter and longer input; copy the shorter one */
308 if (a->nwords <= b->nwords)
309 {
310 result = bms_copy(a);
311 other = b;
312 }
313 else
314 {
315 result = bms_copy(b);
316 other = a;
317 }
318 /* And intersect the longer input with the result */
319 resultlen = result->nwords;
320 lastnonzero = -1;
321 i = 0;
322 do
323 {
324 result->words[i] &= other->words[i];
325
326 if (result->words[i] != 0)
327 lastnonzero = i;
328 } while (++i < resultlen);
329 /* If we computed an empty result, we must return NULL */
330 if (lastnonzero == -1)
331 {
332 pfree(result);
333 return NULL;
334 }
335
336 /* get rid of trailing zero words */
337 result->nwords = lastnonzero + 1;
338 return result;
339}

References a, Assert, b, bms_copy(), fb(), i, Bitmapset::nwords, pfree(), and Bitmapset::words.

Referenced by build_joinrel_tlist(), classify_matching_subplans(), create_lateral_join_info(), distribute_qual_to_rels(), find_em_for_rel(), get_matching_part_pairs(), identify_current_nestloop_params(), make_outerjoininfo(), match_eclasses_to_foreign_key_col(), pullup_replace_vars_callback(), rebuild_joinclause_attr_needed(), set_param_references(), test_bms_intersect(), test_random_operations(), and UpdateChangedParamSet().

◆ bms_is_member()

bool bms_is_member ( int  x,
const Bitmapset a 
)

Definition at line 510 of file bitmapset.c.

511{
512 int wordnum,
513 bitnum;
514
516
517 /* XXX better to just return false for x<0 ? */
518 if (x < 0)
519 elog(ERROR, "negative bitmapset member not allowed");
520 if (a == NULL)
521 return false;
522
523 wordnum = WORDNUM(x);
524 bitnum = BITNUM(x);
525 if (wordnum >= a->nwords)
526 return false;
527 if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
528 return true;
529 return false;
530}

References a, Assert, BITNUM, elog, ERROR, fb(), WORDNUM, and x.

Referenced by add_non_redundant_clauses(), add_nulling_relids_mutator(), add_outer_joins_to_relids(), add_row_identity_var(), adjust_appendrel_attrs_mutator(), adjust_child_relids(), adjust_relid_set(), adjust_rowcount_for_semijoins(), bms_member_index(), build_joinrel_tlist(), check_index_predicates(), check_redundant_nullability_qual(), check_relation_privileges(), checkInsertTargets(), clause_selectivity_ext(), clauselist_selectivity_ext(), clauselist_selectivity_or(), ComputePartitionAttrs(), consider_groupingsets_paths(), contain_invalid_rfcolumn_walker(), contain_placeholder_references_walker(), cost_incremental_sort(), create_foreignscan_plan(), create_lateral_join_info(), create_nestloop_path(), createTableConstraints(), deconstruct_distribute_oj_quals(), DefineIndex(), deparseFromExprForRel(), deparseLockingClause(), deparseRangeTblRef(), deparseTargetList(), deparseVar(), dependencies_clauselist_selectivity(), dependency_is_fully_matched(), do_analyze_rel(), DoCopy(), dropconstraint_internal(), enum_known_sorted(), estimate_multivariate_ndistinct(), examine_variable(), ExecBuildSlotValueDescription(), ExecBuildUpdateProjection(), ExecCheckPermissions(), ExecEvalGroupingFunc(), ExecGetRangeTableRelation(), ExecInitLockRows(), ExecInitModifyTable(), ExecScanFetch(), execute_attr_map_cols(), expand_indexqual_rowcompare(), expand_single_inheritance_child(), ExplainSubPlans(), extract_lateral_vars_from_PHVs(), extractRemainingColumns(), ExtractReplicaIdentity(), fetch_remote_table_info(), filter_event_trigger(), find_hash_columns(), find_modifytable_subplan(), fixup_whole_row_references(), foreign_expr_walker(), func_get_detail(), gen_partprune_steps_internal(), gen_prune_steps_from_opexps(), generate_base_implied_equalities(), get_eclass_for_sort_expr(), get_eclass_indexes_for_relids(), get_expression_sortgroupref(), get_foreign_key_join_selectivity(), get_join_domain_min_rels(), get_matching_hash_bounds(), get_memoize_path(), get_placeholder_nulling_relids(), get_translated_update_targetlist(), get_variable(), get_xmltable(), group_similar_or_args(), has_partition_attrs(), hashagg_spill_tuple(), HeapDetermineColumnsInfo(), identify_current_nestloop_params(), index_expression_changed_walker(), index_unchanged_by_update(), InitPartitionPruneContext(), InitPlan(), is_foreign_param(), is_pseudo_constant_for_index(), is_subquery_var(), is_var_in_aggref_only(), IsBinaryTidClause(), isPlainForeignVar(), IsTidEqualAnyClause(), join_clause_is_movable_to(), join_is_removable(), lo_manage(), logicalrep_rel_mark_updatable(), logicalrep_should_publish_column(), logicalrep_write_attrs(), make_outerjoininfo(), make_window_input_target(), mark_expr(), mark_invalid_subplans_as_finished(), mark_rels_nulled_by_join(), match_opclause_to_indexcol(), match_orclause_to_indexcol(), match_rowcompare_to_indexcol(), match_saopclause_to_indexcol(), mbms_is_member(), MergeAttributes(), partitions_are_ordered(), perform_pruning_base_step(), plpgsql_param_fetch(), postgresExplainForeignScan(), prepare_projection_slot(), preprocess_rowmarks(), process_subquery_nestloop_params(), pub_collist_validate(), pub_contains_invalid_column(), pullup_replace_vars_callback(), rangeTableEntry_used_walker(), rebuild_joinclause_attr_needed(), remove_leftjoinrel_from_query(), remove_nulling_relids_mutator(), remove_rel_from_eclass(), remove_rel_from_query(), remove_self_joins_one_group(), remove_self_joins_recurse(), remove_unused_subquery_outputs(), remove_useless_groupby_columns(), replace_nestloop_params_mutator(), replace_relid_callback(), rewriteTargetListIU(), rewriteValuesRTE(), semijoin_target_ok(), set_join_column_names(), set_rtable_names(), show_modifytable_info(), statext_mcv_clauselist_selectivity(), subquery_planner(), substitute_phv_relids_walker(), test_bms_is_member(), test_random_operations(), tfuncLoadRows(), transformGroupClauseExpr(), translate_col_privs(), TriggerEnabled(), try_hashjoin_path(), try_mergejoin_path(), try_nestloop_path(), tsvector_update_trigger(), tuples_equal(), update_eclasses(), use_physical_tlist(), var_is_nonnullable(), and view_cols_are_auto_updatable().

◆ bms_is_subset()

bool bms_is_subset ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 412 of file bitmapset.c.

413{
414 int i;
415
418
419 /* Handle cases where either input is NULL */
420 if (a == NULL)
421 return true; /* empty set is a subset of anything */
422 if (b == NULL)
423 return false;
424
425 /* 'a' can't be a subset of 'b' if it contains more words */
426 if (a->nwords > b->nwords)
427 return false;
428
429 /* Check all 'a' members are set in 'b' */
430 i = 0;
431 do
432 {
433 if ((a->words[i] & ~b->words[i]) != 0)
434 return false;
435 } while (++i < a->nwords);
436 return true;
437}

References a, Assert, b, fb(), and i.

Referenced by add_child_rel_equivalences(), add_outer_joins_to_relids(), add_paths_to_joinrel(), add_placeholders_to_joinrel(), add_vars_to_attr_needed(), add_vars_to_targetlist(), build_joinrel_tlist(), check_functional_grouping(), check_index_only(), choose_best_statistics(), clause_sides_match_join(), compute_semijoin_info(), convert_ANY_sublink_to_join(), convert_EXISTS_sublink_to_join(), create_agg_clause_infos(), create_index_paths(), distribute_qual_to_rels(), eager_aggregation_possible_for_relation(), eclass_already_used(), eclass_useful_for_merging(), extract_lateral_vars_from_PHVs(), extract_rollup_sets(), final_cost_hashjoin(), finalize_plan(), find_computable_ec_member(), find_ec_member_matching_expr(), find_em_for_rel(), find_join_domain(), foreign_join_ok(), generate_implied_equalities_for_column(), generate_join_implied_equalities_broken(), generate_join_implied_equalities_normal(), get_appendrel_parampathinfo(), get_baserel_parampathinfo(), get_cheapest_fractional_path_for_pathkeys(), get_cheapest_parameterized_child_path(), get_cheapest_path_for_pathkeys(), get_join_index_paths(), get_join_variables(), get_joinrel_parampathinfo(), get_switched_clauses(), has_join_restriction(), has_relevant_eclass_joinclause(), have_join_order_restriction(), have_partkey_equi_join(), identify_current_nestloop_params(), initial_cost_mergejoin(), innerrel_is_unique_ext(), is_simple_subquery(), join_clause_is_movable_into(), join_is_legal(), join_is_removable(), jointree_contains_lateral_outer_refs(), make_grouped_join_rel(), make_outerjoininfo(), pg_get_expr_worker(), populate_joinrel_with_paths(), process_implied_equality(), process_subquery_nestloop_params(), pullup_replace_vars_callback(), remove_rel_from_query(), reparameterize_path(), replace_nestloop_params_mutator(), search_indexed_tlist_for_phv(), search_indexed_tlist_for_var(), statext_mcv_clauselist_selectivity(), subbuild_joinrel_joinlist(), subbuild_joinrel_restrictlist(), test_bms_is_subset(), try_partial_nestloop_path(), and use_physical_tlist().

◆ bms_join()

Bitmapset * bms_join ( Bitmapset a,
Bitmapset b 
)

Definition at line 1229 of file bitmapset.c.

1230{
1231 Bitmapset *result;
1233 int otherlen;
1234 int i;
1235
1238
1239 /* Handle cases where either input is NULL */
1240 if (a == NULL)
1241 {
1242#ifdef REALLOCATE_BITMAPSETS
1244#endif
1245
1246 return b;
1247 }
1248 if (b == NULL)
1249 {
1250#ifdef REALLOCATE_BITMAPSETS
1252#endif
1253
1254 return a;
1255 }
1256
1257 /* Identify shorter and longer input; use longer one as result */
1258 if (a->nwords < b->nwords)
1259 {
1260 result = b;
1261 other = a;
1262 }
1263 else
1264 {
1265 result = a;
1266 other = b;
1267 }
1268 /* And union the shorter input into the result */
1270 i = 0;
1271 do
1272 {
1273 result->words[i] |= other->words[i];
1274 } while (++i < otherlen);
1275 if (other != result) /* pure paranoia */
1276 pfree(other);
1277
1278#ifdef REALLOCATE_BITMAPSETS
1279 result = bms_copy_and_free(result);
1280#endif
1281
1282 return result;
1283}

References a, Assert, b, fb(), i, Bitmapset::nwords, pfree(), and Bitmapset::words.

Referenced by add_paths_to_joinrel(), alias_relid_set(), build_joinrel_tlist(), finalize_primnode(), find_nonnullable_rels_walker(), get_partkey_exec_paramids(), get_relids_in_jointree(), make_partition_pruneinfo(), process_equivalence(), pull_up_sublinks_jointree_recurse(), pull_varnos_walker(), test_bms_join(), and UpdateChangedParamSet().

◆ bms_make_singleton()

Bitmapset * bms_make_singleton ( int  x)

Definition at line 216 of file bitmapset.c.

217{
218 Bitmapset *result;
219 int wordnum,
220 bitnum;
221
222 if (x < 0)
223 elog(ERROR, "negative bitmapset member not allowed");
224 wordnum = WORDNUM(x);
225 bitnum = BITNUM(x);
226 result = (Bitmapset *) palloc0(BITMAPSET_SIZE(wordnum + 1));
227 result->type = T_Bitmapset;
228 result->nwords = wordnum + 1;
229 result->words[wordnum] = ((bitmapword) 1 << bitnum);
230 return result;
231}

References BITMAPSET_SIZE, BITNUM, elog, ERROR, fb(), Bitmapset::nwords, palloc0(), WORDNUM, Bitmapset::words, and x.

Referenced by add_row_identity_var(), ATExecDropColumn(), ATPrepAlterColumnType(), bms_add_member(), build_base_rel_tlists(), build_simple_rel(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), deconstruct_distribute_oj_quals(), deconstruct_recurse(), deparseReturningList(), DiscreteKnapsack(), examine_simple_variable(), expand_inherited_rtentry(), extract_lateral_references(), find_dependent_phvs(), find_dependent_phvs_in_jointree(), find_nonnullable_rels_walker(), get_matching_hash_bounds(), get_matching_list_bounds(), get_matching_range_bounds(), get_relids_in_jointree(), load_enum_cache_data(), make_group_input_target(), make_pathkeys_for_sortclauses_extended(), mark_nullable_by_grouping(), pg_column_is_updatable(), pg_get_expr_worker(), pull_up_sublinks_jointree_recurse(), pullup_replace_vars_callback(), rebuild_lateral_attr_needed(), reconsider_full_join_clause(), reduce_outer_joins(), reduce_outer_joins_pass1(), remove_rel_from_query(), set_upper_references(), split_pathtarget_walker(), subquery_planner(), test_bms_make_singleton(), and transform_MERGE_to_join().

◆ bms_member_index()

int bms_member_index ( Bitmapset a,
int  x 
)

Definition at line 539 of file bitmapset.c.

540{
541 int bitnum;
542 int wordnum;
543 int result = 0;
544 bitmapword mask;
545
547
548 /* return -1 if not a member of the bitmap */
549 if (!bms_is_member(x, a))
550 return -1;
551
552 wordnum = WORDNUM(x);
553 bitnum = BITNUM(x);
554
555 /* count bits in preceding words */
556 for (int i = 0; i < wordnum; i++)
557 {
558 bitmapword w = a->words[i];
559
560 /* No need to count the bits in a zero word */
561 if (w != 0)
562 result += bmw_popcount(w);
563 }
564
565 /*
566 * Now add bits of the last word, but only those before the item. We can
567 * do that by applying a mask and then using popcount again. To get
568 * 0-based index, we want to count only preceding bits, not the item
569 * itself, so we subtract 1.
570 */
571 mask = ((bitmapword) 1 << bitnum) - 1;
572 result += bmw_popcount(a->words[wordnum] & mask);
573
574 return result;
575}

References a, Assert, BITNUM, bms_is_member(), bmw_popcount, fb(), i, WORDNUM, and x.

Referenced by clauselist_apply_dependencies(), mcv_get_match_bitmap(), mcv_match_expression(), and test_bms_member_index().

◆ bms_membership()

BMS_Membership bms_membership ( const Bitmapset a)

◆ bms_next_member()

int bms_next_member ( const Bitmapset a,
int  prevbit 
)

Definition at line 1305 of file bitmapset.c.

1306{
1307 int nwords;
1308 bitmapword mask;
1309
1311
1312 if (a == NULL)
1313 return -2;
1314 nwords = a->nwords;
1315 prevbit++;
1316 mask = (~(bitmapword) 0) << BITNUM(prevbit);
1317 for (int wordnum = WORDNUM(prevbit); wordnum < nwords; wordnum++)
1318 {
1319 bitmapword w = a->words[wordnum];
1320
1321 /* ignore bits before prevbit */
1322 w &= mask;
1323
1324 if (w != 0)
1325 {
1326 int result;
1327
1328 result = wordnum * BITS_PER_BITMAPWORD;
1329 result += bmw_rightmost_one_pos(w);
1330 return result;
1331 }
1332
1333 /* in subsequent words, consider all bits */
1334 mask = (~(bitmapword) 0);
1335 }
1336 return -2;
1337}

References a, Assert, BITNUM, BITS_PER_BITMAPWORD, bmw_rightmost_one_pos, fb(), and WORDNUM.

Referenced by add_child_join_rel_equivalences(), add_child_rel_equivalences(), add_join_clause_to_rels(), add_part_relids(), adjust_group_pathkeys_for_groupagg(), adjust_view_column_set(), alias_relid_set(), all_rows_selectable(), apply_scanjoin_target_to_paths(), approximate_joinrel_size(), attnumstoint2vector(), build_attnums_array(), check_relation_privileges(), check_selective_binary_conversion(), choose_next_subplan_for_worker(), choose_next_subplan_locally(), clauselist_apply_dependencies(), ComputePartitionAttrs(), convert_EXISTS_sublink_to_join(), create_lateral_join_info(), create_partitionwise_grouping_paths(), CreatePartitionPruneState(), CreateStatistics(), DefineIndex(), deparseLockingClause(), dependencies_clauselist_selectivity(), DoCopy(), eager_aggregation_possible_for_relation(), eclass_member_iterator_next(), EstimateParamExecSpace(), ExecAppendAsyncBegin(), ExecAppendAsyncEventWait(), ExecAppendAsyncRequest(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), ExecInitAgg(), ExecInitAppend(), ExecInitMergeAppend(), ExecMergeAppend(), ExecReScanAppend(), ExecScanReScan(), ExecSetParamPlanMulti(), expand_partitioned_rtentry(), find_appinfos_by_relids(), find_dependent_phvs_in_jointree(), find_hash_columns(), find_matching_subplans_recurse(), fixup_inherited_columns(), format_expr_params(), generate_base_implied_equalities(), generate_implied_equalities_for_column(), generate_join_implied_equalities(), get_eclass_for_sort_expr(), get_eclass_indexes_for_relids(), get_loop_count(), get_matching_partitions(), get_placeholder_nulling_relids(), grouping_planner(), has_relevant_eclass_joinclause(), have_relevant_eclass_joinclause(), HeapDetermineColumnsInfo(), InitExecPartitionPruneContexts(), logicalrep_get_attrs_str(), logicalrep_rel_mark_updatable(), lookup_var_attr_stats(), make_build_data(), make_partitionedrel_pruneinfo(), make_row_comparison_op(), mark_rels_nulled_by_join(), match_eclasses_to_foreign_key_col(), offset_relid_set(), offset_relid_set(), outBitmapset(), overexplain_bitmapset(), postgresBeginForeignScan(), postgresExplainForeignScan(), postgresPlanForeignModify(), pub_contains_invalid_column(), publication_add_relation(), pullup_replace_vars_callback(), remove_join_clause_from_rels(), remove_self_join_rel(), remove_self_joins_one_group(), remove_self_joins_recurse(), remove_useless_results_recurse(), remove_useless_self_joins(), SerializeParamExecParams(), show_result_replacement_info(), statext_is_compatible_clause(), test_bms_next_member(), and test_random_operations().

◆ bms_nonempty_difference()

bool bms_nonempty_difference ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 640 of file bitmapset.c.

641{
642 int i;
643
646
647 /* Handle cases where either input is NULL */
648 if (a == NULL)
649 return false;
650 if (b == NULL)
651 return true;
652 /* if 'a' has more words then it must contain additional members */
653 if (a->nwords > b->nwords)
654 return true;
655 /* Check all 'a' members are set in 'b' */
656 i = 0;
657 do
658 {
659 if ((a->words[i] & ~b->words[i]) != 0)
660 return true;
661 } while (++i < a->nwords);
662 return false;
663}

References a, Assert, b, fb(), and i.

Referenced by add_placeholders_to_base_rels(), add_placeholders_to_joinrel(), allow_star_schema_join(), bms_difference(), build_joinrel_tlist(), ExecReScanMemoize(), foreign_join_ok(), is_var_needed_by_join(), test_bms_nonempty_difference(), and use_physical_tlist().

◆ bms_num_members()

int bms_num_members ( const Bitmapset a)

◆ bms_overlap()

bool bms_overlap ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 581 of file bitmapset.c.

582{
583 int shortlen;
584 int i;
585
588
589 /* Handle cases where either input is NULL */
590 if (a == NULL || b == NULL)
591 return false;
592 /* Check words in common */
593 shortlen = Min(a->nwords, b->nwords);
594 i = 0;
595 do
596 {
597 if ((a->words[i] & b->words[i]) != 0)
598 return true;
599 } while (++i < shortlen);
600 return false;
601}

References a, Assert, b, fb(), i, and Min.

Referenced by add_child_join_rel_equivalences(), add_nulling_relids_mutator(), add_paths_to_joinrel(), adjust_child_relids_multilevel(), allow_star_schema_join(), calc_nestloop_required_outer(), calc_non_nestloop_required_outer(), choose_bitmap_and(), classify_matching_subplans(), compute_semijoin_info(), create_nestloop_path(), distribute_qual_to_rels(), eclass_useful_for_merging(), examine_variable(), ExecInitGenerated(), ExecReScanAgg(), ExecReScanAppend(), ExecReScanFunctionScan(), ExecReScanMergeAppend(), ExecUpdateLockMode(), extract_lateral_vars_from_PHVs(), generate_implied_equalities_for_column(), generate_join_implied_equalities(), generate_join_implied_equalities_for_ecs(), get_appendrel_parampathinfo(), get_baserel_parampathinfo(), get_dependent_generated_columns(), get_joinrel_parampathinfo(), get_useful_ecs_for_relation(), has_join_restriction(), has_legal_joinclause(), has_partition_attrs(), have_join_order_restriction(), have_partkey_equi_join(), have_relevant_eclass_joinclause(), have_relevant_joinclause(), heap_update(), identify_current_nestloop_params(), join_clause_is_movable_into(), join_clause_is_movable_to(), join_is_legal(), join_is_removable(), join_search_one_level(), make_join_rel(), make_outerjoininfo(), make_plain_restrictinfo(), make_rels_by_clause_joins(), make_rels_by_clauseless_joins(), mbms_overlap_sets(), partitions_are_ordered(), path_is_reparameterizable_by_child(), pullup_replace_vars_callback(), reduce_outer_joins_pass2(), remove_nulling_relids_mutator(), remove_self_joins_recurse(), reparameterize_path_by_child(), select_outer_pathkeys_for_merge(), set_append_rel_size(), subbuild_joinrel_restrictlist(), test_bms_overlap(), try_hashjoin_path(), try_mergejoin_path(), try_nestloop_path(), and try_partitionwise_join().

◆ bms_overlap_list()

bool bms_overlap_list ( const Bitmapset a,
const List b 
)

Definition at line 607 of file bitmapset.c.

608{
609 ListCell *lc;
610 int wordnum,
611 bitnum;
612
614
615 if (a == NULL || b == NIL)
616 return false;
617
618 foreach(lc, b)
619 {
620 int x = lfirst_int(lc);
621
622 if (x < 0)
623 elog(ERROR, "negative bitmapset member not allowed");
624 wordnum = WORDNUM(x);
625 bitnum = BITNUM(x);
626 if (wordnum < a->nwords)
627 if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
628 return true;
629 }
630
631 return false;
632}

References a, Assert, b, BITNUM, elog, ERROR, fb(), lfirst_int, NIL, WORDNUM, and x.

Referenced by preprocess_grouping_sets(), and test_bms_overlap_list().

◆ bms_prev_member()

int bms_prev_member ( const Bitmapset a,
int  prevbit 
)

Definition at line 1365 of file bitmapset.c.

1366{
1367 int ushiftbits;
1368 bitmapword mask;
1369
1371
1372 /*
1373 * If set is NULL or if there are no more bits to the right then we've
1374 * nothing to do.
1375 */
1376 if (a == NULL || prevbit == 0)
1377 return -2;
1378
1379 /* Validate callers didn't give us something out of range */
1381 Assert(prevbit >= -1);
1382
1383 /* transform -1 to the highest possible bit we could have set */
1384 if (prevbit == -1)
1385 prevbit = a->nwords * BITS_PER_BITMAPWORD - 1;
1386 else
1387 prevbit--;
1388
1390 mask = (~(bitmapword) 0) >> ushiftbits;
1391 for (int wordnum = WORDNUM(prevbit); wordnum >= 0; wordnum--)
1392 {
1393 bitmapword w = a->words[wordnum];
1394
1395 /* mask out bits left of prevbit */
1396 w &= mask;
1397
1398 if (w != 0)
1399 {
1400 int result;
1401
1402 result = wordnum * BITS_PER_BITMAPWORD;
1403 result += bmw_leftmost_one_pos(w);
1404 return result;
1405 }
1406
1407 /* in subsequent words, consider all bits */
1408 mask = (~(bitmapword) 0);
1409 }
1410 return -2;
1411}

References a, Assert, BITNUM, BITS_PER_BITMAPWORD, bmw_leftmost_one_pos, fb(), and WORDNUM.

Referenced by choose_next_subplan_locally(), and test_bms_prev_member().

◆ bms_replace_members()

Bitmapset * bms_replace_members ( Bitmapset a,
const Bitmapset b 
)

Definition at line 971 of file bitmapset.c.

972{
973 int i;
974
977
978 if (a == NULL)
979 return bms_copy(b);
980 if (b == NULL)
981 {
982 pfree(a);
983 return NULL;
984 }
985
986 if (a->nwords < b->nwords)
987 a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(b->nwords));
988
989 i = 0;
990 do
991 {
992 a->words[i] = b->words[i];
993 } while (++i < b->nwords);
994
995 a->nwords = b->nwords;
996
997#ifdef REALLOCATE_BITMAPSETS
998
999 /*
1000 * There's no guarantee that the repalloc returned a new pointer, so copy
1001 * and free unconditionally here.
1002 */
1004#endif
1005
1006 return a;
1007}

References a, Assert, b, BITMAPSET_SIZE, bms_copy(), fb(), i, pfree(), and repalloc().

Referenced by DiscreteKnapsack(), and test_bms_replace_members().

◆ bms_singleton_member()

int bms_singleton_member ( const Bitmapset a)

Definition at line 671 of file bitmapset.c.

672{
673 int result = -1;
674 int nwords;
675 int wordnum;
676
678
679 if (a == NULL)
680 elog(ERROR, "bitmapset is empty");
681
682 nwords = a->nwords;
683 wordnum = 0;
684 do
685 {
686 bitmapword w = a->words[wordnum];
687
688 if (w != 0)
689 {
690 if (result >= 0 || HAS_MULTIPLE_ONES(w))
691 elog(ERROR, "bitmapset has multiple members");
692 result = wordnum * BITS_PER_BITMAPWORD;
693 result += bmw_rightmost_one_pos(w);
694 }
695 } while (++wordnum < nwords);
696
697 /* we don't expect non-NULL sets to be empty */
698 Assert(result >= 0);
699 return result;
700}

References a, Assert, BITS_PER_BITMAPWORD, bmw_rightmost_one_pos, elog, ERROR, fb(), and HAS_MULTIPLE_ONES.

Referenced by fix_append_rel_relids(), get_matching_part_pairs(), remove_useless_joins(), split_selfjoin_quals(), and test_bms_singleton_member().

◆ bms_subset_compare()

BMS_Comparison bms_subset_compare ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 445 of file bitmapset.c.

446{
447 BMS_Comparison result;
448 int shortlen;
449 int i;
450
453
454 /* Handle cases where either input is NULL */
455 if (a == NULL)
456 {
457 if (b == NULL)
458 return BMS_EQUAL;
459 return BMS_SUBSET1;
460 }
461 if (b == NULL)
462 return BMS_SUBSET2;
463
464 /* Check common words */
465 result = BMS_EQUAL; /* status so far */
466 shortlen = Min(a->nwords, b->nwords);
467 i = 0;
468 do
469 {
470 bitmapword aword = a->words[i];
471 bitmapword bword = b->words[i];
472
473 if ((aword & ~bword) != 0)
474 {
475 /* a is not a subset of b */
476 if (result == BMS_SUBSET1)
477 return BMS_DIFFERENT;
478 result = BMS_SUBSET2;
479 }
480 if ((bword & ~aword) != 0)
481 {
482 /* b is not a subset of a */
483 if (result == BMS_SUBSET2)
484 return BMS_DIFFERENT;
485 result = BMS_SUBSET1;
486 }
487 } while (++i < shortlen);
488 /* Check extra words */
489 if (a->nwords > b->nwords)
490 {
491 /* if a has more words then a is not a subset of b */
492 if (result == BMS_SUBSET1)
493 return BMS_DIFFERENT;
494 return BMS_SUBSET2;
495 }
496 else if (a->nwords < b->nwords)
497 {
498 /* if b has more words then b is not a subset of a */
499 if (result == BMS_SUBSET2)
500 return BMS_DIFFERENT;
501 return BMS_SUBSET1;
502 }
503 return result;
504}

References a, Assert, b, BMS_DIFFERENT, BMS_EQUAL, BMS_SUBSET1, BMS_SUBSET2, fb(), i, and Min.

Referenced by add_path(), consider_index_join_outer_rels(), remove_useless_groupby_columns(), set_cheapest(), and test_bms_subset_compare().

◆ bms_union()

Bitmapset * bms_union ( const Bitmapset a,
const Bitmapset b 
)

Definition at line 251 of file bitmapset.c.

252{
253 Bitmapset *result;
254 const Bitmapset *other;
255 int otherlen;
256 int i;
257
260
261 /* Handle cases where either input is NULL */
262 if (a == NULL)
263 return bms_copy(b);
264 if (b == NULL)
265 return bms_copy(a);
266 /* Identify shorter and longer input; copy the longer one */
267 if (a->nwords <= b->nwords)
268 {
269 result = bms_copy(b);
270 other = a;
271 }
272 else
273 {
274 result = bms_copy(a);
275 other = b;
276 }
277 /* And union the shorter input into the result */
278 otherlen = other->nwords;
279 i = 0;
280 do
281 {
282 result->words[i] |= other->words[i];
283 } while (++i < otherlen);
284 return result;
285}

References a, Assert, b, bms_copy(), fb(), i, and Bitmapset::words.

Referenced by add_nulling_relids_mutator(), build_join_rel(), build_joinrel_restrictlist(), BuildParameterizedTidPaths(), calc_nestloop_required_outer(), calc_non_nestloop_required_outer(), check_index_predicates(), check_relation_privileges(), compute_semijoin_info(), consider_index_join_outer_rels(), create_join_clause(), create_nestloop_plan(), deconstruct_distribute(), deconstruct_distribute_oj_quals(), deconstruct_jointree(), deconstruct_recurse(), ExecConstraints(), ExecGetAllUpdatedCols(), ExecPartitionCheckEmitError(), ExecWithCheckOptions(), finalize_plan(), find_hash_columns(), foreign_join_ok(), generate_join_implied_equalities(), generate_join_implied_equalities_for_ecs(), generate_nonunion_paths(), generate_recursion_path(), get_baserel_parampathinfo(), get_joinrel_parampathinfo(), get_rel_all_updated_cols(), get_tuple_desc(), has_legal_joinclause(), identify_current_nestloop_params(), index_unchanged_by_update(), join_is_removable(), make_join_rel(), make_outerjoininfo(), make_plain_restrictinfo(), markNullableIfNeeded(), min_join_parameterization(), postgresGetForeignPaths(), pull_up_sublinks_jointree_recurse(), reduce_unique_semijoins(), remove_leftjoinrel_from_query(), ReportNotNullViolationError(), resolve_special_varno(), rewriteTargetView(), substitute_phv_relids_walker(), test_bms_union(), test_random_operations(), and try_partitionwise_join().