On 14/10/2026 17:29, Zsolt Parragi wrote:
> What is missing is the relispopulated boolean from pg_class, and I
> don't see how that could stay with this approach.
Right.
> pg_class.relispopulated could only stay if we could update it after
> recovery, but before accepting connections (as otherwise it could
> become stale for unlogged matviews), and I don't see an easy way to do
> that, that's why I implemented this patch in a different way.
> Otherwise, it could become stale, that's why the patch removes it.
>
> But looking at pgadmin, it would be easy to patch it in a way that
> works with both all earlier versions and this patch.
Right. I'm pretty sure things like this already happened in past
releases, I just thought I should bring it up in case it is avoidable --
pgAdmin certainly isn't the only tool relying on it.
I took another look and the only thing that caught my attention some
error messages:
/*
* An unlogged matview has no storage on a standby, though its
* relpopulated may still carry an epoch stamp from the primary. The
* generic recovery guard just below would reject it too, but reporting it
* as unpopulated matches what the same matview does on the primary once a
* crash has invalidated its stamp. Permanent matviews are excluded so
* plan-time behavior is unchanged. No REFRESH hint, as that cannot run
* during recovery.
*/
if (relation->rd_rel->relkind == RELKIND_MATVIEW &&
!RelationIsPermanent(relation) &&
RecoveryInProgress() &&
!RelationIsPopulated(relation))
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("materialized view \"%s\" has not been populated",
RelationGetRelationName(relation))));
I realise it is a matter of taste, but I find the generic error message
more accurate than this new one.
-- from a standby.
-- umv1 is an unlogged matview, and ut1 is an unlogged table
postgres=# select * from umv1;
ERROR: materialized view "umv1" has not been populated
postgres=# select * from ut1;
ERROR: cannot access temporary or unlogged relations during recovery
The hint in copy is not very accurate during a recovery session.
postgres=# copy umv1 to stdout;
ERROR: cannot copy from unpopulated materialized view "umv1"
HINT: Use the REFRESH MATERIALIZED VIEW command.
Other than that, I don't have anything else to add at this point. Thanks
for the patch.
BTW, while testing it I may have found a bug in unlogged tables with copy:
postgres=# copy ut1 to stdout;
ERROR: could not open file "base/5/16420": No such file or directory
.. but I will report it in another thread.
Jim