Convert nullingrels match checks from Asserts to test-and-elog.
authorTom Lane <[email protected]>
Wed, 17 May 2023 14:50:35 +0000 (10:50 -0400)
committerTom Lane <[email protected]>
Wed, 17 May 2023 15:14:04 +0000 (11:14 -0400)
It seems like the code that these checks are backstopping may have
a few bugs left in it.  Use a test-and-elog so that the tests are
performed even in non-assert builds, and so that we get something
more informative than "server closed the connection" on failure.

Committed separately with the idea that eventually we'll revert
this.  It might be awhile though.

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

src/backend/optimizer/plan/setrefs.c

index f6f8a79354c5013174cbee1b1ef7781535168503..a154c71a480bb1f68b3a2b964181268d45515627 100644 (file)
@@ -2786,7 +2786,7 @@ search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
                        Var                *newvar = copyVar(var);
 
                        /*
-                        * Assert that we kept all the nullingrels machinations straight.
+                        * Verify that we kept all the nullingrels machinations straight.
                         *
                         * XXX we skip the check for system columns and whole-row Vars.
                         * That's because such Vars might be row identity Vars, which are
@@ -2799,12 +2799,16 @@ search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
                         * columns, it seems unlikely that a bug in nullingrels logic
                         * would affect only system columns.)
                         */
-                       Assert(varattno <= 0 ||
-                                  (nrm_match == NRM_SUBSET ?
-                                       bms_is_subset(var->varnullingrels, vinfo->varnullingrels) :
-                                       nrm_match == NRM_SUPERSET ?
-                                       bms_is_subset(vinfo->varnullingrels, var->varnullingrels) :
-                                       bms_equal(vinfo->varnullingrels, var->varnullingrels)));
+                       if (!(varattno <= 0 ||
+                                 (nrm_match == NRM_SUBSET ?
+                                  bms_is_subset(var->varnullingrels, vinfo->varnullingrels) :
+                                  nrm_match == NRM_SUPERSET ?
+                                  bms_is_subset(vinfo->varnullingrels, var->varnullingrels) :
+                                  bms_equal(vinfo->varnullingrels, var->varnullingrels))))
+                               elog(ERROR, "wrong varnullingrels %s (expected %s) for Var %d/%d",
+                                        bmsToString(var->varnullingrels),
+                                        bmsToString(vinfo->varnullingrels),
+                                        varno, varattno);
 
                        newvar->varno = newvarno;
                        newvar->varattno = vinfo->resno;
@@ -2851,12 +2855,16 @@ search_indexed_tlist_for_phv(PlaceHolderVar *phv,
                        if (phv->phid != subphv->phid)
                                continue;
 
-                       /* Assert that we kept all the nullingrels machinations straight */
-                       Assert(nrm_match == NRM_SUBSET ?
-                                  bms_is_subset(phv->phnullingrels, subphv->phnullingrels) :
-                                  nrm_match == NRM_SUPERSET ?
-                                  bms_is_subset(subphv->phnullingrels, phv->phnullingrels) :
-                                  bms_equal(subphv->phnullingrels, phv->phnullingrels));
+                       /* Verify that we kept all the nullingrels machinations straight */
+                       if (!(nrm_match == NRM_SUBSET ?
+                                 bms_is_subset(phv->phnullingrels, subphv->phnullingrels) :
+                                 nrm_match == NRM_SUPERSET ?
+                                 bms_is_subset(subphv->phnullingrels, phv->phnullingrels) :
+                                 bms_equal(subphv->phnullingrels, phv->phnullingrels)))
+                               elog(ERROR, "wrong phnullingrels %s (expected %s) for PlaceHolderVar %d",
+                                        bmsToString(phv->phnullingrels),
+                                        bmsToString(subphv->phnullingrels),
+                                        phv->phid);
 
                        /* Found a matching subplan output expression */
                        newvar = makeVarFromTargetEntry(newvarno, tle);