Remove local optimizations of empty Bitmapsets into null pointers.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 2 Mar 2023 17:01:47 +0000 (12:01 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 2 Mar 2023 17:01:47 +0000 (12:01 -0500)
These are all dead code now that it's done centrally.

Patch by me; thanks to Nathan Bossart and Richard Guo for review.

Discussion: https://postgr.es/m/1159933.1677621588@sss.pgh.pa.us

src/backend/executor/execUtils.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/util/pathnode.c
src/backend/optimizer/util/placeholder.c
src/backend/optimizer/util/relnode.c
src/backend/rewrite/rewriteManip.c
src/pl/plpgsql/src/pl_exec.c

index c33a3c0bec7b2c08efa25b600a43d13f39672c06..cfa95a07e40f82f6a508e3d091aae6b09d35347e 100644 (file)
@@ -877,15 +877,7 @@ UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
         * include anything else into its chgParam set.
         */
        parmset = bms_intersect(node->plan->allParam, newchg);
-
-       /*
-        * Keep node->chgParam == NULL if there's not actually any members; this
-        * allows the simplest possible tests in executor node files.
-        */
-       if (!bms_is_empty(parmset))
-               node->chgParam = bms_join(node->chgParam, parmset);
-       else
-               bms_free(parmset);
+       node->chgParam = bms_join(node->chgParam, parmset);
 }
 
 /*
index 011a0337dade5ca530c9edc6a218ef8c4addc8b2..9f4698f2a2807d0130235b462dce0b41d005e47c 100644 (file)
@@ -949,9 +949,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
 
        /* We do not want the index's rel itself listed in outer_relids */
        outer_relids = bms_del_member(outer_relids, rel->relid);
-       /* Enforce convention that outer_relids is exactly NULL if empty */
-       if (bms_is_empty(outer_relids))
-               outer_relids = NULL;
 
        /* Compute loop_count for cost estimation purposes */
        loop_count = get_loop_count(root, rel->relid, outer_relids);
index 174c326cb940d33c237c9eda315db7e6f7440fc4..c6c21a73386cc694a52b5a26bb8b7c3db2905164 100644 (file)
@@ -679,16 +679,10 @@ create_lateral_join_info(PlannerInfo *root)
 
                /* Nothing to do at rels with no lateral refs */
                lateral_relids = brel->lateral_relids;
-               if (lateral_relids == NULL)
+               if (bms_is_empty(lateral_relids))
                        continue;
 
-               /*
-                * We should not have broken the invariant that lateral_relids is
-                * exactly NULL if empty.
-                */
-               Assert(!bms_is_empty(lateral_relids));
-
-               /* Also, no rel should have a lateral dependency on itself */
+               /* No rel should have a lateral dependency on itself */
                Assert(!bms_is_member(rti, lateral_relids));
 
                /* Mark this rel's referencees */
index 22ffe4ca425af29d4afa9f404acdf9e5b7407a3c..052263aea6da7952d588e95d90e52fd0a1a9c91f 100644 (file)
@@ -2825,15 +2825,6 @@ finalize_plan(PlannerInfo *root, Plan *plan,
        /* but not any initplan setParams */
        plan->extParam = bms_del_members(plan->extParam, initSetParam);
 
-       /*
-        * For speed at execution time, make sure extParam/allParam are actually
-        * NULL if they are empty sets.
-        */
-       if (bms_is_empty(plan->extParam))
-               plan->extParam = NULL;
-       if (bms_is_empty(plan->allParam))
-               plan->allParam = NULL;
-
        return plan->allParam;
 }
 
index d749b5057853a9a09f160fa81aa384e5efcdeb2a..e8e06397a9c00888c5d225b75688ca6bae4c01d3 100644 (file)
@@ -2372,12 +2372,6 @@ calc_nestloop_required_outer(Relids outerrelids,
        /* ... and remove any mention of now-satisfied outer rels */
        required_outer = bms_del_members(required_outer,
                                                                         outerrelids);
-       /* maintain invariant that required_outer is exactly NULL if empty */
-       if (bms_is_empty(required_outer))
-       {
-               bms_free(required_outer);
-               required_outer = NULL;
-       }
        return required_outer;
 }
 
index 9c6cb5eba7dfdb095fbf47e4f05cc3d1a1b46ce8..b1723578e6f9dbcc772f47c81f1775c735f329a1 100644 (file)
@@ -125,8 +125,6 @@ find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
         */
        rels_used = pull_varnos(root, (Node *) phv->phexpr);
        phinfo->ph_lateral = bms_difference(rels_used, phv->phrels);
