Reject non-ON-SELECT rules that are named "_RETURN".
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 17 Oct 2022 16:14:39 +0000 (12:14 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 17 Oct 2022 16:14:39 +0000 (12:14 -0400)
DefineQueryRewrite() has long required that ON SELECT rules be named
"_RETURN".  But we overlooked the converse case: we should forbid
non-ON-SELECT rules that are named "_RETURN".  In particular this
prevents using CREATE OR REPLACE RULE to overwrite a view's _RETURN
rule with some other kind of rule, thereby breaking the view.

Per bug #17646 from Kui Liu.  Back-patch to all supported branches.

Discussion: https://postgr.es/m/17646-70c93cfa40365776@postgresql.org

src/backend/rewrite/rewriteDefine.c

index 213eabfbb9f610ed69dbb5bc0b1a83197da708d2..09165b269b30a97e4473485357a4864a0364357f 100644 (file)
@@ -530,6 +530,18 @@ DefineQueryRewrite(const char *rulename,
                                RelationGetDescr(event_relation),
                                false, false);
        }
+
+       /*
+        * And finally, if it's not an ON SELECT rule then it must *not* be
+        * named _RETURN.  This prevents accidentally or maliciously replacing
+        * a view's ON SELECT rule with some other kind of rule.
+        */
+       if (strcmp(rulename, ViewSelectRuleName) == 0)
+           ereport(ERROR,
+                   (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                    errmsg("non-view rule for \"%s\" must not be named \"%s\"",
+                           RelationGetRelationName(event_relation),
+                           ViewSelectRuleName)));
    }
 
    /*