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