Bogus rte->relkind for EXCLUDED pseudo-relation - Mailing list pgsql-hackers

From Tom Lane
Subject Bogus rte->relkind for EXCLUDED pseudo-relation
Date
Msg-id 1999471.1670002476@sss.pgh.pa.us
Whole thread Raw
Responses Re: Bogus rte->relkind for EXCLUDED pseudo-relation  (Andres Freund <andres@anarazel.de>)
List pgsql-hackers
In the wake of b23cd185f (pushed just now), I tried adding Asserts
to rewriteHandler.c that relkinds in RTEs don't change, as attached.
This blew up the regression tests immediately.  On investigation,
I find that

(1) ON CONFLICT's EXCLUDED pseudo-relation is assigned
    rte->relkind = RELKIND_COMPOSITE, a rather horrid hack
    installed by commit ad2278379.

(2) If a stored rule involves ON CONFLICT, then while loading
    the rule AcquireRewriteLocks overwrites that with the actual
    relkind, ie RELKIND_RELATION.  Or it did without the
    attached Assert, anyway.

It appears to me that this means whatever safeguards are created
by the use of RELKIND_COMPOSITE will fail to apply in a rule.
Maybe that's okay because the relevant behaviors only occur at
parse time not rewrite/planning/execution, but even to write that
is to doubt how reliable and future-proof the assumption is.

I'm inclined to think we'd be well advised to undo that aspect of
ad2278379 and solve it some other way.  Maybe a new RTEKind would
be a better idea.  Alternatively, we could drop rewriteHandler.c's
attempts to update relkind.  Theoretically that's safe now, but
I hadn't quite wanted to just pull that trigger right away ...

            regards, tom lane

diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index fb0c687bd8..49e0f54355 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -193,6 +193,7 @@ AcquireRewriteLocks(Query *parsetree,
                  * While we have the relation open, update the RTE's relkind,
                  * just in case it changed since this rule was made.
                  */
+                Assert(rte->relkind == rel->rd_rel->relkind);
                 rte->relkind = rel->rd_rel->relkind;

                 table_close(rel, NoLock);
@@ -3223,6 +3224,7 @@ rewriteTargetView(Query *parsetree, Relation view)
      * While we have the relation open, update the RTE's relkind, just in case
      * it changed since this view was made (cf. AcquireRewriteLocks).
      */
+    Assert(base_rte->relkind == base_rel->rd_rel->relkind);
     base_rte->relkind = base_rel->rd_rel->relkind;

     /*

pgsql-hackers by date:

Previous
From: Andres Freund
Date:
Subject: Re: refactor ExecGrant_*() functions
Next
From: Tom Lane
Date:
Subject: Re: pg_dump: Remove "blob" terminology