-       if (bms_is_empty(phinfo->ph_lateral))
-               phinfo->ph_lateral = NULL;      /* make it exactly NULL if empty */
        phinfo->ph_eval_at = bms_int_members(rels_used, phv->phrels);
        /* If no contained vars, force evaluation at syntactic location */
        if (bms_is_empty(phinfo->ph_eval_at))
index 9ad44a0508cc6e7fa9c03d01eca0e1827bd7e3a1..68fd03359522394169e8f254fbc52f482ded8f75 100644 (file)
@@ -772,8 +772,6 @@ build_join_rel(PlannerInfo *root,
         */
        joinrel->direct_lateral_relids =
                bms_del_members(joinrel->direct_lateral_relids, joinrel->relids);
-       if (bms_is_empty(joinrel->direct_lateral_relids))
-               joinrel->direct_lateral_relids = NULL;
 
        /*
         * Construct restrict and join clause lists for the new joinrel. (The
@@ -1024,11 +1022,6 @@ min_join_parameterization(PlannerInfo *root,
         */
        result = bms_union(outer_rel->lateral_relids, inner_rel->lateral_relids);
        result = bms_del_members(result, joinrelids);
-
-       /* Maintain invariant that result is exactly NULL if empty */
-       if (bms_is_empty(result))
-               result = NULL;
-
        return result;
 }
 
index 04718f66c0bc1810d9f94750f7020091ff0b8544..d28d0da62140ed56c3ad7dd78a6c51978f8a513e 100644 (file)
@@ -1247,16 +1247,11 @@ remove_nulling_relids_mutator(Node *node,
                        !bms_is_member(var->varno, context->except_relids) &&
                        bms_overlap(var->varnullingrels, context->removable_relids))
                {
-                       Relids          newnullingrels = bms_difference(var->varnullingrels,
-                                                                                                               context->removable_relids);
-
-                       /* Micro-optimization: ensure nullingrels is NULL if empty */
-                       if (bms_is_empty(newnullingrels))
-                               newnullingrels = NULL;
                        /* Copy the Var ... */
                        var = copyObject(var);
                        /* ... and replace the copy's varnullingrels field */
-                       var->varnullingrels = newnullingrels;
+                       var->varnullingrels = bms_difference(var->varnullingrels,
+                                                                                                context->removable_relids);
                        return (Node *) var;
                }
                /* Otherwise fall through to copy the Var normally */
@@ -1268,26 +1263,20 @@ remove_nulling_relids_mutator(Node *node,
                if (phv->phlevelsup == context->sublevels_up &&
                        !bms_overlap(phv->phrels, context->except_relids))
                {
-                       Relids          newnullingrels = bms_difference(phv->phnullingrels,
-                                                                                                               context->removable_relids);
-
                        /*
-                        * Micro-optimization: ensure nullingrels is NULL if empty.
-                        *
                         * Note: it might seem desirable to remove the PHV altogether if
                         * phnullingrels goes to empty.  Currently we dare not do that
                         * because we use PHVs in some cases to enforce separate identity
                         * of subexpressions; see wrap_non_vars usages in prepjointree.c.
                         */
-                       if (bms_is_empty(newnullingrels))
-                               newnullingrels = NULL;
                        /* Copy the PlaceHolderVar and mutate what's below ... */
                        phv = (PlaceHolderVar *)
                                expression_tree_mutator(node,
                                                                                remove_nulling_relids_mutator,
                                                                                (void *) context);
                        /* ... and replace the copy's phnullingrels field */
-                       phv->phnullingrels = newnullingrels;
+                       phv->phnullingrels = bms_difference(phv->phnullingrels,
+                                                                                               context->removable_relids);
                        /* We must also update phrels, if it contains a removable RTI */
                        phv->phrels = bms_difference(phv->phrels,
                                                                                 context->removable_relids);
index ffd6d2e3bc3b46de0cfa7929d58b503e27789ce3..b0a2cac2276e21cadbc33ea2a7191354ac42404e 100644 (file)
@@ -6240,12 +6240,9 @@ setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr)
        Assert(expr->plan != NULL);
 
        /*
-        * We only need a ParamListInfo if the expression has parameters.  In
-        * principle we should test with bms_is_empty(), but we use a not-null
-        * test because it's faster.  In current usage bits are never removed from
-        * expr->paramnos, only added, so this test is correct anyway.
+        * We only need a ParamListInfo if the expression has parameters.
         */
-       if (expr->paramnos)
+       if (!bms_is_empty(expr->paramnos))
        {
                /* Use the common ParamListInfo */
                paramLI = estate->paramLI;