While working on the patch in [1], I noticed that ever since
00b41463c, it's now suboptimal to do the following:

switch (bms_membership(relids))
{
    case BMS_EMPTY_SET:
       /* handle empty set */
       break;
    case BMS_SINGLETON:
        /* call bms_singleton_member() and handle singleton set */
        break;
    case BMS_MULTIPLE:
       /* handle multi-member set */
       break;
}

The following is cheaper as we don't need to call bms_membership() and
bms_singleton_member() for singleton sets. It also saves function call
overhead for empty sets.

if (relids == NULL)
       /* handle empty set */
else
{
    int relid;

    if (bms_get_singleton(relids, &relid))
        /* handle singleton set */
   else
       /* handle multi-member set */
}

In the attached, I've adjusted the code to use the latter of the two
above methods in 3 places.  In examine_variable() this reduces the
complexity of the logic quite a bit and saves calling bms_is_member()
in addition to bms_singleton_member().

I'm trying to reduce the footprint of what's being worked on in [1]
and I highlighted this as something that'll help with that.

Any objections to me pushing the attached?

David

[1] 
https://postgr.es/m/caaphdvqhcnkji9crqzg-reqdxtfrwnt5rhzntdqhnrbzaau...@mail.gmail.com
diff --git a/src/backend/optimizer/plan/initsplan.c 
b/src/backend/optimizer/plan/initsplan.c
index b31d892121..83aeca36d6 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -2634,10 +2634,12 @@ distribute_restrictinfo_to_rels(PlannerInfo *root,
        Relids          relids = restrictinfo->required_relids;
        RelOptInfo *rel;
 
-       switch (bms_membership(relids))
+       if (!bms_is_empty(relids))
        {
-               case BMS_SINGLETON:
+               int                     relid;
 
+               if (bms_get_singleton_member(relids, &relid))
+               {
                        /*
                         * There is only one relation participating in the 
clause, so it
                         * is a restriction clause for that relation.
@@ -2650,9 +2652,9 @@ distribute_restrictinfo_to_rels(PlannerInfo *root,
                        /* Update security level info */
                        rel->baserestrict_min_security = 
Min(rel->baserestrict_min_security,
                                                                                
                 restrictinfo->security_level);
-                       break;
-               case BMS_MULTIPLE:
-
+               }
+               else
+               {
                        /*
                         * The clause is a join clause, since there is more 
than one rel
                         * in its relid set.
@@ -2675,15 +2677,15 @@ distribute_restrictinfo_to_rels(PlannerInfo *root,
                         * Add clause to the join lists of all the relevant 
relations.
                         */
                        add_join_clause_to_rels(root, restrictinfo, relids);
-                       break;
-               default:
-
-                       /*
-                        * clause references no rels, and therefore we have no 
place to
-                        * attach it.  Shouldn't get here if callers are 
working properly.
-                        */
-                       elog(ERROR, "cannot cope with variable-free clause");
-                       break;
+               }
+       }
+       else
+       {
+               /*
+                * clause references no rels, and therefore we have no place to 
attach
+                * it.  Shouldn't get here if callers are working properly.
+                */
+               elog(ERROR, "cannot cope with variable-free clause");
        }
 }
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 35c9e3c86f..e11d022827 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -5028,22 +5028,27 @@ examine_variable(PlannerInfo *root, Node *node, int 
varRelid,
 
        onerel = NULL;
 
-       switch (bms_membership(varnos))
+       if (bms_is_empty(varnos))
        {
-               case BMS_EMPTY_SET:
-                       /* No Vars at all ... must be pseudo-constant clause */
-                       break;
-               case BMS_SINGLETON:
-                       if (varRelid == 0 || bms_is_member(varRelid, varnos))
+               /* No Vars at all ... must be pseudo-constant clause */
+       }
+       else
+       {
+               int                     relid;
+
+               if (bms_get_singleton_member(varnos, &relid))
+               {
+                       if (varRelid == 0 || varRelid == relid)
                        {
-                               onerel = find_base_rel(root,
-                                                                          
(varRelid ? varRelid : bms_singleton_member(varnos)));
+                               onerel = find_base_rel(root, relid);
                                vardata->rel = onerel;
                                node = basenode;        /* strip any relabeling 
*/
                        }
                        /* else treat it as a constant */
-                       break;
-               case BMS_MULTIPLE:
+               }
+               else
+               {
+                       /* varnos has multiple relids */
                        if (varRelid == 0)
                        {
                                /* treat it as a variable of a join relation */
@@ -5058,7 +5063,7 @@ examine_variable(PlannerInfo *root, Node *node, int 
varRelid,
                                /* note: no point in expressional-index search 
here */
                        }
                        /* else treat it as a constant */
-                       break;
+               }
        }
 
        bms_free(varnos);
@@ -6381,17 +6386,14 @@ find_join_input_rel(PlannerInfo *root, Relids relids)
 {
        RelOptInfo *rel = NULL;
 
-       switch (bms_membership(relids))
+       if (!bms_is_empty(relids))
        {
-               case BMS_EMPTY_SET:
-                       /* should not happen */
-                       break;
-               case BMS_SINGLETON:
-                       rel = find_base_rel(root, bms_singleton_member(relids));
-                       break;
-               case BMS_MULTIPLE:
+               int                     relid;
+
+               if (bms_get_singleton_member(relids, &relid))
+                       rel = find_base_rel(root, relid);
+               else
                        rel = find_join_rel(root, relids);
-                       break;
        }
 
        if (rel == NULL)

Reply via email to