Re-allow INDEX_VAR as rt_index in ChangeVarNodes().
authorTom Lane <[email protected]>
Thu, 8 Jun 2023 17:11:49 +0000 (13:11 -0400)
committerTom Lane <[email protected]>
Thu, 8 Jun 2023 17:11:49 +0000 (13:11 -0400)
Apparently some extensions are in the habit of calling
ChangeVarNodes() with INDEX_VAR as the rt_index to replace.
That worked before 2489d76c4, at least as long as there were
not PlaceHolderVars in the expression; but now it fails
because bms_is_member spits up.  Add a test to avoid that.

Per report from Anton Melnikov, though this is not his
proposed patch.

Discussion: https://postgr.es/m/5b370a46-f6d2-373d-9dbc-0d55250e82c1@inbox.ru

src/backend/rewrite/rewriteManip.c

index 52b3f77078d1f98933fe2f92d085d4518e5a143e..32bd2f1dc99f23c7d6660e800e9ce8a1f45dd032 100644 (file)
@@ -719,11 +719,16 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
 
 /*
  * Substitute newrelid for oldrelid in a Relid set
+ *
+ * Note: some extensions may pass a special varno such as INDEX_VAR for
+ * oldrelid.  bms_is_member won't like that, but we should tolerate it.
+ * (Perhaps newrelid could also be a special varno, but there had better
+ * not be a reason to inject that into a nullingrels or phrels set.)
  */
 static Relids
 adjust_relid_set(Relids relids, int oldrelid, int newrelid)
 {
-       if (bms_is_member(oldrelid, relids))
+       if (!IS_SPECIAL_VARNO(oldrelid) && bms_is_member(oldrelid, relids))
        {
                /* Ensure we have a modifiable copy */
                relids = bms_copy(relids);