Commit d25367ec authored by Tom Lane's avatar Tom Lane

Add bms_get_singleton_member(), and use it where appropriate.

This patch adds a function that replaces a bms_membership() test followed
by a bms_singleton_member() call, performing both the test and the
extraction of a singleton set's member in one scan of the bitmapset.
The performance advantage over the old way is probably minimal in current
usage, but it seems worthwhile on notational grounds anyway.

David Rowley
parent f4e031c6
......@@ -524,6 +524,50 @@ bms_singleton_member(const Bitmapset *a)
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
*/
......
......@@ -867,9 +867,8 @@ generate_base_implied_equalities_no_const(PlannerInfo *root,
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)
......
......@@ -162,11 +162,12 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
* 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)
......
......@@ -383,10 +383,10 @@ add_placeholders_to_base_rels(PlannerInfo *root)
{
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 */
......
......@@ -72,6 +72,7 @@ extern bool bms_is_member(int x, const Bitmapset *a);
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: */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment