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)