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