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;
 
 	/*

Reply via email to