return result;
}
+/*
+ * bms_get_singleton_member
+ *
+ * Test whether the given set is a singleton.
+ * If so, set *member to the value of its sole member, and return TRUE.
+ * If not, return FALSE, without changing *member.
+ *
+ * This is more convenient and faster than calling bms_membership() and then
+ * bms_singleton_member(), if we don't care about distinguishing empty sets
+ * from multiple-member sets.
+ */
+bool
+bms_get_singleton_member(const Bitmapset *a, int *member)
+{
+ int result = -1;
+ int nwords;
+ int wordnum;
+
+ if (a == NULL)
+ return false;
+ nwords = a->nwords;
+ for (wordnum = 0; wordnum < nwords; wordnum++)
+ {
+ bitmapword w = a->words[wordnum];
+
+ if (w != 0)
+ {
+ if (result >= 0 || HAS_MULTIPLE_ONES(w))
+ return false;
+ result = wordnum * BITS_PER_BITMAPWORD;
+ while ((w & 255) == 0)
+ {
+ w >>= 8;
+ result += 8;
+ }
+ result += rightmost_one_pos[w & 255];
+ }
+ }
+ if (result < 0)
+ return false;
+ *member = result;
+ return true;
+}
+
/*
* bms_num_members - count members of set
*/
int relid;
Assert(!cur_em->em_is_child); /* no children yet */
- if (bms_membership(cur_em->em_relids) != BMS_SINGLETON)
+ if (!bms_get_singleton_member(cur_em->em_relids, &relid))
continue;
- relid = bms_singleton_member(cur_em->em_relids);
Assert(relid < root->simple_rel_array_size);
if (prev_ems[relid] != NULL)
* going to be able to do anything with it.
*/
if (sjinfo->jointype != JOIN_LEFT ||
- sjinfo->delay_upper_joins ||
- bms_membership(sjinfo->min_righthand) != BMS_SINGLETON)
+ sjinfo->delay_upper_joins)
+ return false;
+
+ if (!bms_get_singleton_member(sjinfo->min_righthand, &innerrelid))
return false;
- innerrelid = bms_singleton_member(sjinfo->min_righthand);
innerrel = find_base_rel(root, innerrelid);
if (innerrel->reloptkind != RELOPT_BASEREL)
{
PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
Relids eval_at = phinfo->ph_eval_at;
+ int varno;
- if (bms_membership(eval_at) == BMS_SINGLETON)
+ if (bms_get_singleton_member(eval_at, &varno))
{
- int varno = bms_singleton_member(eval_at);
RelOptInfo *rel = find_base_rel(root, varno);
/* add it to reltargetlist if needed above the rel scan level */
extern bool bms_overlap(const Bitmapset *a, const Bitmapset *b);
extern bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b);
extern int bms_singleton_member(const Bitmapset *a);
+extern bool bms_get_singleton_member(const Bitmapset *a, int *member);
extern int bms_num_members(const Bitmapset *a);
/* optimized tests when we don't need to know exact membership count: */